12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358 |
- % -*- Mode: TeX -*-
- % Evaluation Control
- % Macros
- % Declarations
- % Introspection
- %-------------------- Lambda Expressions --------------------
- %%% ========== LAMBDA (symbol)
- \begincom{lambda}\ftype{Symbol}
- \issue{DECLS-AND-DOC}
- \label Syntax::
- \Defspec lambda {lambda-list {\DeclsAndDoc} \starparam{form}}
- \label Arguments::
- \param{lambda-list}---an \term{ordinary lambda list}.
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
-
- \param{documentation}---a \term{string}; \noeval.
- \param{form}---a \term{form}.
- \label Description::
- A \term{lambda expression} is a \term{list} that can be used in place of a
- \term{function name} in certain contexts to denote a \term{function} by
- directly describing its behavior rather than indirectly by referring to the
- name of an \term{established} \term{function}.
- \param{Documentation} is attached to the denoted \param{function} (if any
- is actually created) as a \term{documentation string}.
- \label See Also::
- \specref{function},
- \specref{documentation},
- {\secref\LambdaExpressions},
- {\secref\LambdaForms},
- {\secref\DocVsDecls}
- \label Notes::
- The \term{lambda form}
- \code
- ((lambda \param{lambda-list} . \param{body}) . \param{arguments})
- \endcode
- is semantically equivalent to the \term{function form}
- \code
- (funcall #'(lambda \param{lambda-list} . \param{body}) . \param{arguments})
- \endcode
- \endissue{DECLS-AND-DOC}
- \endcom%{lambda}
- %%% ========== LAMBDA (macro)
- \issue{ISO-COMPATIBILITY:ADD-SUBSTRATE}
- \begincom{lambda}\ftype{Macro}
- \label Syntax::
- %% 7.6.0 7
- \DefmacWithValues lambda
- {lambda-list {\DeclsAndDoc} \starparam{form}}
- {\param{function}}
- \label Arguments and Values::
- \param{lambda-list}---an \term{ordinary lambda list}.
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
-
- \param{documentation}---a \term{string}; \noeval.
- \param{form}---a \term{form}.
- \param{function}---a \term{function}.
- \label Description::
- Provides a shorthand notation for a \specref{function} \term{special form}
- involving a \term{lambda expression} such that:
- \code
- (lambda \param{lambda-list} {\DeclsAndDoc} \starparam{form})
- \EQ (function (lambda \param{lambda-list} {\DeclsAndDoc} \starparam{form}))
- \EQ #'(lambda \param{lambda-list} {\DeclsAndDoc} \starparam{form})
- \endcode
- \label Examples::
- \code
- (funcall (lambda (x) (+ x 3)) 4) \EV 7
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \misc{lambda} (symbol)
- \label Notes::
- This macro could be implemented by:
- \code
- (defmacro lambda (&whole form &rest bvl-decls-and-body)
- (declare (ignore bvl-decls-and-body))
- `#',form)
- \endcode
- \endcom%{lambda}
- \endissue{ISO-COMPATIBILITY:ADD-SUBSTRATE}
- %-------------------- Evaluation Control --------------------
- %%% ========== COMPILE
- \begincom{compile}\ftype{Function}
- \issue{FUNCTION-NAME:LARGE}
- %%\param{Name} has been changed to \param{function-name} throughout.}
- \endissue{FUNCTION-NAME:LARGE}
- \label Syntax::
- \DefunWithValues compile {name {\opt} definition} {function, warnings-p, failure-p}
- \label Arguments and Values::
- \param{name}---a \term{function name}, or \nil.
-
- %% 25.1.0 5
- \param{definition}---a \term{lambda expression} or a \term{function}.
- \Default{the function definition of \param{name} if it names a \term{function},
- or the \term{macro function} of \param{name} if it names a \term{macro}}
- The consequences are undefined if no \param{definition} is supplied
- when the \param{name} is \nil.
- %% 25.1.0 6
- \param{function}---the \param{function-name},
- \issue{COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN}
- or a \term{compiled function}.
- \endissue{COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN}
- \param{warnings-p}---a \term{generalized boolean}.
- \param{failure-p}---a \term{generalized boolean}.
- \label Description::
- Compiles an \term{interpreted function}.
- %% Moon: Intent is compilation envirionment = startup environment.
- %% Just delete this phrase, I think.
- %in the current \term{dynamic environment}.
- \funref{compile} produces a \term{compiled function} from \param{definition}.
- If the \param{definition} is a \term{lambda expression},
- it is coerced to a \term{function}.
- \issue{COMPILE-ARGUMENT-PROBLEMS-AGAIN:FIX}
- If the \param{definition} is already a \term{compiled function},
- \funref{compile} either produces that function itself (\ie is an identity operation)
- or an equivalent function.
- \endissue{COMPILE-ARGUMENT-PROBLEMS-AGAIN:FIX}
- \editornote{KMP: There are a number of ambiguities here that still need resolution.}%!!!
- % Cases of interest:
- % Given: (defmacro foist (x) `(car ,x))
- % What do these do:
- % (compile 'foist (macro-function 'foist))
- % (compile 'foist (symbol-function 'foist))
- % (compile 'foist '(lambda (x y) (+ x y)))
- If the \param{name} is \nil,
- the resulting \term{compiled function} is returned directly as the \term{primary value}.
- If a \term{non-nil} \param{name} is given,
- then the resulting \term{compiled function} replaces
- the existing \term{function} definition of \param{name}
- and the \param{name} is returned as the \term{primary value};
- if \param{name} is a \term{symbol} that names a \term{macro},
- its \term{macro function} is updated
- and the \param{name} is returned as the \term{primary value}.
- % I moved this paragraph so it isn't in the middle of the discussion
- % of compiler diagnostics. --sjl 7 Mar 92
- \issue{QUOTE-SEMANTICS:NO-COPYING}
- % Constants -> Literal objects. -kmp 15-Jan-91
- \term{Literal objects} appearing in code processed by
- the \funref{compile} function are neither copied nor \term{coalesced}.
- The code resulting from the execution of \funref{compile}
- references \term{objects} that are \funref{eql} to the corresponding
- \term{objects} in the source code.
- \endissue{QUOTE-SEMANTICS:NO-COPYING}
- \issue{COMPILER-DIAGNOSTICS:USE-HANDLER}
- \funref{compile} is permitted, but not required, to \term{establish}
- a \term{handler} for \term{conditions} \oftype{error}.
- For example, the \term{handler} might issue a warning and
- restart compilation from some \term{implementation-dependent} point
- in order to let the compilation proceed without manual intervention.
- \endissue{COMPILER-DIAGNOSTICS:USE-HANDLER}
- The \term{secondary value}, \param{warnings-p}, is \term{false}
- % clarify ``compiler diagnostics'' --sjl 7 Mar 92
- %if no compiler diagnostics were issued, and \term{true} otherwise.
- if no \term{conditions} \oftype{error} or \typeref{warning}
- were detected by the compiler, and \term{true} otherwise.
- The \term{tertiary value}, \param{failure-p}, is \term{false}
- % clarify ``compiler diagnostics'' --sjl 7 Mar 92
- %if no compiler diagnostics other than \term{style warnings} were issued.
- %A value of \term{true} indicates that there were serious compiler diagnostics
- %issued, or that other \term{conditions} \oftype{error} or \typeref{warning}
- %(but not \oftype{style-warning}) were signaled during compilation.
- if no \term{conditions} \oftype{error} or \typeref{warning}
- (other than \typeref{style-warning})
- were detected by the compiler, and \term{true} otherwise.
- \label Examples::
- \code
- (defun foo () "bar") \EV FOO
- (compiled-function-p #'foo) \EV \term{implementation-dependent}
- (compile 'foo) \EV FOO
- (compiled-function-p #'foo) \EV \term{true}
- (setf (symbol-function 'foo)
- (compile nil '(lambda () "replaced"))) \EV #<Compiled-Function>
- (foo) \EV "replaced"
- \endcode
- % (defun foo ...) \EV foo ;A function definition.
- % (compile 'foo) \EV foo ;Compile it.
- % ;Now foo runs faster.
- \label Affected By::
- \issue{COMPILER-WARNING-STREAM}
- \varref{*error-output*},
- \endissue{COMPILER-WARNING-STREAM}
- \varref{*macroexpand-hook*}.
- The presence of macro definitions and proclamations.
- \label Exceptional Situations::
- \issue{COMPILE-ARGUMENT-PROBLEMS-AGAIN:FIX}
- The consequences are undefined if the \term{lexical environment} surrounding the
- \term{function} to be compiled contains any \term{bindings} other than those for
- \term{macros}, \term{symbol macros}, or \term{declarations}.
- % The consequences are undefined if the \term{function} to be compiled
- % was defined in a \term{non-null lexical environment}.
- % The consequences are unspecified if the \term{function} is already a
- % \term{compiled function}.
- \endissue{COMPILE-ARGUMENT-PROBLEMS-AGAIN:FIX}
- %% should be an error signaled if name is nil and no definition is supplied.
- %% also if function is already compiled.
- %ERROR and WARNING conditions may be signaled within
- % COMPILE or COMPILE-FILE, including arbitrary errors which may
- % occur due to compile-time processing of (EVAL-WHEN (:COMPILE-TOPLEVEL) ...)
- % forms or macro expansion.
- %
- % The following information is mostly redundant with info in the chapter 3
- % concept section, and contains some inconsistencies. Better to just
- % put in a cross-reference. --sjl 4 mar 92
- % \issue{COMPILER-DIAGNOSTICS:USE-HANDLER}
- % The following list considers only
- % those conditions signaled by the compiler as
- % opposed to within the compiler.
- %
- % An error \oftype{error} might be signaled by the compiler in
- % situations where the compilation cannot proceed without
- % intervention.
- % Examples include
- % file open errors and
- % syntax errors.
- %
- % An error \oftype{warning} might be signaled by the compiler in
- % situations where the standard explicitly states
- % that a warning must, should, or might be signaled.
- % Also, an error \oftype{warning} might be signaled
- % by the compiler in situations where the compiler can determine
- % that a situation with undefined consequences or that would cause
- % an error to be signaled would result at runtime.
- % Examples include
- % violation of type declarations,
- % \term{assigning} or \term{binding} a \term{constant variable},
- % calling a built-in Lisp function with the wrong number of arguments
- % or malformed keyword argument lists,
- % referencing a variable declared \declref{ignore},
- % and the usage of unrecognized declaration specifiers.
- %
- % The compiler is permitted to signal errors \oftype{style-warning}
- % about matters of programming style. Although \term{style warnings} might
- % be signaled in these situations, no implementation is required to
- % signal them. However, if an implementation does choose to signal an
- % error about matters of programming style,
- % that error is \oftype{style-warning} and is signaled by a call to \funref{warn}.
- % Examples include
- % redefinition of a \term{function} with a different argument list,
- % calling a \term{function} with the wrong number of arguments,
- % \term{accessing} unreferenced local variables not declared \declref{ignore},
- % and usage of declaration specifiers described in the standard but ignored by the compiler.
- %
- % \issue{COMPILER-WARNING-STREAM}
- % %%This is now implied by the remarks about using WARN above.
- % %\funref{compile} is permitted to issue warnings through \term{error output}.
- % \endissue{COMPILER-WARNING-STREAM}
- %
- % \endissue{COMPILER-DIAGNOSTICS:USE-HANDLER}
- For information about errors detected during the compilation process,
- \seesection\FileCompilerExceptions.
- \label See Also::
- \funref{compile-file}
- \label Notes:\None.
- \endcom
- %%% ========== EVAL
- \begincom{eval}\ftype{Function}
- \label Syntax::
- \DefunWithValues eval {form} {\starparam{result}}
- \label Arguments and Values::
- \param{form}---a \term{form}.
- \param{results}---the \term{values} \term{yielded} by the \term{evaluation} of \param{form}.
- %% Goes without saying. -kmp 8-Aug-91
- % %% 7.9.2 4
- % Returns multiple values if \param{form} produces multiple values.
- \label Description::
- %% 20.1.0 2
- Evaluates \param{form} in the current \term{dynamic environment}
- and the \term{null lexical environment}.
- %% 20.1.0 1
- \funref{eval} is a user interface to the evaluator.
- %% 8.2.0 5
- The evaluator expands macro calls as if through the use of \funref{macroexpand-1}.
- %%% 9.1.0 3
- %It is an error to attempt to evaluate a declaration.
- %Those \term{forms} that permit declarations to appear
- %perform explicit checks for their presence.
- \issue{QUOTE-SEMANTICS:NO-COPYING}
- Constants appearing in code
- processed by \funref{eval} are
- not copied nor coalesced. The code resulting from the execution of
- \funref{eval}
- references \term{objects}
- that are \funref{eql} to the corresponding \term{objects} in
- the source code.
- \endissue{QUOTE-SEMANTICS:NO-COPYING}
- %!!! Barmar: What about compiler macros?
- \label Examples::
- \code
- (setq form '(1+ a) a 999) \EV 999
- (eval form) \EV 1000
- (eval 'form) \EV (1+ A)
- (let ((a '(this would break if eval used local value))) (eval form))
- \EV 1000
- \endcode
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \issue{EVALHOOK-STEP-CONFUSION:X3J13-NOV-89}
- %\funref{evalhook},
- %\funref{applyhook},
- \endissue{EVALHOOK-STEP-CONFUSION:X3J13-NOV-89}
- \funref{macroexpand-1},
- {\secref\EvaluationModel}
- \label Notes::
- %% 20.1.0 4
- To obtain the current dynamic value of a \term{symbol},
- use of \funref{symbol-value} is equivalent (and usually preferable)
- to use of \funref{eval}.
- %% 20.1.0 3
- Note that an \funref{eval} \term{form} involves two levels of \term{evaluation}
- for its \term{argument}. First, \param{form} is \term{evaluated} by the
- normal argument evaluation mechanism as would occur with any \term{call}.
- The \term{object} that results from this normal \term{argument} \term{evaluation}
- becomes the \term{value} of the \param{form} \term{parameter}, and is then
- \term{evaluated} as part of the \funref{eval} \term{form}.
- For example:
- \code
- (eval (list 'cdr (car '((quote (a . b)) c)))) \EV b
- \endcode
- The \term{argument} \term{form} \f{(list 'cdr (car '((quote (a . b)) c)))} is evaluated
- in the usual way to produce the \term{argument} \f{(cdr (quote (a . b)))};
- % this is then given to \funref{eval}
- % because \funref{eval} is being called explicitly,
- % and
- \funref{eval} then evaluates its \term{argument}, \f{(cdr (quote (a . b)))}, to produce \f{b}.
- Since a single \term{evaluation} already occurs for any \term{argument} \term{form}
- in any \term{function form},
- \funref{eval} is sometimes said to perform ``an extra level of evaluation.''
- \issue{EVALHOOK-STEP-CONFUSION:FIX}
- % Hooks are provided for user-supplied debugging routines
- % to obtain control during the execution of an interpretive evaluator.
- % \funref{evalhook} and \funref{applyhook} provide alternative
- % interfaces to the evaluator mechanism for use by these debugging routines.
- \endissue{EVALHOOK-STEP-CONFUSION:FIX}
- \endcom
- %%% ========== EVAL-WHEN
- \begincom{eval-when}\ftype{Special Operator}
- \label Syntax::
- \DefspecWithValues eval-when
- {\paren{\starparam{situation}} \starparam{form}}
- {\starparam{result}}
- \label Arguments and Values::
- \issue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
- \param{situation}---One of the \term{symbols}
- \kwd{compile-toplevel}\idxkwd{compile-toplevel},
- \kwd{load-toplevel}\idxkwd{load-toplevel},
- \kwd{execute}\idxkwd{execute},
- \misc{compile}\idxref{compile},
- \misc{load}\idxref{load}, or
- \misc{eval}\idxref{eval}.
- The use of \misc{eval}, \misc{compile}, and \misc{load} is deprecated.
- \issue{EVAL-WHEN-OBSOLETE-KEYWORDS:X3J13-MAR-1993}
- %They are supported when \specref{eval-when} is a \term{top level form},
- %but their meaning is not defined elsewhere.
- \endissue{EVAL-WHEN-OBSOLETE-KEYWORDS:X3J13-MAR-1993}
- \endissue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
- \param{forms}---an \term{implicit progn}.
- \param{results}---the \term{values} of the \term{forms} if they are executed,
- or \nil\ if they are not.
- \label Description::
- %%% 5.3.3 2
- %\specref{eval-when} specifies when a particular body
- %of code is to be evaluated.
- %%% 5.3.3 1.5
- %\specref{eval-when} allows pieces of code to
- %be executed only at compile time, only in compiled code, or
- %when interpreted but not compiled.
- %If no \param{forms} are executed, \specref{eval-when} returns
- %\nil.
- %
- %%% 5.3.3 3
- %\f{eval} specifies that the interpreter should process the body.
- %\f{compile} specifies that the compiler should evaluate the body
- %at compile time in the compilation context.
- %\f{load} specifies that the compiler should arrange to evaluate
- %the forms in the body when the compiled file containing the
- %\specref{eval-when} form is \term{loaded}.
- %
- %The body of \specref{eval-when} is processed as an implicit
- %\specref{progn}, but only in the allowed \param{situations}.
- %
- %
- \issue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
- The body of an \specref{eval-when} form is processed as an \term{implicit progn},
- but only in the \param{situations} listed.
- %Each \param{situation} must be a symbol,
- % either COMPILE, LOAD, or EVAL.
- % The file compilation section only describe processing by COMPILE-FILE.
- % We must say something explicit here about EVAL and COMPILE.
- % (The last paragraph from the eval-when cleanup has gotten lost.)
- % I have rewritten this below to include the missing info. --sjl 5 Mar 92
-
- % The use of the \param{situations} \kwd{compile-toplevel} ({\tt compile}) and
- % \kwd{load-toplevel} ({\tt load}) controls whether and when processing
- % occurs for \term{top level forms}. The use of
- % the situation \kwd{execute} ({\tt eval}) controls whether
- % processing occurs for \term{non-top-level forms}.
- %
- % For a description of \specref{eval-when} processing, \seesection\FileCompilation.
- The use of the \param{situations} \kwd{compile-toplevel} (or {\tt compile}) and
- \kwd{load-toplevel} (or {\tt load}) controls whether and when \term{evaluation}
- occurs when \specref{eval-when} appears as a \term{top level form} in
- code processed by \funref{compile-file}. \Seesection\FileCompilation.
- The use of the \param{situation} \kwd{execute} (or {\tt eval}) controls whether
- evaluation occurs for other \specref{eval-when} \term{forms}; that is,
- those that are not \term{top level forms}, or those in code processed by
- \funref{eval} or \varref{compile}. If the \kwd{execute} situation is
- specified in such a \term{form}, then the body \param{forms} are processed as
- an \term{implicit progn}; otherwise, the \specref{eval-when} \term{form}
- returns \nil.
-
- % The \specref{eval-when}
- %construct can be more precisely understood in terms of
- % a model of how the file compiler, COMPILE-FILE, processes forms in a
- % file to be compiled.
- %When successive \term{forms} are
- %read from the file by \funref{compile-file},
- %these \term{top level forms} are normally processed in
- % not-compile-time mode. There is one other mode, called
- % compile-time-too mode, that is also used for processing \term{top level forms}.
- % The \specref{eval-when} special form
- %is used to annotate a program
- % in a way that allows the program doing the processing to select
- % the appropriate mode.
- %
- %When \funref{compile-file}
- %encounters an \specref{eval-when} form, the \term{form}
- %is handled according to
- %the table in \thenextfigure.
- %
- %\boxfig
- %{\dimen0=.75pc
- %\tabskip \dimen0 plus .5 fil
- %\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip
- %\dimen0 plus .5 fil&#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus 1fil
- %&#\hfil\cr
- %\noalign{\vskip -9pt}
- %\hfil{\bf A} & {\bf B} & {\bf C} & {\bf D}& {\bf Action} \cr
- %& & & & \cr
- % Yes & Yes &-- &-- &Process body in compile-time-too
- %mode\cr
- % No &Yes &Yes &Yes &Process body in compile-time-too mode\cr
- % No &Yes &Yes &No &Process body in not-compile-time mode\cr
- % No &Yes &No &-- &Process body in not-compile-time mode\cr
- % Yes &No &-- &-- &Evaluate body\cr
- % No &No &Yes &Yes &Evaluate body\cr
- % No &No &Yes &No &do nothing\cr
- % No &No &No &-- &do nothing\cr
- %\noalign{\vskip -9pt}
- %}}
- %\caption{\specref{eval-when} processing}
- %\endfig
- %Column A indicates
- %{\tt :compile-toplevel} processing.
- %Column B indicates \kwd{load-toplevel} processing.
- %Column C indicates {\tt :execute} processing.
- %Column D indicates compile-time-too processing.
- %
- % Process body means to process the body (using the procedure
- % outlined in this subsection) as an implicit toplevel \specref{progn}.
- %
- %
- % Evaluate body means to evaluate the body \param{forms} as an
- % \term{implicit progn} in the
- % % dynamic execution context
- % \term{dynamic environment} of the compiler and in the
- % \term{lexical environment} in which the \specref{eval-when} appears.
- %
- % For an \specref{eval-when}
- %form that is not a \term{top level form},
- %if the \kwd{execute} situation is specified,
- %the body of the \specref{eval-when}
- %is treated as an \term{implicit progn}. Otherwise, the
- %\specref{eval-when}
- % form returns \nil.
- %An \specref{eval-when} form is a \term{non-top-level form}
- %if it is one of the following:
- %in the interpreter, in \funref{compile}, or in \funref{compile-file}
- %but not a \term{top level form}.
- \endissue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
- %!!! Barmar: Redundant. (KMP: I'll have to think about that.)
- \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW}
- \specref{eval-when}
- normally appears as a \term{top level form}, but it is meaningful
- for it to appear as a \term{non-top-level form}.
- However, the compile-time side
- effects described in {\secref\Compilation}
- only take place when \specref{eval-when} appears as a
- \term{top level form}.
- \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW}
-
- %\specref{eval-when} is meaningful only as a \term{top level form}.
- \label Examples::
- %!!! Are the EVAL-WHEN return values correct?? -kmp 29-Aug-91
- %% Moon: Why isn't this compile toplevel? Maybe this example is not portable?
- %% It's an obfuscating example anyway. Delete it.
- % \code
- % (setq temp 3) \EV 3
- % (eval-when (:compile-toplevel) (setq temp 2)) \EV NIL
- % temp \EV 3
- % (eval-when (:execute) (setq temp 2)) \EV 2
- % temp \EV 2
- % \endcode
- %% 5.3.3 10
- One example of the use of \specref{eval-when} is that for the
- compiler to be able to read a file properly when it uses user-defined
- \term{reader macros}, it is necessary to write
- \code
- (eval-when (:compile-toplevel :load-toplevel :execute)
- (set-macro-character #\\$ #'(lambda (stream char)
- (declare (ignore char))
- (list 'dollar (read stream))))) \EV T
- \endcode
- This causes the call to \funref{set-macro-character} to be executed
- in the compiler's execution environment, thereby modifying its
- reader syntax table.
- \code
- ;;; The EVAL-WHEN in this case is not at toplevel, so only the :EXECUTE
- ;;; keyword is considered. At compile time, this has no effect.
- ;;; At load time (if the LET is at toplevel), or at execution time
- ;;; (if the LET is embedded in some other form which does not execute
- ;;; until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
- ;;; returns 1.
- (let ((x 1))
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo1) #'(lambda () x))))
- ;;; If this expression occurs at the toplevel of a file to be compiled,
- ;;; it has BOTH a compile time AND a load-time effect of setting
- ;;; (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (let ((x 2))
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo2) #'(lambda () x)))))
- ;;; If this expression occurs at the toplevel of a file to be compiled,
- ;;; it has BOTH a compile time AND a load-time effect of setting the
- ;;; function cell of FOO3 to a function which returns 3.
- (eval-when (:execute :load-toplevel :compile-toplevel)
- (setf (symbol-function 'foo3) #'(lambda () 3)))
-
- ;;; #4: This always does nothing. It simply returns NIL.
- (eval-when (:compile-toplevel)
- (eval-when (:compile-toplevel)
- (print 'foo4)))
- ;;; If this form occurs at toplevel of a file to be compiled, FOO5 is
- ;;; printed at compile time. If this form occurs in a non-top-level
- ;;; position, nothing is printed at compile time. Regardless of context,
- ;;; nothing is ever printed at load time or execution time.
- (eval-when (:compile-toplevel)
- (eval-when (:execute)
- (print 'foo5)))
-
- ;;; If this form occurs at toplevel of a file to be compiled, FOO6 is
- ;;; printed at compile time. If this form occurs in a non-top-level
- ;;; position, nothing is printed at compile time. Regardless of context,
- ;;; nothing is ever printed at load time or execution time.
- (eval-when (:execute :load-toplevel)
- (eval-when (:compile-toplevel)
- (print 'foo6)))
- \endcode
-
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{compile-file}, {\secref\Compilation}
- \label Notes::
- \issue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
- The following effects are logical consequences of the definition of
- \specref{eval-when}:
-
- \beginlist
- \itemitem{\bull}
- Execution of a single \specref{eval-when}
- expression executes the body code at most once.
-
- \itemitem{\bull}
- \term{Macros} intended for use in \term{top level forms}
- should be written so that side-effects are done by the \term{forms}
- in the macro expansion. The macro-expander itself should not do
- the side-effects.
-
- For example:
- Wrong:
- \code
- (defmacro foo ()
- (really-foo)
- `(really-foo))
- \endcode
-
- Right:
- \code
- (defmacro foo ()
- `(eval-when (:compile-toplevel :execute :load-toplevel) (really-foo)))
- \endcode
-
- Adherence to this convention means that such \term{macros} behave
- intuitively when appearing as \term{non-top-level forms}.
-
- \itemitem{\bull}
- Placing a variable binding around an \specref{eval-when} reliably
- captures the binding because the compile-time-too mode cannot occur
- (\ie introducing a variable binding means that the \specref{eval-when}
- is not a \term{top level form}).
- For example,
-
- \code
- (let ((x 3))
- (eval-when (:execute :load-toplevel :compile-toplevel) (print x)))
- \endcode
- prints {\tt 3}
- at execution (\ie load) time, and does not print anything at
- compile time. This is important so that expansions of
- \macref{defun} and
- \macref{defmacro}
- can be done in terms of \specref{eval-when} and can correctly capture
- the \term{lexical environment}.
-
- \code
- (defun bar (x) (defun foo () (+ x 3)))
- \endcode
-
- might expand into
-
- \code
- (defun bar (x)
- (progn (eval-when (:compile-toplevel)
- (compiler::notice-function-definition 'foo '(x)))
- (eval-when (:execute :load-toplevel)
- (setf (symbol-function 'foo) #'(lambda () (+ x 3))))))
- \endcode
- which would be treated by the above rules the same as
-
- \code
- (defun bar (x)
- (setf (symbol-function 'foo) #'(lambda () (+ x 3))))
- \endcode
-
- when the definition of \f{bar} is not a \term{top level form}.
- \endlist
-
- \endissue{EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS}
-
- \endcom
- %% Replaced per X3J13. -kmp 05-Oct-93
- % %%% ========== LOAD-TIME-VALUE
- % \begincom{load-time-value}\ftype{Special Operator}
- % \issue{LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM}
- %
- % \label Syntax::
- %
- % \DefspecWithValues load-time-value {form {\opt} read-only-p} {object}
- %
- % \label Arguments and Values::
- %
- % \param{form}---a \term{form}; \evalspecial.
- %
- % \param{read-only-p}---one of the \term{symbols} \t\ or \nil; \noeval.
- %
- % \param{object}---the \term{primary value} resulting from evaluating \param{form}.
- %
- % \label Description::
- %
- % \specref{load-time-value} provides a mechanism for delaying evaluation of \param{form}
- % until the expression is in the run-time environment; \seesection\Compilation.
- %
- % \param{Read-only-p} designates whether the result can be considered a
- % \term{constant object}. If \nil\ (the default), the result must be considered
- % ordinary, modifiable data. If \t, the result is a read-only quantity
- % that can, if appropriate to the \term{implementation},
- % be copied into read-only space and/or \term{coalesced} with \term{similar}
- % \term{constant objects} from other \term{programs}.
- %
- % If a \specref{load-time-value} expression is processed by \funref{compile-file},
- % the compiler performs its normal semantic processing (such as macro expansion
- % and translation into machine code) on \param{form}, but arranges for the
- % execution of \param{form} to occur at load time in a \term{null lexical environment},
- % with the result of this \term{evaluation} then being treated as
- % %an immediate quantity
- % a \term{literal object}
- % at run time. It is guaranteed that the evaluation of \param{form}
- % will take place only once when the \term{file} is \term{loaded}, but
- % the order of evaluation with respect to the evaluation of
- % \term{top level forms} in the file is \term{implementation-dependent}.
- % \idxtext{order of evaluation}\idxtext{evaluation order}
- %
- % If a \specref{load-time-value} expression appears within a function compiled
- % with \funref{compile}, the \param{form} is evaluated at compile time in a
- % \term{null lexical environment}. The result of this compile-time evaluation
- % is treated as
- % %an immediate quantity
- % a \term{literal object}
- % in the compiled code.
- %
- % If a \specref{load-time-value} expression is processed by \funref{eval},
- % \param{form} is evaluated in a \term{null lexical environment},
- % and one value is returned. Implementations that implicitly compile
- % (or partially compile) expressions processed by \funref{eval}
- % %"can" => "might". Barrett thought "can" was clumsy.
- % might evaluate \param{form} only once, at the time this compilation is performed.
- % %This is intentionally similar to the
- % % freedom which implementations are given for the time of expanding
- % % macros in interpreted code.
- %
- % If the \term{same} \term{list} \f{(load-time-value \param{form})} is
- % evaluated or compiled more than once, it is \term{implementation-dependent}
- % whether \param{form} is evaluated only once or is evaluated more than once.
- % This can happen both when an expression being evaluated or compiled shares
- % substructure, and when the \term{same} \term{form} is processed by \funref{eval} or
- % \funref{compile} multiple times.
- % Since a \specref{load-time-value} expression can be
- % referenced in more than one place and can be evaluated multiple times
- % by \funref{eval}, it is
- % \term{implementation-dependent} whether each execution returns
- % a fresh \term{object}
- % or returns the same \term{object} as some other execution.
- % Users must use caution when destructively modifying the resulting
- % \term{object}.
- %
- % If two lists \f{(load-time-value \param{form})}
- % that are the \term{same} under \funref{equal} but are not \term{identical}
- % are evaluated or compiled,
- % their values always come from distinct evaluations of \param{form}.
- % %Per Barrett: "These forms" => "Their values"
- % Their \term{values} may not be coalesced
- % %Added per Barmar:
- % unless \param{read-only-p} is \t.
- %
- % \label Examples:\None.
- %
- % \label Affected By:\None.
- %
- % \label Exceptional Situations:\None.
- %
- % \label See Also::
- %
- % \funref{compile-file},
- % \funref{compile},
- % \funref{eval},
- % {\secref\MinimalCompilation},
- % {\secref\Compilation}
- %
- % \label Notes::
- %
- % \specref{load-time-value} must appear outside of quoted structure in a
- % ``for \term{evaluation}'' position. In situations which would appear to call
- % for use of \specref{load-time-value} within a quoted structure,
- % the \term{backquote} \term{reader macro} is probably called for;
- % \seesection\Backquote.
- %
- % \endissue{LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM}
- %
- % \endcom
- %%% ========== LOAD-TIME-VALUE
- \begincom{load-time-value}\ftype{Special Operator}
- \issue{LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM}
- \label Syntax::
- \DefspecWithValues load-time-value {form {\opt} read-only-p} {object}
- \label Arguments and Values::
- \param{form}---a \term{form}; \evalspecial.
- \param{read-only-p}---a \term{boolean}; \noeval.
- \param{object}---the \term{primary value} resulting from evaluating \param{form}.
- \label Description::
- \specref{load-time-value} provides a mechanism for delaying evaluation of \param{form}
- until the expression is in the run-time environment; \seesection\Compilation.
-
- \param{Read-only-p} designates whether the result can be considered a
- \term{constant object}.
- If \t,
- the result is a read-only quantity that can,
- if appropriate to the \term{implementation},
- be copied into read-only space and/or \term{coalesced} with \term{similar}
- \term{constant objects} from other \term{programs}.
- If \nil\ (the default),
- the result must be neither copied nor coalesced;
- it must be considered to be potentially modifiable data.
- If a \specref{load-time-value} expression is processed by \funref{compile-file},
- the compiler performs its normal semantic processing (such as macro expansion
- and translation into machine code) on \param{form}, but arranges for the
- execution of \param{form} to occur at load time in a \term{null lexical environment},
- with the result of this \term{evaluation} then being treated as
- %an immediate quantity
- a \term{literal object}
- at run time. It is guaranteed that the evaluation of \param{form}
- will take place only once when the \term{file} is \term{loaded}, but
- the order of evaluation with respect to the evaluation of
- \term{top level forms} in the file is \term{implementation-dependent}.
- \idxtext{order of evaluation}\idxtext{evaluation order}
-
- If a \specref{load-time-value} expression appears within a function compiled
- with \funref{compile}, the \param{form} is evaluated at compile time in a
- \term{null lexical environment}. The result of this compile-time evaluation
- is treated as
- %an immediate quantity
- a \term{literal object}
- in the compiled code.
-
- If a \specref{load-time-value} expression is processed by \funref{eval},
- \param{form} is evaluated in a \term{null lexical environment},
- and one value is returned. Implementations that implicitly compile
- (or partially compile) expressions processed by \funref{eval}
- %"can" => "might". Barrett thought "can" was clumsy.
- might evaluate \param{form} only once, at the time this compilation is performed.
- %This is intentionally similar to the
- % freedom which implementations are given for the time of expanding
- % macros in interpreted code.
-
- If the \term{same} \term{list} \f{(load-time-value \param{form})} is
- evaluated or compiled more than once, it is \term{implementation-dependent}
- whether \param{form} is evaluated only once or is evaluated more than once.
- This can happen both when an expression being evaluated or compiled shares
- substructure, and when the \term{same} \term{form} is processed by \funref{eval} or
- \funref{compile} multiple times.
- Since a \specref{load-time-value} expression can be
- referenced in more than one place and can be evaluated multiple times
- by \funref{eval}, it is
- \term{implementation-dependent} whether each execution returns
- a fresh \term{object}
- or returns the same \term{object} as some other execution.
- Users must use caution when destructively modifying the resulting
- \term{object}.
- If two lists \f{(load-time-value \param{form})}
- that are the \term{same} under \funref{equal} but are not \term{identical}
- are evaluated or compiled,
- their values always come from distinct evaluations of \param{form}.
- %Per Barrett: "These forms" => "Their values"
- Their \term{values} may not be coalesced
- %Added per Barmar:
- unless \param{read-only-p} is \t.
-
- \label Examples::
- \code
- ;;; The function INCR1 always returns the same value, even in different images.
- ;;; The function INCR2 always returns the same value in a given image,
- ;;; but the value it returns might vary from image to image.
- (defun incr1 (x) (+ x #.(random 17)))
- (defun incr2 (x) (+ x (load-time-value (random 17))))
- ;;; The function FOO1-REF references the nth element of the first of
- ;;; the *FOO-ARRAYS* that is available at load time. It is permissible for
- ;;; that array to be modified (e.g., by SET-FOO1-REF); FOO1-REF will see the
- ;;; updated values.
- (defvar *foo-arrays* (list (make-array 7) (make-array 8)))
- (defun foo1-ref (n) (aref (load-time-value (first *my-arrays*) nil) n))
- (defun set-foo1-ref (n val)
- (setf (aref (load-time-value (first *my-arrays*) nil) n) val))
- ;;; The function BAR1-REF references the nth element of the first of
- ;;; the *BAR-ARRAYS* that is available at load time. The programmer has
- ;;; promised that the array will be treated as read-only, so the system
- ;;; can copy or coalesce the array.
- (defvar *bar-arrays* (list (make-array 7) (make-array 8)))
- (defun bar1-ref (n) (aref (load-time-value (first *my-arrays*) t) n))
- ;;; This use of LOAD-TIME-VALUE permits the indicated vector to be coalesced
- ;;; even though NIL was specified, because the object was already read-only
- ;;; when it was written as a literal vector rather than created by a constructor.
- ;;; User programs must treat the vector v as read-only.
- (defun baz-ref (n)
- (let ((v (load-time-value #(A B C) nil)))
- (values (svref v n) v)))
- ;;; This use of LOAD-TIME-VALUE permits the indicated vector to be coalesced
- ;;; even though NIL was specified in the outer situation because T was specified
- ;;; in the inner situation. User programs must treat the vector v as read-only.
- (defun baz-ref (n)
- (let ((v (load-time-value (load-time-value (vector 1 2 3) t) nil)))
- (values (svref v n) v)))
- \endcode
-
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{compile-file},
- \funref{compile},
- \funref{eval},
- {\secref\MinimalCompilation},
- {\secref\Compilation}
- \label Notes::
- \specref{load-time-value} must appear outside of quoted structure in a
- ``for \term{evaluation}'' position. In situations which would appear to call
- for use of \specref{load-time-value} within a quoted structure,
- the \term{backquote} \term{reader macro} is probably called for;
- \seesection\Backquote.
- Specifying \nil\ for \param{read-only-p} is not a way to force an object
- to become modifiable if it has already been made read-only. It is only a way
- to say that, for an object that is modifiable, this operation is not intended
- to make that object read-only.
- \endissue{LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM}
-
- \endcom
- %%% ========== QUOTE
- \begincom{quote}\ftype{Special Operator}
- \label Syntax::
- \DefspecWithValues quote {object} {object}
- \label Arguments and Values::
- \param{object}---an \term{object}; \noeval.
- \label Description::
- %% 7.1.1 3
- \Thespecop{quote} just returns \param{object}.
- % added --sjl 3 Mar 92
- The consequences are undefined if \term{literal objects} (including
- \term{quoted objects}) are destructively modified.
- \label Examples::
- \code
- (setq a 1) \EV 1
- (quote (setq a 3)) \EV (SETQ A 3)
- a \EV 1
- 'a \EV A
- ''a \EV (QUOTE A)
- '''a \EV (QUOTE (QUOTE A))
- (setq a 43) \EV 43
- (list a (cons a 3)) \EV (43 (43 . 3))
- (list (quote a) (quote (cons a 3))) \EV (A (CONS A 3))
- 1 \EV 1
- '1 \EV 1
- "foo" \EV "foo"
- '"foo" \EV "foo"
- (car '(a b)) \EV A
- '(car '(a b)) \EV (CAR (QUOTE (A B)))
- #(car '(a b)) \EV #(CAR (QUOTE (A B)))
- '#(car '(a b)) \EV #(CAR (QUOTE (A B)))
- \endcode
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- {\secref\Evaluation},
- {\secref\QuoteMacro},
- \issue{CONSTANT-MODIFICATION:DISALLOW}
- {\secref\ConstantModification}
- \endissue{CONSTANT-MODIFICATION:DISALLOW}
- \label Notes::
- The textual notation \f{'\param{object}} is equivalent to \f{(quote \param{object})};
- \seesection\ConstantModification.
- %% 7.1.0 1
- Some \term{objects}, called \term{self-evaluating objects},
- do not require quotation by \specref{quote}.
- However, \term{symbols} and \term{lists} are used to represent parts of programs,
- and so would not be useable as constant data in a program without \specref{quote}.
- Since \specref{quote} suppresses the \term{evaluation} of these \term{objects},
- they become data rather than program.
- \endcom
- %-------------------- Macros --------------------
- %%% ========== COMPILER-MACRO-FUNCTION
- \begincom{compiler-macro-function}\ftype{Accessor}
- \issue{DEFINE-COMPILER-MACRO:X3J13-NOV89}
- \label Syntax::
- \DefunWithValues compiler-macro-function {name {\opt} environment} {function}
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \Defsetf compiler-macro-function {name {\opt} environment} {new-function}
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \label Arguments and Values::
- \param{name}---a \term{function name}.
- \param{environment}---an \term{environment} \term{object}.
- \param{function}, \param{new-function}---a \term{compiler macro function}, or \nil.
-
- \label Description::
- \term{Accesses} the \term{compiler macro function} named \param{name}, if any,
- in the \param{environment}.
- A value of \nil\ denotes the absence of a \term{compiler macro function} named \param{name}.
- \label Examples:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
-
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- The consequences are undefined if \param{environment} is \term{non-nil}
- in a use of \SETFof{compiler-macro-function}.
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \label See Also::
-
- \macref{define-compiler-macro}, {\secref\CompilerMacros}
- \label Notes:\None.
- \endissue{DEFINE-COMPILER-MACRO:X3J13-NOV89}
- \endcom
- %%% ========== DEFINE-COMPILER-MACRO
- \begincom{define-compiler-macro}\ftype{Macro}
-
- \issue{DECLS-AND-DOC}
- \label Syntax::
- \DefmacWithValuesNewline define-compiler-macro
- {name lambda-list {\DeclsAndDoc} \starparam{form}}
- {name}
- \label Arguments and Values::
- \param{name}---a \term{function name}.
- % tweaked. --sjl 5 Mar 92
- % \param{lambda-list}---a \term{lambda list};
- % can contain the lambda list keywords
- % \keyref{allow-other-keys},
- % \keyref{aux},
- % \keyref{body},
- % \keyref{environment},
- % \keyref{key},
- % \keyref{optional},
- % \keyref{rest},
- % and
- % \keyref{whole}.
- \param{lambda-list}---a \term{macro lambda list}.
-
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
-
- \param{documentation}---a \term{string}; \noeval.
- \param{form}---a \term{form}.
- \label Description::
- \editornote{KMP: This definition probably needs to be fully expanded to not
- refer through the definition of defmacro, but should suffice for now.}
- % If this rewriting happens, be sure to copy the compile-time side-effects
- % info from DEFMACRO too. -- sjl 5 Mar 92
- This is the normal mechanism for defining a \term{compiler macro function}.
- Its manner of definition is the same as for \macref{defmacro}; the only
- differences are:
- \beginlist
- \itemitem{\bull} The \param{name} can be a \term{function name} naming
- any \term{function} or \term{macro}.
- \itemitem{\bull} The expander function is installed as a \term{compiler macro function}
- for the \param{name}, rather than as a \term{macro function}.
- \itemitem{\bull} The \keyref{whole} argument is bound to the form argument that
- is passed to the \term{compiler macro function}. The remaining lambda-list
- parameters are specified as if this form contained the function name in the
- \term{car} and the actual arguments in the \term{cdr}, but if the \term{car}
- of the actual form is the symbol \funref{funcall}, then the destructuring of
- the arguments is actually performed using its \term{cddr} instead.
- \itemitem{\bull}\issue{DOCUMENTATION-FUNCTION-BUGS:FIX}%
- \param{Documentation} is attached as a \term{documentation string}
- to \param{name} (as kind \specref{compiler-macro})
- and to the \term{compiler macro function}.
- \endissue{DOCUMENTATION-FUNCTION-BUGS:FIX}
- \itemitem{\bull} Unlike an ordinary \term{macro}, a \term{compiler macro}
- can decline to provide an expansion merely by returning a form that is
- the \term{same} as the original (which can be obtained by using
- \keyref{whole}).
- \endlist
- \label Examples::
- \code
- (defun square (x) (expt x 2)) \EV SQUARE
- (define-compiler-macro square (&whole form arg)
- (if (atom arg)
- `(expt ,arg 2)
- (case (car arg)
- (square (if (= (length arg) 2)
- `(expt ,(nth 1 arg) 4)
- form))
- (expt (if (= (length arg) 3)
- (if (numberp (nth 2 arg))
- `(expt ,(nth 1 arg) ,(* 2 (nth 2 arg)))
- `(expt ,(nth 1 arg) (* 2 ,(nth 2 arg))))
- form))
- (otherwise `(expt ,arg 2))))) \EV SQUARE
- (square (square 3)) \EV 81
- (macroexpand '(square x)) \EV (SQUARE X), \term{false}
- (funcall (compiler-macro-function 'square) '(square x) nil)
- \EV (EXPT X 2)
- (funcall (compiler-macro-function 'square) '(square (square x)) nil)
- \EV (EXPT X 4)
- (funcall (compiler-macro-function 'square) '(funcall #'square x) nil)
- \EV (EXPT X 2)
- (defun distance-positional (x1 y1 x2 y2)
- (sqrt (+ (expt (- x2 x1) 2) (expt (- y2 y1) 2))))
- \EV DISTANCE-POSITIONAL
- (defun distance (&key (x1 0) (y1 0) (x2 x1) (y2 y1))
- (distance-positional x1 y1 x2 y2))
- \EV DISTANCE
- (define-compiler-macro distance (&whole form
- &rest key-value-pairs
- &key (x1 0 x1-p)
- (y1 0 y1-p)
- (x2 x1 x2-p)
- (y2 y1 y2-p)
- &allow-other-keys
- &environment env)
- (flet ((key (n) (nth (* n 2) key-value-pairs))
- (arg (n) (nth (1+ (* n 2)) key-value-pairs))
- (simplep (x)
- (let ((expanded-x (macroexpand x env)))
- (or (constantp expanded-x env)
- (symbolp expanded-x)))))
- (let ((n (/ (length key-value-pairs) 2)))
- (multiple-value-bind (x1s y1s x2s y2s others)
- (loop for (key) on key-value-pairs by #'cddr
- count (eq key ':x1) into x1s
- count (eq key ':y1) into y1s
- count (eq key ':x2) into x2s
- count (eq key ':y1) into y2s
- count (not (member key '(:x1 :x2 :y1 :y2)))
- into others
- finally (return (values x1s y1s x2s y2s others)))
- (cond ((and (= n 4)
- (eq (key 0) :x1)
- (eq (key 1) :y1)
- (eq (key 2) :x2)
- (eq (key 3) :y2))
- `(distance-positional ,x1 ,y1 ,x2 ,y2))
- ((and (if x1-p (and (= x1s 1) (simplep x1)) t)
- (if y1-p (and (= y1s 1) (simplep y1)) t)
- (if x2-p (and (= x2s 1) (simplep x2)) t)
- (if y2-p (and (= y2s 1) (simplep y2)) t)
- (zerop others))
- `(distance-positional ,x1 ,y1 ,x2 ,y2))
- ((and (< x1s 2) (< y1s 2) (< x2s 2) (< y2s 2)
- (zerop others))
- (let ((temps (loop repeat n collect (gensym))))
- `(let ,(loop for i below n
- collect (list (nth i temps) (arg i)))
- (distance
- ,@(loop for i below n
- append (list (key i) (nth i temps)))))))
- (t form))))))
- \EV DISTANCE
- (dolist (form
- '((distance :x1 (setq x 7) :x2 (decf x) :y1 (decf x) :y2 (decf x))
- (distance :x1 (setq x 7) :y1 (decf x) :x2 (decf x) :y2 (decf x))
- (distance :x1 (setq x 7) :y1 (incf x))
- (distance :x1 (setq x 7) :y1 (incf x) :x1 (incf x))
- (distance :x1 a1 :y1 b1 :x2 a2 :y2 b2)
- (distance :x1 a1 :x2 a2 :y1 b1 :y2 b2)
- (distance :x1 a1 :y1 b1 :z1 c1 :x2 a2 :y2 b2 :z2 c2)))
- (print (funcall (compiler-macro-function 'distance) form nil)))
- \OUT (LET ((#:G6558 (SETQ X 7))
- \OUT (#:G6559 (DECF X))
- \OUT (#:G6560 (DECF X))
- \OUT (#:G6561 (DECF X)))
- \OUT (DISTANCE :X1 #:G6558 :X2 #:G6559 :Y1 #:G6560 :Y2 #:G6561))
- \OUT (DISTANCE-POSITIONAL (SETQ X 7) (DECF X) (DECF X) (DECF X))
- \OUT (LET ((#:G6567 (SETQ X 7))
- \OUT (#:G6568 (INCF X)))
- \OUT (DISTANCE :X1 #:G6567 :Y1 #:G6568))
- \OUT (DISTANCE :X1 (SETQ X 7) :Y1 (INCF X) :X1 (INCF X))
- \OUT (DISTANCE-POSITIONAL A1 B1 A2 B2)
- \OUT (DISTANCE-POSITIONAL A1 B1 A2 B2)
- \OUT (DISTANCE :X1 A1 :Y1 B1 :Z1 C1 :X2 A2 :Y2 B2 :Z2 C2)
- \EV NIL
- \endcode
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \funref{compiler-macro-function},
- \macref{defmacro},
- \funref{documentation},
- {\secref\DocVsDecls}
- \label Notes::
- The consequences of writing a \term{compiler macro} definition for a function
- in \thepackage{common-lisp} are undefined; it is quite possible that in some
- \term{implementations} such an attempt would override an equivalent or equally
- important definition. In general, it is recommended that a programmer only
- write \term{compiler macro} definitions for \term{functions} he or she personally
- maintains--writing a \term{compiler macro} definition for a function maintained
- elsewhere is normally considered a violation of traditional rules of modularity
- and data abstraction.
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== DEFMACRO
- \begincom{defmacro}\ftype{Macro}
- \issue{DECLS-AND-DOC}
- \label Syntax::
- \DefmacWithValuesNewline defmacro {name lambda-list {\DeclsAndDoc} \starparam{form}} {name}
-
- \label Arguments and Values::
- \param{name}---a \term{symbol}. %!!! maybe call it a "user symbol" ?? -kmp 2-Aug-91
-
- %% 8.1.0 9
- %% 8.1.0 10
- %% 8.1.0 11
- %% 8.1.0 12
- \param{lambda-list}---a \term{macro lambda list}.
-
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
-
- \param{documentation}---a \term{string}; \noeval.
-
- \param{form}---a \term{form}.
-
- \label Description::
- %% 8.1.0 6
- Defines \param{name} as a \term{macro}
- by associating a \term{macro function} with that \param{name}
- in the global environment.
- \issue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW}
- % Reworded garbled text. --sjl 7 Mar 92
- %When the \term{macro function} is called,
- %the \param{forms} are evaluated in
- %the \term{lexical environment} in which the \macref{defmacro} form was evaluated.
- The \term{macro function} is defined in the same \term{lexical environment}
- in which the \macref{defmacro} \term{form} appears.
- \endissue{DEFINING-MACROS-NON-TOP-LEVEL:ALLOW}
-
- %% 8.1.0 7
- The parameter variables in \param{lambda-list} are bound to
- destructured portions of the macro call.
-
- The expansion function
- accepts two arguments, a \term{form} and an
- \term{environment}. The expansion function returns a \term{form}.
- The body of the expansion function is specified by \param{forms}.
- \param{Forms} are executed in order. The value of the
- last \param{form} executed is returned as the expansion of the
- \term{macro}.
- \issue{FLET-IMPLICIT-BLOCK:YES}
- \issue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS}
- The body \param{forms} of the expansion function (but not the \param{lambda-list})
- \endissue{DEFMACRO-BLOCK-SCOPE:EXCLUDES-BINDINGS}
- are implicitly enclosed in a \term{block} whose name is \param{name}.
- \endissue{FLET-IMPLICIT-BLOCK:YES}
-
- The \param{lambda-list} conforms to the requirements described in \secref\MacroLambdaLists.
-
- \issue{DOCUMENTATION-FUNCTION-BUGS:FIX}
- \param{Documentation} is attached as a \term{documentation string}
- to \param{name} (as kind \specref{function})
- and to the \term{macro function}.
- \endissue{DOCUMENTATION-FUNCTION-BUGS:FIX}
-
- %% 8.1.0 17
- \macref{defmacro} can be used to redefine a \term{macro} or to replace
- a \term{function} definition with a \term{macro} definition.
-
- %% sandra says this is redundant
- %The consequences are undefined if a \term{special form} is redefined
- %using \macref{defmacro}.
-
- \issue{RECURSIVE-DEFTYPE:EXPLICITLY-VAGUE}
- Recursive expansion of the \term{form} returned must terminate,
- including the expansion of other \term{macros} which are \term{subforms}
- of other \term{forms} returned.
- %% Per Moon#13 (first public review) -kmp 5-May-93
- The consequences are undefined if the result of fully macroexpanding
- %a form contains any non-constant circular list structure.
- a \term{form}
- contains any \term{circular} \term{list structure} except in \term{literal objects}.
- \endissue{RECURSIVE-DEFTYPE:EXPLICITLY-VAGUE}
-
- \issue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY}
- % added qualification about top-level-ness --sjl 5 Mar 92
- If a \macref{defmacro} \term{form} appears as a \term{top level form},
- the \term{compiler} must store the \term{macro} definition at compile time,
- so that occurrences of the macro later on in the file can be expanded correctly.
- Users must ensure that the body of the \term{macro} can be evaluated at
- compile time if it is referenced within the \term{file} being \term{compiled}.
- \endissue{COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY}
- \label Examples::
- \code
- (defmacro mac1 (a b) "Mac1 multiplies and adds"
- `(+ ,a (* ,b 3))) \EV MAC1
- (mac1 4 5) \EV 19
- (documentation 'mac1 'function) \EV "Mac1 multiplies and adds"
- (defmacro mac2 (&optional (a 2 b) (c 3 d) &rest x) `'(,a ,b ,c ,d ,x)) \EV MAC2
- (mac2 6) \EV (6 T 3 NIL NIL)
- (mac2 6 3 8) \EV (6 T 3 T (8))
- (defmacro mac3 (&whole r a &optional (b 3) &rest x &key c (d a))
- `'(,r ,a ,b ,c ,d ,x)) \EV MAC3
- (mac3 1 6 :d 8 :c 9 :d 10) \EV ((MAC3 1 6 :D 8 :C 9 :D 10) 1 6 9 8 (:D 8 :C 9 :D 10))
- \endcode
- % (defmacro mac4
- % (&whole (su &rest (p &rest q)) a
- % &optional (b 3) &rest x &key c (d a))
- % `'(,su ,p ,a ,b ,c ,d ,x)) \EV MAC4
- % (mac4 1 6 :d 8 :c 9 :d 10) \EV (MAC4 1 1 6 9 8 (:D 8 :C 9 :D 10))
-
- %An example of destructuring follows:
- %
- %\code
- % (defmacro halibut ((mouth eye1 eye2)
- % ((fin1 length1) (fin2 length2))
- % tail)
- % ...)
- %\endcode
- %Now consider this macro call:
- %
- %\code
- % (halibut (m (car eyes) (cdr eyes))
- % ((f1 (count-scales f1)) (f2 (count-scales f2)))
- % my-favorite-tail) \EV NIL
- %\endcode
- %This would cause the expansion function to receive the
- %values in \thenextfigure\ for its parameters:
- %
- %\boxfig
- %{\dimen0=.75pc
- %\tabskip \dimen0 plus .5 fil
- %\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr
- %\noalign{\vskip -9pt}
- %\hfil{{\sl Parameter\/}} & {{\sl Value\/}} \cr
- %\noalign{\vskip 2pt\hrule\vskip 2pt}
- %mouth & m \cr
- %eye1 & (car eyes) \cr
- %eye2 & (cdr eyes) \cr
- %fin1 & f1 \cr
- %length1 & (count-scales f1) \cr
- %fin2 & f2 \cr
- %length2 & (count-scales f2) \cr
- %tail & my-favorite-tail \cr
- %\noalign{\vskip -9pt}
- %}}
- %\caption{Destructuring example expansion function values}
- %\endfig
- %The following macro call would be in error because there would be no
- %argument form to match the parameter \f{length1}:
- %
- %\code
- % (halibut (m (car eyes) (cdr eyes))
- % ((f1) (f2 (count-scales f2)))
- % my-favorite-tail)
- %\endcode
- %The following macro call would be in error because a \term{symbol} appears
- %in the call where the structure of the \term{lambda list} requires a
- %\term{list}:
- %
- %\code
- % (halibut my-favorite-head
- % ((f1 (count-scales f1)) (f2 (count-scales f2)))
- % my-favorite-tail)
- %\endcode
- %The fact that the value of the variable \f{my-favorite-head}
- %might happen to be a \term{list} is irrelevant here. It is the macro call
- %itself whose structure must match that of the \macref{defmacro}
- %\term{lambda list}.
- %
- %%% 8.1.0 25
- %The use of \term{lambda list keywords} is illustrated as follows.
- %Suppose it is convenient within the expansion
- %function for \f{halibut} to be able to refer to the \term{list}
- %whose components are called \f{mouth}, \f{eye1}, and \f{eye2}
- %as \f{head}.
- %This may be written as follows:
- %
- %\code
- % (defmacro halibut ((&whole head mouth eye1 eye2)
- % ((fin1 length1) (fin2 length2))
- % tail)
- % ...)
- %\endcode
- %Now consider the same valid macro call as before:
- %
- %\code
- % (halibut (m (car eyes) (cdr eyes))
- % ((f1 (count-scales f1)) (f2 (count-scales f2)))
- % my-favorite-tail) \EV NIL
- %\endcode
- %This would cause the expansion function to receive the same
- %values for its parameters and also a value for the parameter \f{head}
- %as in \thenextfigure.
- %
- %\boxfig
- %{\dimen0=.75pc
- %\tabskip \dimen0 plus .5 fil
- %\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr
- %\noalign{\vskip -9pt}
- %\hfil{{\sl Parameter\/}} & {{\sl Value\/}} \cr
- %\noalign{\vskip 2pt\hrule\vskip 2pt}
- %head & (m (car eyes) (cdr eyes)) \cr
- %\noalign{\vskip -9pt}
- %}}
- %\caption{Lambda list keywords expansion function values example}
- %\endfig
- %
- %%% 8.1.0 19
- %The following implements a conditional \term{form} analogous to the
- %\fortran\ arithmetic IF statement.
- %The \term{form} should accept four argument forms: a \f{test-value},
- %a \f{neg-form}, a \f{zero-form}, and a \f{pos-form}.
- %One of the last three forms is chosen to be executed according
- %to whether the value of the \f{test-form} is positive, negative,
- %or zero.
- %Using \macref{defmacro}, a definition for such a \term{form}
- %might look like this:
- %
- %\code
- % (defmacro arithmetic-if (test neg-form zero-form pos-form)
- % (let ((var (gensym)))
- % `(let ((,var ,test))
- % (cond ((< ,var 0) ,neg-form)
- % ((= ,var 0) ,zero-form)
- % (t ,pos-form))))) \EV ARITHMETIC-IF
- %\endcode
- %Note the use of the backquote facility in this definition,
- %and also the use of \funref{gensym} to generate a new variable name.
- %This is necessary to avoid conflict with any variables that might
- %be referred to in \f{neg-form}, \f{zero-form}, or \f{pos-form}.
- %
- %%% 8.1.0 20
- %If the form is executed by the interpreter, it will cause the
- %function definition of the symbol \f{arithmetic-if}
- %to be a macro associated with which is
- %a two-argument expansion function roughly equivalent to:
- %
- %\code
- % (lambda (calling-form environment)
- % (declare (ignore environment))
- % (let ((var (gensym)))
- % (list 'let
- % (list (list 'var (cadr calling-form)))
- % (list 'cond
- % (list (list '< var '0) (caddr calling-form))
- % (list (list '= var '0) (cadddr calling-form))
- % (list 't (fifth calling-form))))))
- %\endcode
-
-
- % Barmar had noted that if we were going to show the above lambda, we should show
- % the defmacro that might have produced it. But since we're not going to show it,
- % I guess the issue is moot. -kmp 28-Dec-90
- %
- %%% 8.1.0 21
- %The \term{lambda expression}
- %could have been produced by the \macref{defmacro} macro.
- %The calls to \funref{list} are the (hypothetical) result
- %of the backquote (\f{\bq})
- %macro character and its associated commas.
- %The precise macro expansion function might depend on the implementation.
- %For example, the implementation
- %might provide some degree of explicit error checking on the number
- %of argument forms in the macro call.
- %
- %%% 8.1.0 22
- %
- %%If \funref{eval} encounters
- %%
- %%\code
- % (arithmetic-if (- x 4.0)
- %% (- x)
- %% (error "Strange zero")
- %% x)
- %%\endcode
- %this will be expanded into something like
- %
- %\code
- % (let ((g407 (- x 4.0)))
- % (cond ((< g407 0) (- x))
- % ((= g407 0) (error "Strange zero"))
- % (t x)))
- %\endcode
- %and \funref{eval} tries again on this new form.
- %
- %%% 8.1.0 23
- %To expand on this example
- %the \f{pos-form}
- %and \f{zero-form} could be omitted, allowing their values to default to \nil,
- %in the same way that the \f{else} form of \specref{if}
- %may be omitted:
- %
- %\code
- % (defmacro arithmetic-if (test neg-form &optional zero-form pos-form)
- % (let ((var (gensym)))
- % \bq(let ((,var ,test))
- % (cond ((< ,var 0) ,neg-form)
- % ((= ,var 0) ,zero-form)
- % (t ,pos-form)))))
- %\endcode
- %Then
- %
- %\code
- % (arithmetic-if (- x 4.0) (print x))
- %\endcode
- %would be expanded into something like
- %
- %\code
- % (let ((g408 (- x 4.0)))
- % (cond ((< g408 0) (print x))
- % ((= g408 0) nil)
- % (t nil)))
- %\endcode
-
- %% 8.1.0 26
- The stipulation that
- an embedded \term{destructuring lambda list} is permitted only
- where \term{ordinary lambda list} syntax would permit a parameter name
- but not a \term{list} is made to prevent ambiguity. For example,
- the following is not valid:
-
- \code
- (defmacro loser (x &optional (a b &rest c) &rest z)
- ...)
- \endcode
- because \term{ordinary lambda list} syntax does permit a
- \term{list} following \optional;
- the list \f{(a b \&rest c)} would be interpreted as describing an
- optional parameter named \f{a} whose default value is that of the
- form \f{b}, with a supplied-p parameter named \keyref{rest} (not valid),
- and an extraneous symbol \f{c} in the list (also not valid). An almost
- correct way to express this is
-
- \code
- (defmacro loser (x &optional ((a b &rest c)) &rest z)
- ...)
- \endcode
- The extra set of parentheses removes the ambiguity. However, the
- definition is now incorrect because a macro call such as \f{(loser (car pool))}
- would not provide any argument form for the lambda list \f{(a b \&rest c)},
- and so the default value against which to match the \term{lambda list} would be
- \nil\ because no explicit default value was specified.
- The consequences of this are unspecified
- since the empty list, \nil, does not have \term{forms} to satisfy the
- parameters \f{a} and \f{b}. The fully correct definition would be either
-
- \code
- (defmacro loser (x &optional ((a b &rest c) '(nil nil)) &rest z)
- ...)
- \endcode
- or
-
- \code
- (defmacro loser (x &optional ((&optional a b &rest c)) &rest z)
- ...)
- \endcode
- These differ slightly: the first requires that if the macro call
- specifies \f{a} explicitly then it must also specify \f{b} explicitly,
- whereas the second does not have this requirement. For example,
-
- \code
- (loser (car pool) ((+ x 1)))
- \endcode
- would be a valid call for the second definition but not for the first.
-
- \issue{DEFMACRO-LAMBDA-LIST:TIGHTEN-DESCRIPTION}
-
- \code
- (defmacro dm1a (&whole x) `',x)
- (macroexpand '(dm1a)) \EV (QUOTE (DM1A))
- (macroexpand '(dm1a a)) is an error.
-
- (defmacro dm1b (&whole x a &optional b) `'(,x ,a ,b))
- (macroexpand '(dm1b)) is an error.
- (macroexpand '(dm1b q)) \EV (QUOTE ((DM1B Q) Q NIL))
- (macroexpand '(dm1b q r)) \EV (QUOTE ((DM1B Q R) Q R))
- (macroexpand '(dm1b q r s)) is an error.
- \endcode
-
- \code
- (defmacro dm2a (&whole form a b) `'(form ,form a ,a b ,b))
- (macroexpand '(dm2a x y)) \EV (QUOTE (FORM (DM2A X Y) A X B Y))
- (dm2a x y) \EV (FORM (DM2A X Y) A X B Y)
- (defmacro dm2b (&whole form a (&whole b (c . d) &optional (e 5))
- &body f &environment env)
- ``(,',form ,,a ,',b ,',(macroexpand c env) ,',d ,',e ,',f))
- ;Note that because backquote is involved, implementations may differ
- ;slightly in the nature (though not the functionality) of the expansion.
- (macroexpand '(dm2b x1 (((incf x2) x3 x4)) x5 x6))
- \EV (LIST* '(DM2B X1 (((INCF X2) X3 X4))
- X5 X6)
- X1
- '((((INCF X2) X3 X4)) (SETQ X2 (+ X2 1)) (X3 X4) 5 (X5 X6))),
- T
- (let ((x1 5))
- (macrolet ((segundo (x) `(cadr ,x)))
- (dm2b x1 (((segundo x2) x3 x4)) x5 x6)))
- \EV ((DM2B X1 (((SEGUNDO X2) X3 X4)) X5 X6)
- 5 (((SEGUNDO X2) X3 X4)) (CADR X2) (X3 X4) 5 (X5 X6))
- \endcode
-
- \endissue{DEFMACRO-LAMBDA-LIST:TIGHTEN-DESCRIPTION}
-
- \label Affected By:\None.
- \label Exceptional Situations:\none.
- % adequately covered in the packages chapter. --sjl 5 Mar 92
- % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % The consequences are undefined if \param{name}
- % is a \term{symbol} in \thepackage{common-lisp}.
- % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % Barmar writes:
- % "Macros must not modify any of the structure they are given."
- % We outlawed displacing at some point.
- % but I couldn't find anything to back up this claim. Issue MACRO-CACHING
- % had this in mind, but didn't go far enough. So I've left this alone for now.
- % -kmp 2-Aug-91
- \label See Also::
- \issue{DEFINE-COMPILER-MACRO:X3J13-NOV89}
- \macref{define-compiler-macro},
- \endissue{DEFINE-COMPILER-MACRO:X3J13-NOV89}
- \macref{destructuring-bind},
- \funref{documentation},
- \funref{macroexpand},
- \varref{*macroexpand-hook*},
- \specref{macrolet},
- \funref{macro-function},
- {\secref\Evaluation},
- {\secref\Compilation},
- {\secref\DocVsDecls}
- \label Notes:\None.
-
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== MACRO-FUNCTION
- \begincom{macro-function}\ftype{Accessor}
-
- \label Syntax::
- \DefunWithValues macro-function {symbol {\opt} environment} {function}
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- % % If it's an error to supply the environment argument here, the syntax
- % % shouldn't show it. Compare w/COMPILER-MACRO-FUNCTION. --sjl 5 Mar 92
- % % \Defsetf macro-function {symbol {\opt} environment} {new-function}
- % \Defsetf macro-function {symbol} {new-function}
- %% Reinstated per X3J13.
- \Defsetf macro-function {symbol {\opt} environment} {new-function}
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \label Arguments and Values::
- \param{symbol}---a \term{symbol}.
-
- \issue{MACRO-FUNCTION-ENVIRONMENT}
- \param{environment}---an \term{environment} \term{object}.
- \endissue{MACRO-FUNCTION-ENVIRONMENT}
- \param{function}---a \term{macro function} or \nil.
-
- \param{new-function}---a \term{macro function}.
- \label Description::
- %% 8.1.0 2
- Determines whether \param{symbol} has a function definition
- as a macro in the specified \param{environment}.
-
- If so, the macro expansion function, a function of two arguments,
- is returned. If \param{symbol} has no function definition
- in the lexical environment \param{environment}, or its definition
- is not a \term{macro}, \funref{macro-function} returns \nil.
-
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \issue{MACRO-FUNCTION-ENVIRONMENT}
- % The consequences are undefined if \param{environment} is supplied
- % in a use of \funref{macro-function} as a \macref{setf} location specifier.
- \endissue{MACRO-FUNCTION-ENVIRONMENT}
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- %This doesn't belong here. -kmp 09-Apr-91
- % \issue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC}
- % The \term{environment} \term{object} has
- % \term{dynamic extent}; the consequences are undefined if
- % the \keyref{environment} argument is
- % referred to outside the \term{dynamic extent}
- % of the macro expansion function.
- % \endissue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC}
-
- \issue{MACRO-FUNCTION-ENVIRONMENT}
- % The following will be deleted:
- %
- % %% 8.1.0 4
- % \funref{macro-function}
- % cannot be used to determine whether \param{symbol} names
- % a locally defined macro established by \specref{macrolet};
- % %% or \specref{symbol-macrolet}
- % \funref{macro-function} can
- % examine only global definitions.
- \endissue{MACRO-FUNCTION-ENVIRONMENT}
-
- %% 8.1.0 3
- It is possible for both \funref{macro-function} and
- \issue{SPECIAL-FORM-P-MISNOMER:RENAME}
- \funref{special-operator-p}
- \endissue{SPECIAL-FORM-P-MISNOMER:RENAME}
- to return \term{true} of \param{symbol}. The \term{macro} definition must
- be available for use by programs that understand only the standard
- \clisp\ \term{special forms}.
-
- \label Examples::
- \code
- (defmacro macfun (x) '(macro-function 'macfun)) \EV MACFUN
- (not (macro-function 'macfun)) \EV \term{false}
- \endcode
- %;;--- The next four lines are not valid Common Lisp, as equal
- %;;--- is not defined for functions --Moon
- % (and (setf (macro-function 'macfun) #'equal)
- % (equal (macro-function 'macfun) #'equal)) \EV \term{true}
- % (macrolet ((macfun (x) "local"))
- % (equal (macro-function 'macfun) #'equal)) \EV \term{true}
- \issue{MACRO-FUNCTION-ENVIRONMENT}
- \code
- (macrolet ((foo (&environment env)
- (if (macro-function 'bar env)
- ''yes
- ''no)))
- (list (foo)
- (macrolet ((bar () :beep))
- (foo))))
-
- \EV (NO YES)
- \endcode
- \endissue{MACRO-FUNCTION-ENVIRONMENT}
-
- \label Affected By::
- \f{(setf macro-function)}, \macref{defmacro}, and \specref{macrolet}.
- \label Exceptional Situations::
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- The consequences are undefined if \param{environment} is \term{non-nil}
- in a use of \SETFof{macro-function}.
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
-
- \label See Also::
- \macref{defmacro}, {\secref\Evaluation}
-
- \label Notes::
-
- %% 8.1.0 5
- \macref{setf} can be used with \funref{macro-function} to install
- a \term{macro} as a symbol's global function definition:
-
- \code
- (setf (macro-function symbol) fn)
- \endcode
- The value installed must be a \term{function} that accepts two arguments,
- the entire macro call and an \term{environment},
- and computes the expansion for that call.
- Performing this operation causes \param{symbol} to have only that
- macro definition as its global function definition; any previous
- definition, whether as a \term{macro} or as a
- \term{function}, is lost.
-
- \endcom
- %%% ========== MACROEXPAND
- %%% ========== MACROEXPAND-1
- \begincom{macroexpand, macroexpand-1}\ftype{Function}
-
- \label Syntax::
- \DefunWithValues macroexpand {form {\opt} env} {expansion, expanded-p}
- \DefunWithValues macroexpand-1 {form {\opt} env} {expansion, expanded-p}
-
- \label Arguments and Values::
- \param{form}---a \term{form}.
-
- \param{env}---an \term{environment} \term{object}.
- \Default{\nil}
-
- \param{expansion}---a \term{form}.
-
- \issue{MACROEXPAND-RETURN-VALUE:TRUE}
- \param{expanded-p}---a \term{generalized boolean}.
- \endissue{MACROEXPAND-RETURN-VALUE:TRUE}
-
- \label Description::
- \funref{macroexpand} and \funref{macroexpand-1} expand \term{macros}.
-
- %% 8.2.0 2
- %% 8.2.0 3
- If \param{form} is a \term{macro form},
- then \funref{macroexpand-1} expands the \term{macro form} call once.
-
- %% 8.2.0 7
- \funref{macroexpand}
- repeatedly expands \param{form} until it is no longer a \term{macro form}.
- In effect, \funref{macroexpand} calls \funref{macroexpand-1} repeatedly
- until the \term{secondary value} it returns is \nil.
- %% 8.2.0 2
- If \param{form} is a \term{macro form},
- then the \param{expansion} is a \term{macro expansion}
- and \param{expanded-p} is \term{true}.
- Otherwise,
- the \param{expansion} is the given \param{form}
- and \param{expanded-p} is \term{false}.
-
- %% 8.2.0 4
- Macro expansion is carried out as follows.
- Once \funref{macroexpand-1} has
- determined that the \param{form} is a \term{macro form},
- it obtains an appropriate expansion \term{function} for the
- \term{macro} or \term{symbol macro}.
- The value of
- \varref{*macroexpand-hook*} is
- \issue{FUNCTION-TYPE:X3J13-MARCH-88}
- coerced to a \term{function} and
- \endissue{FUNCTION-TYPE:X3J13-MARCH-88}
- then called as a \term{function} of three arguments:
- the expansion \term{function},
- the \param{form},
- and the \param{env}.
- The \term{value} returned from this call is taken to be the expansion
- of the \param{form}.
- %% Augmented this first sentence to mention global environment
- %% and local symbol-macrolet definitions. -kmp 12-May-93
- In addition to \term{macro} definitions in the global environment,
- any local macro definitions established within \param{env} by \specref{macrolet}
- or \specref{symbol-macrolet} are considered.
- If only \param{form} is supplied as an argument,
- then the environment is effectively null, and only global macro definitions
- as established by \macref{defmacro} are considered.
- %% Sandra addition
- \term{Macro} definitions are shadowed by local \term{function} definitions.
- %% end Sandra addition
- \label Examples::
- \code
- (defmacro alpha (x y) `(beta ,x ,y)) \EV ALPHA
- (defmacro beta (x y) `(gamma ,x ,y)) \EV BETA
- (defmacro delta (x y) `(gamma ,x ,y)) \EV EPSILON
- (defmacro expand (form &environment env)
- (multiple-value-bind (expansion expanded-p)
- (macroexpand form env)
- `(values ',expansion ',expanded-p))) \EV EXPAND
- (defmacro expand-1 (form &environment env)
- (multiple-value-bind (expansion expanded-p)
- (macroexpand-1 form env)
- `(values ',expansion ',expanded-p))) \EV EXPAND-1
- \medbreak
- ;; Simple examples involving just the global environment
- (macroexpand-1 '(alpha a b)) \EV (BETA A B), \term{true}
- (expand-1 (alpha a b)) \EV (BETA A B), \term{true}
- (macroexpand '(alpha a b)) \EV (GAMMA A B), \term{true}
- (expand (alpha a b)) \EV (GAMMA A B), \term{true}
- (macroexpand-1 'not-a-macro) \EV NOT-A-MACRO, \term{false}
- (expand-1 not-a-macro) \EV NOT-A-MACRO, \term{false}
- (macroexpand '(not-a-macro a b)) \EV (NOT-A-MACRO A B), \term{false}
- (expand (not-a-macro a b)) \EV (NOT-A-MACRO A B), \term{false}
- \medbreak
- ;; Examples involving lexical environments
- (macrolet ((alpha (x y) `(delta ,x ,y)))
- (macroexpand-1 '(alpha a b))) \EV (BETA A B), \term{true}
- (macrolet ((alpha (x y) `(delta ,x ,y)))
- (expand-1 (alpha a b))) \EV (DELTA A B), \term{true}
- (macrolet ((alpha (x y) `(delta ,x ,y)))
- (macroexpand '(alpha a b))) \EV (GAMMA A B), \term{true}
- (macrolet ((alpha (x y) `(delta ,x ,y)))
- (expand (alpha a b))) \EV (GAMMA A B), \term{true}
- (macrolet ((beta (x y) `(epsilon ,x ,y)))
- (expand (alpha a b))) \EV (EPSILON A B), \term{true}
- (let ((x (list 1 2 3)))
- (symbol-macrolet ((a (first x)))
- (expand a))) \EV (FIRST X), \term{true}
- (let ((x (list 1 2 3)))
- (symbol-macrolet ((a (first x)))
- (macroexpand 'a))) \EV A, \term{false}
- (symbol-macrolet ((b (alpha x y)))
- (expand-1 b)) \EV (ALPHA X Y), \term{true}
- (symbol-macrolet ((b (alpha x y)))
- (expand b)) \EV (GAMMA X Y), \term{true}
- (symbol-macrolet ((b (alpha x y))
- (a b))
- (expand-1 a)) \EV B, \term{true}
- (symbol-macrolet ((b (alpha x y))
- (a b))
- (expand a)) \EV (GAMMA X Y), \term{true}
- \medbreak
- ;; Examples of shadowing behavior
- (flet ((beta (x y) (+ x y)))
- (expand (alpha a b))) \EV (BETA A B), \term{true}
- (macrolet ((alpha (x y) `(delta ,x ,y)))
- (flet ((alpha (x y) (+ x y)))
- (expand (alpha a b)))) \EV (ALPHA A B), \term{false}
- (let ((x (list 1 2 3)))
- (symbol-macrolet ((a (first x)))
- (let ((a x))
- (expand a)))) \EV A, \term{false}
- \endcode
-
- \label Affected By::
- \macref{defmacro},
- \macref{setf} of \macref{macro-function},
- \specref{macrolet},
- \specref{symbol-macrolet}
- \label Exceptional Situations:\None.
-
- \label See Also::
- \varref{*macroexpand-hook*},
- \macref{defmacro},
- \macref{setf} of \macref{macro-function},
- \specref{macrolet},
- \specref{symbol-macrolet},
- {\secref\Evaluation}
-
- \label Notes::
-
- Neither \funref{macroexpand} nor \funref{macroexpand-1}
- makes any explicit attempt to expand \term{macro forms} that are
- either \term{subforms} of the \param{form}
- or \term{subforms} of the \param{expansion}.
- Such expansion might occur implicitly, however,
- due to the semantics or implementation of the \term{macro function}.
- \endcom
- \issue{ISO-COMPATIBILITY:ADD-SUBSTRATE}
- %%% ========== DEFINE-SYMBOL-MACRO
- \begincom{define-symbol-macro}\ftype{Macro}
- \label Syntax::
-
- \DefmacWithValuesNewline define-symbol-macro {symbol expansion} {symbol}
-
- \label Arguments and Values::
-
- \param{symbol}---a \term{symbol}.
-
- \param{expansion}---a \term{form}.
-
- \label Description::
- Provides a mechanism for globally affecting the \term{macro expansion}
- of the indicated \param{symbol}.
- Globally establishes an expansion function for the \term{symbol macro}
- named by \param{symbol}.
- %% Patterned after wording from SYMBOL-MACROLET (per issue SYMBOL-MACROLET-SEMANTICS).
- The only guaranteed property of an expansion \term{function} for a \term{symbol macro}
- is that when it is applied to the \term{form} and the \term{environment} it returns
- the correct expansion. (In particular, it is \term{implementation-dependent}
- whether the expansion is conceptually stored in the expansion function,
- the \term{environment}, or both.)
- Each global reference to \param{symbol} (\ie not \term{shadowed}\meaning{2} by a
- \term{binding} for a \term{variable} or \term{symbol macro} named by
- the same \term{symbol}) is expanded by the normal macro expansion process;
- \seesection\SymbolsAsForms.
- The expansion of a \term{symbol macro} is subject to further \term{macro expansion}
- in the same \term{lexical environment} as the \term{symbol macro} reference,
- exactly analogous to normal \term{macros}.
-
- %% Patterned after wording from SYMBOL-MACROLET (per issue SYMBOL-MACROLET-DECLARE).
- The consequences are unspecified if a \declref{special} declaration is made for
- \param{symbol} while in the scope of this definition (\ie when it is not
- \term{shadowed}\meaning{2} by a \term{binding} for a \term{variable}
- or \term{symbol macro} named by the same \term{symbol}).
- Any use of \specref{setq} to set the value of
- %% Per X3J13. -kmp 5-Oct-93
- %one of
- the \param{symbol}
- while in the scope of this definition
- is treated as if it were a \macref{setf}.
- \macref{psetq} of \param{symbol}
- is treated as if it were a \macref{psetf}, and
- \macref{multiple-value-setq}
- is treated as if it were a \specref{setf} of \funref{values}.
- A \term{binding} for a \term{symbol macro} can be \term{shadowed}\meaning{2}
- by \specref{let} or \specref{symbol-macrolet}.
- \label Examples::
-
- \code
- (defvar *things* (list 'alpha 'beta 'gamma)) \EV *THINGS*
- (define-symbol-macro thing1 (first *things*)) \EV THING1
- (define-symbol-macro thing2 (second *things*)) \EV THING2
- (define-symbol-macro thing3 (third *things*)) \EV THING3
- thing1 \EV ALPHA
- (setq thing1 'ONE) \EV ONE
- *things* \EV (ONE BETA GAMMA)
- (multiple-value-setq (thing2 thing3) (values 'two 'three)) \EV TWO
- thing3 \EV THREE
- *things* \EV (ONE TWO THREE)
- (list thing2 (let ((thing2 2)) thing2)) \EV (TWO 2)
- \endcode
-
- \label Affected By:\None.
-
- \label Exceptional Situations::
- %% See issues LISP-SYMBOL-REDEFINITION and SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS.
- If \param{symbol} is already defined as a \term{global variable},
- an error \oftype{program-error} is signaled.
- \label See Also::
-
- \specref{symbol-macrolet},
- \funref{macroexpand}
-
- \label Notes:\None.
- \endcom%{define-symbol-macro}
- \endissue{ISO-COMPATIBILITY:ADD-SUBSTRATE}
- %%% ========== SYMBOL-MACROLET
- \begincom{symbol-macrolet}\ftype{Special Operator}
- \issue{DECLS-AND-DOC}
- \issue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM}
- \label Syntax::
-
- \DefspecWithValuesNewline symbol-macrolet
- {\paren{\starparen{symbol expansion}}
- \starparam{declaration}
- \starparam{form}}
- {\starparam{result}}
-
- \label Arguments and Values::
-
- \param{symbol}---a \term{symbol}.
-
- \param{expansion}---a \term{form}.
- \issue{SYMBOL-MACROLET-DECLARE:ALLOW}
- \param{declaration}---a \misc{declare} \term{expression}; \noeval.
- \endissue{SYMBOL-MACROLET-DECLARE:ALLOW}
-
- \param{forms}---an \term{implicit progn}.
-
- \param{results}---the \term{values} returned by the \param{forms}.
-
- \label Description::
-
- %A number of changes in here due to Moore #1 (first public review).
- \specref{symbol-macrolet} provides a mechanism for
- affecting the \term{macro expansion} environment for \term{symbols}.
- \specref{symbol-macrolet} lexically establishes expansion functions
- for each of the \term{symbol macros} named by \param{symbols}.
- \issue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM}
- The only guaranteed property of an expansion \term{function} for a \term{symbol macro}
- is that when it is applied to the \term{form} and the \term{environment} it returns
- the correct expansion. (In particular, it is \term{implementation-dependent}
- whether the expansion is conceptually stored in the expansion function,
- the \term{environment}, or both.)
- \endissue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM}
- Each reference to \param{symbol} as a variable within the lexical \term{scope}
- of \specref{symbol-macrolet} is expanded by the normal macro expansion process;
- \seesection\SymbolsAsForms.
- The expansion of a symbol macro is subject to further macro expansion
- in the same lexical environment as the symbol macro invocation, exactly
- analogous to normal \term{macros}.
- \issue{SYMBOL-MACROLET-DECLARE:ALLOW}
- Exactly the same \param{declarations} are allowed as for \specref{let}
- with one exception: \specref{symbol-macrolet} signals an error
- if a \declref{special} declaration names one of the \term{symbols}
- being defined by \specref{symbol-macrolet}.
- % Discussion of declarations moved to TYPE dictionary entry. --sjl 5 Mar 92
- \endissue{SYMBOL-MACROLET-DECLARE:ALLOW}
-
- When the \param{forms} of the \specref{symbol-macrolet} form are expanded,
- any use of \specref{setq} to set the value of one of the specified variables
- is treated as if it were a \macref{setf}.
- \macref{psetq} of a \term{symbol} defined as a symbol macro
- is treated as if it were a \macref{psetf}, and
- \macref{multiple-value-setq}
- is treated as if it were a \specref{setf} of \funref{values}.
- The use of \specref{symbol-macrolet} can be shadowed by \specref{let}.
- In other words, \specref{symbol-macrolet} only substitutes for occurrences
- of \param{symbol} that would be in the \term{scope} of a lexical binding of
- \param{symbol} surrounding the \param{forms}.
- \label Examples::
-
- \code
- ;;; The following is equivalent to
- ;;; (list 'foo (let ((x 'bar)) x)),
- ;;; not
- ;;; (list 'foo (let (('foo 'bar)) 'foo))
- (symbol-macrolet ((x 'foo))
- (list x (let ((x 'bar)) x)))
- \EV (foo bar)
- \NV (foo foo)
-
- (symbol-macrolet ((x '(foo x)))
- (list x))
- \EV ((FOO X))
- \endcode
-
- \label Affected By:\None.
-
- \label Exceptional Situations::
- \issue{SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SIGNALS-AN-ERROR}
- \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- If an attempt is made to bind a \term{symbol} that is defined as a \term{global variable},
- an error \oftype{program-error} is signaled.
- \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- \endissue{SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SIGNALS-AN-ERROR}
- If \param{declaration} contains a \declref{special} declaration
- that names one of the \term{symbols} being bound by \specref{symbol-macrolet},
- an error \oftype{program-error} is signaled.
- \label See Also::
-
- \macref{with-slots}, \funref{macroexpand}
-
- \label Notes::
-
- The special form \specref{symbol-macrolet} is the basic mechanism that is used to
- implement \macref{with-slots}.
- If a \specref{symbol-macrolet} \term{form} is a \term{top level form},
- the \param{forms} are also processed as \term{top level forms}.
- \Seesection\FileCompilation.
- \endissue{SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM}
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== *MACROEXPAND-HOOK*
- \begincom{*macroexpand-hook*}\ftype{Variable}
- \issue{FUNCTION-TYPE:X3J13-MARCH-88}
- \label Value Type::
- a \term{designator} for a \term{function} of three \term{arguments}:
- a \term{macro function},
- a \term{macro form},
- and an \term{environment} \term{object}.
- \label Initial Value::
- \issue{MACROEXPAND-HOOK-DEFAULT:EXPLICITLY-VAGUE}
- \issue{MACROEXPAND-HOOK-INITIAL-VALUE:IMPLEMENTATION-DEPENDENT}
- a \term{designator} for a function that is equivalent to \thefunction{funcall},
- but that might have additional \term{implementation-dependent} side-effects.
- \endissue{MACROEXPAND-HOOK-INITIAL-VALUE:IMPLEMENTATION-DEPENDENT}
- \endissue{MACROEXPAND-HOOK-DEFAULT:EXPLICITLY-VAGUE}
- \label Description::
- %% 8.2.0 7
- Used as the expansion interface hook by \funref{macroexpand-1} to
- control the \term{macro expansion} process.
- When a \term{macro form} is to be expanded,
- this \term{function} is called with three arguments:
- the \term{macro function},
- the \term{macro form},
- and the \term{environment} in which the \term{macro form} is to be expanded.
- \issue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC}
- The \term{environment} \term{object} has \term{dynamic extent};
- the consequences are undefined if the \term{environment} \term{object} is
- referred to outside the \term{dynamic extent} of the macro expansion function.
- \endissue{MACRO-ENVIRONMENT-EXTENT:DYNAMIC}
-
- \label Examples::
- \code
- (defun hook (expander form env)
- (format t "Now expanding: ~S~%" form)
- (funcall expander form env)) \EV HOOK
- (defmacro machook (x y) `(/ (+ ,x ,y) 2)) \EV MACHOOK
- (macroexpand '(machook 1 2)) \EV (/ (+ 1 2) 2), \term{true}
- (let ((*macroexpand-hook* #'hook)) (macroexpand '(machook 1 2)))
- \OUT Now expanding (MACHOOK 1 2)
- \EV (/ (+ 1 2) 2), \term{true}
- \endcode
-
- \label Affected By:\None.
- \label See Also::
- \funref{macroexpand}, \funref{macroexpand-1}, \funref{funcall}, {\secref\Evaluation}
-
- \label Notes::
- The net effect of the chosen initial value is to just invoke the
- \term{macro function}, giving it the \term{macro form} and
- \term{environment} as its two arguments.
- Users or user programs can \term{assign} this \term{variable} to
- customize or trace the \term{macro expansion} mechanism. Note, however,
- that this \term{variable} is a global resource, potentially shared by
- multiple \term{programs}; as such, if any two \term{programs} depend for
- their correctness on the setting of this \term{variable}, those
- \term{programs} may not be able to run in the same \term{Lisp image}.
- For this reason, it is frequently best to confine its uses to debugging
- situations.
- \issue{MACROEXPAND-HOOK-INITIAL-VALUE:IMPLEMENTATION-DEPENDENT}
- Users who put their own function into \varref{*macroexpand-hook*}
- should consider saving the previous value of the hook, and calling that
- value from their own.
- \endissue{MACROEXPAND-HOOK-INITIAL-VALUE:IMPLEMENTATION-DEPENDENT}
- \endissue{FUNCTION-TYPE:X3J13-MARCH-88}
- \endcom
- %-------------------- Declarations --------------------
- %%% ========== PROCLAIM
- \begincom{proclaim}\ftype{Function}
- \label Syntax::
- \DefunWithValues proclaim {declaration-specifier} {\term{implementation-dependent}}
- \label Arguments and Values::
- \param{declaration-specifier}---a \term{declaration specifier}.
- \label Description::
- %% 9.1.0 11
- \term{Establishes} the \term{declaration} specified by \param{declaration-specifier}
- in the \term{global environment}.
- %% 9.1.0 13
- Such a \term{declaration}, sometimes called a \term{global declaration}
- or a \term{proclamation}, is always in force unless locally \term{shadowed}.
- %% 9.1.0 12
- \term{Names} of \term{variables} and \term{functions} within
- \param{declaration-specifier} refer to \term{dynamic variables}
- and global \term{function} definitions, respectively.
- \Thenextfigure\ shows a list of \param{declaration identifiers}
- that can be used with \funref{proclaim}.
- % IGNORE, IGNORABLE, and DYNAMIC-EXTENT removed as consequence of vote
- % taken at 5-Oct-93 X3J13 meeting.
- \issue{DYNAMIC-EXTENT:NEW-DECLARATION}
- \issue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- \displayfour{Global Declaration Specifiers}{
- declaration&inline&optimize&type\cr
- ftype¬inline&special&\cr
- }
- %function removed.
- \endissue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- \endissue{DYNAMIC-EXTENT:NEW-DECLARATION}
- %% 9.2.0 20
- An implementation is free to support other (\term{implementation-defined})
- \term{declaration identifiers} as well.
- \label Examples::
- \code
- (defun declare-variable-types-globally (type vars)
- (proclaim `(type ,type ,@vars))
- type)
- ;; Once this form is executed, the dynamic variable *TOLERANCE*
- ;; must always contain a float.
- (declare-variable-types-globally 'float '(*tolerance*))
- \EV FLOAT
- \endcode
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \specref{declaim},
- \misc{declare},
- {\secref\Compilation}
- \label Notes::
- Although the \term{execution} of a \funref{proclaim} \term{form}
- has effects that might affect compilation, the compiler does not make
- any attempt to recognize and specially process \funref{proclaim} \term{forms}.
- A \term{proclamation} such as the following, even if a \term{top level form},
- does not have any effect until it is executed:
- \code
- (proclaim '(special *x*))
- \endcode
- If compile time side effects are desired, \specref{eval-when} may be useful.
- For example:
- \code
- (eval-when (:execute :compile-toplevel :load-toplevel)
- (proclaim '(special *x*)))
- \endcode
- In most such cases, however, it is preferrable to use \macref{declaim} for
- this purpose.
- \issue{DECLARE-MACROS:FLUSH}
- Since \funref{proclaim} \term{forms} are ordinary \term{function forms},
- \term{macro forms} can expand into them.
- %Barrett: So what?
- %Sandra: DUMB!
- %KMP: Tough. I think this is a commonly asked question, and perfectly
- % appropriate for a Note even though it's not a revelation. Technically,
- % anything in the Notes should be describable as "so what?" or "dumb"
- % or we should ask why it's in the Notes and not the Description.
- \endissue{DECLARE-MACROS:FLUSH}
- \endcom
- %%% ========== DECLAIM
- \begincom{declaim}\ftype{Macro}
- \issue{PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO}
- \label Syntax::
- \DefmacWithValues declaim
- {\starparam{declaration-specifier}}
- {\term{implementation-dependent}}
- \label Arguments and Values::
- \param{declaration-specifier}---a \term{declaration specifier}; \noeval.
- \label Description::
- Establishes the \term{declarations} specified by the \param{declaration-specifiers}.
- If a use of this macro appears as a \term{top level form} in a \term{file}
- being processed by the \term{file compiler}, the proclamations are also made
- at compile-time. As with other defining macros, it is unspecified whether or
- not the compile-time side-effects of a \macref{declaim} persist after the
- \term{file} has been \term{compiled}.
- \label Examples::
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \misc{declare},
- \funref{proclaim}
- \label Notes:\None.
- %!!! How does proclaim relate to declaim.
- % Not quite as simple as
- % (declaim <x>) == (eval-when (:compile-toplevel :load-toplevel :execute) (proclaim '<x>))
- % but close...
- % Clarify that calls to PROCLAIM should be treated the same as any
- % other function call. Users should wrap an explicit EVAL-WHEN around
- % top-level calls to PROCLAIM if they want them to affect compilation,
- % or use the macro DECLAIM.
- \endissue{PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO}
- \endcom
- %%% ========== DECLARE
- \begincom{declare}\ftype{Symbol}
- %!!! Barmar: This entry needs A LOT of work. It is highly redundant and perhaps inconsistent.
- \label Syntax::
- \Defspec declare {\starparam{declaration-specifier}}
- \label Arguments::
- %% 9.1.0 6
- \param{declaration-specifier}---a \term{declaration specifier}; \noeval.
- \label Description::
- %% 9.1.0 2
- A \misc{declare} \term{expression}, sometimes called a \term{declaration},
- can occur only at the beginning of the bodies of certain \term{forms};
- that is, it may be preceded only by other \misc{declare} \term{expressions},
- or by a \term{documentation string} if the context permits.
- A \misc{declare} \term{expression} can occur in a \term{lambda expression}
- or in any of the \term{forms} listed in \thenextfigure.
- \issue{DECLS-AND-DOC}
- \issue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS}
- \issue{SYMBOL-MACROLET-DECLARE:ALLOW}
- \issue{WITH-ADDED-METHODS:DELETE}
- \issue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- \displaythree{Standardized Forms In Which Declarations Can Occur}{
- defgeneric&do-external-symbols&prog\cr
- define-compiler-macro&do-symbols&prog*\cr
- define-method-combination&dolist&restart-case\cr
- define-setf-expander&dotimes&symbol-macrolet\cr
- defmacro&flet&with-accessors\cr
- defmethod&handler-case&with-hash-table-iterator\cr
- defsetf&labels&with-input-from-string\cr
- deftype&let&with-open-file\cr
- defun&let*&with-open-stream\cr
- destructuring-bind&locally&with-output-to-string\cr
- do¯olet&with-package-iterator\cr
- do*&multiple-value-bind&with-slots\cr
- do-all-symbols&pprint-logical-block&\cr
- }
- %Deleted GENERIC-FLET, GENERIC-LABELS, GENERIC-FUNCTION -kmp 7-Feb-92
- %Deleted WITH-ADDED-METHODS. -kmp 7-Jan-91
- %Added DEFINE-COMPILER-MACRO, DESTRUCTURING-BIND, HANDLER-CASE,
- % PPRINT-LOGICAL-BLOCK, RESTART-CASE, WITH-HASH-TABLE-ITERATOR,
- % and WITH-PACKAGE-ITERATOR. -kmp 15-Feb-92
- \endissue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- \endissue{WITH-ADDED-METHODS:DELETE}
- \endissue{SYMBOL-MACROLET-DECLARE:ALLOW}
- \endissue{SETF-METHOD-VS-SETF-METHOD:RENAME-OLD-TERMS}
- \endissue{DECLS-AND-DOC}
- A \misc{declare} \term{expression} can only occur
- where specified by the syntax of these \term{forms}.
- %% 9.1.0 3
- The consequences of attempting to evaluate a \misc{declare} \term{expression}
- are undefined. In situations where such \term{expressions} can appear,
- explicit checks are made for their presence and they are never actually evaluated;
- it is for this reason that they
- are called ``\misc{declare} \term{expressions}''
- rather than ``\misc{declare} \term{forms}.''
- % This doesn't belong here. I think it is adequately covered by the
- % discussion of lambda lists and scoping of lambda variables. --sjl 5 mar 92
- % When evaluating a \term{lambda form},
- % none of the \term{bound declarations} made by \misc{declare} \term{expressions}
- % appearing at the beginning of the body
- % of the \term{lambda expression} apply to the \term{argument} \term{evaluations}.
- % However, such \term{declarations} apply to the \term{initialization form} code (if any)
- % for \keyref{optional}, \keyref{key}, and \keyref{aux} \term{bindings}
- % % Added to please KMP (and hopefully Moon, too).
- % subsequent to the \term{name} to which the \term{bound declaration} refers;
- % \seesection\DeclScope.
- \issue{DECLARE-MACROS:FLUSH}
- %\term{macro}
- %calls may expand into declarations as long as this syntax is observed.
- \term{Macro forms} cannot expand into declarations;
- \misc{declare} \term{expressions} must appear as actual \term{subexpressions} of
- the \term{form} to which they refer.
- % the only valid declarations are \term{lists} whose \term{car} is the symbol \misc{declare}.
- %% Removed because this is already said in PROCLAIM.
- % \term{Macro forms} can expand into \funref{proclaim} forms, however.
- \endissue{DECLARE-MACROS:FLUSH}
- \Thenextfigure\ shows a list of \term{declaration identifiers}
- that can be used with \misc{declare}.
- \issue{DYNAMIC-EXTENT:NEW-DECLARATION}
- \issue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- \displaythree{Local Declaration Specifiers}{
- dynamic-extent&ignore&optimize\cr
- ftype&inline&special\cr
- ignorable¬inline&type\cr
- }
- %function removed.
- \endissue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- \endissue{DYNAMIC-EXTENT:NEW-DECLARATION}
- %% 9.2.0 20
- An implementation is free to support other (\term{implementation-defined})
- \term{declaration identifiers} as well.
- \label Examples::
- \code
- (defun nonsense (k x z)
- (foo z x) ;First call to foo
- (let ((j (foo k x)) ;Second call to foo
- (x (* k k)))
- (declare (inline foo) (special x z))
- (foo x j z))) ;Third call to foo
- \endcode
- In this example,
- the \declref{inline} declaration applies
- only to the third call to \f{foo}, but not to the first or second ones.
- The \declref{special} declaration of \f{x} causes \specref{let}
- to make a dynamic \term{binding} for \f{x}, and causes the reference to
- \f{x}
- in the body of \specref{let} to be a dynamic reference.
- The reference to \f{x} in the second call to \f{foo} is a local reference
- to the second parameter of {\tt nonsense}.
- The reference to \f{x} in the first call to \f{foo} is a local
- reference, not a \declref{special} one. The \declref{special} declaration of \f{z}
- causes the reference to \f{z} in the
- %Added for Moon:
- third
- call
- to \f{foo} to be a dynamic reference; it does not
- refer to the parameter to \f{nonsense} named \f{z}, because that
- parameter \term{binding} has not been declared to be \declref{special}.
- (The \declref{special} declaration of \f{z} does not appear in the body
- of \macref{defun}, but in an inner \term{form}, and therefore does not
- affect the \term{binding} of the \term{parameter}.)
- \label Affected By:\None.
- \label Exceptional Situations::
- The consequences of trying to use a \misc{declare} \term{expression} as
- a \term{form} to be \term{evaluated} are undefined.
- \editornote{KMP: Probably we need to say something here about ill-formed
- declare expressions.}
- \label See Also::
- \funref{proclaim},
- \secref\TypeSpecifiers,
- \declref{declaration},
- \declref{dynamic-extent},
- \declref{ftype},
- \declref{ignorable},
- \declref{ignore},
- \declref{inline},
- \declref{notinline},
- \declref{optimize},
- \declref{type}
- \label Notes:\None.
- %In all cases such additional code is within the scope of any \term{pervasive}
- %declarations appearing before the body of the \term{form}.
- %Declarations that affect \term{bindings}
- %have no effect on such code, except (of course)
- %in those situations where the code is defined to be within the scope
- %of the variables affected by such non-\term{pervasive} declarations.
- %%% 9.1.0 3
- %Those \term{forms} that permit declarations to appear
- %perform explicit checks for their presence.
- \endcom
- %%% ========== IGNORE
- %%% ========== IGNORABLE
- \begincom{ignore, ignorable}\ftype{Declaration}
- \issue{DOTIMES-IGNORE:X3J13-MAR91}
- \label Syntax::
- \f{\paren{ignore \star{\curly{\param{var} | \paren{\misc{function} \param{fn}}}}}}
- \f{\paren{ignorable \star{\curly{\param{var} | \paren{\misc{function} \param{fn}}}}}}
- \label Arguments::
- \param{var}---a \term{variable} \term{name}.
- \param{fn}---a \term{function} \term{name}.
- \label Valid Context::
- \term{declaration}
- %% Removed per X3J13 -kmp 4-Oct-93
- %or \term{proclamation}
- \label Binding Types Affected::
- \term{variable}, \term{function}
- \label Description::
- \issue{IGNORE-USE-TERMINOLOGY:VALUE-ONLY}
- The \declref{ignore} and \declref{ignorable} declarations
- refer to \term{for-value} \term{references}
- to \term{variable} \term{bindings} for the \param{vars}
- and to \term{function} \term{bindings} for the \param{fns}.
- An \declref{ignore} \term{declaration} specifies that
- \term{for-value} \term{references} to the indicated \term{bindings}
- will not
- occur within the scope of the \term{declaration}.
- Within the \term{scope} of such a \term{declaration},
- it is desirable
- for a compiler to issue a warning about
- the presence of
- either a \term{for-value} \term{reference} to any \param{var} or \param{fn},
- or a \declref{special} \term{declaration} for any \param{var}.
- An \declref{ignorable} \term{declaration} specifies that
- \term{for-value} \term{references} to the indicated \term{bindings}
- might or might not
- occur within the scope of the \term{declaration}.
- Within the \term{scope} of such a \term{declaration},
- it is not desirable
- for a compiler to issue a warning about
- the presence or absence of
- either a \term{for-value} \term{reference} to any \param{var} or \param{fn},
- or a \declref{special} \term{declaration} for any \param{var}.
- When not within the \term{scope}
- of a \declref{ignore} or \declref{ignorable} \term{declaration},
- it is desirable
- for a compiler to issue a warning about
- any \param{var} for which there is
- neither a \term{for-value} \term{reference}
- nor a \declref{special} \term{declaration},
- or about
- any \param{fn} for which there is
- no \term{for-value} \term{reference}.
- Any warning about a ``used'' or ``unused'' \term{binding} must be \oftype{style-warning},
- and may not affect program semantics.
- \endissue{IGNORE-USE-TERMINOLOGY:VALUE-ONLY}
- %!!! Maybe separate out to a concept section?
- %!!! Once these functions are described as using stream vars,
- % we can maybe remove this enumeration.
- % Alternatively, we could make a table and put it in the chapter of "general rules".
- The \term{stream variables} established by
- \macref{with-open-file},
- \macref{with-open-stream},
- \macref{with-input-from-string},
- and \macref{with-output-to-string},
- and all \term{iteration variables} are, by definition, always ``used''.
- Using \f{(declare (ignore \param{v}))},
- for such a \term{variable} \param{v} has unspecified consequences.
- \endissue{DOTIMES-IGNORE:X3J13-MAR91}
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- % % added. I interpolated the bit about ignorable, since this was
- % % not covered in the original proposal. --sjl 4 Mar 92
- % \issue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- % \declref{ignore} and \declref{ignorable} declarations may apply to
- % \term{symbol macros}. Such a declaration specifies that the named
- % \term{symbol macro} must not (in the case of \declref{ignore}) or
- % may not (in the case of \declref{ignorable}) be referenced within
- % the scope of the declaration.
- % \endissue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \label See Also::
- \misc{declare}
- %% Removed per X3J13. -kmp 4-Oct-93
- % , \macref{declaim},
- % \funref{proclaim}
- \endcom
- %%% ========== DYNAMIC-EXTENT
- \begincom{dynamic-extent}\ftype{Declaration}
- \label Syntax::
- \f{(dynamic-extent \interleave{\starparam{var} |
- \star{\paren{\misc{function} \param{fn}}}})}
- \label Arguments::
- \param{var}---a \term{variable} \term{name}.
- \param{fn}---a \term{function} \term{name}.
- \label Valid Context::
- \term{declaration}
- %% Removed per X3J13 -kmp 4-Oct-93
- %or \term{proclamation}
- \label Binding Types Affected::
- \term{variable}, \term{function}
- \label Description::
- \issue{DYNAMIC-EXTENT:NEW-DECLARATION}
- %!!! This needs work. -kmp 23-Aug-91
- % Suppose that form <f> contains a DYNAMIC-EXTENT declaration for
- % variable <v> (which need not be bound by <f>). Consider the values
- % <w1>, ..., <wN> taken on by <v> during the course of some execution of
- % <f>. The declaration asserts that if object <x> is an OIP of <wI>
- % when <wI> ever becomes the value of <v>, then just after execution of
- % <f> terminates <x> will be either inaccessible or still an OIP of <v>.
- In some containing \term{form}, \param{F}, this declaration
- asserts for each \param{var$\sub{i}$} (which need not be bound by \param{F}),
- and for each \term{value} \param{v$\sub{ij}$} that \param{var$\sub{i}$} takes on,
- and for each \term{object} \param{x$\sub{ijk}$} that
- %% Removed per Moon
- %\param{v$\sub{ij}$}
- is
- an \term{otherwise inaccessible part} of \param{v$\sub{ij}$} at any time when
- %% "it" => V[ij] per Moon
- %it
- \param{v$\sub{ij}$}
- becomes the value of \param{var$\sub{i}$},
- that just after the execution of \param{F} terminates,
- \param{x$\sub{ijk}$} is either \term{inaccessible}
- (if \param{F} established a \term{binding} for \param{var$\sub{i}$})
- or still an \term{otherwise inaccessible part} of the current value of
- \param{var$\sub{i}$} (if \param{F} did not establish a \term{binding}
- for \param{var$\sub{i}$}).
- \issue{DYNAMIC-EXTENT-FUNCTION:EXTEND}
- % The \param{var} may either be a symbol naming a variable,
- % or a list of the form {\tt (function \i{name})} which names a function.
- The same relation holds for each \param{fn$\sub{i}$},
- except that the \term{bindings} are in the \term{function} \term{namespace}.
- \endissue{DYNAMIC-EXTENT-FUNCTION:EXTEND}
- The compiler is permitted to use
- %make whatever optimizations are appropriate given
- %% For RPG:
- this information in any way that is appropriate to the \term{implementation}
- and that does not conflict with the semantics of \clisp.
- \declref{dynamic-extent} declarations can be \term{free declarations}
- or \term{bound declarations}.
- % added. --sjl 4 Mar 92
- \issue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- The \param{vars} and \param{fns} named in a \declref{dynamic-extent}
- declaration must not refer to \term{symbol macro} or \term{macro} bindings.
- \endissue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- \label Examples::
- Since stack allocation of the initial value entails knowing at the
- \term{object}'s creation time that the \term{object} can be
- \term{stack-allocated}, it is not generally useful to make a
- \declref{dynamic-extent} \term{declaration} for \term{variables}
- which have no lexically apparent initial value.
- For example, it is probably useful to write:
-
- \code
- (defun f ()
- (let ((x (list 1 2 3)))
- (declare (dynamic-extent x))
- ...))
- \endcode
-
- This would permit those compilers that wish to do so to \term{stack allocate}
- the list held by the local variable {\tt x}. It is permissible,
- but in practice probably not as useful, to write:
-
- \code
- (defun g (x) (declare (dynamic-extent x)) ...)
- (defun f () (g (list 1 2 3)))
- \endcode
-
- Most compilers would probably not \term{stack allocate} the \term{argument}
- to {\tt g} in {\tt f} because it would be a modularity violation for the compiler
- to assume facts about {\tt g} from within {\tt f}. Only an implementation that
- was willing to be responsible for recompiling {\tt f} if the definition of {\tt g}
- changed incompatibly could legitimately \term{stack allocate} the \term{list}
- argument to {\tt g} in {\tt f}.
-
- Here is another example:
- \code
- (declaim (inline g))
- (defun g (x) (declare (dynamic-extent x)) ...)
- (defun f () (g (list 1 2 3)))
-
- (defun f ()
- (flet ((g (x) (declare (dynamic-extent x)) ...))
- (g (list 1 2 3))))
-
- \endcode
- In the previous example, some compilers might determine that optimization was
- possible and others might not.
-
- A variant of this is the so-called ``stack allocated rest list''
- that can be achieved (in implementations supporting the optimization) by:
-
- \code
- (defun f (&rest x)
- (declare (dynamic-extent x))
- ...)
- \endcode
-
- Note that although the initial value of {\tt x} is not explicit, the {\tt f}
- function is responsible for assembling the list {\tt x} from the passed arguments,
- so the {\tt f} function can be optimized by the compiler to construct a
- \term{stack-allocated} list instead of a heap-allocated list in implementations
- that support such.
-
- In the following example,
- \code
- (let ((x (list 'a1 'b1 'c1))
- (y (cons 'a2 (cons 'b2 (cons 'c2 nil)))))
- (declare (dynamic-extent x y))
- ...)
- \endcode
- The \term{otherwise inaccessible parts} of {\tt x} are three
- \term{conses}, and the \term{otherwise inaccessible parts}
- of {\tt y} are three other \term{conses}.
- None of the symbols {\tt a1}, {\tt b1}, {\tt c1}, {\tt a2},
- {\tt b2}, {\tt c2}, or \nil\ is an
- \term{otherwise inaccessible part} of {\tt x} or {\tt y} because each
- is \term{interned} and hence \term{accessible} by the \term{package}
- (or \term{packages}) in which it is \term{interned}.
- However, if a freshly allocated \term{uninterned} \term{symbol} had
- been used, it would have been an \term{otherwise inaccessible part} of
- the \term{list} which contained it.
- \code
- ;; In this example, the implementation is permitted to \term{stack allocate}
- ;; the list that is bound to X.
- (let ((x (list 1 2 3)))
- (declare (dynamic-extent x))
- (print x)
- :done)
- \OUT (1 2 3)
- \EV :DONE
-
- ;; In this example, the list to be bound to L can be \term{stack-allocated}.
- (defun zap (x y z)
- (do ((l (list x y z) (cdr l)))
- ((null l))
- (declare (dynamic-extent l))
- (prin1 (car l)))) \EV ZAP
- (zap 1 2 3)
- \OUT 123
- \EV NIL
- ;; Some implementations might open-code LIST-ALL-PACKAGES in a way
- ;; that permits using \term{stack allocation} of the list to be bound to L.
- (do ((l (list-all-packages) (cdr l)))
- ((null l))
- (declare (dynamic-extent l))
- (let ((name (package-name (car l))))
- (when (string-search "COMMON-LISP" name) (print name))))
- \OUT "COMMON-LISP"
- \OUT "COMMON-LISP-USER"
- \EV NIL
- ;; Some implementations might have the ability to \term{stack allocate}
- ;; rest lists. A declaration such as the following should be a cue
- ;; to such implementations that stack-allocation of the rest list
- ;; would be desirable.
- (defun add (&rest x)
- (declare (dynamic-extent x))
- (apply #'+ x)) \EV ADD
- (add 1 2 3) \EV 6
- (defun zap (n m)
- ;; Computes (RANDOM (+ M 1)) at relative speed of roughly O(N).
- ;; It may be slow, but with a good compiler at least it
- ;; doesn't waste much heap storage. :-\}
- (let ((a (make-array n)))
- (declare (dynamic-extent a))
- (dotimes (i n)
- (declare (dynamic-extent i))
- (setf (aref a i) (random (+ i 1))))
- (aref a m))) \EV ZAP
- (< (zap 5 3) 3) \EV \term{true}
- \endcode
-
- The following are in error, since the value of {\tt x} is used outside of its
- \term{extent}:
-
- \code
- (length (list (let ((x (list 1 2 3))) ; Invalid
- (declare (dynamic-extent x))
- x)))
- (progn (let ((x (list 1 2 3))) ; Invalid
- (declare (dynamic-extent x))
- x)
- nil)
- \endcode
- \endissue{DYNAMIC-EXTENT:NEW-DECLARATION}
- \label See Also::
- \misc{declare}
- %% Removed per X3J13. -kmp 4-Oct-93
- % , \macref{declaim},
- % \funref{proclaim}
- \label Notes::
- The most common optimization is to \term{stack allocate} the
- initial value of the \term{objects} named by the \param{vars}.
- It is permissible for an implementation to simply ignore this declaration.
- \endcom
- %%% ========== TYPE
- \begincom{type}\ftype{Declaration}
- \label Syntax::
- \f{(type \param{typespec} \starparam{var})}
- \f{(\param{typespec} \starparam{var})}
- \label Arguments::
- \param{typespec}---a \term{type specifier}.
- \param{var}---a \term{variable} \term{name}.
- \label Valid Context::
- \term{declaration} or \term{proclamation}
- \label Binding Types Affected::
- \term{variable}
- \label Description::
- Affects
- only variable \term{bindings} and specifies that the
- \param{vars} take on
- values only of the specified \param{typespec}.
- In particular, values assigned to the variables by \specref{setq},
- as well as the initial values of the \param{vars} must be of
- the specified \param{typespec}.
- \declref{type} declarations never apply to function \term{bindings} (see \declref{ftype}).
- %% This is already said in the stuff on COMMON-LISP package.
- %% !!! Maybe add a cross-reference? -kmp 9-Feb-92
- % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % Except where explicitly allowed, the consequences are undefined if a
- % \term{symbol} in \thepackage{common-lisp} is used as a
- % \param{var} argument.
- % If such a \term{symbol} is not globally
- % defined
- % %"by this standard" added per barmar: -kmp 28-Dec-90
- % by this standard
- % as a variable or a constant, it is allowed to lexically bind it
- % and to declare the {\tt type} of that \term{binding}. For example,
- % the lexical variable names {\tt list} and {\tt car} are permitted.
- % \editornote{KMP: This is unintelligible to me and needs to be rewritten to clarify
- % that binding CL special variables is ok, but that their type decls are lexical.}
- % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- \issue{SYMBOL-MACROLET-DECLARE:ALLOW}
- A type declaration of a \term{symbol}
- defined by \specref{symbol-macrolet} is equivalent
- to wrapping a \specref{the}
- expression around the expansion of that \term{symbol},
- \endissue{SYMBOL-MACROLET-DECLARE:ALLOW}
- % moved here from symbol-macrolet dictionary entry --sjl 5 mar 92
- \issue{SYMBOL-MACROLET-TYPE-DECLARATION:NO}
- although the \term{symbol}'s \term{macro expansion} is not actually affected.
- \endissue{SYMBOL-MACROLET-TYPE-DECLARATION:NO}
- \issue{DECLARE-TYPE-FREE:LEXICAL}
- The meaning of a type declaration
- is equivalent to changing each reference to
- a variable (\param{var}) within the scope of the
- declaration to {\tt (the \param{typespec} \param{var})},
- changing each expression assigned to the
- variable (\param{new-value}) within the scope of the declaration to
- {\tt (the \param{typespec} \param{new-value})},
- and executing
- {\tt (the \param{typespec} \param{var})} at the moment the scope of the declaration
- is entered.
-
- A \term{type} declaration is valid in all declarations. The interpretation
- of a type declaration is as follows:
- \beginlist
- \itemitem{1.} During the execution of any reference to the
- declared variable within the scope of the declaration, the consequences
- are
- %"unspecified" -> "undefined" per barmar. i concur. -kmp
- %unspecified
- undefined
- if
- the value of the declared variable is not of the declared \term{type}.
- \itemitem{2.} During the execution of any
- \specref{setq} of the declared variable within the scope
- of the declaration, the consequences are
- %"unspecified" -> "undefined" per barmar. i concur. -kmp
- %unspecified
- undefined
- if the newly assigned value of the
- declared variable is not of the declared \term{type}.
- \itemitem{3.} At the moment the
- scope of the declaration is entered, the consequences are
- %"unspecified" -> "undefined" per barmar. i concur. -kmp
- %unspecified
- undefined
- if the value of the
- declared variable is not of the declared \term{type}.
- \endlist
- A \term{type} declaration affects only variable references within
- its scope.
- % and the meaning of free and "variable-binding-associated" type
- % declarations can be described identically.
- If nested \term{type} declarations refer to the same variable,
- then the value of the variable must be a member of the intersection of
- the declared \term{types}.
- \endissue{DECLARE-TYPE-FREE:LEXICAL}
- \issue{SPECIAL-TYPE-SHADOWING:CLARIFY}
- If there is a local {\tt type} declaration for a dynamic
- variable, and there is also a global {\tt type} proclamation for that same
- variable, then the value of the variable within the scope of the local
- declaration must be a member of the intersection of the two declared
- \term{types}.
- \endissue{SPECIAL-TYPE-SHADOWING:CLARIFY}
-
- \declref{type} declarations can be \term{free declarations}
- or \term{bound declarations}.
- \issue{TYPE-DECLARATION-ABBREVIATION:ALLOW-ALL}
- %!!! This paragraph might be better off elsewhere, but can live here for now.
- A \term{symbol} cannot be both the name of a \term{type} and the name of a
- declaration. Defining a \term{symbol} as the \term{name} of a \term{class},
- \term{structure}, \term{condition}, or \term{type}, when the \term{symbol}
- has been \term{declared} as a declaration name, or vice versa, signals an error.
- \endissue{TYPE-DECLARATION-ABBREVIATION:ALLOW-ALL}
- %% The following was inserted after GLS checked this out.
- \issue{DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE}
- Within the \term{lexical scope} of an \typeref{array} type declaration,
- all references to \term{array} \term{elements} are assumed to satisfy the
- \term{expressed array element type} (as opposed to the \term{upgraded array element type}).
- %The consequences are undefined if this is ever violated.
- A compiler can treat
- the code within the scope of the \typeref{array} type declaration as if each
- \term{access} of an \term{array} \term{element} were surrounded by an appropriate
- \specref{the} form.
- \endissue{DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE}
- \label Examples::
- \code
- (defun f (x y)
- (declare (type fixnum x y))
- (let ((z (+ x y)))
- (declare (type fixnum z))
- z)) \EV F
- (f 1 2) \EV 3
- ;; The previous definition of F is equivalent to
- (defun f (x y)
- ;; This declaration is a shorthand form of the TYPE declaration
- (declare (fixnum x y))
- ;; To declare the type of a return value, it's not necessary to
- ;; create a named variable. A THE special form can be used instead.
- (the fixnum (+ x y))) \EV F
- (f 1 2) \EV 3
- \endcode
- \issue{DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE}
- % There were some comments on this code (from the Cleanup issue, probably)
- % that no one liked, so I removed them. This example might do better with
- % some explanation, but better no explanation than a broken one. -kmp 14-Feb-92
- \code
- (defvar *one-array* (make-array 10 :element-type '(signed-byte 5)))
- (defvar *another-array* (make-array 10 :element-type '(signed-byte 8)))
-
- (defun frob (an-array)
- (declare (type (array (signed-byte 5) 1) an-array))
- (setf (aref an-array 1) 31)
- (setf (aref an-array 2) 127)
- (setf (aref an-array 3) (* 2 (aref an-array 3)))
- (let ((foo 0))
- (declare (type (signed-byte 5) foo))
- (setf foo (aref an-array 0))))
-
- (frob *one-array*)
- (frob *another-array*)
- \endcode
- \medbreak
- The above definition of \f{frob} is equivalent to:
- \code
- (defun frob (an-array)
- (setf (the (signed-byte 5) (aref an-array 1)) 31)
- (setf (the (signed-byte 5) (aref an-array 2)) 127)
- (setf (the (signed-byte 5) (aref an-array 3))
- (* 2 (the (signed-byte 5) (aref an-array 3))))
- (let ((foo 0))
- (declare (type (signed-byte 5) foo))
- (setf foo (the (signed-byte 5) (aref an-array 0)))))
- \endcode
- %!!! Barmar: What does upgrading matter?
- Given an implementation in which
- \term{fixnums} are 29 bits but \typeref{fixnum} \term{arrays}
- are upgraded to signed 32-bit \term{arrays},
- the following
- %% "should->could" per barmar. i concur. -kmp 27-Dec-90
- %should
- could be compiled with all \term{fixnum} arithmetic:
-
- \code
- (defun bump-counters (counters)
- (declare (type (array fixnum *) bump-counters))
- (dotimes (i (length counters))
- (incf (aref counters i))))
- \endcode
- \endissue{DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES:RESTRICTIVE}
- \label See Also::
- \misc{declare},
- \macref{declaim},
- \funref{proclaim}
- \label Notes::
- \f{(\param{typespec} \starparam{var})}
- is an abbreviation for \f{(type \param{typespec} \starparam{var})}.
- \issue{TYPE-DECLARATION-ABBREVIATION:ALLOW-ALL}
- %provided that \param{typespec} is one of the standard \term{type specifier}
- %\term{symbols} in \figref\StandardizedAtomicTypeSpecs.
- \endissue{TYPE-DECLARATION-ABBREVIATION:ALLOW-ALL}
- A \declref{type} declaration for the arguments to a function does not
- necessarily imply anything about the type of the result. The following
- function is not permitted to be compiled using \term{implementation-dependent}
- \term{fixnum}-only arithmetic:
- \code
- (defun f (x y) (declare (fixnum x y)) (+ x y))
- \endcode
- To see why, consider \f{(f most-positive-fixnum 1)}.
- Common Lisp defines that \f{F} must return a \term{bignum} here, rather
- than signal an error or produce a mathematically incorrect result.
- If you have special knowledge such ``\term{fixnum} overflow'' cases will
- not come up, you can declare the result value to be in the \term{fixnum}
- range, enabling some compilers to use more efficient arithmetic:
- \code
- (defun f (x y)
- (declare (fixnum x y))
- (the fixnum (+ x y)))
- \endcode
- Note, however, that in the three-argument case, because of the possibility
- of an implicit intermediate value growing too large, the following will not
- cause \term{implementation-dependent} \term{fixnum}-only arithmetic to be used:
- \code
- (defun f (x y)
- (declare (fixnum x y z))
- (the fixnum (+ x y z)))
- \endcode
- To see why, consider \f{(f most-positive-fixnum 1 -1).}
- Although the arguments and the result are all \term{fixnums}, an intermediate
- value is not a \term{fixnum}. If it is important that
- \term{implementation-dependent} \term{fixnum}-only arithmetic be selected
- in \term{implementations} that provide it,
- consider writing something like this instead:
- \code
- (defun f (x y)
- (declare (fixnum x y z))
- (the fixnum (+ (the fixnum (+ x y)) z)))
- \endcode
- \endcom
- %%% ========== INLINE
- %%% ========== NOTINLINE
- \begincom{inline, notinline}\ftype{Declaration}
- \label Syntax::
- {\tt (inline \starparam{function-name})}
- {\tt (notinline \starparam{function-name})}
- \label Arguments::
- \param{function-name}---a \term{function name}.
- \label Valid Context::
- \term{declaration} or \term{proclamation}
- \label Binding Types Affected::
- \term{function}
- \label Description::
- \issue{FUNCTION-NAME:LARGE}
- \declref{inline} specifies that
- it is desirable for the compiler to produce inline calls
- to the \term{functions} named by \param{function-names};
- that is, the code for a specified \param{function-name}
- \endissue{FUNCTION-NAME:LARGE}
- should be integrated into the calling routine, appearing ``in line''
- in place of a procedure call.
- %This declaration is \term{pervasive}.
- A compiler is free to ignore this declaration.
- \declref{inline} declarations never apply to variable \term{bindings}.
- %% 9.2.0 14
- If one of the \term{functions} mentioned has a lexically apparent local definition
- (as made by \specref{flet} or \specref{labels}), then the declaration
- applies to that local definition and not to the global function definition.
- \issue{ALLOW-LOCAL-INLINE:INLINE-NOTINLINE}
- While no \term{conforming implementation} is required to perform inline expansion
- of user-defined functions, those \term{implementations} that do attempt
- to recognize the following paradigm:
- To define a \term{function} \f{f} that is not \declref{inline} by default
- but for which \f{(declare (inline f))} will make \param{f} be locally inlined,
- the proper definition sequence is:
-
- \code
- (declaim (inline f))
- (defun f ...)
- (declaim (notinline f))
- \endcode
- The \declref{inline} proclamation preceding the \macref{defun} \term{form}
- ensures that the \term{compiler} has the opportunity save the information
- necessary for inline expansion, and the \declref{notinline} proclamation
- following the \macref{defun} \term{form} prevents \f{f} from being expanded
- inline everywhere.
- \endissue{ALLOW-LOCAL-INLINE:INLINE-NOTINLINE}
- \issue{FUNCTION-NAME:LARGE}
- \declref{notinline} specifies that it is
- \endissue{FUNCTION-NAME:LARGE}
- undesirable to compile the \term{functions}
- named by \param{function-names} in-line.
- %This declaration is \term{pervasive}.
- A compiler is not free to ignore this declaration;
- %clarifying clause added per barmar. -kmp 28-Dec-90
- calls to the specified functions must be implemented as out-of-line subroutine calls.
- %% 9.2.0 16
- If one of the \term{functions}
- mentioned has a lexically apparent local definition
- (as made by \specref{flet} or \specref{labels}), then the declaration
- applies to that local definition and not to the global function definition.
- % added. --sjl 4 Mar 92
- \issue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- In the presence of a \term{compiler macro} definition for
- \param{function-name}, a \declref{notinline} declaration prevents that
- \issue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- \term{compiler macro} from being used.
- % in preference to the normal definition
- % of \param{function-name} as a \term{function} or \term{macro}.
- \endissue{KMP-COMMENTS-ON-SANDRA-COMMENTS:X3J13-MAR-92}
- An \declref{inline} declaration may be used to encourage use of
- \term{compiler macro} definitions. \declref{inline} and \declref{notinline}
- declarations otherwise have no effect when the lexically visible definition
- of \param{function-name} is a \term{macro} definition.
- \endissue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- \declref{inline} and \declref{notinline} declarations can be \term{free declarations} or
- \term{bound declarations}.
- \declref{inline} and \declref{notinline} declarations of functions that
- appear before the body of a
- \specref{flet}
- or \specref{labels}
- \issue{WITH-ADDED-METHODS:DELETE}
- % \specref{with-added-methods},
- \endissue{WITH-ADDED-METHODS:DELETE}
- \issue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- % \specref{generic-flet},
- % and
- % \specref{generic-labels}
- \endissue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- \term{form} that defines that function are \term{bound declarations}.
- Such declarations in other contexts are \term{free declarations}.
- \label Examples::
- \code
- ;; The globally defined function DISPATCH should be open-coded,
- ;; if the implementation supports inlining, unless a NOTINLINE
- ;; declaration overrides this effect.
- (declaim (inline dispatch))
- (defun dispatch (x) (funcall (get (car x) 'dispatch) x))
- ;; Here is an example where inlining would be encouraged.
- (defun top-level-1 () (dispatch (read-command)))
- ;; Here is an example where inlining would be prohibited.
- (defun top-level-2 ()
- (declare (notinline dispatch))
- (dispatch (read-command)))
- ;; Here is an example where inlining would be prohibited.
- (declaim (notinline dispatch))
- (defun top-level-3 () (dispatch (read-command)))
- ;; Here is an example where inlining would be encouraged.
- (defun top-level-4 ()
- (declare (inline dispatch))
- (dispatch (read-command)))
- \endcode
- \label See Also::
- \misc{declare},
- \macref{declaim},
- \funref{proclaim}
- \endcom
- %%% ========== FTYPE
- \begincom{ftype}\ftype{Declaration}
- \label Syntax::
- \issue{FUNCTION-NAME:LARGE}
- \f{(ftype \param{type} \starparam{function-name})}
- \endissue{FUNCTION-NAME:LARGE}
- \label Arguments::
- \param{function-name}---a \term{function name}.
- % added --sjl 7 Mar 92
- \param{type}---a \term{type specifier}.
- \label Valid Context::
- \term{declaration} or \term{proclamation}
- \label Binding Types Affected::
- \term{function}
- \label Description::
- Specifies that the \term{functions} named by \param{function-names} are of
- the functional type \param{type}.
- For example:
- \code
- (declare (ftype (function (integer list) t) ith)
- (ftype (function (number) float) sine cosine))
- \endcode
- If one of the \term{functions} mentioned has a lexically apparent local definition
- (as made by \specref{flet} or \specref{labels}), then the declaration
- applies to that local definition and not to the global function definition.
- \declref{ftype} declarations never apply to variable \term{bindings} (see {\tt type}).
- % added. --sjl 4 Mar 92
- \issue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- The lexically apparent bindings of \param{function-names} must not be
- \term{macro} definitions. (This is because \declref{ftype} declares the
- functional definition of each \term{function name} to be of a particular
- subtype of \typeref{function}, and \term{macros} do not denote
- \term{functions}.)
- \endissue{MACRO-DECLARATIONS:MAKE-EXPLICIT}
- % This is adequately covered in the packages chapter. --sjl 5 Mar 92
- % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % Except where explicitly allowed, the consequences are undefined if
- % a \term{symbol} in \thepackage{common-lisp}
- % is used as a \param{function-name} argument.
- % If such a \term{symbol} is not defined
- % %"by this standard" added per barmar: -kmp 28-Dec-90
- % by this standard
- % as a \term{function}, \term{macro}, or \term{special form},
- % it is allowed to declare the
- % \declref{ftype} of that \term{binding}.
- % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- \declref{ftype}
- \issue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- %and \declref{function}
- \endissue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- declarations
- can be \term{free declarations} or \term{bound declarations}.
- \declref{ftype} declarations of functions that appear before the body of a
- \specref{flet}
- or \specref{labels}
- \issue{WITH-ADDED-METHODS:DELETE}
- % \specref{with-added-methods},
- \endissue{WITH-ADDED-METHODS:DELETE}
- \issue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- % \specref{generic-flet},
- % and
- % \specref{generic-labels}
- \endissue{GENERIC-FLET-POORLY-DESIGNED:DELETE}
- \term{form} that defines that function are \term{bound declarations}.
- Such declarations in other contexts are \term{free declarations}.
- \issue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- %
- % {\tt (function \param{var1} \param{var2}...)}
- % is equivalent to
- % {\tt (type function \param{var1} \param{var2}...)}
- %
- %
- %%% 9.2.0 12
- %If one of the \term{functions}
- %mentioned has a lexically apparent local definition
- %(as made by \specref{flet} or \specref{labels}), then the declaration
- %applies to that local definition and not to the global function definition.
- %
- %
- % See \declref{type} and \declref{ftype}.
- %
- \endissue{DECLARE-FUNCTION-AMBIGUITY:DELETE-FTYPE-ABBREVIATION}
- \label See Also::
- \misc{declare},
- \macref{declaim},
- \funref{proclaim}
- \endcom
- %%% ========== DECLARATION
- \begincom{declaration}\ftype{Declaration}
- \label Syntax::
- \f{(declaration \starparam{name})}
- \label Arguments::
- \param{name}---a \term{symbol}.
- \label Binding Types Affected:\None.
- \label Valid Context::
- \term{proclamation} only
- \label Description::
- %% 9.2.0 19
- Advises the compiler that each \param{name} is a valid but potentially
- non-standard declaration name. The purpose of this is to tell one
- compiler not to issue warnings for declarations meant for another
- compiler or other program processor.
- % Already said in the packages chapter. --sjl 5 Mar 92
- % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % The consequences are undefined if a \term{symbol} in \thepackage{common-lisp}
- % is used as a \i{name} argument.
- % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- %!!! Couldn't figure this out. It's obviously better to omit it than include it but...
- % \reviewer{Barmar: What does this mean??}%!!!
- % \f{(\i{declaration} x)} never applies to a \term{binding} of {\tt y}.
- \label Examples::
- \code
- (declaim (declaration author target-language target-machine))
- (declaim (target-language ada))
- (declaim (target-machine IBM-650))
- (defun strangep (x)
- (declare (author "Harry Tweeker"))
- (member x '(strange weird odd peculiar)))
- \endcode
- \label See Also::
- \macref{declaim},
- \funref{proclaim}
- \endcom
- %%% ========== OPTIMIZE
- %%% ========== COMPILATION-SPEED
- %%% ========== DEBUG
- %%% ========== SAFETY
- %%% ========== SPACE
- %%% ========== SPEED
- \begincom{optimize}\ftype{Declaration}
- \label Syntax::
- \f{(optimize \star{\curly{\param{quality} | (\param{quality} \param{value})}})}
- \idxref{compilation-speed}%
- \idxref{debug}%
- \idxref{safety}%
- \idxref{space}%
- \idxref{speed}
- \label Arguments::
- \param{quality}---an \term{optimize quality}.
- \param{value}---one of the \term{integers} \f{0}, \f{1}, \f{2}, or \f{3}.
- \label Valid Context::
- \term{declaration} or \term{proclamation}
- \label Binding Types Affected:\None.
- \label Description::
- Advises the compiler that each \param{quality} should be given attention
- according to the specified corresponding \param{value}.
- Each \param{quality} must be a \term{symbol} naming an \term{optimize quality};
- the names and meanings of the standard \param{optimize qualities} are shown in
- \thenextfigure.
- \issue{OPTIMIZE-DEBUG-INFO:NEW-QUALITY}
- \tablefigtwo{Optimize qualities}{Name}{Meaning}{
- \declref{compilation-speed} & speed of the compilation process \cr
- \declref{debug} & ease of debugging \cr
- \declref{safety} & run-time error checking \cr
- \declref{space} & both code size and run-time space \cr
- \declref{speed} & speed of the object code \cr
- }
- \endissue{OPTIMIZE-DEBUG-INFO:NEW-QUALITY}
- There may be other, \term{implementation-defined} \term{optimize qualities}.
- A \param{value} \f{0} means that the corresponding \param{quality} is totally
- unimportant, and \f{3} that the \param{quality} is extremely important;
- \f{1} and \f{2} are intermediate values, with \f{1} the
- %% "average" -> "neutral" since KAB balked and I think this will be less weird. -kmp 3-Oct-91
- %average
- neutral value.
- \f{(\param{quality} 3)} can be abbreviated to \param{quality}.
- %This declaration is \term{pervasive}.
- Note that \term{code} which has the optimization \f{(safety 3)},
- or just \typeref{safety},
- is called \term{safe} \term{code}.
- % Added per Sandra in response to Barrett query ...
- The consequences are unspecified if a \param{quality} appears more than once
- with \term{different} \param{values}.
- \label Examples::
- \code
- (defun often-used-subroutine (x y)
- (declare (optimize (safety 2)))
- (error-check x y)
- (hairy-setup x)
- (do ((i 0 (+ i 1))
- (z x (cdr z)))
- ((null z))
- ;; This inner loop really needs to burn.
- (declare (optimize speed))
- (declare (fixnum i))
- ))
- \endcode
- \label See Also::
- \misc{declare},
- \macref{declaim},
- \funref{proclaim},
- {\secref\DeclScope}
- \label Notes::
- An \declref{optimize} declaration never applies to either a \term{variable} or
- a \term{function} \term{binding}. An \declref{optimize} declaration can only
- be a \term{free declaration}. For more information, \seesection\DeclScope.
- \endcom
- % I moved the dictionary entry for the special declaration here.
- % It used to be in chapter 5, but it seemed more logical to put it with
- % all the other declaration specifiers. -- sjl 5 Mar 92
- %%% ========== SPECIAL
- \begincom{special}\ftype{Declaration}
- \label Syntax::
- \f{(special \starparam{var})}
- \label Arguments::
- \param{var}---a \term{symbol}.
- \label Valid Context::
- \term{declaration} or \term{proclamation}
- \label Binding Types Affected::
- \term{variable}
- \label Description::
-
- Specifies that all of
- the \param{vars} named are dynamic.
- This specifier affects variable \term{bindings} and
- affects references.
- All variable \term{bindings} affected are made to be dynamic \term{bindings},
- and affected variable references refer to the current dynamic
- \term{binding}.
- %rather than the current lexical \term{binding}.
- For example:
- \code
- (defun hack (thing *mod*) ;The binding of the parameter
- (declare (special *mod*)) ; *mod* is visible to hack1,
- (hack1 (car thing))) ; but not that of thing.
- (defun hack1 (arg)
- (declare (special *mod*)) ;Declare references to *mod*
- ;within hack1 to be special.
- (if (atom arg) *mod*
- (cons (hack1 (car arg)) (hack1 (cdr arg)))))
- \endcode
- %% 9.2.0 4
- A \declref{special} declaration does not affect inner \term{bindings}
- of a \param{var}; the inner \term{bindings} implicitly shadow
- a \declref{special} declaration and must be explicitly re-declared to
- be \declref{special}.
- \declref{special} declarations never apply to function \term{bindings}.
- % adequately covered in the packages chapter. --sjl 5 Mar 92
- % \issue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- % Except where explicitly allowed, the consequences are undefined if
- % a \term{symbol} in \thepackage{common-lisp}
- % is used as a \param{var} argument.
- % \endissue{LISP-SYMBOL-REDEFINITION:MAR89-X3J13}
- \declref{special} declarations can be either \term{bound declarations},
- affecting both a binding and references, or \term{free declarations},
- affecting only references, depending on whether the declaration is
- attached to a variable binding.
- %% 9.1.0 14
- When used in a \term{proclamation}, a \declref{special}
- \term{declaration specifier}
- applies to all \term{bindings} as well as to all references of the
- mentioned variables. For example, after
- \code
- (declaim (special x))
- \endcode
- then in a function definition such as
- \code
- (defun example (x) ...)
- \endcode
- the parameter \f{x} is bound as a dynamic variable
- rather than as a lexical variable.
- \label Examples::
- \code
- (defun declare-eg (y) ;this y is special
- (declare (special y))
- (let ((y t)) ;this y is lexical
- (list y
- (locally (declare (special y)) y)))) ;this y refers to the
- ;special binding of y
- \EV DECLARE-EG
- (declare-eg nil) \EV (T NIL)
- \endcode
- \code
- (setf (symbol-value 'x) 6)
- (defun foo (x) ;a lexical binding of x
- (print x)
- (let ((x (1+ x))) ;a special binding of x
- (declare (special x)) ;and a lexical reference
- (bar))
- (1+ x))
- (defun bar ()
- (print (locally (declare (special x))
- x)))
- (foo 10)
- \OUT 10
- \OUT 11
- \EV 11
- \endcode
- \code
- (setf (symbol-value 'x) 6)
- (defun bar (x y) ;[1] 1st occurrence of x
- (let ((old-x x) ;[2] 2nd occurrence of x -- same as 1st occurrence
- (x y)) ;[3] 3rd occurrence of x
- (declare (special x))
- (list old-x x)))
- (bar 'first 'second) \EV (FIRST SECOND)
- \endcode
- \code
- (defun few (x &optional (y *foo*))
- (declare (special *foo*))
- ...)
- \endcode
- The reference to \f{*foo*}
- in the first line of this example is not \declref{special}
- even though there is a \declref{special} declaration in the second line.
- \code
- (declaim (special prosp)) \EV \term{implementation-dependent}
- (setq prosp 1 reg 1) \EV 1
- (let ((prosp 2) (reg 2)) ;the binding of prosp is special
- (set 'prosp 3) (set 'reg 3) ;due to the preceding proclamation,
- (list prosp reg)) ;whereas the variable reg is lexical
- \EV (3 2)
- (list prosp reg) \EV (1 3)
- (declaim (special x)) ;x is always special.
- (defun example (x y)
- (declare (special y))
- (let ((y 3) (x (* x 2)))
- (print (+ y (locally (declare (special y)) y)))
- (let ((y 4)) (declare (special y)) (foo x)))) \EV EXAMPLE
- \endcode
- In the contorted code above, the outermost and innermost \term{bindings} of
- \f{y} are dynamic,
- but the middle
- binding is lexical. The two arguments to \f{+} are different,
- one being the value, which is \f{3}, of the lexical variable
- \f{y}, and the other being the value of the dynamic variable named \f{y}
- (a \term{binding}
- of which happens, coincidentally, to lexically surround it at
- an outer level). All the \term{bindings}
- of \f{x} and references to \f{x}
- are dynamic, however, because of the proclamation that \f{x} is
- always \declref{special}.
- \label See Also::
- \macref{defparameter},
- \macref{defvar}
- \endcom
- %%% ========== LOCALLY
- \begincom{locally}\ftype{Special Operator}
- \issue{DECLS-AND-DOC}
- \label Syntax::
- \issue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- \DefspecWithValues locally
- {\starparam{declaration} \starparam{form}}
- {\starparam{result}}
- \endissue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- \label Arguments and Values::
- \param{Declaration}---a \misc{declare} \term{expression}; \noeval.
- \param{forms}---an \term{implicit progn}.
- \issue{RETURN-VALUES-UNSPECIFIED:SPECIFY}
- \param{results}---the \term{values} of the \param{forms}.
- \endissue{RETURN-VALUES-UNSPECIFIED:SPECIFY}
- \label Description::
- %% 9.1.0 10
- Sequentially evaluates a body of \param{forms}
- in a \term{lexical environment} where the given \param{declarations} have effect.
- \label Examples::
- \code
- (defun sample-function (y) ;this y is regarded as special
- (declare (special y))
- (let ((y t)) ;this y is regarded as lexical
- (list y
- (locally (declare (special y))
- ;; this next y is regarded as special
- y))))
- \EV SAMPLE-FUNCTION
- (sample-function nil) \EV (T NIL)
- (setq x '(1 2 3) y '(4 . 5)) \EV (4 . 5)
- ;;; The following declarations are not notably useful in specific.
- ;;; They just offer a sample of valid declaration syntax using LOCALLY.
- (locally (declare (inline floor) (notinline car cdr))
- (declare (optimize space))
- (floor (car x) (cdr y))) \EV 0, 1
- \endcode
- \issue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- %Barmar: Say what the example does.
- %KMP: I added some comments. OK?
- \code
- ;;; This example shows a definition of a function that has a particular set
- ;;; of OPTIMIZE settings made locally to that definition.
- (locally (declare (optimize (safety 3) (space 3) (speed 0)))
- (defun frob (w x y &optional (z (foo x y)))
- (mumble x y z w)))
- \EV FROB
- ;;; This is like the previous example, except that the optimize settings
- ;;; remain in effect for subsequent definitions in the same compilation unit.
- (declaim (optimize (safety 3) (space 3) (speed 0)))
- (defun frob (w x y &optional (z (foo x y)))
- (mumble x y z w))
- \EV FROB
- \endcode
- \endissue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations:\None.
- \label See Also::
- \misc{declare}
- \label Notes::
- The \declref{special} declaration may be used with \specref{locally}
- to affect references to, rather than \term{bindings} of, \term{variables}.
- %Barrett: So what?
- \issue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- If a \specref{locally} \term{form} is a \term{top level form}, the body \param{forms}
- are also processed as \term{top level forms}. \Seesection\FileCompilation.
- \endissue{LOCALLY-TOP-LEVEL:SPECIAL-FORM}
- \endissue{DECLS-AND-DOC}
- \endcom
- %%% ========== THE
- \begincom{the}\ftype{Special Operator}
- \label Syntax::
- \DefspecWithValues the {value-type form} {\starparam{result}}
- \label Arguments and Values::
- \param{value-type}---a \term{type specifier}; \noeval.
- \param{form}---a \term{form}; \eval.
- \issue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- %% 7.9.2 19
- \param{results}---the \term{values} resulting from the \term{evaluation} of \param{form}.
- These \term{values} must conform to the \term{type} supplied by \param{value-type};
- see below.
- \endissue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- \label Description::
- %% 9.3.0 2
- \specref{the} specifies that the \term{values}\meaning{1a} returned by \param{form}
- are of the \term{types} specified by \param{value-type}.
- The consequences are undefined if any \param{result}
- is not of the declared type.
- \issue{THE-AMBIGUITY:FOR-DECLARATION}
- %% This text has been removed per Moon #19 (first public review). -kmp 8-May-93
- % %!!! Barmar: If this is true, the THE form is equivalent to the form argument.
- % \param{Value-type} can be any valid \term{type specifier}.
- % In the case that \param{form} returns one
- % value and \param{value-type} is not a
- % \declref{values} \term{type specifier},
- %
- % \code
- % (the type exp)
- % \EQ
- % (let ((#:g0001 exp))
- % (declare (type type #:g0001))
- % #:g0001)
- % \endcode
- \endissue{THE-AMBIGUITY:FOR-DECLARATION}
- \issue{JUN90-TRIVIAL-ISSUES:27}
- \issue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- It is permissible for \param{form} to \term{yield} a different number of \term{values}
- than are specified by \param{value-type}, provided that the values
- for which \param{types} are declared are indeed of those \term{types}.
- Missing values are treated as \nil\ for the purposes of checking their \term{types}.
- Regardless of number of \term{values} declared by \param{value-type},
- the number of \term{values} returned by \thespecform{the} is the same as
- the number of \term{values} returned by \param{form}.
- \endissue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- \endissue{JUN90-TRIVIAL-ISSUES:27}
- \label Examples::
- \issue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- \code
- (the symbol (car (list (gensym)))) \EV #:G9876
- (the fixnum (+ 5 7)) \EV 12
- (the (values) (truncate 3.2 2)) \EV 1, 1.2
- (the integer (truncate 3.2 2)) \EV 1, 1.2
- (the (values integer) (truncate 3.2 2)) \EV 1, 1.2
- (the (values integer float) (truncate 3.2 2)) \EV 1, 1.2
- (the (values integer float symbol) (truncate 3.2 2)) \EV 1, 1.2
- (the (values integer float symbol t null list)
- (truncate 3.2 2)) \EV 1, 1.2
- (let ((i 100))
- (declare (fixnum i))
- (the fixnum (1+ i))) \EV 101
- (let* ((x (list 'a 'b 'c))
- (y 5))
- (setf (the fixnum (car x)) y)
- x) \EV (5 B C)
- \endcode
- \endissue{THE-VALUES:RETURN-NUMBER-RECEIVED}
- \label Affected By:\None.
- \label Exceptional Situations::
- The consequences are undefined if
- the \term{values} \term{yielded} by the \param{form}
- are not of the \term{type} specified by \param{value-type}.
- \label See Also::
- \declref{values}
- \label Notes::
- The \declref{values} \term{type specifier} can be used to indicate the types
- of \term{multiple values}:
- \code
- (the (values integer integer) (floor x y))
- (the (values string t)
- (gethash the-key the-string-table))
- \endcode
- \macref{setf} can be used with \specref{the} type declarations.
- In this case the declaration is transferred to the form that
- specifies the new value. The resulting \macref{setf} \term{form}
- is then analyzed.
- \endcom
- %-------------------- Introspection --------------------
- %%% ========== SPECIAL-OPERATOR-P
- \begincom{special-operator-p}\ftype{Function}
- \issue{SPECIAL-FORM-P-MISNOMER:RENAME}
- \label Syntax::
- \DefunWithValues special-operator-p {symbol} {generalized-boolean}
- \label Arguments and Values::
- \param{symbol}---a \term{symbol}.
- \param{generalized-boolean}---a \term{generalized boolean}.
- \label Description::
- %% 7.1.1 22
- \Predicate{symbol}{a \term{special operator}}
- \label Examples::
- \code
- (special-operator-p 'if) \EV \term{true}
- (special-operator-p 'car) \EV \term{false}
- (special-operator-p 'one) \EV \term{false}
- \endcode
- \label Side Effects:\None.
- \label Affected By:\None.
- \label Exceptional Situations::
- Should signal \typeref{type-error} if its argument is not a \term{symbol}.
- \label See Also:\None.
- \label Notes::
- Historically, this function was called \f{special-form-p}. The name was
- finally declared a misnomer and changed, since it returned true for
- \term{special operators}, not \term{special forms}.
- %This is beyond the scope of the language. -kmp 26-Dec-90
- % A returned \term{non-nil} value is typically a \term{function}
- % of \term{implementation-dependent} nature that can be used to
- % interpret (evaluate) the \term{special form}.
- \endissue{SPECIAL-FORM-P-MISNOMER:RENAME}
- \endcom
- %%% ========== CONSTANTP
- \begincom{constantp}\ftype{Function}
- \issue{CONSTANTP-DEFINITION:INTENTIONAL}
- \issue{CONSTANTP-ENVIRONMENT:ADD-ARG}
- \label Syntax::
- \DefunWithValues constantp {form {\opt} environment} {generalized-boolean}
- \label Arguments and Values::
- \param{form}---a \term{form}.
- \param{environment}---an \term{environment} \term{object}.
- \Default{\nil}
- \param{generalized-boolean}---a \term{generalized boolean}.
- \label Description::
- %% 20.1.0 14
- %% 20.1.0 15
- Returns \term{true} if \param{form} can be determined
- by the \term{implementation} to be a \term{constant form}
- in the indicated \param{environment};
- otherwise, it returns \term{false} indicating either
- that the \term{form} is not a \term{constant form}
- or that it cannot be determined whether or not \term{form} is a \term{constant form}.
- The following kinds of \term{forms} are considered \term{constant forms}:
- \beginlist
- \itemitem{\bull}
- % This is the wrong term. --sjl 5 Mar 92
- % \term{Constant objects}
- \term{Self-evaluating objects}
- (such as \term{numbers},
- \term{characters},
- and the various kinds of \term{arrays})
- are always considered \term{constant forms}
- and must be recognized as such by \funref{constantp}.
- \itemitem{\bull}
- \term{Constant variables}, such as \term{keywords},
- symbols defined by \clisp\ as constant (such as \nil, \t, and \conref{pi}),
- and symbols declared as constant by the user in the indicated \param{environment}
- using \macref{defconstant}
- are always considered \term{constant forms}
- and must be recognized as such by \funref{constantp}.
- \itemitem{\bull}
- \specref{quote} \term{forms} are always considered \term{constant forms}
- and must be recognized as such by \funref{constantp}.
- \itemitem{\bull}
- An \term{implementation} is permitted, but not required, to detect
- additional \term{constant forms}. If it does, it is also permitted,
- but not required, to make use of information in the \param{environment}.
- Examples of \term{constant forms} for which \funref{constantp} might
- or might not return \term{true} are:
- \f{(sqrt pi)},
- \f{(+ 3 2)},
- \f{(length '(a b c))},
- and
- \f{(let ((x 7)) (zerop x))}.
- \endlist
- If an \term{implementation} chooses to make use of the \param{environment}
- information, such actions as expanding \term{macros} or performing function
- inlining are permitted to be used, but not required;
- however, expanding \term{compiler macros} is not permitted.
- \label Examples::
- \code
- (constantp 1) \EV \term{true}
- (constantp 'temp) \EV \term{false}
- (constantp ''temp)) \EV \term{true}
- (defconstant this-is-a-constant 'never-changing) \EV THIS-IS-A-CONSTANT
- (constantp 'this-is-a-constant) \EV \term{true}
- (constantp "temp") \EV \term{true}
- (setq a 6) \EV 6
- (constantp a) \EV \term{true}
- (constantp '(sin pi)) \EV \term{implementation-dependent}
- (constantp '(car '(x))) \EV \term{implementation-dependent}
- (constantp '(eql x x)) \EV \term{implementation-dependent}
- (constantp '(typep x 'nil)) \EV \term{implementation-dependent}
- (constantp '(typep x 't)) \EV \term{implementation-dependent}
- (constantp '(values this-is-a-constant)) \EV \term{implementation-dependent}
- (constantp '(values 'x 'y)) \EV \term{implementation-dependent}
- (constantp '(let ((a '(a b c))) (+ (length a) 6))) \EV \term{implementation-dependent}
- \endcode
- \label Side Effects:\None!
- \label Affected By::
- The state of the global environment (\eg which \term{symbols} have been
- declared to be the \term{names} of \term{constant variables}).
- \label Exceptional Situations:\None!
- \label See Also::
- \macref{defconstant}
- \label Notes:\None.
- \endissue{CONSTANTP-ENVIRONMENT:ADD-ARG}
- \endissue{CONSTANTP-DEFINITION:INTENTIONAL}
- \endcom
- \issue{SYNTACTIC-ENVIRONMENT-ACCESS:RETRACTED-MAR91}
- % The following functions were removed due to the retraction of
- % issue SYNTACTIC-ENVIRONMENT-ACCESS by X3J13 at the Mar 91 meeting.
- % AUGMENT-ENVIRONMENT
- % DECLARATION-INFORMATION
- % DEFINE-DECLARATION
- % ENCLOSE
- % FUNCTION-INFORMATION
- % PARSE-MACRO
- % VARIABLE-INFORMATION
- \endissue{SYNTACTIC-ENVIRONMENT-ACCESS:RETRACTED-MAR91}
|