Unless you use Common Lisp extensions as suggested by @legoscia, you need to check if the optional argument was specified. Note that you don't really need to use let here. This seems more idiomatic to me:
(defun command (a &optional b)
(or b (setq b default))
(command-body a b))
As suggested in the comments, using unless may be preferable to or:
(defun command (a &optional b)
(unless b (setq b default))
(command-body a b))
Also from the comments: the more pure functional style would be to use let, as in the original question, but you don't need separate variable names:
(defun my-command (a &optional b)
(let ((b (or b default)))
(command-body a b)))
Of course, if the optional parameter is only needed once you should just do this:
(defun my-command (a &optional b)
(command-body a (or b default)))
setqin a “pure” boolean form likeor. In my opinionwhenis definitely more appropriate here, but generallyletis the expression of choice to establish or change local bindings. IOW, the original code looks much nicer to me. – Jul 23 '15 at 20:46(unless b (setq b default)might be better. Personally, I thinkletis redundant here becausebis already local to thedefun. – glucas Jul 23 '15 at 20:59letover a side-effecting form likesetq. It's code for a parameter default, but liberal use ofsetqto change local variables makes code hard to read and to follow. I think it's best to consider all local bindings immutable, and only establish new bindings withlet. IOW, prefer a functional style over an imperative one. – Jul 23 '15 at 21:09