背景

过去几年,开发商催图的力度越来越大,实在是不堪其扰,无奈之下,只得硬着头皮逼着自己学会了autolisp。在开发自用的cad插件之余,也在闲鱼上帮助了不少网友,开发了上百个插件。

前几天,有网友在闲鱼上留言,询问是否可以帮助写几段lisp代码,在表示可以办到之后,他发来下面这样的消息,说是先搞定这个,然后再谈其他几段代码。

some lisp code piece

遗憾的是,因为价格没谈拢,最终没能帮到他。

函数功能分析

从他这个代码来看,很显然,是要求实现2个功能:

  1. 找出奇数
  2. 将奇数乘以2,也就是翻倍、倍增

应该说,功能是比较简单的,从我在闲鱼上帮人写代码的经验来看,属于大学cs专业的入门级难度。

可惜的是,这哥们似乎完全没入门。

现有代码为啥跑不动?

这样一个简单的函数,能写成这样,肯定是跑不动的,因为

  1. 调用函数的时候,函数名写错了。定义的是odd-doulber,调用的则是odd-doubler。
  2. 函数定义错误,lisp用defun定义函数,defun之后即为函数名,函数名之后的list中元素为函数形参, 在这个list前加上 ' 就大错特错了。
  3. ' 是quote的别名,二者的含义和作用是相同的,都代表对后续list或symbol的引用,不执行eval操作。

连函数都不知道怎么写,这不是没入门又是什么呢?

倍增函数的源代码

某些lisp实现,比如emacs lisp,没有内置oddp函数,这时候,需要自己写一个oddp函数, 我的oddp函数源代码如下:

1
(defun oddp (x) (= 1 (abs (rem x 2.0))))

当然,如果interpreter已经实现了oddp,就不必造轮子了。

有了oddp,就可以通过oddp找到奇数,然后直接乘以2即可。对于lisper来说,递归是母胎技能,所以, 这里给出的实现自然也是用递归写的。

1
2
3
4
5
(defun odd-doubler (lst) 
  (cond 
    ((null lst) '())
    ((oddp (car lst)) (cons (* 2 (car lst)) (odd-doubler (cdr lst))))
    (t (cons (car lst) (odd-doubler (cdr lst))))))

这就是我的odd-doubler函数源代码。如果用scheme来写,会有些许的不同,以后有机会的话,再写出来吧。

需要写cad插件,或者写lisp、scheme、racket代码的朋友,可以通过页面底部的微博联系我。