Lisp
文章平均质量分 64
keyboardOTA
喜欢技术挑战
展开
-
Lisp编程环境的搭建
对很多程序员来讲Lisp都是一个神秘的语言,有可能从来没有接触过Lisp,或者根本没有听说过Lisp。不过,如果你接触一些黑客大家的文章,你会经常看到Lisp这个名字,而且在很多大虾眼中Lisp都是一个超级牛语言,不少大虾把Lisp列为程序员必学的语言之一。很多人因为大虾的鼓吹开始学习Lisp语言,其中也包括我自己,不过Lisp和其它语言真的差别太大,常常让人摸不着门道,就是简单的环境设置都让人叫原创 2012-05-28 19:23:44 · 18114 阅读 · 10 评论 -
Lisp语言:控制台输出与输入
Lisp全名是Lisp Processor,就是列表处理语言的意思,所以Lisp语言以列表为中心。正因为这个原因,很多Lisp语言的教程在简单介绍基本Lisp后就开始讨论Lisp中的列表,出现一堆令人费解的列表和无尽的括号。对于很多普通的程序员来讲,这种方式总是让人觉的不舒服,难道不能像学习一般语言那样进行学习吗?或许我们可以试试!下面我们像写一个普通c或者是java程序那样写个Lisp程序。大家原创 2012-05-29 23:58:38 · 8240 阅读 · 0 评论 -
Lisp语言:条件判断
学习了Lisp语言的控制台输出与输入,让我们来看看Lisp语言的条件判断。Lisp中的条件判断看起来和其它语言差不多,学习起来还是比较简单的。1. 基本用法:基本的用法像下面这个样子:(if 条件判断 条件成立时的结果 条件不成立时的结果)我把其中的空间加长了,看起来比较清晰,反正Lisp对一个空格和多个空格的处理是一样的。按上面原创 2012-06-02 22:47:32 · 11250 阅读 · 1 评论 -
Lisp语言:循环控制
了解了Lisp语言的条件判断,让我们看看Lisp语言的循环控制。对于稍有编程经验的人来说,循环是比较容易理解的,一般语言里面的循环无外乎for循环,while循环,do until循环等,有些语言的循环稍微复杂一点,也不过是一些变化形式。而Lisp语言里的循环却不是这么简单,查找Lisp中loop的使用就可以发现一系列的资料,有关于loop的简单使用的,有关于loop的高阶使用的,仔细看起来会觉得原创 2012-06-05 09:28:46 · 8097 阅读 · 1 评论 -
Lisp语言:函数的定义,调用以及参数的传递
进一步了解一下Lisp语言中函数的使用,虽然从这篇文章才开始介绍函数,但是我们在之前的Lisp文章中已经多次接触函数了。函数的定义在Lisp中函数的定义使用下面的格式:(defun function1 () (format *query-io* "in function1~%"))其中defun是函数定义的关键字,function1是函数名,跟着的()是参数定义,在这里不需要参数,原创 2012-06-07 18:23:27 · 13054 阅读 · 0 评论 -
Lisp语言:函数的可选参数,剩余参数以及关键字参数
上一篇有关Lisp函数的文章简单介绍了函数的定义和调用,其中使用的参数是一般的参数。为了方便大家,将那篇文章的链接列出:http://blog.csdn.net/keyboardota/article/details/7642767如上文所述,如果定义函数时定义的是一般的参数,调用函数时传入参数的数量必须和函数定义的参数的数量相同,参数太多或者太少都会导致程序错误。这样的函数调用起来真是有点不灵活原创 2012-06-15 01:03:39 · 6598 阅读 · 0 评论 -
Lisp语言:二维数组和多维数组
很多情况下只有一维数组是不够用的,有时我们需要使用二维数组甚至是多维数组。Lisp中二维数组的使用和一维数组很接近,都是使用make-array函数来创建。创建一维数组的样例如下:(setf test-array-1 (make-array 10 :initial-element "xxx"))而创建二维数组的样例看起来非常相似:(setf test-array-2 (make-array '(3原创 2012-07-04 18:10:32 · 4769 阅读 · 0 评论 -
Lisp语言:可变长数组
之前讨论的数组都是定长数组,定长数组最大的问题就是数组的长度不能动态改变。如果定义数组时定义的数组长度不够,数组满了就不能另外添加元素,如果数组定义的长度太长,又浪费内存空间。为了应对这个问题,我们需要一个可以动态改变长度的数组。讨论到这时c程序员会想到链表,而java程序员可能会想到Vector,它们都通过一定的性能牺牲实现了可变长度的数组。Lisp中也有类似的数据结构,可以称之为可变长数组,在原创 2012-07-05 21:01:00 · 4035 阅读 · 3 评论 -
使用hunchentoot搭建Lisp web 服务器。
很多人学习Lisp的时候都觉得Lisp学习起来很枯燥,不能用来写俄罗斯方块,不能用来写画图板,来来回回都是写一些基于文本的样例,很是无聊。其实Lisp可以用来写很多东西,而且写起来很有意思。因为Lisp文本处理能力很强,很适合写网站,所以对初学者来讲,如果希望做一些实际一点的小应用,写个Lisp网站是个不错的选择。要写Lisp网站的话第一个问题就是如何搭建一个支持Lisp的web服务器,下面就详细原创 2012-06-12 00:04:40 · 9591 阅读 · 6 评论 -
Lisp语言:变量以及变量的作用范围
到现在才讨论变量似乎有点迟,在过去的文章中我们已经很多次使用变量。之所以到现在才讨论变量是因为不想各位因为复杂的变量使用规定感到困惑。如果只是基本使用,理解变量确实可以很简单。就像在之前的几篇文章中,我们使用了很多变量,我们不用进行复杂的讨论也可以理解这些变量。变量的简单使用也就是如何赋值,如何取值。前面的文章我们使用setq函数对变量赋值,使用时直接通过变量名代表对应的值。如下面这样的代码:(s原创 2012-06-21 15:47:22 · 7481 阅读 · 4 评论 -
Lisp语言:散列表(hash table)
散列表,也就是hash-table,在编程过程中会经常使用到,它以“关键字--数值”这样的对应关系保存数据,适合用于保存那些需要通过关键字查找数值的数据。这里不打算详细介绍散列表的原理,希望深入了解散列表的同学请参考其它相关资料,这里只是介绍如何在Lisp中使用散列表。再说,这种涉及理论的高深话题也不是我这种半途出家的人能说明白的,就是叫我讲我也不一定讲的清楚。说来惭愧,在刚开始工作的第一年中,我原创 2012-07-10 00:19:04 · 3306 阅读 · 0 评论 -
Lisp语言:列表(List)
终于开始讨论列表了,列表是Lisp的精华之一,也是学习Lisp的难点之一。列表的精彩之处在于,它不仅仅是Lisp中的一种数据结构,它也是Lisp语言的构成部分,Lisp语言中的所有语句都是一个列表。反观我们常见的编程语言,语言中的语句有特定的语法,而这些语法只有编译器可以理解,用编程语言自己去解释自己几乎就成了一个不可能完成的任务。举个例子,看看下面的java语句:int i = j + 10 ;原创 2012-07-10 21:15:15 · 13792 阅读 · 7 评论 -
Lisp语言:数组
讨论了变量以后让我们来看看Lisp中的数组,对于非Lisp程序员来讲这是再自然不过的了,很多编程语言的教材上都是在讲述了一般性语法后讲解数组。不过,Lisp程序员可能会有点疑问,为什么不开始介绍列表呢?列表作为Lisp语言的关键在Lisp中起到了重要的作用,所以很多有关Lisp的材料都是以介绍列表开始,这对于一般程序员来讲有在思路转换上有点困难。所以在这里还是按一般程序员的习惯,先介绍数组等常见的原创 2012-07-02 13:01:56 · 5423 阅读 · 3 评论 -
Lisp语言:Do循环的使用
有关Lisp语言中的Do循环,就像很多人说的一样,初看起来太奇怪了,不知道怎么理解。所以在这里做一个简单的介绍,看完大家可以发现其实Lisp中的do循环也是比较简单的。 先看看Lisp语言中对于do循环的说明:(do (variable-definitions*) (end-test-form result-form*) statement*)翻译成“中文”大概意思是这样的:原创 2012-11-29 17:35:36 · 8969 阅读 · 1 评论 -
Lisp语言:在Windows环境下使用什么编辑器
前面一篇博文讲述了Windows环境下CLisp的安装,文章链接如下:http://blog.csdn.net/keyboardota/article/details/8237185安装了CLisp环境后,我们可以使用任何一种文本编辑器编写Lisp程序,然后在CLisp环境中通过(load "c:\your-path\your-lisp-file.lisp")来加载Lisp程序文件,并对程序文件中原创 2012-12-09 23:13:33 · 18029 阅读 · 0 评论 -
Lisp语言:文件操作
作为一个基本功能,文件操作对于大多数语言来讲都是必须支持的,Lisp语言和大多数语言一样提供了文件操作接口。 在Lisp中对文件的操作通过函数open来实现,通过open函数打开一个文件,然后通过read函数读取文件内容,或者通过format函数将数据写入文件中。 函数open的第一个参数是目标文件的路径和文件名,然后是一些参数,包括::direction用于指定文件打开后会执行的操作,缺省值是读原创 2012-12-17 15:30:04 · 9032 阅读 · 0 评论 -
Lisp语言:如何在hash table中使用字符串作为关键字(key)?
前面的博文讨论了Lisp中hash table的基本使用,文章链接如下:http://blog.csdn.net/keyboardota/article/details/7681767在使用Lisp中的hash table时,有一点是需要注意的,就是hash table使用什么方式去比较不同的关键字(key)。如果对以上问题理解不清楚,现实编程中很容易出现一个问题,就是使用字符串作为关键字时发现用原创 2012-12-17 17:18:59 · 2979 阅读 · 1 评论 -
Lisp 语言: Emacs和Slime的配置
说实在话,Windows环境中进行Lisp编程,用久了还是觉得Emacs+Slime的环境比较好用。 有关Emacs和slime的配置在网上已经有很多很详细的文章了,这里只是展现一下我当时安装Emacs+slime环境的过程,共大家参考。 首先需要下载emacs,emacs是一个非常绿色的软件,下载解压就可以运行emacs的官网下载链接如下:http://ftp.gnu.org/pub/gnu/e原创 2013-01-11 10:50:10 · 14778 阅读 · 2 评论 -
Win7下Emacs间歇性变慢的问题
最近在新安装的Win7下使用Emacs,发现使用的很不爽,因为在新安装的Win7下我们Emacs经常间歇性变慢,过十几二十秒才反应过来。 后来找了一些网上的文章看了看,发现其他人在连接企业域的Win7上也会有这个问题,原因是Windows上的netlogon服务会去尝试连接DC进行查找动作。解决方法是直接停掉netlogon服务就好了。原文链接如下:http://www.hydrus.org.uk原创 2013-01-18 17:24:45 · 5194 阅读 · 0 评论 -
List 语言:set和setq差别
在Lisp中,如果我们希望对一个变量赋值,可以使用set函数,用法如下:(set ‘my-value "my string")上面的代码是对变量my-value进行赋值,值是"my String"。注意其中的'my-value前面是有一个单引号的。 我们知道,在Lisp中,'my-value其实是(quote my-value)的简写,所以上面的set函数代码也可以写成这样:(set (quote原创 2013-01-18 16:45:19 · 18632 阅读 · 1 评论 -
在Mac上安装MIT的scheme
如果你在读SICP(《计算机程序的构造和解释》)的话,无疑你希望安装一个MIT的scheme运行环境以测试书中的样例,或者是完成书中的练习。如果你恰好使用的是Mac的话,你当然就会和我一样,希望在Mac上安装MIT的scheme。很高兴地告诉你,在Mac上安装mit-scheme非常简单,你可以通过brew快速安装好mit-scheme。如果你已经安装配置好brew的话,通过以下命令就可以安装mi原创 2013-05-10 16:46:55 · 10046 阅读 · 0 评论 -
Mac 上为mit-scheme配置emacs环境
前两天写了在Mac上安装mit-scheme的文章,讲了在Mac上安装mit-scheme的过程。安装了mit-scheme以后,可以通过命令行直接执行mit-scheme命令进入mit-scheme的REPL环境。除了可以在REPL环境中直接编写mit-scheme代码以外,也可以通过一般的编辑器编写好mit-scheme代码,然后在REPL环境中通过(load "")命令加载进来测试。无论怎么原创 2013-06-01 00:00:33 · 11552 阅读 · 1 评论 -
SICP习题 (1.12)解题总结
SICP 习题 1.12 要完成的工作是帕斯卡三角,有没有觉得“帕斯卡”这三个字很熟悉呀,在你人生知识水平的最高点上你应该接触过他,不过现在你可能忘了。仔细回想的话,你可能会有点印象,物理中的压强单位就是“帕斯卡”。很开心地告诉你,这两个“帕斯卡”是同一个人。帕斯卡不仅是个物理学家,还是个数学家,百度百科里这样描述:“布莱士.帕斯卡是法国数学家、物理学家、哲学家、散文家。” 。人家还是个散文家!!原创 2013-09-23 19:58:17 · 6059 阅读 · 1 评论 -
SICP 习题 (1.13) 解题总结
SICP习题1.13要求证明Fib(n)是最接近 的整数,其中。题目还有一个提示,提示解题者利用归纳法和斐波那契数的定义证明Fib(n)=说实话,面对这道题我是完败,完全没有思路那种。不过,在讲计算机程序的书里跑出一道纯数学题有点过分了吧!太不把我们这些没有数学天分的程序员当程序员看了!然后我好长时间没去做这道题,后来我去看了《算法导论》,才突然发现SICP相比之下是如此平易近人,于是才回过头将就原创 2013-10-10 00:19:15 · 6654 阅读 · 2 评论 -
SICP 习题 (1.14)解题总结
SICP 习题 1.14要求计算出过程count-change的增长阶。count-change是书中1.2.2节讲解的用于计算零钱找换方案的过程。要解答习题1.14,首先你需要理解count-change的工作方式,要理解count-change的工作方式,最好是自己去实现一遍count-change,为了避免自己直接抄书中的代码,我决定自己实现一遍用来找换人民币的的“count-change”原创 2013-10-13 00:05:59 · 6675 阅读 · 0 评论 -
SICP 习题 (1.15) 解题总结
SICP 习题 1.15要求计算过程Sine的空间和步数增长阶。先看看Sine过程的定义,书中全写出来了,照抄出来:(define (cube x) (* x x x))(define (p x) (- (* 3 x) (* 4 (cube x))))(define (sine angle) (if (not (> (abs angle) 0.1)) angle原创 2013-10-14 00:51:06 · 5572 阅读 · 1 评论 -
SICP 习题 (1.16)解题总结
SICP习题1.16要求将书中递归形式的求幂过程fast-expt改写成迭代的。 如果对我们之前对于递归计算过程和迭代计算过程理解的比较透彻的话做这道题问题不大。 首先看看书中的fast-expt过程:(define (fast-expt b n) (cond ((= n 0) 1) ((even? n) (square (fast-expt b (/ n 2)))) (else (* b原创 2013-10-16 00:24:02 · 4280 阅读 · 2 评论 -
SICP 习题 ( 1.17) 解题总结
SICP习题 1.17 是将一个计算加法的过程修改成一个只使用对数计算步数的方法。 其实这个习题是对书中对数步数求幂方法的强调,对数步数求幂的方法是将一系列的乘法变成对数步数的求幂。本习题就是要求将一系列的加法变成对数步数的乘法。 需要转换的过程如下:(define (* a b) (if (= b 0) 0 (+ a (* a (- b 1))))) 我们要做的就是对原创 2013-10-23 23:08:27 · 3222 阅读 · 1 评论 -
SICP 习题 (1.18) 解题总结
SICP 习题 1.18是习题1.17的扩展,要求我们将1.17题中的对数步数求加法的过程修改成迭代方式。同时,习题1.18习题也是对习题1.16的强调,习题1.16是通过迭代方法求幂,这里是通过迭代方法求加法。 所以我们需要回过头去看习题1.16和1.17。习题1.16是将以下函数进行修改:(define (fast-expt b n) (cond ((= n 0) 1) ((even?原创 2013-11-02 00:21:38 · 4332 阅读 · 2 评论 -
SICP 习题 (1.19) 解题总结
SICP习题1.19要求用对数步数求斐波那契数,有关斐波那契数我们在习题1.13 中讨论过,书中1.2.2节也详细讲解了斐波那契数的求法。在1.2.2节中讲述了斐波那契数的递归求法和迭代求法,其中递归求法的步数为Fib(n),而迭代求法的步数相对于n是线性的。虽然迭代求法的步数已经很少了,但是我们可以通过一种方法将步数减少为对数步数,其中的关键就是前面习题中提到的,将两个连续变换转换成一次变换的方原创 2013-12-06 00:22:27 · 4555 阅读 · 1 评论 -
SICP 习题 (1.20) 解题总结
SICP 习题 1.20 又回去讲正则序和应用序了,题目主要是考察书中提到的求最大公约数的过程gcd,问正则序中(gcd 206 40)调用了几次remainder,而应用序中(gcd 206 40)又调用了几次remainder。 gcd过程的定义如下:(define (gcd a b) (if (= b 0) a (gcd b (remainder a b))))对于(gcd 206原创 2013-12-18 00:06:12 · 3457 阅读 · 0 评论 -
SICP 习题 (1.21) 解题总结
SICP 习题1.21要求用书中的smallest-divisor过程找出199, 1999, 19999的最小因子。这道题是个纯复习题,没有新知识,也没有什么难度。为了方便,将书中的smallest-divisor过程列出如下:(define (smallest-divisor n) (find-divisor n 2))(define (find-divisor n test-divisor原创 2013-12-25 23:07:40 · 2057 阅读 · 0 评论 -
SICP 习题 (1.22) 解题总结
SICP 习题 1.22 要求改进题中列举出来检查素数的过程,用来求1000, 10000, 100 000,还有1000 000附近的素数,然后比较求这些素数的时间,看是否符合θ(√n)的复杂度。 要完成这道题首先要将题目中列出的过程照抄到你的Scheme环境中。因为书中的代码使用了(runtime)过程,我就先在我的环境中测试了(runtime)的结果,很悲剧地发现(runtime)的返回值好原创 2014-01-19 21:40:49 · 2546 阅读 · 0 评论 -
SICP 习题 (1.23) 解题总结
SICP 习题 1.23要求改进smallest-deivisor过程,因为samllest-devisor过程从2开始一直检测所有小于“根号n”的数,查找最小的因数。其实在检测了2以后就可以不再检测4,6,8,10等偶数,直接检查3,5,7,9等数就好了。 这题比较简单,就是定义一个过程,不断生成下一个奇数就好了,过程如下:(define (next-candidate n) (if (=原创 2014-02-11 23:36:15 · 2355 阅读 · 0 评论 -
SICP 习题 (1.26) 解题总结
SCIP 习题1.26是对expmod过程的讨论。 我不知道这道题对你来说是否简单,我个人是觉得比较简单。 题目说的是一个叫Louis Reasoner的人将expmod 过程实现成下面这个样子:(define (expmod base exp m) (cond (( = exp 0) 1) ((even? exp) (remainder (* (expmod base (/ exp原创 2014-02-26 00:27:16 · 3077 阅读 · 0 评论 -
SICP 习题 (1.24) 解题总结
SICP 习题 1.24 要求使用费马检测检测素数,可以说我的噩梦是从这道题开始的,从这道题开始的好几个星期内完全处于怀疑自己智商的状态中,因为我发现我要面对的不是会不会解题这个问题,而是我能不能理解题目的问题。 后来的努力证明,普通人也是可以理解复杂的数学问题的,所以各位可以继续努力!! 说到费马检测,首先是要去看看最朴素的素数检测方法,就是使用我们之前的smallest-divisor找最小因原创 2014-02-13 23:53:35 · 2684 阅读 · 0 评论 -
SICP 习题 (1.25) 解题总结
SICP 习题 1.25 就是我上面说过的伤自尊的题了。 习题1.25说到有个叫Allyssa P. Hacker的人说expmod过程完全没有必要搞那么麻烦,直接使用前面的fast-expt过程和remainder过程就好了,她(叫Alyssa的应该是女的吧)觉得可以这样定义expmod:(define (expmod base exp m) (remainder (fast-expt bas原创 2014-02-15 23:20:08 · 3519 阅读 · 0 评论 -
SICP 习题 (1.27) 解题总结
SICP 习题 1.27要求我们证明书中指出的Carmichael数可以骗过费马检测。 要证明这一点其实很简单,对于一个Carmichael数,找比这个数小同时大于1的所有数,逐个进行费马检测,如果有90%以上的数可以通过费马检测,那么这个数就有很大的几率骗过费马检测了。 事实上,我测试发现,Carmichael数(561,1105,1729,2465,2821,6601 这些)可以100%通过费原创 2014-02-28 00:18:52 · 3083 阅读 · 0 评论 -
SICP 习题 (1.28)解题总结
SICP 习题 1.28 要求使用 Miller-Rabin检查来检测素数。题目中说到Miller-Rabin检查是费马检查的一种变形,不过这种变形不会被Carmichael数欺骗。上几题搞费马检查都已经苦死我了,现在还来费马检查的变形?变形金刚我就知道,擎天柱我很喜欢,大黄蜂也不错。对着习题1.28回忆了一段童年动画片以后,题目还是摆在那里纹丝不动,于是最终还是硬着头皮去看题目细节。首先来看看这原创 2014-03-02 01:00:21 · 4457 阅读 · 2 评论 -
SICP 习题 (1.29)解题总结
SICP 习题 1.29 要求辛普森规则求函数f在范围a 和 b之间的定积分的近似值。在经过前面习题的磨练之后,我对这种充满数学定义的题目已经麻木了,觉得自己能完成题目就行,有些时候不需要去理会哪些折磨人的数学定义,比如什么函数的定积分,更不用说什么辛普森规则。其实SICP在1.3.1这节主要讲的是将过程作为参数,这里的题目也是看你是否能掌握这个概念,可以轻松地将一个过程作为参数进行传递和使用。说原创 2014-03-07 23:01:07 · 2969 阅读 · 1 评论