Macros
Forum rules
Please respect your teacher's guidelines. Homework is a learning tool. If we just post answers, we aren't actually helping. When you post questions, be sure to show what you have tried or what you don't understand.
Please respect your teacher's guidelines. Homework is a learning tool. If we just post answers, we aren't actually helping. When you post questions, be sure to show what you have tried or what you don't understand.
Macros
Hello everybody ,
can someone help me in macros .
are there any useful books or sites which contains good examples of macros .
Actually , I have some functions about sorted list and binary trees, I have to write the same functions by using macros .
I don`t know how , and my functions are not short (about 9 functions) .
so if there is someone can help me , I will put the code to discuss about it .
Thank you very much .
can someone help me in macros .
are there any useful books or sites which contains good examples of macros .
Actually , I have some functions about sorted list and binary trees, I have to write the same functions by using macros .
I don`t know how , and my functions are not short (about 9 functions) .
so if there is someone can help me , I will put the code to discuss about it .
Thank you very much .
Re: Macros
Which dialect are you using? Scheme and CL have significantly different macro systems...
The following sources describe CL macros.
Practical Common Lisp has a couple introductory chapters
On Lisp has much deeper coverage
The following sources describe CL macros.
Practical Common Lisp has a couple introductory chapters
On Lisp has much deeper coverage
Re: Macros
thanks for your reply , actually my question about common lisp macros
Re: Macros
Well. Common Lisp macroes are easy when the problem is easy.
A little example here:
Now a macro i CL is a function with the source arguments as parameters and the result is what the CL actually evaluates.
It means you would make a macro with the body evaluating to the list structure (+ 10 <whatever you put as num>) like this:
So when you write (add10 (+ 3 5)) add10 is expanded with (+ 3 5) as num and the result is (+ 10 (+ 3 5)).
Being so simple it does not have problems with variable capturing (hygiene), arguments being evaluated more than once and sometimes in the wrong order, but for real life situations those things are what makes CL macros difficult to master. When testing macros you should always try arguments with side effects like (add10 (print 10)) that should print 10 once and evaluate to 20. With more arguments they should print in order once each before returning whatever it should. Use this to see what your macro does and what gets feed to CL:
Have fun 
A little example here:
Code: Select all
;; function
(defun add10 (num)
(+ 10 num))
It means you would make a macro with the body evaluating to the list structure (+ 10 <whatever you put as num>) like this:
Code: Select all
;; old style, but more verbose and less easy to read (when macro is more complex)
(defmacro add10 (num)
(list '+ 10 num))
;; or by using quasiquote
(defmacro add10 (num)
`(+ 10 ,num))
Being so simple it does not have problems with variable capturing (hygiene), arguments being evaluated more than once and sometimes in the wrong order, but for real life situations those things are what makes CL macros difficult to master. When testing macros you should always try arguments with side effects like (add10 (print 10)) that should print 10 once and evaluate to 20. With more arguments they should print in order once each before returning whatever it should. Use this to see what your macro does and what gets feed to CL:
Code: Select all
(macroexpand-1 '(add10 (print 10)))
==> (+ 10 (PRINT 10))

I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p
Currently I'm planning a Scheme compiler :p
Re: Macros
thanks for replying
as I understand ( maybe I understood wrong) that we can replace the function to macro by simple changes in code , is it right?????
for example if I have this function which use to insert in Binary search tree :
(defun BST-insert (B E)
(if (BST-empty-p B)
(make-bin-tree-leaf E)
(BST-nonempty-insert B E)))
how I can make macro instead of this function (with the same internal code ) ?????????
as I understand ( maybe I understood wrong) that we can replace the function to macro by simple changes in code , is it right?????
for example if I have this function which use to insert in Binary search tree :
(defun BST-insert (B E)
(if (BST-empty-p B)
(make-bin-tree-leaf E)
(BST-nonempty-insert B E)))
how I can make macro instead of this function (with the same internal code ) ?????????
Re: Macros
For better understanding
if you have a macro:
you can also have a function with quasiquotation:
The difference is that macros are evaluated in compile-time and get unevaluated arguments. Back to the aforedefined function, the function can be called like this:
or more clearly:
and it returns:
But we give it only data and get data from it too, coincidentally they look like code (on the input side we reached it with quote -- that apostrophe). If we use a macro instead of a function for example:
The compiler invokes the macro function and passes the calling form* to that function (it's nicely parsed, due to the lambda-list in a defmacro form) so we don't quote, it does the compiler.
The macro function returns something which is expected to be code which is processed by the compiler further and afterwards the result of compilation is evaluated during run-time.
The macro can be written with the help of our function:
Maybe will help you the information: in CL beside macros exist reader macros which take part during read-time, the key is to realise differences among run-time, compile-time and read-time. At least for me it was the key, but reader macros are beyond this single post.
Rather try this sample:
After typing defun form (insert the code into REPL line by line) it will hang because of read so type some lisp form which evaluates to number and try the new defined function; it won't hang because there is no read in that function.
*Compare function lambda-list and macro one (for example &whole keyword).
if you have a macro:
Code: Select all
(defmacro add10-m (num)
`(+ 10 ,num))
Code: Select all
(defun add10-f (num)
`(+ 10 ,num))
Code: Select all
(add10-f '(+ 1 2))
Code: Select all
(add10-f (list '+ 1 2))
Code: Select all
(+ 10 (+ 1 2))
Code: Select all
(add10-m (+ 1 2))
The macro function returns something which is expected to be code which is processed by the compiler further and afterwards the result of compilation is evaluated during run-time.
The macro can be written with the help of our function:
Code: Select all
(defmacro add10-m (num)
(add10-f num))
Rather try this sample:
Code: Select all
(defmacro some-value () (read))
(defun add (num) (+ num (some-value))
(add 10)
*Compare function lambda-list and macro one (for example &whole keyword).
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.
Re: Macros
Change the function so that when run it will return like this:omarasl wrote:thanks for replying
as I understand ( maybe I understood wrong) that we can replace the function to macro by simple changes in code , is it right?????
for example if I have this function which use to insert in Binary search tree :
(defun BST-insert (B E)
(if (BST-empty-p B)
(make-bin-tree-leaf E)
(BST-nonempty-insert B E)))
how I can make macro instead of this function (with the same internal code ) ?????????
Code: Select all
(defun BST-insert (B E) ...)
(BTS-insert 'q 'w) ==>
(if (BST-empty-p q)
(make-bin-tree-leaf w)
(BST-nonempty-insert q w))
Code: Select all
(BTS-insert '(make-bin-tree-leaf e) 'w) ==>
(let ((tmpvar (make-bin-tree-leaf e)))
(if (BST-empty-p tmpvar)
(make-bin-tree-leaf w)
(BST-nonempty-insert tmpvar w)))
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p
Currently I'm planning a Scheme compiler :p
Re: Macros
And after you get hygiene and a multiple evaluation issue you can stop reinventing the wheel and use well-known macros: with-gensyms & once-only.
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version). Temporary mirrors of aferomentioned: CLHS and a dark version.
Re: Macros
Useful, but learning Lisp is all about reinventing the wheelGoheeca wrote:And after you get hygiene and a multiple evaluation issue you can stop reinventing the wheel and use well-known macros: with-gensyms & once-only.

I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p
Currently I'm planning a Scheme compiler :p