Page 1 of 1

I do not understand symbol-macros

Posted: Sat Dec 13, 2014 3:16 pm
by porky11
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?

Re: I do not understand symbol-macros

Posted: Sat Dec 13, 2014 5:16 pm
by Goheeca
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.

Re: I do not understand symbol-macros

Posted: Sat Dec 13, 2014 6:06 pm
by pjstirling
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).

Re: I do not understand symbol-macros

Posted: Mon Dec 15, 2014 2:07 pm
by porky11
It is ok, but I don't like it

Re: I do not understand symbol-macros

Posted: Tue Dec 16, 2014 7:28 pm
by pjstirling
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)))

Re: I do not understand symbol-macros

Posted: Fri Dec 19, 2014 8:23 pm
by pjstirling
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).