In compunng quad-roots. the valuc of
Jtr-4ec
i\ u sod lwice. For rcasons ofctlidcncy. as woli as clcgancc. we should computc (his value ooły oncc. saving il in a\ariablc for usc in computing the iwo roots. Bascd on this idea. aa inilial implcmcntaiion of quad-roots mighi be:
(dofun quad-roots-1 (a b c)
(sotq lamp (aqrt (- (* b b) (‘ 4 a c))))
(!•«(/(♦ (- b) temp) C 2 a))
</(-(-b) temp) ('2 a))))
Noic that ihe abovc impkmcnialion assumes ihat the couation docs noi havc imagi-nary root>. as attcmpcing (o lako the $qu3ic rooc of a ncgativc number would causc the sqrt function to hall with an cnor condiiion. Modifying ihe codc lo handle ihis ense is straight* forward and not relevant to ihis discussion.
Although. with this cxccp»ion. the codc is correct. cvaluation of the function body will ha\c the side cffcct of setting the valuc of tomp in the głobal emironment:
> (quad-roots-l 121)
> temp
It is much morę desi rabie to make temp local to the function quad-roots. thereby eliminating this side effect. This can be done through the usc of a let błock. A lei expres* sion has the syntax:
(lot (<!ocal'variab!es>) <expresslons>)
where the clcments of (<local-variables>) are either symbolic atoms or pairs of the form:
(<symbol> <oxpression>)
When a let form (or błock as it is usualły callcd) is evaluated. it establishes a local cmiroomcnt consisting of all of the symbols in (<iocal-variables>). If a symbol is the tiret element of a pair. the sccond element is evaluatcd and the symbol is bound to this result: symbols that arc not indudcd in pairs arc bound to nil. If nny of thesc symbols are alrcady bound in the global emironment. these global bindings arc savcd and restored w hen the (et błock łermirutes.
After thcsc local bindings arc established. the <expressions> arc evaluatcd in order within this emironment. When the let statement (erminates. it retums the valuc of the but eapression evalualed within the błock.
The bchav ior of the let błock is illustratcd by the following cxample:
> (s«tq o O)
O
> (io» ((a 3) t»>
(s«tq b 4)
(♦ • b»
7
> a O
> b|
ERROR - b is not bound at top lovel.
In this cxample. beforc the lot błock is cxccuicd. a is bound to O and b i% unbound at the tofv-levcl cnvironmcnt. When the let is evaluatcd. a as bound to 3 and b is bound to nil The satef as»igns b to 4. and the sum of a and b is retumed by the let Muicmcni. Lp»»n termination of the lot. a and b are restored to their prcvious xaloes, induding the unbouad status of b.
Using the lot statement, quad-roots can be implcmcnted with no global side cflccts: {dofun quad*roots-2 (a b c)
{let (temp)
(setq temp (sqrt (— (• b b) (* 4 a c)»)
(list (/ (♦ (- t>) temp) C 2 a»
{/ (- (- b) temp) C 2 a)))))
Altcmativcly. temp mny be bound when it is declared in the let statement. gning a MHiicwhai morę concisc implemcntation of quad-roota. In ihis finał \ersioo. the dc nocni-nator of the formula. 2a. is also compulcd once and saved in a local \ariaUe. den om;
{dofun quad-roots-3 (a b c)
(let ((temp (sqrt <- (• b b) (• 4 a c))»
(denom (• 2 a)))
(list (/ (♦ (- t>) temp) denom)
(/ (- (- b) temp) denom))))
In addition to avoiding side cflects. quad-roots-3 is the most cfińcient of the thrcc vct-siotis. becausc it docs not recompule values unncccss&rily.
LISP provides the uscr with a number of built-in data typcs. Thcse incUidc inccgcn. float* ing-point numbers. stringa. and charaeters. LISP also ineludes such structunrd types as arrays. hash tablcs. sets. and slructures. Ali of thcse typcs include the appropriate operat i on s on tlte typc and predicates for lesting whether an objcct is an i ostańce of the type. For cxamplc, lists are supported by such functions as listp. which Mkntifici an objrect Ust; nuli. which tdentifies the empty list. and constnictons and eccessocs Stach as list. nth. car. and cdr.
70*1
CHAPTER 15/AN IMTRODiiCTIOW TO USP