LISP中的变量和符号有什么区别? [英] What is the difference between a variable and a symbol in LISP?

查看:177
本文介绍了LISP中的变量和符号有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就范围而言?在内存中的实际执行?语法?例如,如果(让a 1)是'a'变量或符号?

解决方案

Jörg的回答指向正确的方向。让我补充一点。



我会谈谈与Common Lisp类似的Lisp。



符号作为数据结构

符号是Lisp中真正的数据结构。您可以创建符号,您可以使用符号,可以存储符号,可以传递符号,符号可以是较大数据结构的一部分,例如符号列表。一个符号有一个名称,可以有一个值,可以有一个函数值。



所以你可以带一个符号并设置它的值。 b

 (setf(symbol-value'foo)42)

通常会写(setq foo 42)(set'foo 42)(setf foo 42)



表示变量的符号



但!!

 (defun foo(a)
(setq a 42))



<$ p $ ($($))
(setq a 42))

在源代码中的上述两种形式中都有符号, a 被写为符号并使用函数 READ 读取该源代码将在某个列表中返回一个符号 a 。但 setq 操作不会将 a 的符号值设置为 42 。这里 LET DEFUN 引入了一个 VARIABLE a ,我们用一个符号来写。因此, SETQ 操作会将变量值设置为 42



因此,如果我们看一下:

<$ p $

(bq)
(setq foo 3)
(setq baz 3))
(defvar foo nil)

我们引入一个全局变量 FOO



栏中第一个 SETQ 设置全局变量 FOO 的符号值, 。第二个 SETQ 将局部变量 BAZ 设置为 3 。在这两种情况下,我们都使用相同的 SETQ ,我们将该变量作为符号编写,但在第一种情况下, FOO 捐献一个全局变量和那些存储值在符号值中。在第二种情况下, BAZ 表示一个局部变量以及值如何存储,我们不知道。我们所能做的就是访问变量来获得它的价值。在Common Lisp中,没有办法使用符号 BAZ 并获取局部变量值。我们无法使用符号访问局部变量绑定及其值。这是Common Lisp中局部变量的词汇绑定工作的一部分。



例如,这导致观察,即在没有记录调试信息的编译代码中,符号 BAZ 不见了。它可以是处理器中的寄存器,也可以是其他方式实现的。符号 FOO 仍然存在,因为我们将它用作全局变量。



符号

符号是一种数据类型,是Lisp中的数据结构。



变量是一个概念性的东西。全局变量基于符号。本地词汇变量不是。



在源代码中,我们使用符号为函数,类和变量编写各种名称。



有一些概念上的重叠:

 (defun foo(bar)(setq bar'baz))

在上面的SOURCE代码中, defun foo bar setq baz 都是符号。



DEFUN 是提供宏的符号。
FOO 是提供功能的符号。
SETQ 是提供特殊操作符的符号。
BAZ 是用作数据的符号。因此,在 BAZ 之前的报价。
BAR 是一个变量。在编译的代码中,不再需要它的符号。

In terms of scope? Actual implementation in memory? The syntax? For eg, if (let a 1) Is 'a' a variable or a symbol?

解决方案

Jörg's answer points in the right direction. Let me add a bit to it.

I'll talk about Lisps that are similar to Common Lisp.

Symbols as a data structure

A symbol is a real data structure in Lisp. You can create symbols, you can use symbols, you can store symbols, you can pass symbols around and symbols can be part of larger data structures, for example lists of symbols. A symbol has a name, can have a value and can have a function value.

So you can take a symbol and set its value.

(setf (symbol-value 'foo) 42)

Usually one would write (setq foo 42), or (set 'foo 42) or (setf foo 42).

Symbols in code denoting variables

But!

(defun foo (a)
  (setq a 42))

or

(let ((a 10))
   (setq a 42))

In both forms above in the source code there are symbols and a is written like a symbol and using the function READ to read that source returns a symbol a in some list. But the setq operation does NOT set the symbol value of a to 42. Here the LET and the DEFUN introduce a VARIABLE a that we write with a symbol. Thus the SETQ operation then sets the variable value to 42.

Lexical binding

So, if we look at:

(defvar foo nil)

(defun bar (baz)
  (setq foo 3)
  (setq baz 3))

We introduce a global variable FOO.

In bar the first SETQ sets the symbol value of the global variable FOO. The second SETQ sets the local variable BAZ to 3. In both case we use the same SETQ and we write the variable as a symbol, but in the first case the FOO donates a global variable and those store values in the symbol value. In the second case BAZ denotes a local variable and how the value gets stored, we don't know. All we can do is to access the variable to get its value. In Common Lisp there is no way to take a symbol BAZ and get the local variable value. We don't have access to the local variable bindings and their values using symbols. That's a part of how lexical binding of local variables work in Common Lisp.

This leads for example to the observation, that in compiled code with no debugging information recorded, the symbol BAZ is gone. It can be a register in your processor or implemented some other way. The symbol FOO is still there, because we use it as a global variable.

Various uses of symbols

A symbol is a data type, a data structure in Lisp.

A variable is a conceptual thing. Global variables are based on symbols. Local lexical variables not.

In source code we write all kinds of names for functions, classes and variables using symbols.

There is some conceptual overlap:

(defun foo (bar) (setq bar 'baz))

In the above SOURCE code, defun, foo, bar, setq and baz are all symbols.

DEFUN is a symbol providing a macro. FOO is a symbol providing a function. SETQ is a symbol providing a special operator. BAZ is a symbol used as data. Thus the quote before BAZ. BAR is a variable. In compiled code its symbol is no longer needed.

这篇关于LISP中的变量和符号有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆