以下内容只是我的学习记录笔记
很早之前看过《黑客与画家》,对lisp心生向往,之后认识的大神推荐《计算机程序的构造与解释》,之前一段时间看了一点,然后又中断了。决定开始好好学习,重新拿起那本已经泛灰的老书。
首先你可能会问为什么要学lisp这一门古老的编程语言?作为一名小白,显然是没办法回答你这个问题的…看看王垠大神怎么说的吧,Lisp 已死,Lisp 万岁!
首先你得配置下scheme相关的环境对吧,然后当然我又扔给你一个链接,还是王垠大神的,希望以后自己能够早日修炼成神,不用到处扔别的大神的链接,Scheme 编程环境的设置。
如果你用的mac或者linux,应该很快就把环境给配置好啦,然后接下来的问题就是,卧槽,emacs是什么东西,作为一名程序员,你当然听过,(没听过的也假装听过,反正现在听过了),但是,问题来了,你并不会用,我也不会,作为一个习惯各种ide编辑器或者vim党的程序员,不会用emacs还是很正常的…默默的在心里默念,自己怎么这么渣。
那就好好学吧,网上找找教程,先学学基本的吧,比如说 Emacs入门系列:3分钟学会Emacs基本操作,说好的3分钟,其实都是骗人的,不过拿来入门是不错的,感觉写的挺好的。或者直接看emacs的tutorial,随便你吧。加一个,发现一篇很不错的文章, 一年成为Emacs高手(像神一样使用编辑器)。
然后我先去好好学习一些emacs的基本操作吧,等我一天,然后继续来闲聊。
ps:我用的mac,emacs版本24.5.1
Day 1 Emacs 基本操作
设置终端下的meta键
iTerm2 的话在 "Preferences" -> "Profiles" -> "your Profile" -> "Keys" -> 界面的右下角有关于 left/right option key 的映射配置,改成 +Esc 就可以了。
系统自带终端的话类似。linux的话应该没有这类问题。
光标移动
光标移动先掌握以下12个吧,其他的再说,之后有时间可以搞个图便于理解
ctrl 相关(小范围内的移动)
ctrl+p: 上一行 (previous)
ctrl+n: 下一行 (next)
ctrl+b: 前一个字符 (backward)
ctrl+f: 后一个字符 (forward)
ctrl+a: 行首 (a是第一个字母)
ctrl+e: 行尾 (end)
meta相关(mac改过配置之后就是alt/option键)
M+b: 向前一个单词
M+f: 向后一个单词
M+{: 段首
M+}: 段位
M+<: 文档首
M+>: 文档尾
还是再加几个吧
ctrl+v: 下移一屏
M+v: 上移一屏
M+g M+g:Emacs会要求输入行号,移动光标到指定行
好了,现在你可以在字符间自由的游动了!优秀!
至于设置行号显示,只要在~/.emacs里面加上
;;show line number (global-linum-mode 1)
如果不行的话,那么可能你的emacs版本太低,自己解决吧你,或者升级一下吧。
删除
删除还是很重要的对不,嗯嗯对,好,那来学点删除的命令吧
ctrl+d: 删除光标所在处字符
backspace: 删除光标前一个字符(这个就是我们常用的删除键啦)
M+d: 删除单词光标之后的部分
M+backspace: 删除单词光标之前的部分
ctrl+k: 删除从光标到行尾
M+k: 删除从光标到句尾
感觉删除还是没有vim用起来方便啊,或者学的太少不习惯…
比如假如要删除到行首怎么办?不像vim那样d+0就可以,你得怎么做?
首先你得先学一下选中这个命令
ctrl+@: 选择
然后再按ctrl+a跳到行首,然后
ctrl+w剪切
M+w复制
ctrl+y 粘贴
好了,今天就学这么多吧,休息休息,该干嘛干嘛去吧:)
感觉好像偏离正题了,我们是要学习scheme的!好吧,emacs的操作就不再介绍了,大家自己慢慢折腾去吧,先把最简单的掌握了就好。
ctrl+x ctrl+c: 保存并退出
如果想不保存退出的话,直接kill吧,ctrl+z
下面开始正式的学习啦,我用的自学教材是《计算机程序的构造和解释》,当当、亚马逊之类的一搜就有,不要吝惜那几十块钱哈,买买买!
然后渣渣们做题不会了怎么办,看看大神们的答案吧…
Day 2 程序设计的基本元素
- 表达式
- 组合的方法
- 抽象的方法
前缀表达式的优点
- 不会出现歧义
- 可以直接扩充
环境所扮演的角色就是用去确定表达式中各个符号的意义。
定义的一般形式(define (<name> <formal parameters>) <body>)
过程应用的代换模型
- 应用序:先求值参数后应用(lisp采用:避免对表达式的重复求值)
- 正则序:完全展开后归约
来看一道题目:
ex1.5:
Ben Bitdiddle发明了一种检测方法,能够确定解释器究竟采用的哪种序求值,是采用正则序,还是采用应用序,他定义了下面两个过程:
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
而后他求值下列的表达式:
(test 0 (p))
假如是应用序的话就会死循环,假如是正则序则很快算出结果0。
在数学里,人们通常关心的是说明性的描述(是什么),而在计算机科学里,人们则通常关心行动性的描述(怎么做)。
比如平方根的问题,以下是代码,大家感受一下。
(define (sqrt x)
(sqrt-iter 1.0 x))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (good-enough? guess x)
(< (abs (- guess x)) 0.001))
(define (improve guess x)
(average guess x))
(define (average x y))
(define (abs x)
(if (< x 0))
-x
x)
过程的形式参数名必须局部于有关的过程体。
(待续)