8 ms·
> But IF is a special form, built into the language. It doesn't have to be built into the language; it could be a macro based on COND or even on WHEN/UNLESS. B
by zeveb 11y ago
> But IF is a special form, built into the language.
It doesn't have to be built into the language; it could be a macro based on COND or even on WHEN/UNLESS. But…
> A basic set of special forms is needed and can't be implemented as macros.
One has to have some special forms in order to build everything else as macros. And in practice, of course, there can be some big efficiency gains to having lots of special forms vice having only a few and lots of macrology.
- lispm 11y ago> It doesn't have to be built into the language; it could be a macro based on COND or even on WHEN/UNLESS. But… In Common Lisp IF is built in and COND is a macro. One of the conditionals needs to be built-in. http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm#if http://www.lispworks.com/documentation/HyperSpec/Body/s_if.h... > One has to have some special forms in order to build everything else as macros. For conditionals, one conditional needs to be there, into which the other macro-based conditionals can be expanded. > And in practice, of course, there can be some big efficiency gains to having lots of special forms vice having only a few and lots of macrology. Not really. Common Lisp has a minimum of special forms and usually has some of the faster Lisp implementations.
- lisper 11y ago> One of the conditionals needs to be built-in. That's actually not true. IF can be implemented in terms of LAMBDA. (defun _true (then else) then) (defun _false (then else) else) (defmacro _if (condition then else) `(funcall (funcall (function ,condition) (lambda () ,then) (lambda () ,else)))) ? (_if _true (print 123) (print 456)) 123 123 ? (_if _false (print 123) (print 456)) 456 456 ?
- ClashTheBunny 11y agoThere are problems with infinite recursion if you do that, no? http://stackoverflow.com/questions/1171252/whats-the-explanation-for-exercise-1-6-in-sicp http://stackoverflow.com/questions/1171252/whats-the-explana...
- lisper 11y agoNope. That's the reason for wrapping THEN and ELSE inside lambdas, to delay the evaluation until after one of them is selected. Try it. [UPDATE] You have to make some minor tweaks to my original code to make it work. Here's a fully tested version: (defun _true (then else) then) (defun _false (then else) else) (defmacro _if (condition then else) `(funcall (funcall ,condition (lambda () ,then) (lambda () ,else)))) (setf (get t 'altboolean) '_true) (setf (get nil 'altboolean) '_false) (defun ->altboolean (condition) (get condition 'altboolean)) (defun _fact (n) (_if (->altboolean (<= n 1)) 1 (* n (_fact (1- n)))))
- junke 11y agoDoes "fully tested" means it is supposed to work as a replacement of IF in Common Lisp? Or is it just a toy example in a made-up Lisp/Scheme to beat that dead horse? >> In Common Lisp IF is built in and COND is a macro. One of the conditionals needs to be built-in. > That's actually not true. The context was about Common Lisp, not Haskell nor Scheme (of course other languages do things as they wish, including lazy evaluation). There need to be at least one conditional built-in in CL in order to map generalized booleans to {T, NIL}. This conditional could even be eager, but there has to be a construct which selects the approprate value. Which of the other 24 special forms is suitable?
- lisper 11y agoFully tested means that it solves the problem of infinite recursion cited in the stackoverflow question. As implemented, it's not quite a drop-in replacement for IF, but it can be made so by rolling the call to ->ALTBOOLEAN in to the _IF macro. > The context was about Common Lisp Yes, I know that. The example code is written in Common Lisp. > there has to be a construct which selects the approprate value Yes. LAMBDA can do that. > Which of the other 24 special forms is suitable? LAMBDA. It can be used both to select the appropriate value and to delay evaluation. LAMBDA is really all you need. Making IF a special form is just an optimization.
- lispm 11y agoWelcome to the real world. I'm not talking about Lambda Calculus and related. I'm talking about Lisp implementation. Real world Lisp implementation.
- kazinator 11y agoActually, all operators can be macros. Why? Because macros can use some, ahem, special API to generate machine code objects directly. Thus anything that looks like it ought to be a special form can be registered as an actual macro, called by the macro-expander. Instead of producing a tree structure, it produces some code object. The compilation pass knows what to do with that object and so it goes. (We can think of that object as a special form, effectively, but it isn't really a form at all.) (Also note that Lisp macros don't have to be all written in Lisp. They are just expander functions. When you're bootstrapping a Lisp, you can write macros in the bootstrapping language. So the chicken-and-egg problem of "how do you write the first macros if there are no special forms" doesn't exist. You write the raw functions in assembly, or C or whatever, and register them as macro-expanders.)