邮件组新人加入

70 views
Skip to first unread message

yin xu

unread,
Jan 14, 2012, 1:09:09 AM1/14/12
to lis...@googlegroups.com
今天是我第一次想了解下LISP,只是想改变下偶的程序设计观~
网上找了common lisp .1000多页,坑爹不止两三天~~
有没有简单点的教程~~

Jeova Sanctus Unus

unread,
Jan 25, 2012, 1:46:56 AM1/25/12
to lis...@googlegroups.com
买实用common lisp编程 http://book.douban.com/subject/6859720/
或者看英文版来入门 http://www.gigamonkeys.com/book/
> --
> Lisp-cn(Lisp中文用户组)
> CLUG http://lisp.org.cn

Xiaofeng Yang

unread,
Jan 25, 2012, 1:55:24 AM1/25/12
to lis...@googlegroups.com
Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。
Common Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php, javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。
简单点的教程:Practical Common Lisp
LISP系个人感觉最简单的编程语言:LOGO

LISP是一个大家族,跟Common Lisp是两个概念。

如果要改变编程观念,也许以下语言可以参考,这些语言让你不得不换一种思路来编程(习惯的力量时强大的,只有当你被逼迫的时候,才能学会一种新的思路):
Haskell - 流行的纯函数式编程语言,较有名的实现,如GHC。另外,如OCaml等编程语言,尽管支持多范性,但是如果不使用纯函数式编程会需要比较麻烦的方法(其实Haskell也是如此)。
ISO Prolog - 流行的纯逻辑式编程语言,较有名的实现,如BProlog, SWI-Prolog, GNU Prolog, 等
当然还有很多基于其它计算模型的编程语言,只不过如上的两种类型是最常被提到的。

另外,你可以加入社区群:25342018


     Best regards,
Xiaofeng Yang


在 2012年1月14日 下午2:09,yin xu <loveu...@gmail.com>写道:

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

CRLF0710

unread,
Jan 25, 2012, 5:16:33 AM1/25/12
to lis...@googlegroups.com
在 2012年1月14日 下午2:09,yin xu <loveu...@gmail.com>写道:
只是想改变下偶的程序设计观

只是出于这个目的的话,读读SICP就够了,再来随便拿本CL的书看看Lisp的那些设施会被怎样使用就可以啦。个人感觉这样性价比比较高。

--
Wir müssen wissen; wir werden wissen!
CrLF.0710

Xiaofeng Yang

unread,
Jan 25, 2012, 5:28:04 AM1/25/12
to lis...@googlegroups.com
晕,不过也算能让不少人开眼界的书.....

同时推荐这一套,内容更进一步且易懂:http://www.cs.berkeley.edu/~bh/logo.html
Computer Science Logo Style




     Best regards,
Xiaofeng Yang


Jianshi Huang

unread,
Jan 25, 2012, 6:06:30 AM1/25/12
to lis...@googlegroups.com
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:

> Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。

Wrong wrong wrong, 你应该来上次的 lisper meetup 听我的第二个演讲的:)

> Common Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php,
> javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。

very wrong.

> 简单点的教程:Practical Common Lisp
> LISP系个人感觉最简单的编程语言:LOGO
>
> LISP是一个大家族,跟Common Lisp是两个概念。
>
> 如果要改变编程观念,也许以下语言可以参考,这些语言让你不得不换一种思路来编程(习惯的力量时强大的,只有当你被逼迫的时候,才能学会一种新的思路):
> Haskell -
> 流行的纯函数式编程语言,较有名的实现,如GHC。另外,如OCaml等编程语言,尽管支持多范性,但是如果不使用纯函数式编程会需要比较麻烦的方法(其实Haskell也是如此)。
> ISO Prolog - 流行的纯逻辑式编程语言,较有名的实现,如BProlog, SWI-Prolog, GNU Prolog, 等
> 当然还有很多基于其它计算模型的编程语言,只不过如上的两种类型是最常被提到的。
>

比较的方法就是真正做一些项目!然后你就明白灵活性是多么重要了。


Cheers,
--
黄 澗石 (Jianshi Huang)
http://huangjs.net/

Xiaofeng Yang

unread,
Jan 25, 2012, 6:43:25 AM1/25/12
to lis...@googlegroups.com
我很希望能听到你的详细观点,而不是简单的一个“wrong”。

     Best regards,
Xiaofeng Yang


Jianshi Huang

unread,
Jan 25, 2012, 7:08:25 AM1/25/12
to lis...@googlegroups.com
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:
> 我很希望能听到你的详细观点,而不是简单的一个“wrong”。

>
>> 2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:
>> > Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。
>>
>> Wrong wrong wrong, 你应该来上次的 lisper meetup 听我的第二个演讲的:)
>>

最近非常忙,我只能稍微提一些。

1) code as data (这点你说了,但像 lisp 这般彻底的没有,专业一点叫 homoiconic programming language)
2) reflection,几乎所有编程需要的信息都可以在 runtime 里得到,bindings info (var, func,
macro, etc.),types,declarations,source code!
3) composability,基本上所有的都是 expressions

以上组成了强大的 generative programming 工具。


>> > Common
>> > Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php,
>> > javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。
>>
>> very wrong.
>>

当你用 javascript 的方式写 lisp 程序,可读性自然上不去。

Xiaofeng Yang

unread,
Jan 25, 2012, 8:00:58 AM1/25/12
to lis...@googlegroups.com
在 2012年1月25日 下午8:08,Jianshi Huang <jiansh...@gmail.com>写道:
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:
> 我很希望能听到你的详细观点,而不是简单的一个“wrong”。
>
>> 2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:
>> > Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。
>>
>> Wrong wrong wrong, 你应该来上次的 lisper meetup 听我的第二个演讲的:)
>>

最近非常忙,我只能稍微提一些。

1) code as data (这点你说了,但像 lisp 这般彻底的没有,专业一点叫 homoiconic programming language)

怎样才算得上彻底呢?访问所有的源代码?这几乎所有的编程语言都可以轻松实现,源代码本质上就是字符串,一般存储在文件里。
 
2) reflection,几乎所有编程需要的信息都可以在 runtime 里得到,bindings info (var, func,
macro, etc.),types,declarations,source code!

这包含两点,一个是本身提供的反射功能,类似的功能可以在如Java等语言里面找到。
另外一个是,由于运行时里面包含调试器,所以所有的信息都可以在运行时找得到,前提是,必须带上调试信息进行编译,否则,同样找不到。那么,如果我的其他语言的程序里面同样也集成了一个调试器库,同样也能轻松访问到,这并不是一件很困难的事情。
 
3) composability,基本上所有的都是 expressions

我理解的你的意思应该是,一来全是表达式方式的语法,二来可以一层套一层。
这种在其他语言里面非常多,一个例子是F#。
例如,我可以在Common Lisp里面编写一个let套上另外一个let:
(let ((x 1))
  (let ((y 2))
    (+ x y)))
我同样也可以在F#里面一个let套上一个let:
let x = 1 in
  let y = 2 in
    x + y
如果喜欢括号和前缀表达式,那么也可以这样写:
(let x = 1 in
  (let y = 2 in
    ((+) x y)))

其实上面都是一层套一层的很明显的形式。

另外,任何编程语言的语法(除非是汇编等过于简单的可能除外),其语法定义本身就是一层套一层的。比如下面的简单的一个语法定义(C风格的类型定义简化版,没仔细检查,也许会有一些手误):
type-definition ::= type-spec var-list
type-spec ::= int | float
var-list ::= var-list , var | var
var ::= id
那么,像如下的定义:
int a,b,c
其实可以理解为这样子的一层套一层:
(type-definition (type-spec int)
                 (var-list
                  (var-list
                   (var-list (var a)) , (var b)) , (var c))



 

以上组成了强大的 generative programming 工具。


>> > Common
>> > Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php,
>> > javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。
>>
>> very wrong.
>>

当你用 javascript 的方式写 lisp 程序,可读性自然上不去。

貌似我没提到用javascript的方式写lisp程序。不过真的以类似javascript的方式写lisp程序其实也是可以的。
CL从其本身的设计上说,更多的偏向命令式,如各种SO,变量,各种环境状态,等等。



 

Zoom.Quiet

unread,
Jan 25, 2012, 8:37:40 AM1/25/12
to lis...@googlegroups.com
在 2012年1月14日 下午2:09,yin xu <loveu...@gmail.com> 写道:

- 欢迎!
- 中文已经有实效 CLISP 的图书了,,,
- 简单的,48小时学会 scheme 的也都有
- 不过,怎么学会,和教程长短没有关系,看专心与否了,,,

> --
> Lisp-cn(Lisp中文用户组)
> CLUG http://lisp.org.cn

--
人生苦短, Pythonic! 冗余不做,日子甭过!备份不做,十恶不赦!
俺: http://about.me/zoom.quiet
文字协议: http://creativecommons.org/licenses/by-sa/2.5/cn/

Jianshi Huang

unread,
Jan 25, 2012, 8:38:38 AM1/25/12
to lis...@googlegroups.com
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:

>> 1) code as data (这点你说了,但像 lisp 这般彻底的没有,专业一点叫 homoiconic programming
>> language)
>
>
> 怎样才算得上彻底呢?访问所有的源代码?这几乎所有的编程语言都可以轻松实现,源代码本质上就是字符串,一般存储在文件里。
>

Lisp code is not text or string! 虽然存储媒介可以是字符串!但你操作的时候,不是操作字符串。这是最根本最本质的区别。

>>
>> 2) reflection,几乎所有编程需要的信息都可以在 runtime 里得到,bindings info (var, func,
>> macro, etc.),types,declarations,source code!
>
>
> 这包含两点,一个是本身提供的反射功能,类似的功能可以在如Java等语言里面找到。
> 另外一个是,由于运行时里面包含调试器,所以所有的信息都可以在运行时找得到,前提是,必须带上调试信息进行编译,否则,同样找不到。那么,如果我的其他语言的程序里面同样也集成了一个调试器库,同样也能轻松访问到,这并不是一件很困难的事情。
>

应该有你所说的调试器库,不过请举一些非调试情况下的使用方式,至少我是不知道。

哦,对了,除了 runtime (eval-time),还有 compile-time 的 reflection -- environments。

>>
>> 3) composability,基本上所有的都是 expressions
>
>
> 我理解的你的意思应该是,一来全是表达式方式的语法,二来可以一层套一层。
> 这种在其他语言里面非常多,一个例子是F#。
> 例如,我可以在Common Lisp里面编写一个let套上另外一个let:
> (let ((x 1))
> (let ((y 2))
> (+ x y)))
> 我同样也可以在F#里面一个let套上一个let:
> let x = 1 in
> let y = 2 in
> x + y
> 如果喜欢括号和前缀表达式,那么也可以这样写:
> (let x = 1 in
> (let y = 2 in
> ((+) x y)))
>
> 其实上面都是一层套一层的很明显的形式。
>

你说的没错,任何 FP language 都很强调这点。 meta-programming 必须的。但 f# 没有1)和2),无法简单生成程序。

> 另外,任何编程语言的语法(除非是汇编等过于简单的可能除外),其语法定义本身就是一层套一层的。比如下面的简单的一个语法定义(C风格的类型定义简化版,没仔细检查,也许会有一些手误):
> type-definition ::= type-spec var-list
> type-spec ::= int | float
> var-list ::= var-list , var | var
> var ::= id
> 那么,像如下的定义:
> int a,b,c
> 其实可以理解为这样子的一层套一层:
> (type-definition (type-spec int)
> (var-list
> (var-list
> (var-list (var a)) , (var b)) , (var c))
>

问题是你能不能随意得把某个 subtree 用其他的 tree替换,而不影响 evaluation? C 里面分 statement 和
expression。在生成 statement 的地方可以用 x=x+1 也可以用 x++,但 expression 的地方只能用 x++
虽然两者做的事情一样。 if then else 和 :? 又是一个例子。

lisp 的 code 本身就是 ast 形式,3)保证了任何 unit 可以相互组合。

我的 argument 是 1 and 2 and 3,三者不可缺一!

Jeova Sanctus Unus

unread,
Jan 25, 2012, 8:41:41 AM1/25/12
to lis...@googlegroups.com
请不要把common lisp简称为clisp,请简称为CL

Jianshi Huang

unread,
Jan 25, 2012, 8:43:31 AM1/25/12
to lis...@googlegroups.com
2012/1/25 Jianshi Huang <jiansh...@gmail.com>:

>
> 哦,对了,除了 runtime (eval-time),还有 compile-time 的 reflection -- environments。

还有一种 reflection,学术上 reflection 又称 computational reflection,其基本的组成部分是
meta-circular interpreter!

说实话 sicp 里讲了很多关键的东西,只是因为面向初学者,不能展开得太多,建议多看看 paper!

reflection 和 meta-circular interpreter 可以看 3-lisp 的 paper

Xiaofeng Yang

unread,
Jan 25, 2012, 9:39:51 AM1/25/12
to lis...@googlegroups.com
在 2012年1月25日 下午9:38,Jianshi Huang <jiansh...@gmail.com>写道:
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:

>> 1) code as data (这点你说了,但像 lisp 这般彻底的没有,专业一点叫 homoiconic programming
>> language)
>
>
> 怎样才算得上彻底呢?访问所有的源代码?这几乎所有的编程语言都可以轻松实现,源代码本质上就是字符串,一般存储在文件里。
>

Lisp code is not text or string! 虽然存储媒介可以是字符串!但你操作的时候,不是操作字符串。这是最根本最本质的区别。
Common Lisp首先读取源代码(作为字符串),然后将源代码断开成一个一个的token,然后再将其组合并标上一些信息,然后再在这个基础上提供一些接口供程序员操作,我想你所说的就是这个。
作为字符串操作,其实对于Common Lisp来说,也同样提供了这个级别的接口。
Common Lisp的标准库提供了编译器接口,而不少语言并没有提供,这就是你提到的“本质区别”。
对于如OCaml等,本身其实也提供了编译器接口。
对于如C等的语言,也有不少用于操作的库,同时也有不少可扩展的编译器,包括JIT编译器,这些可以提供如Common Lisp一样对源代码进行处理的方式。尽管这种方式提供了便利,但也导致了很多的困难,例如,同一个源代码在两次编译中可能产生完全不同的代码,而且这种不同并不仅仅只是由于优化导致的不同。不少人担心C++会由于模板、宏等因素导致已知源代码却完全无法预知的程序行为,如果他们使用Common Lisp,也许会疯掉。;-) 开个玩笑了,不过的确如此。

 

>>
>> 2) reflection,几乎所有编程需要的信息都可以在 runtime 里得到,bindings info (var, func,
>> macro, etc.),types,declarations,source code!
>
>
> 这包含两点,一个是本身提供的反射功能,类似的功能可以在如Java等语言里面找到。
> 另外一个是,由于运行时里面包含调试器,所以所有的信息都可以在运行时找得到,前提是,必须带上调试信息进行编译,否则,同样找不到。那么,如果我的其他语言的程序里面同样也集成了一个调试器库,同样也能轻松访问到,这并不是一件很困难的事情。
>

应该有你所说的调试器库,不过请举一些非调试情况下的使用方式,至少我是不知道。

哦,对了,除了 runtime (eval-time),还有 compile-time 的 reflection -- environments。


同前边所述,只要有一个提供相应接口的编译器,那么这些并不是问题。
 
>>
>> 3) composability,基本上所有的都是 expressions
>
>
> 我理解的你的意思应该是,一来全是表达式方式的语法,二来可以一层套一层。
> 这种在其他语言里面非常多,一个例子是F#。
> 例如,我可以在Common Lisp里面编写一个let套上另外一个let:
> (let ((x 1))
>   (let ((y 2))
>     (+ x y)))
> 我同样也可以在F#里面一个let套上一个let:
> let x = 1 in
>   let y = 2 in
>     x + y
> 如果喜欢括号和前缀表达式,那么也可以这样写:
> (let x = 1 in
>   (let y = 2 in
>     ((+) x y)))
>
> 其实上面都是一层套一层的很明显的形式。
>

你说的没错,任何 FP language 都很强调这点。 meta-programming 必须的。但 f# 没有1)和2),无法简单生成程序。

1)和2)其实是指编译器接口。原生的编译器接口,比如F#的前辈语言OCaml就已经提供。
 

> 另外,任何编程语言的语法(除非是汇编等过于简单的可能除外),其语法定义本身就是一层套一层的。比如下面的简单的一个语法定义(C风格的类型定义简化版,没仔细检查,也许会有一些手误):
> type-definition ::= type-spec var-list
> type-spec ::= int | float
> var-list ::= var-list , var | var
> var ::= id
> 那么,像如下的定义:
> int a,b,c
> 其实可以理解为这样子的一层套一层:
> (type-definition (type-spec int)
>                  (var-list
>                   (var-list
>                    (var-list (var a)) , (var b)) , (var c))
>

问题是你能不能随意得把某个 subtree 用其他的 tree替换,而不影响 evaluation? C 里面分 statement 和
expression。在生成 statement 的地方可以用 x=x+1 也可以用 x++,但 expression 的地方只能用 x++
虽然两者做的事情一样。 if then else 和 :? 又是一个例子。

lisp 的 code 本身就是 ast 形式,3)保证了任何 unit 可以相互组合。

我的 argument 是 1 and 2 and 3,三者不可缺一!

Common Lisp的基本语法如同C一样,不能乱套。Common Lisp的special operator如同C的各种statement/expression一样,都有自己的语法,不能乱写。至于其他的,如同C一样,要么是调用宏,要么是调用函数。Common Lisp还有个特点,它的special operator基本不提供多少功能,所以它的很多东西只能使用标准库里面的宏或者函数来实现,因此也给人错觉,似乎什么东西看起来都是一样的。
不过,如果要说Common Lisp的代码就是ast形式,从某种意义上说,它们的确是非常接近(甚至绝大多数情况下看起来是一样的)。

P.S.
1. x=x+1也是一个expression,它返回x+1的值。
2. 是Common Lisp而不是Lisp,搞清楚这一点,非常重要。如果仅仅因为Common Lisp就得出“lisp 的 code 本身就是 ast 形式”,那就是大错特错了。
 






--
黄 澗石 (Jianshi Huang)
http://huangjs.net/

Jianshi Huang

unread,
Jan 25, 2012, 9:54:58 AM1/25/12
to lis...@googlegroups.com
算了,没时间详细回你了,仁者见仁,智者见智吧。

2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:
>
> 1)和2)其实是指编译器接口。原生的编译器接口,比如F#的前辈语言OCaml就已经提供。
>

你是说 metaCaml 还是 Camlp4? Camlp4 本身问题多多,语言也不是 ocaml

>
> Common Lisp的基本语法如同C一样,不能乱套。Common Lisp的special
> operator如同C的各种statement/expression一样,都有自己的语法,不能乱写。至于其他的,如同C一样,要么是调用宏,要么是调用函数。Common
> Lisp还有个特点,它的special
> operator基本不提供多少功能,所以它的很多东西只能使用标准库里面的宏或者函数来实现,因此也给人错觉,似乎什么东西看起来都是一样的。
> 不过,如果要说Common Lisp的代码就是ast形式,从某种意义上说,它们的确是非常接近(甚至绝大多数情况下看起来是一样的)。
>

语法当然不能乱,但

“什么东西看起来都是一样的。”有太多的好处了,可以讲三天三夜。

> P.S.
> 1. x=x+1也是一个expression,它返回x+1的值。

恩,assignment 是 expression,我搞错了。

> 2. 是Common Lisp而不是Lisp,搞清楚这一点,非常重要。如果仅仅因为Common Lisp就得出“lisp 的 code 本身就是 ast
> 形式”,那就是大错特错了。
>

哪里错了?

Jianshi Huang

unread,
Jan 25, 2012, 9:56:33 AM1/25/12
to lis...@googlegroups.com
2012/1/25 Jianshi Huang <jiansh...@gmail.com>:
>
> 语法当然不能乱,但

语法当然不能乱,但不区分 statement 和 expression 是重要的一点。e.g. if

Jianshi Huang

unread,
Jan 25, 2012, 10:01:36 AM1/25/12
to lis...@googlegroups.com
我建议你实现一下编译过程,包括里面各种 control-flow analysis 和 dataflow
analysis,intermediate representation,然后你可能会明白 lisp 的便利的地方。

当然我不是说 lisp 是完美的。但作为程序语言毫无疑问是最灵活最便利的。

CRLF0710

unread,
Jan 25, 2012, 11:04:48 AM1/25/12
to lis...@googlegroups.com
sigh。 这也能吵起来。 果然是 LispUsersAreArrogant ……
开个玩笑,有时候太较真了不好……你们就互相让一让。YXF你少钻点牛角尖(this can be offensive),多注意表述自己的观点而不是攻击别人叙述中的漏洞(this can be offensive, too),HJS 你多考虑一下特殊情况(比如LOGO,比如读取宏),“最”这种主观色彩浓烈的词尽量少用(can be offensive, too)。世界不就和谐了……

----拉回正题---

新手的学习当然应该是迭代式的,先拿点有lisp味儿浓厚,学习周期很短的东西来让人家看看喜欢不喜欢,有没有兴趣。喜欢就留下,不喜欢也不用勉强……

* 我还是推荐上手SICP多一点。以前MIT的学生学的就是这本。你读了会觉得这就是The Lisp way of programming. 的感觉,虽然传授的语言内容相当窄。做做课后习题,收获会不小。
* 楼上面提到的Practical Common Lisp当然也不错啦,最近中文版出了,蛮火的。但是缺点也就在practical上。 它就是想教你program in common lisp,思想的内容其实不多,范围也蛮窄的,不注重完整性,但是书里有不少代码给你读和模仿。如果你打算做一些简单的Lisp开发试试,那么推荐之。
* 如果更喜欢scheme风格,但由于某些原因接受不了sicp,可以读读HtDP看看,内容比SICP浅,不过思想性也弱了一些。

以上是有中文版的书,还有一些没有中文版,可以下到pdf:
* Common Lisp : a gentle introduction to symbolic programming 有点老,于是个人感觉稍微有点misleading.但是整体来说是不错的入门书。还有课后习题。
* Land of Lisp 蛮好玩的。这书比较新,我上次去美国在MIT的书店里关于lisp的书只看到这本和sicp。 
* ANSI Common Lisp 据说作入门也不错,我还没有来得及读这本,不好评价,惭愧惭愧。
* The Little Lisper 有点老啦,但是风格很独特,而且短。不过这也是缺点……
* The Little Schemer 同上。
* 楼上面提到的Computer Science Logo Style 是用另一种很不一样的Lisp方言(Logo)来讲计算机科学的内容。缺点是太厚,而且因为讲的东西巨多,所以只推荐作为拓宽视野用。(好吧,这本我也只读了前两章)


总之,
Happy Hacking~

Xiaofeng Yang

unread,
Jan 25, 2012, 11:06:39 AM1/25/12
to lis...@googlegroups.com
这些都做过…

     Best regards,
Xiaofeng Yang


Xiaofeng Yang

unread,
Jan 25, 2012, 11:18:41 AM1/25/12
to lis...@googlegroups.com
在 2012年1月26日 上午12:04,CRLF0710 <crlf...@gmail.com>写道:
sigh。 这也能吵起来。 果然是 LispUsersAreArrogant ……
开个玩笑,有时候太较真了不好……你们就互相让一让。YXF你少钻点牛角尖(this can be offensive),多注意表述自己的观点而不是攻击别人叙述中的漏洞(this can be offensive, too),HJS 你多考虑一下特殊情况(比如LOGO,比如读取宏),“最”这种主观色彩浓烈的词尽量少用(can be offensive, too)。世界不就和谐了……

 
你少钻点牛角尖”我觉得你这样想不好。这个世界上本来就没有牛角尖,你认为我钻了,那我就钻了。你已经在评价我的行为为“钻牛角尖”了,这就是你思维上的失误。你从我们用语言表达的话题转换成了对我行为的指责。像“有时候太较真了不好”这样的想法都是阻碍你深入思考的根源之一。什么钻牛角尖之类的想法,只有在中国传统的经验主义思想里面才有。经验是不可靠的。

多注意表述自己的观点而不是攻击别人叙述中的漏洞”我不认可你这种想法。而且这种表达明显是针对人儿不是针对我们邮件的内容了。而且直接用了“攻击”这样子的词语。我希望你引用原文并且给出攻击的通用定义然后再对我的“攻击行为”作出证明。

以下的内容我还没看,先对你表达不爽。

P.S.
这些又有什么不好呢?我觉得非常好。应该发扬!
说话者没有漏洞,也就不会被别人钻(注意,是“钻”,不是攻击),语言严谨,本来就是好事,如果是一种习惯,那就更好。“钻牛角尖”,本来的意思就是“深入钻研”,发现别人发现不到并且忽略的地方,这些都是好事。





 
----拉回正题---

新手的学习当然应该是迭代式的,先拿点有lisp味儿浓厚,学习周期很短的东西来让人家看看喜欢不喜欢,有没有兴趣。喜欢就留下,不喜欢也不用勉强……

* 我还是推荐上手SICP多一点。以前MIT的学生学的就是这本。你读了会觉得这就是The Lisp way of programming. 的感觉,虽然传授的语言内容相当窄。做做课后习题,收获会不小。
* 楼上面提到的Practical Common Lisp当然也不错啦,最近中文版出了,蛮火的。但是缺点也就在practical上。 它就是想教你program in common lisp,思想的内容其实不多,范围也蛮窄的,不注重完整性,但是书里有不少代码给你读和模仿。如果你打算做一些简单的Lisp开发试试,那么推荐之。
* 如果更喜欢scheme风格,但由于某些原因接受不了sicp,可以读读HtDP看看,内容比SICP浅,不过思想性也弱了一些。

以上是有中文版的书,还有一些没有中文版,可以下到pdf:
* Common Lisp : a gentle introduction to symbolic programming 有点老,于是个人感觉稍微有点misleading.但是整体来说是不错的入门书。还有课后习题。
* Land of Lisp 蛮好玩的。这书比较新,我上次去美国在MIT的书店里关于lisp的书只看到这本和sicp。 
* ANSI Common Lisp 据说作入门也不错,我还没有来得及读这本,不好评价,惭愧惭愧。
* The Little Lisper 有点老啦,但是风格很独特,而且短。不过这也是缺点……
* The Little Schemer 同上。
* 楼上面提到的Computer Science Logo Style 是用另一种很不一样的Lisp方言(Logo)来讲计算机科学的内容。缺点是太厚,而且因为讲的东西巨多,所以只推荐作为拓宽视野用。(好吧,这本我也只读了前两章)


总之,
Happy Hacking~

--
Wir müssen wissen; wir werden wissen!
CrLF.0710

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

刘滔

unread,
Jan 25, 2012, 11:43:36 AM1/25/12
to lis...@googlegroups.com
哈哈,受教了,各位的争论很精彩啊,又发现自己知识存在不小的缺漏,可以回去补习一番了。

另外,如果还要继续探讨的话,建议再开一个话题,这个毕竟是别人的报道贴~
--
Liutos Love Linux LaTeX Lisp Ling

我的博客,纪念我死去的GAE

Jianshi Huang

unread,
Jan 25, 2012, 11:54:37 AM1/25/12
to lis...@googlegroups.com
2012/1/26 Xiaofeng Yang <n.akr....@gmail.com>:
> 这些都做过...
>

赞!But then I'm even more confused :)

我举一个实际的例子说明 lisp 的灵活性

最近在做一个程序分析的项目,用 haskell,需要改进 simplifier 部分,最大的问题是 equal
太慢,两棵一样的树必须从头到尾遍历一遍才能确定是否相同。

ok, 不改变源程序(或者很少)的情况下,如何改进?

symbolic computation 里有一个很有用的 technique,hash consing,即 cons
的时候比较检查是否已有一样的 cons 存在,因为 side-effect free,存在的情况下无需新的 cons。这样的好处是:1)
可以大幅度减少内存的使用(当重复 subtree 很多的情况下) 2) equal 可以用 eq 代替,equal is O(n), eq
is O(1),通常 eq 只比较 register 的值是否一致(primitive or memory address)

用 lisp 的话可以这么做,

1) 在 simplifier 模块中找出所有使用 cons 的函数(因为有 source code),如果 implementation
的 source code 也有,甚至可以自动找出被调用的标准库里的 consing 的函数(比如 mapcar,impl 无源码也可以
load 某个 cl in cl 的实现)。

2) 用 macrolet 将 cons 变成 hash-consing 的版本,将所有 consing 的辅助函数转化成 local
函数(这里 cons 的定义从 built-in function 变成 macro),在这个 environement 下重新编译
simplifier

3) 把所有的 'equal 和 #'equal 变成 'eq #'eq

于是你的 simplifier 就变成完全使用 hash-consing 的版本了。


以上例子的目的是想说明就算是很核心很底层的实现,如果整套系统完全贯彻了 1,2,3 的特性,可以很方便实现你想要的算法而

无需改变源程序!

Jianshi Huang

unread,
Jan 25, 2012, 11:57:07 AM1/25/12
to lis...@googlegroups.com
2012/1/26 CRLF0710 <crlf...@gmail.com>:

> HJS 你多考虑一下特殊情况(比如LOGO,比如读取宏),“最”这种主观色彩浓烈的词尽量少用(can be offensive,
> too)。世界不就和谐了……

本来就是个人观点,我真的是觉得用“最”不为过啊!

我觉得大家能理解其他人的观点才是最重要的。当然语言严谨是美德。。。

Jianshi Huang

unread,
Jan 25, 2012, 12:02:18 PM1/25/12
to lis...@googlegroups.com
2012/1/26 Jianshi Huang <jiansh...@gmail.com>:

> 2) 用 macrolet 将 cons 变成 hash-consing 的版本,将所有 consing 的辅助函数转化成 local
> 函数(这里 cons 的定义从 built-in function 变成 macro),在这个 environement 下重新编译
> simplifier
>
> 3) 把所有的 'equal 和 #'equal 变成 'eq #'eq

应该是

2) 用 macrolet 将 cons 变成 hash-consing 的版本,将所有 consing 的辅助函数转化成 local

函数(这里 cons 的定义从 built-in function 变成 macro),把所有的 'equal 和 #'equal 变成 'eq #'eq

3) 在这个 environement 下重新编译 simplifier

CRLF0710

unread,
Jan 25, 2012, 10:27:51 PM1/25/12
to lis...@googlegroups.com
在 2012年1月26日 上午12:18,Xiaofeng Yang <n.akr....@gmail.com>写道:
你少钻点牛角尖”我觉得你这样想不好。这个世界上本来就没有牛角尖,你认为我钻了,那我就钻了。你已经在评价我的行为为“钻牛角尖”了,这就是你思维上的失误。你从我们用语言表达的话题转换成了对我行为的指责。像“有时候太较真了不好”这样的想法都是阻碍你深入思考的根源之一。什么钻牛角尖之类的想法,只有在中国传统的经验主义思想里面才有。经验是不可靠的。
 计算机技术作为非自然科学或者工程技术,大部分“事实”来源于设计决定和实现时的Workaround。我觉得理解设计意图,期望做出更优秀的设计,比强调哪些是"Fact", "Truth"重要得多。另外关于之前"用语言表达的话题",你真的觉得在这个帖子里继续讨论很合适?

多注意表述自己的观点而不是攻击别人叙述中的漏洞”我不认可你这种想法。而且这种表达明显是针对人儿不是针对我们邮件的内容了。而且直接用了“攻击”这样子的词语。我希望你引用原文并且给出攻击的通用定义然后再对我的“攻击行为”作出证明。
我的意思是,要讨论不要辩论,因为辩论太容易跑题。比如你们说了半天,每个人罗列了不少fact,说了一会已经不知道在讨论啥了。 

以下的内容我还没看,先对你表达不爽。
随便~ 我只是单纯希望结束这场在别人帖子下面的争论。对于楼里面提到的任意一个问题,开个新楼都更恰当。

Jianshi Huang

unread,
Jan 26, 2012, 4:21:18 AM1/26/12
to lis...@googlegroups.com
2012/1/26 CRLF0710 <crlf...@gmail.com>:

>
>> "你少钻点牛角尖"我觉得你这样想不好。这个世界上本来就没有牛角尖,你认为我钻了,那我就钻了。你已经在评价我的行为为"钻牛角尖"了,这就是你思维上的失误。你从我们用语言表达的话题转换成了对我行为的指责。像"有时候太较真了不好"这样的想法都是阻碍你深入思考的根源之一。什么钻牛角尖之类的想法,只有在中国传统的经验主义思想里面才有。经验是不可靠的。
>
> 计算机技术作为非自然科学或者工程技术,大部分"事实"来源于设计决定和实现时的Workaround。我觉得理解设计意图,期望做出更优秀的设计,比强调哪些是"Fact",
> "Truth"重要得多。
>

赞同,而且很多时候 facts, "truth" 是随着理解的加深而改变的。

>>
>> "多注意表述自己的观点而不是攻击别人叙述中的漏洞"我不认可你这种想法。而且这种表达明显是针对人儿不是针对我们邮件的内容了。而且直接用了"攻击"这样子的词语。我希望你引用原文并且给出攻击的通用定义然后再对我的"攻击行为"作出证明。
>
> 我的意思是,要讨论不要辩论,因为辩论太容易跑题。比如你们说了半天,每个人罗列了不少fact,说了一会已经不知道在讨论啥了。
>

我们在讨论,

1)Lisp 哪些地方跟其他语言有本质的区别
2)因为这些区别哪些地方变得相对容易实现

>> 以下的内容我还没看,先对你表达不爽。
>
> 随便~ 我只是单纯希望结束这场在别人帖子下面的争论。对于楼里面提到的任意一个问题,开个新楼都更恰当。
>

我支持开新楼。

P.S.

就没有人讨论一下我昨天发的实例?灰常地伤心!XD

Jianshi Huang

unread,
Jan 26, 2012, 4:54:56 AM1/26/12
to lis...@googlegroups.com
2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:

> Common
> Lisp首先读取源代码(作为字符串),然后将源代码断开成一个一个的token,然后再将其组合并标上一些信息,然后再在这个基础上提供一些接口供程序员操作,我想你所说的就是这个。

你说的token是不准确的,lisp 源代码是 sexp 形式,跟 reader 无关。以CL为例,sexp里不单单可以有 symbol,
cons, primitives, 也可以有 array, struct, clos object 等任何值。你可以想想 CL 的
reader macro,读入后可以是任何值。CL 的 evaluation model 说非 symbol 非 cons 的值的
evaluation 结果是其自身,这点很重要。

举个简单的例子

先定义一个 foo struct
CL-USER> (defstruct foo x y)
FOO

把 foo 绑定为新建的 foo object
CL-USER> (setf foo (make-foo :x 1 :y 2))
#S(FOO :X 1 :Y 2)

一般我们访问 foo 的元素时,用以下形式
CL-USER> (foo-x foo)
1

但我们也可以用以下形式
CL-USER> (foo-x (load-time-value foo))
1

和以下形式
CL-USER> (foo-x #.foo)
1

如果我们想看最后一行的实际代码,quote
CL-USER> '(foo-x #.foo)
(FOO-X #S(FOO :X 1 :Y 2))

这其实也是 pretty-print 之后的输出,想看真正的内容,我们需要用 describe
foo-x 后面那个其实是我们创建的 foo object
CL-USER> (describe (second '(foo-x #.foo)))
#S(FOO :X 1 :Y 2)
[structure-object]
Slots with :INSTANCE allocation:
X = 1
Y = 2

不少 specialization 技巧和 caching 技巧 都利用了以上特性。(可以思考一下 atom 和 constantp 的定义)

刘滔

unread,
Jan 26, 2012, 7:12:24 AM1/26/12
to lis...@googlegroups.com
涧石兄的最后一个例子又让我长见识了,结构体居然在应用#.读取宏后是那样的形式~

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

Jeova Sanctus Unus

unread,
Jan 26, 2012, 9:50:50 AM1/26/12
to lis...@googlegroups.com
低调分享,land of lisp.
http://cfy.googlecode.com/files/Land%20of%20Lisp.pdf.xz

在 2012年1月25日 下午6:16,CRLF0710 <crlf...@gmail.com> 写道:

Zoom.Quiet

unread,
Jan 26, 2012, 10:47:17 AM1/26/12
to lis...@googlegroups.com
在 2012年1月26日 下午10:50,Jeova Sanctus Unus <jeova.san...@gmail.com> 写道:
> 低调分享,land of lisp.
> http://cfy.googlecode.com/files/Land%20of%20Lisp.pdf.xz
>

- 很欢乐的书!

> 在 2012年1月25日 下午6:16,CRLF0710 <crlf...@gmail.com> 写道:
>> 在 2012年1月14日 下午2:09,yin xu <loveu...@gmail.com>写道:
>>>
>>> 只是想改变下偶的程序设计观
>>
>>
>> 只是出于这个目的的话,读读SICP就够了,再来随便拿本CL的书看看Lisp的那些设施会被怎样使用就可以啦。个人感觉这样性价比比较高。
>>

...

屏幕快照 2012-01-26 23.44.40.png

刘滔

unread,
Jan 26, 2012, 11:41:09 PM1/26/12
to lis...@googlegroups.com
我更喜欢《Land of Lisp》的网站前面的漫画部分~

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

Origin Cheung

unread,
Jan 27, 2012, 10:20:11 PM1/27/12
to lis...@googlegroups.com
哈哈,终于尼马找到Land of Lisp了。哈哈哈哈

Junsong Li

unread,
Jan 25, 2012, 4:15:48 AM1/25/12
to lis...@googlegroups.com
@Xiaofeng Yang,你误会人家了,妄写了这么多好的建议。看样子,人家不是想更改编程观念,要不然“十年学会程序设计”人家会不知道?人家点名要简单的教程,类似于学python时候的a byte of python,看半天就看完,看完之后心中充满了冲动那种。

@ying xu:没有简单的。

学 common lisp 的书就那么几本: practical common lisp, ANSI common lisp,on lisp,a land of lisp + 其他杂七杂八不系统的书。
1. 看 practical common lisp 还觉得慢,不是教程的问题。摸着自己的心问问自己,自己到底为什么这么着急?然后转 3
2. 看 on lisp 觉得慢,正常的,去看 ANSI common lisp。
3. 看 ANSI common lisp 还觉得慢。问问自己到底为什么要学 lisp?是为了掌握这么语言,还是为了短时间学出来去装13给人看?
4. 看 a land of lisp 还觉得慢,只能说这种教程不适合你,去看 ANSI common lisp

不断地去找网站,论坛,lisp tutorials,lisp 课程的,不用费劲了,我找过了。我个人而言,没有哪本书比 ANSI Common Lisp 更全面地从基础开始讲解,Paul 的写作水平放在那里,大家有目共睹的。

PS to pythonic readers:lisp 的书里面没有像 a byte of python 那样看几个小时就看完的书。
PS2: 更多的人想问的是,学完一本书之后可以到达什么水平吧?

With my warmest Spring Festival regards,
Junsong Li


On Wed, Jan 25, 2012 at 2:55 PM, Xiaofeng Yang <n.akr....@gmail.com> wrote:
Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。
Common Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php, javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。
简单点的教程:Practical Common Lisp
LISP系个人感觉最简单的编程语言:LOGO

LISP是一个大家族,跟Common Lisp是两个概念。

如果要改变编程观念,也许以下语言可以参考,这些语言让你不得不换一种思路来编程(习惯的力量时强大的,只有当你被逼迫的时候,才能学会一种新的思路):
Haskell - 流行的纯函数式编程语言,较有名的实现,如GHC。另外,如OCaml等编程语言,尽管支持多范性,但是如果不使用纯函数式编程会需要比较麻烦的方法(其实Haskell也是如此)。
ISO Prolog - 流行的纯逻辑式编程语言,较有名的实现,如BProlog, SWI-Prolog, GNU Prolog, 等
当然还有很多基于其它计算模型的编程语言,只不过如上的两种类型是最常被提到的。

另外,你可以加入社区群:25342018


     Best regards,
Xiaofeng Yang


在 2012年1月14日 下午2:09,yin xu <loveu...@gmail.com>写道:
今天是我第一次想了解下LISP,只是想改变下偶的程序设计观~
网上找了common lisp .1000多页,坑爹不止两三天~~
有没有简单点的教程~~

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

Norman Mo

unread,
Jan 25, 2012, 6:46:28 AM1/25/12
to lis...@googlegroups.com
弱弱的初学者现在在看《Land of LISP》,虽然是英文版的,不过感觉还蛮好懂……

在 2012年1月25日 下午7:43,Xiaofeng Yang <n.akr....@gmail.com>写道:
我很希望能听到你的详细观点,而不是简单的一个“wrong”。

     Best regards,
Xiaofeng Yang


在 2012年1月25日 下午7:06,Jianshi Huang <jiansh...@gmail.com>写道:

2012/1/25 Xiaofeng Yang <n.akr....@gmail.com>:

> Common Lisp也许能改变一下你的一部分编程观念,但是不算很多。就算fans沾沾自喜的宏、REPL等其实在很多常见的语言都有同类的东西。

Wrong wrong wrong, 你应该来上次的 lisper meetup 听我的第二个演讲的:)
> Common Lisp其实并不是传说中的函数式语言,或者更准确的说,是支持函数式的多范性编程语言,绝大多数时候,你编写的程序还是命令式的,就和用php,
> javascript编程其实差不多。好处仅仅只是语法十分简单,但同时也牺牲了不少可读性。

very wrong.


> 简单点的教程:Practical Common Lisp
> LISP系个人感觉最简单的编程语言:LOGO
>
> LISP是一个大家族,跟Common Lisp是两个概念。
>
> 如果要改变编程观念,也许以下语言可以参考,这些语言让你不得不换一种思路来编程(习惯的力量时强大的,只有当你被逼迫的时候,才能学会一种新的思路):
> Haskell -
> 流行的纯函数式编程语言,较有名的实现,如GHC。另外,如OCaml等编程语言,尽管支持多范性,但是如果不使用纯函数式编程会需要比较麻烦的方法(其实Haskell也是如此)。
> ISO Prolog - 流行的纯逻辑式编程语言,较有名的实现,如BProlog, SWI-Prolog, GNU Prolog, 等
> 当然还有很多基于其它计算模型的编程语言,只不过如上的两种类型是最常被提到的。
>

比较的方法就是真正做一些项目!然后你就明白灵活性是多么重要了。


Cheers,

--
黄 澗石 (Jianshi Huang)
http://huangjs.net/
--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

刘滔

unread,
Jan 28, 2012, 11:34:59 PM1/28/12
to lis...@googlegroups.com
重新捡起《On Lisp》来啃了,看了5、6次,从来没有一次认真看完过,囧啊~

lei zhang

unread,
Jan 29, 2012, 1:32:28 AM1/29/12
to lis...@googlegroups.com
我也看这个,没看几章,看不下去,回去继续看pcl了,,

CRLF0710

unread,
Jan 29, 2012, 4:34:16 AM1/29/12
to lis...@googlegroups.com
看过On Lisp一遍。个人觉得On Lisp不应该作为CL教程用。

因为这本书的写作风格其实相当的Advisory,它不会告诉你这些东西的具体的specification,而是说,你知道有这个功能吧,你知道有这个功能吧,看,可以这样用哦~~ 然后几行代码一贴~ 于是你就受到启发了,在你下次写程序的时候可能就不自觉的这么写了。

并不是说这本书不好。只是在开始读On Lisp之前,一定要确保它要讲的东西你都知道是怎样工作的(至少大部分),大致明白原理。(它不太详细给你讲的。)因此建议稍微晚一点再读。

另:顺便提一句,最近一段时间在读Common Lisp the Language 2nd (CLtL2),好多细节都是未曾在其他书里提到过的(自认为之前也读了不少Lisp书),收获相当大。如果有时间,有耐心,并且真的对Common Lisp 打算take it serious,推荐一下。不过有点厚,带附录1096页。Guy Steele的语言蛮平实的,但并不难读。

yin xu

unread,
Jan 29, 2012, 4:50:26 AM1/29/12
to lis...@googlegroups.com
看了 CRLF0710  的签名,发现 CRLF0710还懂德语,真不错!

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

CRLF0710

unread,
Jan 29, 2012, 5:13:23 AM1/29/12
to lis...@googlegroups.com
不懂德语啊,签名是Hilbert的名言~  嘻嘻~
338.gif

Xiaofeng Yang

unread,
Jan 29, 2012, 5:25:20 AM1/29/12
to lis...@googlegroups.com
我们需要知道知道我们 


     Best regards,
Xiaofeng Yang


2012/1/29 CRLF0710 <crlf...@gmail.com>
--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

338.gif

yin xu

unread,
Jan 29, 2012, 8:33:49 AM1/29/12
to lis...@googlegroups.com
应当是,我们想要知道的,我们必定能知道!
338.gif

刘滔

unread,
Jan 29, 2012, 9:11:07 PM1/29/12
to lis...@googlegroups.com
CLtL2一直没有看,感觉这是一本参考书,好像是给人了解Common Lisp的一些细枝末节

和阴暗面用的,嗯,可能也是因为了解不深入吧~
338.gif

CRLF0710

unread,
Jan 29, 2012, 11:39:44 PM1/29/12
to lis...@googlegroups.com
差不多,挺接近手册的。不过是一本很生动的手册。Steele会在书里讲这些特性和第一版的区别,还会讲和一些古老LISP的区别和联系。有的功能是从其他语言borrow过来会讲这些特性使用时的注意事项,有时还会说为什么这样设计。有些特性不太好,需要时间来完善。有些已经重新设计过了,有些已经去掉了。有些术语是misnomer,有些术语虽然是misnomer但是很有用大家也习惯了于是继续用。 总之读起来收获蛮大的……(不过看这本书相当耗时……我这个假期基本就没做别的事了,现在才看到接近3/4……)

天国之翼 freewinger

unread,
May 31, 2012, 7:18:26 AM5/31/12
to lis...@googlegroups.com
你们看了吗?
 
Reply all
Reply to author
Forward
0 new messages