(mapcar #'square (list 1 2 3 4))
works fine and returns (1 4 9 16). But why cannot macros be used like first-class functions?
(defmacro cube (n)
(* n n n))
(mapcar #'cube (list 1 2 3 4))
gives
COMMON-LISP-USER::CUBE is a macro, not a function.
[Condition of type UNDEFINED-FUNCTION]
Hello,
both first-class functions and macros are very powerful features. When learning Lisp I especially loved the former and started to use them very often. I am still working towards becoming a macro writer/user. One
thing that puzzled me:
(defun square (n)
(* n n))
(mapcar #'square (list 1 2 3 4))
works fine and returns (1 4 9 16). But why cannot macros be used like first-class functions?
(defmacro cube (n)
(* n n n))
(mapcar #'cube (list 1 2 3 4))
gives
COMMON-LISP-USER::CUBE is a macro, not a function.
[Condition of type UNDEFINED-FUNCTION]
instead of (1 8 27 64). (Of course, "cube" should be a function, not a
macro, but this is just an example.)
I might overlook something obvious to you, but my gut feeling is that
there is a deep theoretical reason for this "limitation". Can anyone
please sketch a brief explanation?
On 2023-04-05, Axel Reichert <ma...@axel-reichert.de> wrote:
(defmacro cube (n)It would be
(* n n n))
(defmacro cube (n)
`(* ,n ,n ,n))
Hello,
both first-class functions and macros are very powerful features. When
learning Lisp I especially loved the former and started to use them very often. I am still working towards becoming a macro writer/user. One
thing that puzzled me:
(defun square (n)
(* n n))
(mapcar #'square (list 1 2 3 4))
works fine and returns (1 4 9 16). But why cannot macros be used like first-class functions?
(defmacro revlist3 (a b c) `(list ,c ,b ,a))REVLIST3
(funcall (macro-function 'revlist3) '(revlist3 1 2 3) nil)(LIST 3 2 1)
(funcall (macro-function 'revlist3)'(revlist3 (- 2 1) (+ 1 1) (/ 6 2)) nil)
Underneath a macro there is a function, and that itself is first
class. However, if we have a macro called foo, we don't get to
that function using #'foo or foo.
We can use (macro-function 'foo) to access the function.
The function doesn't work like the the macro might suggest. If we
write, say,
(defun mac (a b c))
Then (macro-function 'mac) does not refer to a three-argument
lambda. A macro function, regardless of the destructuring
lambda list of the macro, is a two-argument function whose
first argument is the entire macro call form (its literal
syntax) and an environment parameter. Quick demo:
Macro that takes three argument expressions, inserting
them into a (list ...) call in reverse order:
(defmacro revlist3 (a b c) `(list ,c ,b ,a))REVLIST3
We explicitly invoke the expander function on the form (revlist 1 2 3)
to produce (list 3 2 1). (We pass nil as the environment parameter.)
(funcall (macro-function 'revlist3) '(revlist3 1 2 3) nil)(LIST 3 2 1)
First-class function means that a function is a run-time object.
It is applied to arguemnt values.
(defmacro revlist3 (a b c) `(list ,c ,b ,a))REVLIST3
(funcall (macro-function 'revlist3)'(revlist3 (- 2 1) (+ 1 1) (/ 6 2)) nil)
(LIST (/ 6 2) (+ 1 1) (- 2 1))
On Tuesday, April 4, 2023 at 11:17:39 PM UTC-7, STE wrote:
On 2023-04-05, Axel Reichert <ma...@axel-reichert.de> wrote:
(defmacro cube (n)It would be
(* n n n))
(defmacro cube (n)
`(* ,n ,n ,n))
Interestingly, the OP's version will also work, but only when the macro is applied to a literal numeric value. But if it is used with a variable or other
form that needs to be evaluated, it will fail.
(CUBE 2) ==> 8
(LET (x 2) (CUBE x)) ==> Error. You can't multiply the symbol X.
This also provides a hint as to why you can't map the macro, as the mapping would happen at run time, not at macro-expansion time. But then it is too late.
Hello,What you are talking about here reminds me of fexprs. They were
both first-class functions and macros are very powerful features. When learning Lisp I especially loved the former and started to use them very often. I am still working towards becoming a macro writer/user. One
thing that puzzled me:
(defun square (n)
(* n n))
(mapcar #'square (list 1 2 3 4))
works fine and returns (1 4 9 16). But why cannot macros be used like first-class functions?
(defmacro cube (n)
(* n n n))
(mapcar #'cube (list 1 2 3 4))
gives
COMMON-LISP-USER::CUBE is a macro, not a function.
[Condition of type UNDEFINED-FUNCTION]
instead of (1 8 27 64). (Of course, "cube" should be a function, not a
macro, but this is just an example.)
I might overlook something obvious to you, but my gut feeling is that
there is a deep theoretical reason for this "limitation". Can anyone
please sketch a brief explanation?
Best regards
Axel
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 299 |
Nodes: | 16 (2 / 14) |
Uptime: | 28:25:22 |
Calls: | 6,681 |
Calls today: | 4 |
Files: | 12,222 |
Messages: | 5,342,514 |
Posted today: | 2 |