Understanding sharp quote in common lisp

落花浮王杯 提交于 2021-02-17 04:30:49

问题


In my experiments below I've abbreviated where the REPL returns an error, & added [num] so these can be referenced in discussion.

I'm a bit confused as to why my attempts to call a function stored in a variable are failing. It seems to me that the syntax is more complex than it needs to be.

Why can I issue neither (f 3) nor even (#'f 3)? Is sharp quote not allowed as the first element of a form? Why is funcall required here?

[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

[236]> (abs 3)                      ; This is fine
3

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

[239]> (funcall #'f 3)              ; seems very long winded...!
3

Does this mean system functions are treated differently from user defined functions?

For completeness:

[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.

[241]> (funcall #'abs 3)                ; Isn't this verbose... ?
3

I haven't got to the symbols chapter in ANSI Common Lisp yet, maybe that will help... thanks for any tips.


回答1:


[235]> (setf f #'abs)               ; I'm ok with this
#<SYSTEM-FUNCTION ABS>

Above kind of sets a variable named f to a function object - from the function called abs.

[236]> (abs 3)                      ; This is fine
3

Above called the function abs.

[237]> (f 3)                        ; Err due to sep. fn namespace. OK.

Above: there is no function named f.

-- Err[1]: "Undefined function f" --

[238]> (#'f 3)                      ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"

Above: Common Lisp accepts only symbols as function names, symbols as macro names, symbols as special operators or lambda expressions as the first element of a cons form. (function f) is not a function name.

Does this mean system functions are treated differently from user defined functions?

No.

[239]> (funcall #'f 3)              ; seems very long winded...!
3

Above calls the function funcall with the function object from the named function f. funcall then calls this function object with 3 as the argument.

seems very long winded

It is.

Why can I issue neither (f 3) nor even (#'f 3)? Is sharp quote not allowed as the first element of a form?

Because f is not naming a function. It names a variable. #'f is also not a function name. We are required to use a function name (a symbol actually).

Namespaces

Common Lisp (like some other Lisp dialects) has two namespaces for functions and for variables.

Defining a variable foo:

CL-USER 54 > (defvar foo 3)
FOO

Defining a function foo:

CL-USER 55 > (defun foo (x) (* foo 10))
FOO

We can call the function foo with the value obtained from the variable foo:

CL-USER 56 > (foo foo)
30

How to get the function object from the global name of the function:

CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>

CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>

Same as above, but with a short notation:

CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>

CL-USER 59 > (function foo)            ; works also for local functions
#<interpreted function FOO 4230008AAC>

How to get a value from a global variable:

CL-USER 60 > (symbol-value 'foo)
3

Or just use the variable:

CL-USER 61 > foo
3

Some positives:

Positive: No name clashes.

We can write

(defun foo (list) (list list))

and don't have to write

(defun foo (lst) (list lst))

Positive: simpler compilation

(let ((list 3))
  (list 1 list 3))

Above will never be an error in Common Lisp. In Scheme it would be an error: 3 is not a function.



来源:https://stackoverflow.com/questions/55871255/understanding-sharp-quote-in-common-lisp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!