虽然LISP有一些我见过的最简单的语法,但我仍然对基础知识感到困惑。我做过研究,我得出的结论是有两种数据类型:“atoms”和list。然而,我也遇到过“S-expression”这个术语,它似乎描述了原子和列表。那么,S-expression究竟是什么?它是一种数据类型吗?另外,我不确定如何区分LISP中的数据列表中的函数调用。例如,(1 2 3)是列表,而(f 2 3)可以是某个函数。但我怎么知道f是函数名还是某种数据类型?由于列表和函数使用相同的语法,我不知道如何区分这两者。最后,最重要的是,我需要一个心理模型来思考LISP的工作原理。例如,什么是基本数据类型?用于处理基本数据类型的内置过程有哪些?我们怎样才能看到数据和程序不同?例如,在Java中,类顶部的实例变量用于表示数据,而方法是操作数据的过程。这在LISP中看起来像什么?
(我是新人,所以我不确定这个问题是否过于宽泛)
答案 0 :(得分:5)
我推荐了LispBook和Practical Common Lisp。两本好书。一旦你理解了基础知识,我真的,真的推荐Paul Graham's "On Lisp"。
引导您回答特定问题的答案:
数据类型:Lisp有一组丰富的数据类型(数字类型,如整数,有理数,浮点字符和字符串 - 数组和散列表 - 还有更多),但在我看来,假设你是已经习惯使用整数和字符串,您应该首先阅读symbol
和cons
。
symbol
:意识到符号既是标识符又是值。了解每个符号可以“指向”一个数据值,同时“指向”一个函数(还有其他三个您不需要担心的属性)
cons
:发现这个神奇的东西叫做'cons cell'只是一个带有两个指针的结构。一个称为“登记册的地址部分”,另一个称为“登记册的减少部分”。不要担心这些名称的含义(它们不再相关),只要知道car
函数返回寄存器的地址部分的内容,cdr
返回递减部分。现在忘掉所有这一切,只记得现代Lispers将cons单元视为带有两个指针的结构,一个叫做汽车,另一个称为cdr。
名单:“没有勺子。”也没有列表。意识到我们所认为的列表只不过是一组缺点单元格,每个缺点的汽车指向列表中的一个成员,每个缺点的cdr指向下一个缺点(除了最后的缺点) ,其cdr是“空指针”nil)。这对于理解列表操作,嵌套列表,树结构等非常重要。
原子:现在,将原子视为数字,字符,字符串或符号。这足以让你开始,你可以在以后更深入地了解细节。
S表达式:s-expr被定义为“指向两个s表达式的原子或cons单元”。现在不要担心s-expr是什么或不是什么,但是checkout wikipedia for a brief intro
列表与功能调用:男,哦,伙计!我开始的时候就挣扎着这个!但通过一些练习实际上很容易:“五次两次”只是一个英语短语,对吧?但如果我要求你“评价”它,你可能会说“十”。 “1 + 2”是一个数学表达式,但是数学家会将它评估为3.“5”只是一个数字,但是如果你输入计算器并按“=”,计算器会将其评估为答案5在Lisp (+ 1 2)
只是一个列表。它是一个包含符号+
,数字1和数字2的列表。但是 - 如果你要求Lisp评估该列表,它将调用函数+
,将它作为参数传递给1和2 。很大程度上对Lisp感到满意的是学习评估s表达式的时间和地点,以及它们不在何处。现在 - 将评估您在REPL中输入的任何内容,将评估函数调用的参数,可能不会评估宏调用的参数,您可以使用quote
来阻止评估。通过练习,将变得更容易。
基本功能:虽然我说“列表”并不存在(“它一直向下,弗莱先生”),但首先要学习基于列表的内容,car
,{ {1}},cdr
,cons
,list
,append
以及适用的内容reverse
,mapcar
,mapcons
。这些是开始思考列表和函数式编程的好方法。
类,成员数据和方法:我建议稍后保留面向对象。首先学习Lisp的基础知识。在您成为语言本身的朋友之前,要担心担心数据封装,访问控制和多态性。当你准备好了,阅读“On Lisp”,第25章将引导你自己向Lisp添加面向对象,展示Lisp如何真正成为可编程编程语言。本书将向您介绍CLOS,这是Common Lisp中内置的标准面向对象系统。了解CLOS,但肯定会浏览其他OO库。 Lisp是我所知道的唯一一种你可以选择如何你希望语言实现OO的语言。
我要到此为止。对上面的前8个概念感到满意,强大的心理模型将自行解决。
答案 1 :(得分:1)
自我评估的一切都是数据。例如2
,"hello"
。
所引用的一切都是数据。例如'(f 3 4)
,'test
或简写版(quote test)
提供给REPL的其他所有东西都需要是代码。例如(f 3 4)
是代码。它是s表达式,与上面引用的数据无法区分,但它没有被引用,所以它必须是代码。
有一些特殊的表单,例如if
,let
,lambda
,defun
,...您只需要了解其工作原理。你怎么知道if
不是像Java或C#这样的C方言的方法?你只需要了解它们。
您还需要了解一些基本功能。通常,它们会与特殊表单一起引入每个教程中。我建议您阅读Common Land of Lisp和Practical Common Lisp以及针对Racket的Realm of Racket和How to design programs。对于纯方案,我建议The wizard book (SICP)。不要同时做所有这些。当你学会了一个好的东西时,学习其他的很容易。
现在,学习Lisp比学习另一种C方言更难。这是因为它是一种完全不同的语言,有不同的做法。例如。你不会找到for
或while
循环,变量没有类型,但它们引用的对象有。你需要学习如何编程几乎就像你不懂C语言一样。 (实际上,了解C语言可能会使学习变得更加困难)
答案 2 :(得分:1)
“S表达式”是“一个原子,或一个S表达式列表”(这里有一些更多的复杂功能,我现在暂时跳过这些,基本上可以归结为“读取宏”,其中可以完成文本表示和内部表示之间的差异,以简化人类写作。
(1 2 3)
是一个列表。但是,(f 1 2 3)
也是一个列表。但是,在某些(大多数?)情况下,它也可以是函数调用(而不是函数)。
我认为你大部分都有语法,其余的是语义(在非常技术意义上)。在这一点上,我会指出一些好的阅读材料,周围有很多好书(我从早期版本的Winston-Horn's "Lisp"开始。