理解 LISP 的语法
Understanding the syntax of LISP
虽然 LISP 有一些我见过的最简单的语法,但我仍然对基本原理感到困惑。我做了研究,得出的结论是有两种数据类型:"atoms" 和列表。但是,我也遇到了术语 "S-expression",它似乎同时描述了原子和列表。那么,S表达式到底是什么?它是一种数据类型吗?此外,我不确定如何在 LISP 中区分函数调用和数据列表。例如,(1 2 3) 是一个列表,而 (f 2 3) 可能是某个函数。但是我怎么知道 f 是一个函数名还是某种数据类型呢?由于列表和函数使用相同的语法,我不确定如何区分两者。最后,最重要的是,我需要一个思维模型来思考 LISP 的工作原理。例如,什么是基本数据类型?用于处理基本数据类型的内置过程是什么?我们如何才能将数据和程序视为截然不同的呢?例如,在Java中,类顶部的实例变量用于表示数据,而方法是操作数据的过程。这在 LISP 中看起来像什么?
(我是新手,不知道这个问题是不是太宽泛了)
一切自我评价的都是数据。例如 2
、"hello"
。
引用的所有内容都是数据。例如 '(f 3 4)
、'test
或普通版 (quote test)
提供给 REPL 的所有其他内容都需要是代码。例如 (f 3 4)
是代码。它是 s 表达式,与上面引用的数据无法区分,但它没有被引用,所以它必须是代码。
有一些特殊形式,例如 if
、let
、lambda
、defun
,...您只需要了解其工作原理即可。你怎么知道 if
不是像 Java 或 C# 这样的 C 方言中的方法?你只需要记住它们。
您还需要了解一些基本功能。通常它们与特殊形式一起在每个教程中介绍。我建议您阅读 Land of Lisp and Practical Common Lisp for Common Lisp and Realm of Racket and How to design programs for Racket. For pure Scheme I recommend The wizard book (SICP)。不要同时做所有这些。当你学会一个很好的时候,学习其他的就很容易了。
现在学一门Lisp比学一门C方言还难。这是因为它是一种完全不同的语言,具有不同的做事方式。例如。你不会发现 for
或 while
循环和变量没有类型但它们引用的对象有。您需要学习如何编程,就好像您不懂 C 方言一样。 (实际上,会C方言可能会使学习变得更难)
祝你好运!
一个 "S-expression" 是 'an atom, or a list of S-expressions'(这里有一些更复杂的问题,我现在将跳过这些,基本上归结为一个叫做 "read macros" 的东西,其中可以做文本表示和内部表示,简化人的书写)。
(1 2 3)
是一个列表。但是,(f 1 2 3)
也是一个列表。但是,在某些(大多数?)情况下,它也可以是函数调用(而不是函数)。
我认为您主要了解了语法,其余的是语义(在非常技术的意义上)。在这一点上,我会指出一些好的阅读 material,周围有很多好书(我从 Winston-Horn's "Lisp" 的早期版本开始。
我支持 LispBook 和 Practical Common Lisp 的推荐。两本好书。一旦您了解了基础知识,我真的非常推荐 Paul Graham's "On Lisp"。
指导您找到特定问题的答案:
数据类型:Lisp 有一组丰富的数据类型(数字类型,如整数、有理数、浮点数——字符和字符串——数组和哈希表——还有很多),但在我看来,假设您已经熟悉整数和字符串,您应该首先阅读 symbol
和 cons
.
symbol
:认识到一个符号既是一个标识符又是一个值。了解每个符号可以 "point to" 一个数据值,同时 "point to" 一个函数(并且具有您还不需要担心的其他三个属性)
cons
:发现这个叫做 'cons cell' 的神奇东西只是一个有两个指针的结构。一个叫 "the Address part of the Register",另一个叫 "the Decrement part of the register"。不用担心这些名称的含义(它们不再相关),只要知道 car
函数 returns 寄存器地址部分的内容,以及 cdr
returns 减量部分。现在忘掉所有这些,记住现代 Lispers 认为 cons 单元格是一个有两个指针的结构,一个叫做 car,另一个叫做 cdr。
列表:"There is no spoon."也没有列表。意识到我们认为的列表无非是一组cons cells,每个cons的car指向列表中的一个成员,每个cons的cdr指向下一个cons(除了最后一个cons ,其 cdr 为 "the null pointer" nil)。这对于理解列表操作、嵌套列表、树结构等至关重要。
原子:现在,将原子想象成数字、字符、字符串或符号。这足以让您入门,您可以稍后深入了解细节。
S-表达式:一个 s-expr 被定义为 "either an atom, or a cons cell pointing to two s-expressions"。现在不要担心什么是或不是 s-expr,但是 checkout wikipedia for a brief intro
列表与函数调用:伙计,噢,伙计!当我开始时,我为此苦苦挣扎!但实际上只要稍加练习就很容易:"Five times two" 只是一个英文短语,对吧?但是如果我让你 "evaluate" 它,你可能会说 "ten"。 “1 + 2”是一个数学表达式,但数学家会将其计算为 3。“5”只是一个数字,但如果您将其输入计算器并按“=”,计算器会将其计算为答案 5 . 在 Lisp 中 (+ 1 2)
只是一个列表。它是一个包含符号 +
、数字 1 和数字 2 的列表。但是 - 如果您要求 Lisp 计算该列表,它将调用函数 +
,将 1 和 2 作为参数传递给它.熟悉 Lisp 的很大一部分是了解何时何地对 s-表达式求值,以及在哪里不求值。现在 - 您在 REPL 中键入的任何内容都将被评估,函数调用的参数将被评估,宏调用的参数可能不会被评估,您可以使用 quote
来防止评估。通过练习,会变得更容易。
基本功能:虽然我说了"list"并不存在("Its conses all the way down, Mr. Fry"),但还是先学习列表的东西,car
,cdr
、cons
、list
、append
、reverse
和应用程序 mapcar
、mapcons
、apply
。这些是开始思考列表和函数式编程的好方法。
类,成员数据和方法:我建议把面向对象留到以后再说。首先学习Lisp的基础知识。在您熟悉语言本身之前,不要担心数据封装、访问控制和多态性。准备就绪后,请阅读 "On Lisp",第 25 章将引导您自己将面向对象添加到 Lisp 中,展示 Lisp 如何真正成为一种可编程的编程语言。然后本书将向您介绍 CLOS,Common Lisp 中内置的标准面向对象系统。了解 CLOS,但一定要浏览其他 OO 库。 Lisp 是我知道的唯一一种语言,您可以在其中实际选择 如何 您希望该语言实现 OO。
我要到此为止了。熟悉上面的前 8 个概念,一个强大的心智模型就会自行解决。
虽然 LISP 有一些我见过的最简单的语法,但我仍然对基本原理感到困惑。我做了研究,得出的结论是有两种数据类型:"atoms" 和列表。但是,我也遇到了术语 "S-expression",它似乎同时描述了原子和列表。那么,S表达式到底是什么?它是一种数据类型吗?此外,我不确定如何在 LISP 中区分函数调用和数据列表。例如,(1 2 3) 是一个列表,而 (f 2 3) 可能是某个函数。但是我怎么知道 f 是一个函数名还是某种数据类型呢?由于列表和函数使用相同的语法,我不确定如何区分两者。最后,最重要的是,我需要一个思维模型来思考 LISP 的工作原理。例如,什么是基本数据类型?用于处理基本数据类型的内置过程是什么?我们如何才能将数据和程序视为截然不同的呢?例如,在Java中,类顶部的实例变量用于表示数据,而方法是操作数据的过程。这在 LISP 中看起来像什么?
(我是新手,不知道这个问题是不是太宽泛了)
一切自我评价的都是数据。例如 2
、"hello"
。
引用的所有内容都是数据。例如 '(f 3 4)
、'test
或普通版 (quote test)
提供给 REPL 的所有其他内容都需要是代码。例如 (f 3 4)
是代码。它是 s 表达式,与上面引用的数据无法区分,但它没有被引用,所以它必须是代码。
有一些特殊形式,例如 if
、let
、lambda
、defun
,...您只需要了解其工作原理即可。你怎么知道 if
不是像 Java 或 C# 这样的 C 方言中的方法?你只需要记住它们。
您还需要了解一些基本功能。通常它们与特殊形式一起在每个教程中介绍。我建议您阅读 Land of Lisp and Practical Common Lisp for Common Lisp and Realm of Racket and How to design programs for Racket. For pure Scheme I recommend The wizard book (SICP)。不要同时做所有这些。当你学会一个很好的时候,学习其他的就很容易了。
现在学一门Lisp比学一门C方言还难。这是因为它是一种完全不同的语言,具有不同的做事方式。例如。你不会发现 for
或 while
循环和变量没有类型但它们引用的对象有。您需要学习如何编程,就好像您不懂 C 方言一样。 (实际上,会C方言可能会使学习变得更难)
祝你好运!
一个 "S-expression" 是 'an atom, or a list of S-expressions'(这里有一些更复杂的问题,我现在将跳过这些,基本上归结为一个叫做 "read macros" 的东西,其中可以做文本表示和内部表示,简化人的书写)。
(1 2 3)
是一个列表。但是,(f 1 2 3)
也是一个列表。但是,在某些(大多数?)情况下,它也可以是函数调用(而不是函数)。
我认为您主要了解了语法,其余的是语义(在非常技术的意义上)。在这一点上,我会指出一些好的阅读 material,周围有很多好书(我从 Winston-Horn's "Lisp" 的早期版本开始。
我支持 LispBook 和 Practical Common Lisp 的推荐。两本好书。一旦您了解了基础知识,我真的非常推荐 Paul Graham's "On Lisp"。
指导您找到特定问题的答案:
数据类型:Lisp 有一组丰富的数据类型(数字类型,如整数、有理数、浮点数——字符和字符串——数组和哈希表——还有很多),但在我看来,假设您已经熟悉整数和字符串,您应该首先阅读
symbol
和cons
.symbol
:认识到一个符号既是一个标识符又是一个值。了解每个符号可以 "point to" 一个数据值,同时 "point to" 一个函数(并且具有您还不需要担心的其他三个属性)cons
:发现这个叫做 'cons cell' 的神奇东西只是一个有两个指针的结构。一个叫 "the Address part of the Register",另一个叫 "the Decrement part of the register"。不用担心这些名称的含义(它们不再相关),只要知道car
函数 returns 寄存器地址部分的内容,以及cdr
returns 减量部分。现在忘掉所有这些,记住现代 Lispers 认为 cons 单元格是一个有两个指针的结构,一个叫做 car,另一个叫做 cdr。列表:"There is no spoon."也没有列表。意识到我们认为的列表无非是一组cons cells,每个cons的car指向列表中的一个成员,每个cons的cdr指向下一个cons(除了最后一个cons ,其 cdr 为 "the null pointer" nil)。这对于理解列表操作、嵌套列表、树结构等至关重要。
原子:现在,将原子想象成数字、字符、字符串或符号。这足以让您入门,您可以稍后深入了解细节。
S-表达式:一个 s-expr 被定义为 "either an atom, or a cons cell pointing to two s-expressions"。现在不要担心什么是或不是 s-expr,但是 checkout wikipedia for a brief intro
列表与函数调用:伙计,噢,伙计!当我开始时,我为此苦苦挣扎!但实际上只要稍加练习就很容易:"Five times two" 只是一个英文短语,对吧?但是如果我让你 "evaluate" 它,你可能会说 "ten"。 “1 + 2”是一个数学表达式,但数学家会将其计算为 3。“5”只是一个数字,但如果您将其输入计算器并按“=”,计算器会将其计算为答案 5 . 在 Lisp 中
(+ 1 2)
只是一个列表。它是一个包含符号+
、数字 1 和数字 2 的列表。但是 - 如果您要求 Lisp 计算该列表,它将调用函数+
,将 1 和 2 作为参数传递给它.熟悉 Lisp 的很大一部分是了解何时何地对 s-表达式求值,以及在哪里不求值。现在 - 您在 REPL 中键入的任何内容都将被评估,函数调用的参数将被评估,宏调用的参数可能不会被评估,您可以使用quote
来防止评估。通过练习,会变得更容易。基本功能:虽然我说了"list"并不存在("Its conses all the way down, Mr. Fry"),但还是先学习列表的东西,
car
,cdr
、cons
、list
、append
、reverse
和应用程序mapcar
、mapcons
、apply
。这些是开始思考列表和函数式编程的好方法。类,成员数据和方法:我建议把面向对象留到以后再说。首先学习Lisp的基础知识。在您熟悉语言本身之前,不要担心数据封装、访问控制和多态性。准备就绪后,请阅读 "On Lisp",第 25 章将引导您自己将面向对象添加到 Lisp 中,展示 Lisp 如何真正成为一种可编程的编程语言。然后本书将向您介绍 CLOS,Common Lisp 中内置的标准面向对象系统。了解 CLOS,但一定要浏览其他 OO 库。 Lisp 是我知道的唯一一种语言,您可以在其中实际选择 如何 您希望该语言实现 OO。
我要到此为止了。熟悉上面的前 8 个概念,一个强大的心智模型就会自行解决。