From: Pascal J. Bourguignon on
"Captain Obvious" <udodenko(a)users.sourceforge.net> writes:

> HB> I don't get the difference between defun and defmacro ?
>
> Do you get a difference between declarative sentence and interrogative
> sentence?

Syntax of natural languages is rather complex, and IMO uninformative
(almost anything can go).

In the HB> sentence, there's obviously a very big ellipse:

I don't get the difference between defun and defmacro _ ?

should be parsed as:

I don't get the difference between defun and defmacro ; what is the
difference between defun and defmacro ?

;-)

--
__Pascal Bourguignon__
http://www.informatimago.com
From: Alberto Riva on
Haris Bogdanovi� wrote:
> I don't get the difference between defun and defmacro ?
>
> If code is data and data is code then macros are functions and functions are
> macros
> and everything is everything and then comes Monty Python's foot on top of
> that.
>
> I don't get what's about that 'get it' in lisp ?
> That code and data can be and is represented as a tree ?
> Not much of a 'get it'.

On a more practical level, macros are great for "hiding away" complexity
in your code, leading to programs that are more reliable and easier to
maintain. The first example that comes to mind is the WITH-OPEN-FILE
macro. The form:

(with-open-file (in "filename.txt")
(read-something-from in))

expands into:

(LET ((IN (OPEN "filename.txt")) (#:G1973 T))
(UNWIND-PROTECT
(MULTIPLE-VALUE-PROG1 (PROGN (READ-SOMETHING-FROM IN))
(SETQ #:G1973 NIL))
(WHEN (STREAMP IN) (CLOSE IN :ABORT #:G1973))))

This expansion takes care of: a) opening the file, possibly passing the
appropriate options to OPEN; b) assigning the resulting stream to a
local variable; c) executing the body (the forms inside the
WITH-OPEN-FILE call); d) closing the stream correctly at the end, *even
if* the forms produced an error; e) return the value produced by the
body in case of successful termination.

This is the correct sequence of operations to perform when working with
a file. Languages that don't have macros force you to always write
everything explicitly, which means a lot of manual effort to write code
that is always the same (or more likely, that most of the times you'll
forget some part of it, or just decide it's not important enough). A
Lisp macro hides all this away, and if one day you decide that you need
to change something in what your macro performs, you can just change its
definition in one place, recompile, and you're done.

Note that it would not be possible to do this with a function, because
the forms to execute are arbitrary, and you would have to wrap them in
some kind of object that you could pass to the function, and some
languages allow you to do something like that, some don't, but in all
cases you would get in trouble if the forms use local variables (as they
usually do), you would have to know which variables to capture and
create a closure, ie a big mess. *And* all this would have to be taken
care of at runtime, with a performance cost, while a CL macro is
expanded at compilation time...

Alberto
From: Michael Gardner on
On Feb 17, 2010, at 10:16 AM, Alberto Riva wrote:

> Note that it would not be possible to do this with a function, because the forms to execute are arbitrary, and you would have to wrap them in some kind of object that you could pass to the function, and some languages allow you to do something like that, some don't, but in all cases you would get in trouble if the forms use local variables (as they usually do), you would have to know which variables to capture and create a closure, ie a big mess. *And* all this would have to be taken care of at runtime, with a performance cost, while a CL macro is expanded at compilation time...

Let's not get carried away. Quite a few modern languages support lambdas and closures, which make this relatively easy (though still not as easy as CL macros, and at least in Python's case its support for lambdas is pretty anemic). Or are you saying that even with lambdas and closures, it's still a "big mess"?

-Michael
From: Alberto Riva on
Michael Gardner wrote:
> On Feb 17, 2010, at 10:16 AM, Alberto Riva wrote:
>
>> Note that it would not be possible to do this with a function,
>> because the forms to execute are arbitrary, and you would have to
>> wrap them in some kind of object that you could pass to the
>> function, and some languages allow you to do something like that,
>> some don't, but in all cases you would get in trouble if the forms
>> use local variables (as they usually do), you would have to know
>> which variables to capture and create a closure, ie a big mess.
>> *And* all this would have to be taken care of at runtime, with a
>> performance cost, while a CL macro is expanded at compilation
>> time...
>
> Let's not get carried away. Quite a few modern languages support
> lambdas and closures, which make this relatively easy (though still
> not as easy as CL macros, and at least in Python's case its support
> for lambdas is pretty anemic). Or are you saying that even with
> lambdas and closures, it's still a "big mess"?

Yes, I would still claim it is. Maybe not a terribly big mess, but not
trivial either, definitely much harder than wrapping a WITH-OPEN-FILE
around your code and forgetting about it... especially for beginners.

Alberto


From: Haris Bogdanovic on
That's what I meant at first place.
It's great because you can make your language that makes sense, not just a
bunch of commands, so when you look at the code few days later you know what
part does what, don't have to have a headache figuring that out.
So I agree, it's great for maintenance and making large programs.