Earlier quoted context omitted.
That doesn't matter. One can write IF as a function taking functions as THEN and ELSE forms: CL-USER 9 > (defun my-if (test then else) (if test (funcall then) (funcall else))) MY-IF CL-USER 10 > (let ((a 10)) (my-if (> a 5) (lambda () (print 'hello)) (lambda () (print 'world))) 'done) HELLO DONE The lambdas you see above serve the same purpose as blocks in Smalltalk.
It works, but the syntax isn't nice enough to use as-is, so in practice you need a macro. The innovation here is using better syntax for anonymous functions to make such things practical in languages without macros.
CL-USER 19 > (defun bracket-reader (stream char)
(declare (ignore char))
`(lambda () ,@(read-delimited-list #\] stream t)))
BRACKET-READER
CL-USER 20 > (set-macro-character #\[ #'bracket-reader)
T
CL-USER 21 > (let ((a 10))
(my-if (> a 5)
[(print 'hello)]
[(print 'world)])
'done)
HELLO
DONE
With a bit more effort, we could also parse a parameter list.But Lisp does not go the route of making IF a function, because it typically provides three different types of language expressions and IF then is a special operator:
1) function calls
2) macro forms
3) a small set of special operators, which are implemented as built-in functionality. One of them is a core conditional operator. More complex conditional operators then are implemented as macros, which expand eventually into the core conditional operator. The interpreter and compiler will have to specially recognize and implement these special operators.
See IF: http://clhs.lisp.se/Body/s_if.htm
The usual Lisp view is that
[(print 'hello)]
is no useful improvement over (lambda () (print 'hello))
Some disagree, but most of the time the pattern ( ... )
is preferred in Lisp over ...