Common Lisp函数


第五章 函数
functions variables macros 函数 变量 宏是lisp的最重要的基本组件

functions

(defun name (parameter*)
;;Optional documentation string
body-form*)

函数名 推荐使用 连字符 “-“,尽量不使用下划线,或者骆驼名

第二行为函数说明
body-forms是一系列的Lisp expressions 最后一个expression的值将被作为函数的返回值

函数参数
可选参数
在list中可选参数前,添加标志符 &optional
e.g (defun foo (a b &optional c d) (list a b c d)) 如果c d没有被传递,则默认为NIL
也可以指定默认值,只需对可选参数进行默认参数指定
e.g (defun foo (a b &optional (c 10) d) (list a b c d))
可选参数依赖前面非可选参数的参数值
e.g (defun make-rectangle (width &optional (height width)) (list width height))
可选参数绑定是否传递的值,如下,如果c有传递值,则c-supplied-p值为T,反之NIL
e.g (defun foo (a b &optional (c 10 c-supplied-p)) (list a b c c-supplied-p)

&rest标识符,在可选参数未知的时候可使用,会自动收集可选参数并生成list传递给函数
e.g + 的定义 (defun + (&rest numbers))

keyword parameters 指定关键字参数 using symbol &key
e.g (defun foo (&key a b c) (list a b c)) using (foo :a 1 :b 2 :c 3) keyword parameters has all features of &optional
give the keyword parameters a alias
e.g (defun foo (&key ((:apple a)) ((:bear b) 1)) (list a b)) using (foo :apple 2)

in order : required parameters , optional parameters ,rest parameter,keyword parameters

(defun foo (x &optional y &key z) (list x y z))
If called like this, it works fine:
(foo 1 2 :z 3) → (1 2 3)
And this is also fine:
(foo 1) → (1 nil nil)
But this will signal an error:
(foo 1 :z 3) → ERROR

one rule: use keyword parameters as possible as you can,it makes code much easier to maintain and evolve

function return values

use return-from operator to immediately return any value from the function

function as data ,a.k.a higher-order functions

special operator FUNCTION ,getting a function object with a name as argument which isn’t quoted

e.g (defun foo (x) (list (* 2 x))) (function foo)

#’name do the same thing as FUNCTION

once you’ve got the function object,invoke it like this
1、FUNCALL (funcall #’foo 3) you need to know how much parameters you’re going to pass to the function at the time you write the code.

function as argument
(defun plot (fn min max step)
(loop for i from min to max by step do
(loop repeat (funcall fn i) do (format t “*”))
(format t “~%”)))
invoke it like this : (plot #’exp 0 4 1/2) #’exp invoke of built-in function exp that returns the value of ‘e’ raised to the power of its argument (#’exp 1) return the value of ‘e’

2、APPLY
it’s annoying to have to explicitly unpack the arguments like this: (plot (first plot-data) (second plot-data) (third plot-data) (fourth plot-data)
(apply #’plot plot-data)

Anonymous functions

define like this : (lambda (parameters) body)

lambda is a special kind of function name where the name itself directly describes what the function does
such as ((lambda (x y) (+ x y)) 2 3) return 5


发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注