3 ms·
I think they've been done and abandoned. You might want to dig some history to see why (I don't have references handy. Maybe asking comp.lang.lisp would help)
by shiro 19y ago
I think they've been done and abandoned. You might want to dig some history to see why (I don't have references handy. Maybe asking comp.lang.lisp would help).
(1) Let's separate implementation and semantics issues. In semantics level, list as a datatype is defined recursively:
List a = () | (a, List a)
This definition maps well to recursive algorithms.
It also maps well to the implementation that uses cons cell, but as you say, it's not the only way to implement it. There was a technique called CDR-coding, which represents a list as if it's a vector (e.g. cell's CDR doesn't contain a pointer but it overlaps the next cell's CAR); specially tagged pointer distinguished normal cells and CDR-coded cells. I guess it was abandoned since deailng with set-cdr! would be very messy. But if you're creating a new dialect, you can go for big change like dropping set-cdr! (some of Scheme people even talking about dropping mutable cells.) In today's computer where access locality means a lot, maybe you can shed a new light to this old technique.
(2) I think the current state of macro was the result of simplification. IIRC, the old lisp dialects allow to pass around syntactic values (FSUBRs) as if it's first class, but it's easily messes up the semantics. It's conceptually simpler to restrict macros as curretly they are. If passing macro around is allowed, you'll never know how (+ 1 2) in the following function is evaluated until runtime:
(defun call-it (x) (funcall x (+ 1 2)))
It may be evaluated as a normal expr, or in a completely different way, depending on whether x is a macro or not. Or are you suggesting that, in this case, (+ 1 2) is evaluated immediately because funcall is not a macro? It is a possible strategy, but then it clipples the expressive power, since it can't represent the same thing as:
(defmacro call-it (x) `(,x (+ 1 2)))
But there are still people who wants to unify macros and functions. Search comp.lang.lisp and comp.lang.scheme---I've seen some discussions there. Also search "first class macros"; there are some papers.
Another way to eliminate (most) need of macros is to adopt normal order evaluation. I've seen some Lisp dialects using lazy evaluation by default. Beware that it changes the programming style a lot, though.
- ced 19y agoThanks a lot for the comments. You seem to know much more about these things than I do, so I don't have much to add. 2. call-it: What's the problem with not knowing (+ 1 2) until run-time? Efficiency? Then I would argue that expressive power of the core language ought to take precedence. In an actual implementation, funcall could leave (+ 1 2) to be evaluated (or not) inside the function body. I would add funcall-normal-function to the language, which would amount to a funcall + (declare (normal-function f)). Both for documentation and for efficiency. Of course, not knowing if (funcall x (print 2)) will print 2 is unsettling in a way, but that's the same basic argument that's made against macros. They disrupt the evaluation order. I read about normal-order before, but it didn't make much practical sense. I'll Google your pointers and look it up.
- shiro 19y ago> call-it: What's the problem with not knowing (+ 1 2) until run-time? Not only efficiency. You don't even know if (+ 1 2) means "1 plus 2" or "choose 1 or 2 randomly" or "generate a sequence of numbers between 1 and 2" until you know what x really is (assuming funcall does delay evaluation of its arguments and passes the original form in case x is indeed a macro). The macro version of call-it has the same problem, of course, but if you embrace first-class macros in the above way, every higher order function call will have the problem. Considering how often HOF is used, the impact is huge. However, as you suggested, you can have two versions of funcalls, one of which evaluates args no matter what x is; then this problem will be solved. (Or you can use hygienic macros, then you can deduce what '+' means purely from its lexical context, at least.)
- ced 19y ago> Considering how often HOF is used, the impact is huge. Well, yes, that would be the point :) I think I understand what you mean, but I don't see how this is more dangerous/worrying than what is already there. Ok, so (funcall fn (+ 1 2)) may or may not evaluate (+ 1 2). But call-it is already willing to give total control to fn. Will fn call a continuation and never return? Launch nuclear weapons? Giving it additional control over the evaluation of the arguments seems innocent enough.