From: Captain Obvious on
HB> Can I make my own code forms like, for example:

HB> (for i in list do |i|
HB> body
HB> )

HB> or everything is in form of (macro-name arguments) ?
HB> Or here would 'for' be a macro name and everything else an argument ?

Yes. Arguments to a macro are just pieces of code, they can be anything, as
long as reader can read it.



From: Pascal Costanza on
On 16/02/2010 22:11, 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'.

Most tutorials about Lisp explain macros really well. Which ones did you
read so far? Maybe you just need a different tutorial...


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Nicolas Neuss on
Ron Garret <rNOSPAMon(a)flownet.com> writes:

> It's also handy to be able to change the surface syntax.

Recently, I helped a student to program something in C++. There was a
part where in CL one would have nicely used a 'case' form, and I coded
the same thing with 'switch' in C++. Now, my hard times of C coding
lies way back, and I coding rapidly I did not think of terminating each
branch with a break statement (which means that execution falls through
to the next condition and so on).

After we had found this ugly bug -more precisely someone working daily
with C++ saw it immediately- I pointed out that

1. CL (as very often) does the right thing (because in my experience
selecting one of several statements is much more frequently desired).

2. If C/C++ would have a reasonable macro system, people would already
have reprogrammed the 'switch' statement into a 'case' doing the right
thing without break statements.

Nicolas
From: Slobodan Blazeski on
On Feb 16, 10:11 pm, "Haris Bogdanoviæ" <fbogdano...(a)xnet.hr> 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'.

There was a good discussion about it at
http://www.lispforum.com/viewtopic.php?f=2&t=574&sid=b490ca0582705693121add987a930b2b
but the best is advise is go through On Lisp freely available at
http://www.paulgraham.com/onlisptext.html and learn for yourself.

Slobodan
From: Pascal J. Bourguignon on
"Haris Bogdanovi�" <fbogdanovic(a)xnet.hr> writes:

> 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'.


In a sentence, macros are compiler hooks, that is functions that the
compiler will call to compile those forms.

You can see that indeed macros are functions, since you can always write
your macros as functions:

(defun for* (var init step last body)
(let ((vvar (gensym))
(vstep (gensym))
(vlast (gensym)))
`(let ((,vvar ,init)
(,vstep ,step)
(,vlast ,last))
(if (minusp ,vstep)
(tagbody
loop
(if (< ,vvar ,vlast) (go end))
(let ((,var ,vvar)) ,@body)
(incf ,vvar ,vstep)
(go loop)
end)
(tagbody
loop
(if (> ,vvar ,vlast) (go end))
(let ((,var ,vvar)) ,@body)
(incf ,vvar ,vstep)
(go loop)
end)))))



C/USER[26]> (for* 'i '1 '1 '(* n 2) '((print i) (print (sin i))))
(LET ((#1=#:G99188 1) (#2=#:G99189 1) (#3=#:G99190 (* N 2)))
(IF (MINUSP #2#)
(TAGBODY LOOP (IF (< #1# #3#) (GO END))
(LET ((I #1#)) . #4=((PRINT I) (PRINT (SIN I)))) (INCF #1# #2#) (GO LOOP)
END)
(TAGBODY LOOP (IF (> #1# #3#) (GO END)) (LET ((I #1#)) . #4#) (INCF #1# #2#)
(GO LOOP) END)))



Then you can 'hook' this function into the compiler, so that it is used
by the compiler to compile (for i 1 1 (* n 2) (print i) (print (sin
i))):

(defmacro for (var init step last &body body)
(for* var init step last body))


C/USER[28]> (let ((n 2)) (for i 1 1 (* n 2) (print i) (print (sin i))))

1
0.84147096
2
0.9092974
3
0.14112
4
-0.7568025
NIL
C/USER[29]>


Code is data because when you write:

(let ((n 2)) (for i 1 1 (* n 2) (print i) (print (sin i))))

This is the very data that you typed, the codes:

i 1 1 (* n 2) (print i) (print (sin i))

that are passed to the macro function for, and the function for*.
And this is the very same data returned by the function for* and the
macro function foo:

(LET ((#1=#:G99188 1) (#2=#:G99189 1) (#3=#:G99190 (* N 2)))
(IF (MINUSP #2#)
(TAGBODY LOOP (IF (< #1# #3#) (GO END))
(LET ((I #1#)) . #4=((PRINT I) (PRINT (SIN I)))) (INCF #1# #2#) (GO LOOP)
END)
(TAGBODY LOOP (IF (> #1# #3#) (GO END)) (LET ((I #1#)) . #4#) (INCF #1# #2#)
(GO LOOP) END)))

that is used as code by the compiler, to be generated instead of (for
....) which lisp didn't know how to compile before you told it with the
for macro ("compiler hook").


--
__Pascal Bourguignon__
http://www.informatimago.com