We're doing some mathematic calculations in a program we're developing, and we've gotten a nice function to help in the construction called `sum`.
(defun sum
(term a next b
) ;; (sum <term> <lower-bounds> <next> <upper-bounds>)
;; EX: (sum 'cube a 'inc b)
;; summation of a series of integers
0
(sum term
(eval (list next a
)) next b
))) )
For example, our program is summing the cubes of the integers from 1 to 10 and our functions are taking shape and we are getting the results we want.
;; support procedure
;; (cube <integer>)
;; Calculates the cube of a number
(* n n n))
;; (sum-cubes <lower-bounds> <upper-bounds>)
;; compute the sum of the cubes of the integers from 1 to 10.
;;
;; EX: (sum-cubes 1 10)
;; example:
(sum-cubes 1 10)
> 3025
And we're using our `
sum` routine for other things like summing all numbers from 1 to 10:
(defun sum
-integers
(a b
) ;; (sum-integers <lower-bounds> <upper-bounds>)
;; Computes the sum of all the integers in a given range.
;;
;; EX: (sum-integers 1 10)
;; example:
(sum-integers 1 10)
> 55
And we're even approximating pi:
(defun pi
-term
(n
) (/ 1.0 (* n
(+ n
2)))) (defun pi
-next
(n
) (+ n
4)) (sum 'pi-term a 'pi-next b) )
;; example:
(* 8 (pi-sum 1 1000))
> 3.139
But we've started developing a design flaw (an annoyance); instead of having to define formal auxiliary procedures it would be more convenient if we directly write the operations for `
pi-term` and `
pi-next` inside the `
pi-sum` function.
To overcome the need to define `
pi-term` and `
pi-next` we can obviously preform the job with a few simple `
lambda` statements. Normally we'd accomplish that like this:
(sum
(lambda (x
) (/ 1.0 (* x
(+ x
2)))) a
b)
)
But we have also lost a little descriptvness in our function. And `
lambda` itself actually exposes a useful construct we can use to gain that functionality back.
In general lambda has the form of: (lambda (<parameters>) <body>) but `
lambda` can also be used like this:
(
(lambda (x y z) (+ x y z))
1 2 3)
So our "expanded lambda" construct can be defined like this:
(
(lambda (<variable 1> <variable 2>)
<body>)
<expression 1>
<expression 2>
)
In this form we are essentially binding the values 1, 2, 3 to `x, y, & z` and this is so useful in other lisp dialects a function is associated with the construct called `
LET`.
Let is defined as:
(let ((<variable 1> <expression 1>)
(<variable 2> <expression 2>))
<body>
)
In AutoLisp we don't have the function `
LET` but it is essentially syntactic sugar (the same as) our `expanded lambda` syntax so we can now define `
pi-sum` like this:
(
(sum pi-term a pi-next b))
(lambda (x
) (/ 1.0 (* x
(+ x
2)))) )
)
I hope you find the simple function lambda as usefull as I do.