There cannot be an implicit progn for both! Because we don't know where one ends and the other begins.
That is, unless we introduce a signal, like an else keyword/label which separates them, like this:
(if cond form form form
else form form form)
Such macros have existed. A certain John Foderaro of Franz, Inc. was (is?) known for favoring and promoting his if{star} macro. (Of course I mean asterisk by {star} which HN won't let me type).
Info here:
http://franz.com/~jkf/coding_standards.html
http://franz.com/support/documentation/6.0/doc/operators/exc...
Your idea is certainly doable:
(my-if cond
(then-form then-form ...)
(else-form else-form ...))
The macro is trivial:
(defmacro my-if (cond then-forms &optional else-forms)
`(if ,cond
(progn ,@then-forms)
(progn ,@else-forms)))
I've always resisted writing this macro because I felt it has a slight readability issue:
(my-if (some condition)
((consequent)
(consequent2)
(consequent3))
((alternative) ;; relatively quiet signal here
(alternative)))
Maybe it's not that bad, after all. Still, it's just saving a few keystrokes to insert progn and doesn't buy much over cond, which is more general, allowing multiple conditions:
(cond
((some condition)
(consequent)
(consequent2)
(consequent3))
((other condition)
(other)
(other2))
(t (alternative)
(alternative)))
NOTE: cond existed in Lisp first, as a special form. The if macro came later as a syntactic sugar for simple situations involving just one condition!
The thing is that if you keep most of your code functional, a lot of this is moot. We need multiple statements when we are doing something imperative. There is never any reason to have (progn S1 S2) unless S1 has a side effect. If S1 has no side effect, then this is equivalent to (progn S2), which is just S2. If you avoid side effects, the you don't need any progn most of the time (implicit or not).
This is why progn is called what it is; it's Lisp's feature for writing a "program" (in the sense of an imperative list of things to do). Well, "prog" is that feature; and "progn" is the variant which returns the value of the n-th form.
Another mitigation is that lot of the time code binds variables anyway with a let:
(if condition
(let (... vars ...)
this
that)
(let (.... other vars ...)
other))