I do not understand symbol-macros

Discussion of Common Lisp
Post Reply
porky11
Posts: 25
Joined: Fri May 02, 2014 6:46 am

I do not understand symbol-macros

Post by porky11 » Sat Dec 13, 2014 3:16 pm

I thought symbol-macros are like function-like macros, but they only substitute single symbols to expressions, if they are not interpreted as functions or macros.

lets define the symbol-macro as

Code: Select all

(define-symbol-macro macro 0)
so the form

Code: Select all

(let ((macro 1)) macro)
would expand to

Code: Select all

(let ((0 1)) 0)
and throw an error but it evals to 1
maybe this is, because it is a special form
but then it is wierd that this special form

Code: Select all

(setq macro 1)
is not possible
I also can not make the symbol-macro unbound again, as with normal macros, and functions (fmakunbound) and symbols, following code throws an error:

Code: Select all

(fmakunbound macro)
how can I do this?

Another example:

Code: Select all

(defvar *cons* (cons 1 2))
(define-symbol-macro test (car *cons*))
(setq test 0)
now cons is "(0 . 2)"
but if I write the macro-expansion of test in the last function:

Code: Select all

(setq (car *cons*) 1)
it is, like expected, not possible, and throws an error
why are symbol macros setq-able?

Goheeca
Posts: 271
Joined: Thu May 10, 2012 12:54 pm
Contact:

Re: I do not understand symbol-macros

Post by Goheeca » Sat Dec 13, 2014 5:16 pm

Let's consult the CLHS.
lets define the symbol-macro as

Code: Select all

(define-symbol-macro macro 0)
so the form

Code: Select all

(let ((macro 1)) macro)
Each global reference to symbol (i.e., not shadowed[2] by a binding for a variable or symbol macro named by the same symbol) is expanded by the normal macro expansion process
A binding for a symbol macro can be shadowed[2] by let or symbol-macrolet.
So it's just a normal lexical variable.
I also can not make the symbol-macro unbound again, as with normal macros, and functions (fmakunbound) and symbols, following code throws an error:

Code: Select all

(fmakunbound macro)
how can I do this?
Symbol-macros don't appear as a first-class citizen, I consider that's a pity (as everything that's not a first-class citizen).
Another example:

Code: Select all

(defvar *cons* (cons 1 2))
(define-symbol-macro test (car *cons*))
(setq test 0)
Any use of setq to set the value of the symbol while in the scope of this definition is treated as if it were a setf. psetq of symbol is treated as if it were a psetf, and multiple-value-setq is treated as if it were a setf of values.
It's just OK.
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.

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: I do not understand symbol-macros

Post by pjstirling » Sat Dec 13, 2014 6:06 pm

The name of a binding, in a LET binding is unevaluated, so the symbol macro is left unexpanded, and the symbol is used as a name for the binding. (If there wasn't a check for the name being a symbol then you would get the same result with a normal macro in the name form).

porky11
Posts: 25
Joined: Fri May 02, 2014 6:46 am

Re: I do not understand symbol-macros

Post by porky11 » Mon Dec 15, 2014 2:07 pm

It is ok, but I don't like it

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: I do not understand symbol-macros

Post by pjstirling » Tue Dec 16, 2014 7:28 pm

Perhaps you could explain why you want to do this so that we can explain how you might do it.

LET is defined to behave the way it does, writing a macro that WOULD expand your symbol macro isn't hard, I just can't understand why you would want to...

Code: Select all

(defmacro expanding-let (&environment env 
			   bindings
			   &body body)
  (flet ((macroexpand-form (form)
	   (macroexpand form env)))
    `(let ,(mapcar (lambda (binding)
		     (if (listp binding)
			 (mapcar #'macroexpand-form binding)
			 (macroexpand-form binding)))
	    bindings)
       ,@body)))

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: I do not understand symbol-macros

Post by pjstirling » Fri Dec 19, 2014 8:23 pm

It occurred to me that, if you know C/C++, you may expect behaviour like cpp (the C pre-processor), which is capable of little more than global text substitution, and knows nothing about the actual syntax of C (or C++).

cpp is a UNIX tool, which means that its primary goal is to be simple-to-implement, rather than useful-in-all-cases (as anyone who tries to do proper meta-programming in C++ laments).

Post Reply