1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273 |
- @node Conditions, Symbols, Structures, Top
- @chapter Conditions
- @menu
- * Condition System Concepts::
- * Conditions Dictionary::
- @end menu
- @node Condition System Concepts, Conditions Dictionary, Conditions, Conditions
- @section Condition System Concepts
- @c including concept-conditions
- Common Lisp constructs are described not only in terms of their
- behavior in situations during which they are intended to be used (see
- the ``Description'' part of each @i{operator} specification),
- but in all other situations (see the ``Exceptional Situations''
- part of each @i{operator} specification).
- A situation is the evaluation of an expression in a specific context.
- A @i{condition} is an @i{object} that
- represents a specific situation that has been detected.
- @i{Conditions} are @i{generalized instances} of the @i{class} @b{condition}.
- A hierarchy of @i{condition} classes is defined in @r{Common Lisp}.
- A @i{condition} has @i{slots} that contain data
- relevant to the situation that the @i{condition} represents.
- An error is a situation in which normal program execution cannot
- continue correctly without some form of intervention (either
- interactively by the user or under program control). Not all errors
- are detected. When an error goes undetected, the effects can be
- @i{implementation-dependent}, @i{implementation-defined}, unspecified, or
- undefined. See @ref{Definitions}. All detected errors can
- be represented by @i{conditions}, but not all
- @i{conditions} represent errors.
- Signaling is the process by which a @i{condition} can alter
- the flow of control in a program by raising the
- @i{condition} which can then be @i{handled}. The functions
- @b{error}, @b{cerror}, @b{signal}, and
- @b{warn} are used to signal @i{conditions}.
- The process of signaling involves the selection and invocation of a
- @i{handler} from a set of @i{active} @i{handlers}.
- A @i{handler} is a @i{function} of one argument (the
- @i{condition}) that is invoked to handle a @i{condition}.
- Each @i{handler} is associated with a @i{condition} @i{type},
- and a @i{handler} will be invoked only on a @i{condition} of the
- @i{handler}'s associated @i{type}.
- @i{Active} @i{handlers} are @i{established} dynamically
- (see @b{handler-bind} or @b{handler-case}).
- @i{Handlers} are invoked in a @i{dynamic environment}
- equivalent to that of the signaler,
- except that the set of @i{active} @i{handlers}
- is bound in such a way as to include only those that were @i{active}
- at the time the @i{handler} being invoked was @i{established}.
- Signaling a @i{condition} has no side-effect on the @i{condition},
- and there is no dynamic state contained in a @i{condition}.
- If a @i{handler} is invoked, it can address the @i{situation}
- in one of three ways:
- @table @asis
- @item @b{Decline}
- It can decline to @i{handle} the @i{condition}. It does this by
- simply returning rather than transferring control.
- When this happens, any values returned by the handler are
- ignored and the next most recently established handler is invoked.
- If there is no such handler and the signaling function is @b{error}
- or @b{cerror}, the debugger is entered in the
- @i{dynamic environment} of the signaler. If there is no such
- handler and the signaling function is either @b{signal} or
- @b{warn}, the signaling function simply returns~@b{nil}.
- @item @b{Handle}
- It can @i{handle} the @i{condition} by performing a non-local
- transfer of control. This can be done either primitively by using
- @b{go}, @b{return}, @b{throw} or more
- abstractly by using a function such as @b{abort} or
- @b{invoke-restart}.
- @item @b{Defer}
- It can put off a decision about whether to @i{handle} or @i{decline},
- by any of a number of actions, but most commonly by
- signaling another condition,
- resignaling the same condition,
- or forcing entry into the debugger.
- @end table
- @menu
- * Condition Types::
- * Creating Conditions::
- * Printing Conditions::
- * Signaling and Handling Conditions::
- * Assertions::
- * Notes about the Condition System's Background::
- @end menu
- @node Condition Types, Creating Conditions, Condition System Concepts, Condition System Concepts
- @subsection Condition Types
- Figure 9--1 lists the @i{standardized} @i{condition} @i{types}.
- Additional @i{condition} @i{types} can be defined by using @b{define-condition}.
- @group
- @noindent
- @w{ arithmetic-error floating-point-overflow simple-type-error }
- @w{ cell-error floating-point-underflow simple-warning }
- @w{ condition package-error storage-condition }
- @w{ control-error parse-error stream-error }
- @w{ division-by-zero print-not-readable style-warning }
- @w{ end-of-file program-error type-error }
- @w{ error reader-error unbound-slot }
- @w{ file-error serious-condition unbound-variable }
- @w{ floating-point-inexact simple-condition undefined-function }
- @w{ floating-point-invalid-operation simple-error warning }
- @noindent
- @w{ Figure 9--1: Standardized Condition Types }
- @end group
- All @i{condition} types are @i{subtypes} of @i{type} @b{condition}. That is,
- @example
- (typep @i{c} 'condition) @result{} @i{true}
- @end example
- if and only if @i{c} is a @i{condition}.
- @i{Implementations} must define all specified @i{subtype} relationships.
- Except where noted, all @i{subtype} relationships indicated in
- this document are not mutually exclusive.
- A @i{condition} inherits the structure of its @i{supertypes}.
- The metaclass of the @i{class} @b{condition} is not specified.
- @i{Names} of @i{condition} @i{types} may be used to specify
- @i{supertype} relationships in @b{define-condition},
- but the consequences are not specified if an attempt is made to use
- a @i{condition} @i{type} as a @i{superclass} in a @b{defclass} @i{form}.
- Figure 9--2 shows @i{operators} that
- define @i{condition} @i{types} and creating @i{conditions}.
- @group
- @noindent
- @w{ define-condition make-condition }
- @noindent
- @w{ Figure 9--2: Operators that define and create conditions.}
- @end group
- Figure 9--3 shows @i{operators} that @i{read}
- the @i{value} of @i{condition} @i{slots}.
- @group
- @noindent
- @w{ arithmetic-error-operands simple-condition-format-arguments }
- @w{ arithmetic-error-operation simple-condition-format-control }
- @w{ cell-error-name stream-error-stream }
- @w{ file-error-pathname type-error-datum }
- @w{ package-error-package type-error-expected-type }
- @w{ print-not-readable-object unbound-slot-instance }
- @noindent
- @w{ Figure 9--3: Operators that read condition slots. }
- @end group
- @menu
- * Serious Conditions::
- @end menu
- @node Serious Conditions, , Condition Types, Condition Types
- @subsubsection Serious Conditions
- A @i{serious condition} is a @i{condition} serious
- enough to require interactive intervention if not handled.
- @i{Serious conditions} are typically signaled with @b{error} or @b{cerror};
- non-serious @i{conditions} are typically signaled with @b{signal} or @b{warn}.
- @node Creating Conditions, Printing Conditions, Condition Types, Condition System Concepts
- @subsection Creating Conditions
- The function @b{make-condition} can be used to construct
- a @i{condition} @i{object} explicitly. Functions such as @b{error},
- @b{cerror}, @b{signal}, and @b{warn} operate on
- @i{conditions} and might create @i{condition} @i{objects}
- implicitly. Macros such as @b{ccase}, @b{ctypecase},
- @b{ecase}, @b{etypecase}, @b{check-type}, and
- @b{assert} might also implicitly create (and @i{signal})
- @i{conditions}.
- @menu
- * Condition Designators::
- @end menu
- @node Condition Designators, , Creating Conditions, Creating Conditions
- @subsubsection Condition Designators
- A number of the functions in the condition system take arguments which
- are identified as @i{condition designators}
- @IGindex{condition designator}
- .
- By convention, those arguments are notated as
- @i{datum} {&rest} @i{arguments}
- Taken together, the @i{datum} and the @i{arguments} are
- ``@i{designators} for a @i{condition} of default type @i{default-type}.''
- How the denoted @i{condition} is computed depends on the type of the @i{datum}:
- @table @asis
- @item {@t{*}} If the @i{datum} is a @i{symbol}
- naming a @i{condition} @i{type} ...
- The denoted @i{condition} is the result of
- @example
- (apply #'make-condition @i{datum} @i{arguments})
- @end example
- @item {@t{*}} If the @i{datum} is a @i{format control} ...
- The denoted @i{condition} is the result of
- @example
- (make-condition @i{defaulted-type}
- :format-control @i{datum}
- :format-arguments @i{arguments})
- @end example
- where the @i{defaulted-type} is a @i{subtype} of @i{default-type}.
- @item {@t{*}} If the @i{datum} is a @i{condition} ...
- The denoted @i{condition} is the @i{datum} itself.
- In this case, unless otherwise specified by the description of the
- @i{operator} in question, the @i{arguments} must be @i{null};
- that is, the consequences are undefined if any @i{arguments} were supplied.
- @end table
- Note that the @i{default-type} gets used only in the case where
- the @i{datum} @i{string} is supplied. In the other situations,
- the resulting condition is not necessarily of @i{type} @i{default-type}.
- Here are some illustrations of how different @i{condition designators}
- can denote equivalent @i{condition} @i{objects}:
- @example
- (let ((c (make-condition 'arithmetic-error :operator '/ :operands '(7 0))))
- (error c))
- @equiv{} (error 'arithmetic-error :operator '/ :operands '(7 0))
- (error "Bad luck.")
- @equiv{} (error 'simple-error :format-control "Bad luck." :format-arguments '())
- @end example
- @node Printing Conditions, Signaling and Handling Conditions, Creating Conditions, Condition System Concepts
- @subsection Printing Conditions
- If the @t{:report} argument to @b{define-condition} is used,
- a print function is defined that is called whenever
- the defined @i{condition} is printed while the @i{value} of @b{*print-escape*} is @i{false}.
- This function is called the @i{condition reporter}
- @IGindex{condition reporter}
- ;
- the text which it outputs is called a @i{report message}
- @IGindex{report message}
- .
- When a @i{condition} is printed and @b{*print-escape*}
- is @i{false}, the @i{condition reporter} for the @i{condition} is invoked.
- @i{Conditions} are printed automatically by functions such as
- @b{invoke-debugger}, @b{break}, and @b{warn}.
- When @b{*print-escape*} is @i{true}, the @i{object} should print in an
- abbreviated fashion according to the style of the implementation
- (@i{e.g.}, by @b{print-unreadable-object}). It is not required that a
- @i{condition} can be recreated by reading its printed representation.
- No @i{function} is provided for directly @i{accessing}
- or invoking @i{condition reporters}.
- @menu
- * Recommended Style in Condition Reporting::
- * Capitalization and Punctuation in Condition Reports::
- * Leading and Trailing Newlines in Condition Reports::
- * Embedded Newlines in Condition Reports::
- * Note about Tabs in Condition Reports::
- * Mentioning Containing Function in Condition Reports::
- @end menu
- @node Recommended Style in Condition Reporting, Capitalization and Punctuation in Condition Reports, Printing Conditions, Printing Conditions
- @subsubsection Recommended Style in Condition Reporting
- In order to ensure a properly aesthetic result when presenting
- @i{report messages} to the user, certain stylistic conventions are
- recommended.
- There are stylistic recommendations for the content of the messages
- output by @i{condition reporters}, but there are no formal requirements
- on those @i{programs}.
- If a @i{program} violates the recommendations for some message, the
- display of that message might be less aesthetic than if the guideline
- had been observed, but the @i{program} is still considered a
- @i{conforming program}.
- The requirements on a @i{program} or @i{implementation} which
- invokes a @i{condition reporter} are somewhat stronger. A @i{conforming
- program} must be permitted to assume that if these style guidelines are
- followed, proper aesthetics will be maintained. Where appropriate, any
- specific requirements on such routines are explicitly mentioned below.
- @node Capitalization and Punctuation in Condition Reports, Leading and Trailing Newlines in Condition Reports, Recommended Style in Condition Reporting, Printing Conditions
- @subsubsection Capitalization and Punctuation in Condition Reports
- It is recommended that a @i{report message} be a complete sentences, in the
- proper case and correctly punctuated. In English, for example, this
- means the first letter should be uppercase, and there should be a
- trailing period.
- @example
- (error "This is a message") ; Not recommended
- (error "this is a message.") ; Not recommended
- (error "This is a message.") ; Recommended instead
- @end example
- @node Leading and Trailing Newlines in Condition Reports, Embedded Newlines in Condition Reports, Capitalization and Punctuation in Condition Reports, Printing Conditions
- @subsubsection Leading and Trailing Newlines in Condition Reports
- It is recommended that a @i{report message} not begin with any
- introductory text, such as ``@t{Error: }'' or ``@t{Warning: }''
- or even just @i{freshline} or @i{newline}.
- Such text is added, if appropriate to the context,
- by the routine invoking the @i{condition reporter}.
- It is recommended that a @i{report message} not be followed
- by a trailing @i{freshline} or @i{newline}.
- Such text is added, if appropriate to the context,
- by the routine invoking the @i{condition reporter}.
- @example
- (error "This is a message.~
- (error "~&This is a message.") ; Not recommended
- (error "~&This is a message.~
- (error "This is a message.") ; Recommended instead
- @end example
- @node Embedded Newlines in Condition Reports, Note about Tabs in Condition Reports, Leading and Trailing Newlines in Condition Reports, Printing Conditions
- @subsubsection Embedded Newlines in Condition Reports
- Especially if it is long, it is permissible and appropriate for
- a @i{report message} to contain one or more embedded @i{newlines}.
- If the calling routine conventionally inserts some additional prefix
- (such as ``@t{Error: }'' or ``@t{;; Error: }'') on the first line of
- the message, it must also assure that an appropriate prefix will be
- added to each subsequent line of the output, so that the left edge of
- the message output by the @i{condition reporter} will still be properly
- aligned.
- @example
- (defun test ()
- (error "This is an error message.~%It has two lines."))
- ;; Implementation A
- (test)
- This is an error message.
- It has two lines.
- ;; Implementation B
- (test)
- ;; Error: This is an error message.
- ;; It has two lines.
- ;; Implementation C
- (test)
- >> Error: This is an error message.
- It has two lines.
- @end example
- @node Note about Tabs in Condition Reports, Mentioning Containing Function in Condition Reports, Embedded Newlines in Condition Reports, Printing Conditions
- @subsubsection Note about Tabs in Condition Reports
- Because the indentation of a @i{report message} might be shifted to the right or
- left by an arbitrary amount, special care should be taken with the
- semi-standard @i{character} <@i{Tab}>
- (in those @i{implementations} that support such a @i{character}).
- Unless the @i{implementation} specifically defines its behavior
- in this context, its use should be avoided.
- @node Mentioning Containing Function in Condition Reports, , Note about Tabs in Condition Reports, Printing Conditions
- @subsubsection Mentioning Containing Function in Condition Reports
- The name of the containing function should generally not be mentioned in
- @i{report messages}. It is assumed that the @i{debugger} will make this
- information accessible in situations where it is necessary and appropriate.
- @node Signaling and Handling Conditions, Assertions, Printing Conditions, Condition System Concepts
- @subsection Signaling and Handling Conditions
- The operation of the condition system depends on the ordering of
- active @i{applicable handlers} from most recent to least recent.
- Each @i{handler} is associated with a @i{type specifier}
- that must designate a @i{subtype} of @i{type} @b{condition}. A @i{handler}
- is said to be @i{applicable} to a @i{condition} if that
- @i{condition} is of the @i{type} designated by the associated
- @i{type specifier}.
- @i{Active} @i{handlers} are @i{established} by using
- @b{handler-bind} (or an abstraction based on @b{handler-bind},
- such as @b{handler-case} or @b{ignore-errors}).
- @i{Active} @i{handlers} can be @i{established} within the
- dynamic scope of other @i{active} @i{handlers}.
- At any point during program execution, there is a set of @i{active} @i{handlers}.
- When a @i{condition} is signaled, the @i{most recent} active @i{applicable handler}
- for that @i{condition} is selected from this set.
- Given a @i{condition}, the order of recentness of
- active @i{applicable handlers} is defined by the following two rules:
- @table @asis
- @item 1.
- Each handler in a set of active handlers H_1 is
- more recent than every handler in a set H_2 if the
- handlers in H_2 were active when the handlers in H_1 were
- established.
- @item 2.
- Let h_1 and h_2 be two applicable active
- handlers established by the same @i{form}. Then h_1 is
- more recent than h_2 if h_1 was defined to the left of
- h_2 in the @i{form} that established them.
- @end table
- Once a handler in a handler binding @i{form} (such as
- @b{handler-bind} or @b{handler-case}) has been selected, all
- handlers in that @i{form} become inactive for
- the remainder of the signaling process.
- While the selected @i{handler} runs, no other @i{handler} established
- by that @i{form} is active. That is, if the @i{handler} declines,
- no other handler established by that @i{form} will be considered for possible invocation.
- Figure 9--4 shows @i{operators} relating to
- the @i{handling} of @i{conditions}.
- @group
- @noindent
- @w{ handler-bind handler-case ignore-errors }
- @noindent
- @w{ Figure 9--4: Operators relating to handling conditions.}
- @end group
- @menu
- * Signaling::
- * Resignaling a Condition::
- * Restarts::
- * Interactive Use of Restarts::
- * Interfaces to Restarts::
- * Restart Tests::
- * Associating a Restart with a Condition::
- @end menu
- @node Signaling, Resignaling a Condition, Signaling and Handling Conditions, Signaling and Handling Conditions
- @subsubsection Signaling
- When a @i{condition} is signaled, the most recent
- applicable @i{active} @i{handler} is invoked.
- Sometimes a handler will decline by simply returning
- without a transfer of control.
- In such cases, the next most recent applicable active handler is
- invoked.
- If there are no applicable handlers for a @i{condition} that
- has been signaled, or if all applicable handlers decline, the
- @i{condition} is unhandled.
- The functions @b{cerror} and @b{error} invoke the
- interactive @i{condition} handler (the debugger) rather than
- return if the @i{condition} being signaled, regardless of
- its @i{type}, is unhandled. In contrast, @b{signal}
- returns @b{nil} if the @i{condition} being signaled,
- regardless of its @i{type}, is unhandled.
- The @i{variable} @b{*break-on-signals*} can be used to cause the
- debugger to be entered before the signaling process begins.
- Figure 9--5 shows @i{defined names} relating to
- the @i{signaling} of @i{conditions}.
- @group
- @noindent
- @w{ *break-on-signals* error warn }
- @w{ cerror signal }
- @noindent
- @w{ Figure 9--5: Defined names relating to signaling conditions.}
- @end group
- @node Resignaling a Condition, Restarts, Signaling, Signaling and Handling Conditions
- @subsubsection Resignaling a Condition
- During the @i{dynamic extent} of the @i{signaling} process for
- a particular @i{condition} @i{object},
- @b{signaling} the same @i{condition} @i{object} again
- is permitted if and only if the @i{situation} represented in both
- cases are the same.
- For example, a @i{handler} might legitimately @i{signal}
- the @i{condition} @i{object} that is its @i{argument}
- in order to allow outer @i{handlers} first opportunity to @i{handle}
- the condition. (Such a @i{handlers} is sometimes called a ``default handler.'')
- This action is permitted because the @i{situation} which the second
- @i{signaling} process is addressing is really the same @i{situation}.
- On the other hand, in an @i{implementation} that implemented asynchronous
- keyboard events by interrupting the user process with a call to @b{signal},
- it would not be permissible for two distinct asynchronous keyboard events
- to @i{signal} @i{identical} @i{condition} @i{objects}
- at the same time for different
- situations.
- @node Restarts, Interactive Use of Restarts, Resignaling a Condition, Signaling and Handling Conditions
- @subsubsection Restarts
- The interactive condition handler returns only through
- non-local transfer of control to specially defined @i{restarts}
- that can be set up either by the system or by user code. Transferring
- control to a restart is called ``invoking'' the restart. Like
- handlers, active @i{restarts} are @i{established}
- dynamically, and
- only active @i{restarts}
- can be invoked. An active
- @i{restart} can be invoked by the user from
- the debugger or by a program by using @b{invoke-restart}.
- A @i{restart} contains a
- @i{function} to be @i{called} when the @i{restart} is
- invoked, an optional name that can be used to find or invoke the
- @i{restart}, and
- an optional set of interaction information for the debugger to use to
- enable the user to manually invoke a @i{restart}.
- The name of a @i{restart} is
- used by @b{invoke-restart}. @i{Restarts} that can be invoked
- only within the debugger do not need names.
- @i{Restarts} can be established by using @b{restart-bind},
- @b{restart-case}, and @b{with-simple-restart}.
- A @i{restart} function can itself invoke any other @i{restart}
- that was active at the time of establishment of the @i{restart}
- of which the @i{function} is part.
- The @i{restarts} @i{established} by
- a @b{restart-bind} @i{form},
- a @b{restart-case} @i{form},
- or a @b{with-simple-restart} @i{form}
- have @i{dynamic extent}
- which extends for the duration of that @i{form}'s execution.
- @i{Restarts} of the same name can be ordered from least recent to
- most recent according to the following two rules:
- @table @asis
- @item 1.
- Each @i{restart} in a set of active restarts
- R_1 is more recent than every @i{restart} in a
- set R_2 if the @i{restarts}
- in R_2 were active when the @i{restarts} in R_1 were
- established.
- @item 2.
- Let r_1 and r_2 be two active @i{restarts} with
- the same name established by the same @i{form}. Then r_1 is
- more recent than r_2 if r_1 was defined to the
- left of r_2 in the @i{form} that established them.
- @end table
- If a @i{restart} is invoked but does not transfer control,
- the values resulting from the @i{restart} function are
- returned by the function that invoked the restart, either
- @b{invoke-restart} or @b{invoke-restart-interactively}.
- @node Interactive Use of Restarts, Interfaces to Restarts, Restarts, Signaling and Handling Conditions
- @subsubsection Interactive Use of Restarts
- For interactive handling, two pieces of information are needed
- from a @i{restart}: a report function and an interactive function.
- The report function
- is used by a program such as the debugger to
- present a description of the action the @i{restart} will take.
- The report function is specified and established by the
- @t{:report-function} keyword to
- @b{restart-bind} or the
- @t{:report} keyword to @b{restart-case}.
- The interactive function, which can be specified using the
- @t{:interactive-function} keyword to
- @b{restart-bind} or @t{:interactive} keyword
- to @b{restart-case}, is used when the @i{restart}
- is invoked
- interactively, such as from the debugger, to produce a suitable
- list of arguments.
- @b{invoke-restart} invokes the most recently @i{established}
- @i{restart} whose
- name is the same as the first argument to @b{invoke-restart}.
- If a @i{restart} is invoked interactively by the debugger and does
- not transfer control but rather returns values, the precise
- action of the debugger on those values is @i{implementation-defined}.
- @node Interfaces to Restarts, Restart Tests, Interactive Use of Restarts, Signaling and Handling Conditions
- @subsubsection Interfaces to Restarts
- Some @i{restarts} have functional interfaces,
- such as @b{abort}, @b{continue},
- @b{muffle-warning}, @b{store-value}, and
- @b{use-value}.
- They are ordinary functions that use
- @b{find-restart} and @b{invoke-restart} internally,
- that have the same name as the @i{restarts} they manipulate,
- and that are provided simply for notational convenience.
- Figure 9--6 shows @i{defined names} relating to
- @i{restarts}.
- @group
- @noindent
- @w{ abort invoke-restart-interactively store-value }
- @w{ compute-restarts muffle-warning use-value }
- @w{ continue restart-bind with-simple-restart }
- @w{ find-restart restart-case }
- @w{ invoke-restart restart-name }
- @noindent
- @w{ Figure 9--6: Defined names relating to restarts. }
- @end group
- @node Restart Tests, Associating a Restart with a Condition, Interfaces to Restarts, Signaling and Handling Conditions
- @subsubsection Restart Tests
- Each @i{restart} has an associated test, which is a function of one
- argument (a @i{condition} or @b{nil}) which returns @i{true} if the @i{restart}
- should be visible in the current @i{situation}. This test is created by
- the @t{:test-function} option to @b{restart-bind} or
- the @t{:test} option to @b{restart-case}.
- @node Associating a Restart with a Condition, , Restart Tests, Signaling and Handling Conditions
- @subsubsection Associating a Restart with a Condition
- A @i{restart} can be ``associated with'' a @i{condition} explicitly
- by @b{with-condition-restarts}, or implicitly by @b{restart-case}.
- Such an assocation has @i{dynamic extent}.
- A single @i{restart} may be associated with several @i{conditions}
- at the same time.
- A single @i{condition} may have several associated @i{restarts}
- at the same time.
- Active restarts associated with a particular @i{condition} can be detected
- by @i{calling} a @i{function} such as @b{find-restart}, supplying
- that @i{condition} as the @i{condition} @i{argument}.
- Active restarts can also be detected without regard to any associated
- @i{condition} by calling such a function without a @i{condition} @i{argument},
- or by supplying a value of @b{nil} for such an @i{argument}.
- @node Assertions, Notes about the Condition System's Background, Signaling and Handling Conditions, Condition System Concepts
- @subsection Assertions
- Conditional signaling of @i{conditions}
- based on such things as key match, form evaluation,
- and @i{type} are handled by assertion @i{operators}.
- Figure 9--7 shows @i{operators} relating to assertions.
- @group
- @noindent
- @w{ assert check-type ecase }
- @w{ ccase ctypecase etypecase }
- @noindent
- @w{ Figure 9--7: Operators relating to assertions.}
- @end group
- @node Notes about the Condition System's Background, , Assertions, Condition System Concepts
- @subsection Notes about the Condition System's Background
- For a background reference to the abstract concepts detailed in this
- section, see @i{Exceptional Situations in Lisp}. The details of that paper are not binding on
- this document, but may be helpful in establishing a conceptual basis for
- understanding this material.
- @c end of including concept-conditions
- @node Conditions Dictionary, , Condition System Concepts, Conditions
- @section Conditions Dictionary
- @c including dict-conditions
- @menu
- * condition::
- * warning::
- * style-warning::
- * serious-condition::
- * error (Condition Type)::
- * cell-error::
- * cell-error-name::
- * parse-error::
- * storage-condition::
- * assert::
- * error::
- * cerror::
- * check-type::
- * simple-error::
- * invalid-method-error::
- * method-combination-error::
- * signal::
- * simple-condition::
- * simple-condition-format-control::
- * warn::
- * simple-warning::
- * invoke-debugger::
- * break::
- * *debugger-hook*::
- * *break-on-signals*::
- * handler-bind::
- * handler-case::
- * ignore-errors::
- * define-condition::
- * make-condition::
- * restart::
- * compute-restarts::
- * find-restart::
- * invoke-restart::
- * invoke-restart-interactively::
- * restart-bind::
- * restart-case::
- * restart-name::
- * with-condition-restarts::
- * with-simple-restart::
- * abort::
- * continue::
- * muffle-warning::
- * store-value::
- * use-value::
- * abort::
- @end menu
- @node condition, warning, Conditions Dictionary, Conditions Dictionary
- @subsection condition [Condition Type]
- [Reviewer Note by Barrett: I think CONDITION-RESTARTS is not fully integrated.]
- @subsubheading Class Precedence List::
- @b{condition},
- @b{t}
- @subsubheading Description::
- All types of @i{conditions}, whether error or
- non-error, must inherit from this @i{type}.
- No additional @i{subtype} relationships among the specified @i{subtypes} of @i{type} @b{condition}
- are allowed, except when explicitly mentioned in the text; however
- implementations are permitted to introduce additional @i{types}
- and one of these @i{types} can be a @i{subtype} of any
- number of the @i{subtypes} of @i{type} @b{condition}.
- Whether a user-defined @i{condition} @i{type} has @i{slots}
- that are accessible by @i{with-slots} is @i{implementation-dependent}.
- Furthermore, even in an @i{implementation}
- in which user-defined @i{condition} @i{types} would have @i{slots},
- it is @i{implementation-dependent} whether any @i{condition}
- @i{types} defined in this document have such @i{slots} or,
- if they do, what their @i{names} might be;
- only the reader functions documented by this specification may be relied
- upon by portable code.
- @i{Conforming code} must observe the following restrictions related to
- @i{conditions}:
- @table @asis
- @item @t{*}
- @b{define-condition}, not @b{defclass}, must be used
- to define new @i{condition} @i{types}.
- @item @t{*}
- @b{make-condition}, not @b{make-instance}, must be used to
- create @i{condition} @i{objects} explicitly.
- @item @t{*}
- The @t{:report} option of @b{define-condition}, not @b{defmethod}
- for @b{print-object}, must be used to define a condition reporter.
- @item @t{*}
- @b{slot-value}, @b{slot-boundp}, @b{slot-makunbound},
- and @b{with-slots} must not be used on @i{condition} @i{objects}.
- Instead, the appropriate accessor functions (defined by @b{define-condition})
- should be used.
- @end table
- @node warning, style-warning, condition, Conditions Dictionary
- @subsection warning [Condition Type]
- @subsubheading Class Precedence List::
- @b{warning},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{warning} consists of all types of warnings.
- @subsubheading See Also::
- @b{style-warning}
- @node style-warning, serious-condition, warning, Conditions Dictionary
- @subsection style-warning [Condition Type]
- @subsubheading Class Precedence List::
- @b{style-warning},
- @b{warning},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{style-warning} includes those @i{conditions}
- that represent @i{situations} involving @i{code}
- that is @i{conforming code} but that is nevertheless
- considered to be faulty or substandard.
- @subsubheading See Also::
- @ref{muffle-warning}
- @subsubheading Notes::
- An @i{implementation} might signal such a @i{condition}
- if it encounters @i{code}
- that uses deprecated features
- or that appears unaesthetic or inefficient.
- An `unused variable' warning must be of @i{type} @b{style-warning}.
- In general, the question of whether @i{code} is faulty or substandard
- is a subjective decision to be made by the facility processing that @i{code}.
- The intent is that whenever such a facility wishes to complain about
- @i{code} on such subjective grounds, it should use this
- @i{condition} @i{type} so that any clients who wish to redirect or
- muffle superfluous warnings can do so without risking that they will be
- redirecting or muffling other, more serious warnings.
- @node serious-condition, error (Condition Type), style-warning, Conditions Dictionary
- @subsection serious-condition [Condition Type]
- @subsubheading Class Precedence List::
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- All @i{conditions} serious enough to require interactive intervention
- if not handled should inherit from the @i{type} @b{serious-condition}.
- This condition type is provided
- primarily so that it may be included as
- a @i{superclass} of other @i{condition} @i{types};
- it is not intended to be signaled directly.
- @subsubheading Notes::
- Signaling a @i{serious condition} does not itself force entry into
- the debugger. However, except in the unusual situation where the
- programmer can assure that no harm will come from failing to
- @i{handle} a @i{serious condition}, such a @i{condition} is
- usually signaled with @b{error} rather than @b{signal} in
- order to assure that the program does not continue without
- @i{handling} the @i{condition}. (And conversely, it is
- conventional to use @b{signal} rather than @b{error} to signal
- conditions which are not @i{serious conditions}, since normally the
- failure to handle a non-serious condition is not reason enough for the
- debugger to be entered.)
- @node error (Condition Type), cell-error, serious-condition, Conditions Dictionary
- @subsection error [Condition Type]
- @subsubheading Class Precedence List::
- @b{error},
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{error} consists of all @i{conditions} that represent @i{errors}.
- @node cell-error, cell-error-name, error (Condition Type), Conditions Dictionary
- @subsection cell-error [Condition Type]
- @subsubheading Class Precedence List::
- @b{cell-error},
- @b{error},
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{cell-error} consists of error conditions that occur during
- a location @i{access}. The name of the offending cell is initialized by
- the @t{:name} initialization argument to @b{make-condition},
- and is @i{accessed} by the @i{function} @b{cell-error-name}.
- @subsubheading See Also::
- @ref{cell-error-name}
- @node cell-error-name, parse-error, cell-error, Conditions Dictionary
- @subsection cell-error-name [Function]
- @code{cell-error-name} @i{condition} @result{} @i{name}
- @subsubheading Arguments and Values::
- @i{condition}---a @i{condition} of @i{type} @b{cell-error}.
- @i{name}---an @i{object}.
- @subsubheading Description::
- Returns the @i{name} of the offending cell involved in the @i{situation}
- represented by @i{condition}.
- The nature of the result depends on the specific @i{type} of @i{condition}.
- For example,
- if the @i{condition} is of @i{type} @b{unbound-variable}, the result is
- the @i{name} of the @i{unbound variable} which was being @i{accessed},
- if the @i{condition} is of @i{type} @b{undefined-function}, this is
- the @i{name} of the @i{undefined function} which was being @i{accessed},
- and if the @i{condition} is of @i{type} @b{unbound-slot}, this is
- the @i{name} of the @i{slot} which was being @i{accessed}.
- @subsubheading See Also::
- @b{cell-error},
- @b{unbound-slot},
- @b{unbound-variable},
- @b{undefined-function},
- @ref{Condition System Concepts}
- @node parse-error, storage-condition, cell-error-name, Conditions Dictionary
- @subsection parse-error [Condition Type]
- @subsubheading Class Precedence List::
- @b{parse-error},
- @b{error},
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{parse-error} consists of
- error conditions that are related to parsing.
- @subsubheading See Also::
- @ref{parse-namestring}
- ,
- @ref{reader-error}
- @node storage-condition, assert, parse-error, Conditions Dictionary
- @subsection storage-condition [Condition Type]
- @subsubheading Class Precedence List::
- @b{storage-condition},
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{storage-condition} consists of serious conditions that
- relate to problems with memory management that are potentially due to
- @i{implementation-dependent} limits rather than semantic errors
- in @i{conforming programs}, and that typically warrant entry to the
- debugger if not handled. Depending on the details of the @i{implementation},
- these might include such problems as
- stack overflow,
- memory region overflow,
- and
- storage exhausted.
- @subsubheading Notes::
- While some @r{Common Lisp} operations might signal @i{storage-condition}
- because they are defined to create @i{objects},
- it is unspecified whether operations that are not defined to create
- @i{objects} create them anyway
- and so might also signal @b{storage-condition}.
- Likewise, the evaluator itself might create @i{objects}
- and so might signal @b{storage-condition}.
- (The natural assumption might be that such
- @i{object} creation is naturally inefficient,
- but even that is @i{implementation-dependent}.)
- In general, the entire question of how storage allocation is done is
- @i{implementation-dependent},
- and so any operation might signal @b{storage-condition} at any time.
- Because such a @i{condition} is indicative of a limitation
- of the @i{implementation}
- or of the @i{image}
- rather than an error in a @i{program},
- @i{objects} of @i{type} @b{storage-condition} are not of @i{type} @b{error}.
- @node assert, error, storage-condition, Conditions Dictionary
- @subsection assert [Macro]
- @code{assert} @i{test-form @r{[}@r{(}@{@i{place}@}{*}@r{)}
- @r{[}datum-form
- @{@i{argument-form}@}{*}@r{]}@r{]}}@*
- @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{test-form}---a @i{form}; always evaluated.
- @i{place}---a @i{place}; evaluated if an error is signaled.
- @i{datum-form}---a @i{form} that evaluates to a @i{datum}.
- Evaluated each time an error is to be signaled,
- or not at all if no error is to be signaled.
- @i{argument-form}---a @i{form} that evaluates to an @i{argument}.
- Evaluated each time an error is to be signaled,
- or not at all if no error is to be signaled.
- @i{datum}, @i{arguments}---@i{designators} for a @i{condition}
- of default type @b{error}. (These @i{designators} are the
- result of evaluating @i{datum-form} and each of the @i{argument-forms}.)
- @subsubheading Description::
- @b{assert} assures that @i{test-form} evaluates to @i{true}.
- If @i{test-form} evaluates to @i{false}, @b{assert} signals a
- @i{correctable} @i{error} (denoted by @i{datum} and @i{arguments}).
- Continuing from this error using the @b{continue} @i{restart} makes it possible
- for the user to alter the values of the @i{places} before
- @b{assert} evaluates @i{test-form} again.
- If the value of @i{test-form} is @i{non-nil},
- @b{assert} returns @b{nil}.
- The @i{places} are @i{generalized references} to data
- upon which @i{test-form} depends,
- whose values can be changed by the user in attempting to correct the error.
- @i{Subforms} of each @i{place} are only evaluated if an error is signaled,
- and might be re-evaluated if the error is re-signaled (after continuing without
- actually fixing the problem).
- The order of evaluation of the @i{places} is not specified;
- see @ref{Evaluation of Subforms to Places}.
- @ITindex{order of evaluation}
- @ITindex{evaluation order}
- If a @i{place} @i{form} is supplied that produces more values than there
- are store variables, the extra values are ignored. If the supplied
- @i{form} produces fewer values than there are store variables,
- the missing values are set to @b{nil}.
- @subsubheading Examples::
- @example
- (setq x (make-array '(3 5) :initial-element 3))
- @result{} #2A((3 3 3 3 3) (3 3 3 3 3) (3 3 3 3 3))
- (setq y (make-array '(3 5) :initial-element 7))
- @result{} #2A((7 7 7 7 7) (7 7 7 7 7) (7 7 7 7 7))
- (defun matrix-multiply (a b)
- (let ((*print-array* nil))
- (assert (and (= (array-rank a) (array-rank b) 2)
- (= (array-dimension a 1) (array-dimension b 0)))
- (a b)
- "Cannot multiply ~S by ~S." a b)
- (really-matrix-multiply a b))) @result{} MATRIX-MULTIPLY
- (matrix-multiply x y)
- @t{ |> } Correctable error in MATRIX-MULTIPLY:
- @t{ |> } Cannot multiply #<ARRAY ...> by #<ARRAY ...>.
- @t{ |> } Restart options:
- @t{ |> } 1: You will be prompted for one or more new values.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Value for A: @b{|>>}@t{x}@b{<<|}
- @t{ |> } Value for B: @b{|>>}@t{(make-array '(5 3) :initial-element 6)}@b{<<|}
- @result{} #2A((54 54 54 54 54)
- (54 54 54 54 54)
- (54 54 54 54 54)
- (54 54 54 54 54)
- (54 54 54 54 54))
- @end example
- @example
- (defun double-safely (x) (assert (numberp x) (x)) (+ x x))
- (double-safely 4)
- @result{} 8
- (double-safely t)
- @t{ |> } Correctable error in DOUBLE-SAFELY: The value of (NUMBERP X) must be non-NIL.
- @t{ |> } Restart options:
- @t{ |> } 1: You will be prompted for one or more new values.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Value for X: @b{|>>}@t{7}@b{<<|}
- @result{} 14
- @end example
- @subsubheading Affected By::
- @b{*break-on-signals*}
- The set of active @i{condition handlers}.
- @subsubheading See Also::
- @ref{check-type}
- ,
- @ref{error}
- , @ref{Generalized Reference}
- @subsubheading Notes::
- The debugger need not include the @i{test-form} in the error message,
- and the @i{places} should not be included in the message, but they
- should be made available for the user's perusal. If the user gives the
- ``continue'' command, the values of any of the references can be altered.
- The details of this depend on the implementation's style of user interface.
- @node error, cerror, assert, Conditions Dictionary
- @subsection error [Function]
- @code{error} @i{datum {&rest} arguments}
- @result{} #<NoValue>
- @subsubheading Arguments and Values::
- @i{datum}, @i{arguments}---@i{designators} for a @i{condition}
- of default type @b{simple-error}.
- @subsubheading Description::
- @b{error} effectively invokes @b{signal} on the denoted @i{condition}.
- If the @i{condition} is not handled, @t{(invoke-debugger @i{condition})} is done.
- As a consequence of calling @b{invoke-debugger}, @b{error}
- cannot directly return; the only exit from @b{error}
- can come by non-local transfer of control in a handler or by use of
- an interactive debugging command.
- @subsubheading Examples::
- @example
- (defun factorial (x)
- (cond ((or (not (typep x 'integer)) (minusp x))
- (error "~S is not a valid argument to FACTORIAL." x))
- ((zerop x) 1)
- (t (* x (factorial (- x 1))))))
- @result{} FACTORIAL
- (factorial 20)
- @result{} 2432902008176640000
- (factorial -1)
- @t{ |> } Error: -1 is not a valid argument to FACTORIAL.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return to Lisp Toplevel.
- @t{ |> } Debug>
- @end example
- @example
- (setq a 'fred)
- @result{} FRED
- (if (numberp a) (1+ a) (error "~S is not a number." A))
- @t{ |> } Error: FRED is not a number.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{:Continue 1}@b{<<|}
- @t{ |> } Return to Lisp Toplevel.
- (define-condition not-a-number (error)
- ((argument :reader not-a-number-argument :initarg :argument))
- (:report (lambda (condition stream)
- (format stream "~S is not a number."
- (not-a-number-argument condition)))))
- @result{} NOT-A-NUMBER
- (if (numberp a) (1+ a) (error 'not-a-number :argument a))
- @t{ |> } Error: FRED is not a number.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{:Continue 1}@b{<<|}
- @t{ |> } Return to Lisp Toplevel.
- @end example
- @subsubheading Side Effects::
- @i{Handlers} for the specified condition, if any, are invoked
- and might have side effects.
- Program execution might stop, and the debugger might be entered.
- @subsubheading Affected By::
- Existing handler bindings.
- @b{*break-on-signals*}
- Signals an error of @i{type} @b{type-error} if @i{datum} and @i{arguments} are not @i{designators} for a @i{condition}.
- @subsubheading See Also::
- @ref{cerror}
- ,
- @ref{signal}
- ,
- @ref{format}
- ,
- @ref{ignore-errors}
- , @b{*break-on-signals*},
- @ref{handler-bind}
- , @ref{Condition System Concepts}
- @subsubheading Notes::
- Some implementations may provide debugger
- commands for interactively returning from individual stack frames.
- However, it should be possible for the programmer to feel confident
- about writing code like:
- @example
- (defun wargames:no-win-scenario ()
- (if (error "pushing the button would be stupid."))
- (push-the-button))
- @end example
- In this scenario, there should be no chance that
- @b{error} will return
- and the button will get pushed.
- While the meaning of this program is clear and it might be proven `safe'
- by a formal theorem prover, such a proof is no guarantee that the
- program is safe to execute. Compilers have been known to have bugs,
- computers to have signal glitches, and human beings to manually
- intervene in ways that are not always possible to predict. Those kinds
- of errors, while beyond the scope of the condition system to formally
- model, are not beyond the scope of things that should seriously be
- considered when writing code that could have the kinds of sweeping
- effects hinted at by this example.
- @node cerror, check-type, error, Conditions Dictionary
- @subsection cerror [Function]
- @code{cerror} @i{continue-format-control datum {&rest} arguments} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{Continue-format-control}---a @i{format control}.
- [Reviewer Note by Barmar: What is continue-format-control used for??]
- @i{datum}, @i{arguments}---@i{designators} for a @i{condition}
- of default type @b{simple-error}.
- @subsubheading Description::
- @b{cerror} effectively invokes @b{error} on the
- @i{condition} named by @i{datum}. As with any function that
- implicitly calls @b{error}, if the @i{condition} is not handled,
- @t{(invoke-debugger @i{condition})} is executed. While signaling is going on,
- and while in the debugger if it is reached, it is possible to continue
- code execution (@i{i.e.}, to return from @b{cerror}) using the @b{continue} @i{restart}.
- If @i{datum} is a @i{condition}, @i{arguments} can be supplied,
- but are used only in conjunction with the @i{continue-format-control}.
- @subsubheading Examples::
- @example
- (defun real-sqrt (n)
- (when (minusp n)
- (setq n (- n))
- (cerror "Return sqrt(~D) instead." "Tried to take sqrt(-~D)." n))
- (sqrt n))
- (real-sqrt 4)
- @result{} 2.0
- (real-sqrt -9)
- @t{ |> } Correctable error in REAL-SQRT: Tried to take sqrt(-9).
- @t{ |> } Restart options:
- @t{ |> } 1: Return sqrt(9) instead.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @result{} 3.0
- (define-condition not-a-number (error)
- ((argument :reader not-a-number-argument :initarg :argument))
- (:report (lambda (condition stream)
- (format stream "~S is not a number."
- (not-a-number-argument condition)))))
- (defun assure-number (n)
- (loop (when (numberp n) (return n))
- (cerror "Enter a number."
- 'not-a-number :argument n)
- (format t "~&Type a number: ")
- (setq n (read))
- (fresh-line)))
- (assure-number 'a)
- @t{ |> } Correctable error in ASSURE-NUMBER: A is not a number.
- @t{ |> } Restart options:
- @t{ |> } 1: Enter a number.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Type a number: @b{|>>}@t{1/2}@b{<<|}
- @result{} 1/2
- (defun assure-large-number (n)
- (loop (when (and (numberp n) (> n 73)) (return n))
- (cerror "Enter a number~:[~; a bit larger than ~D~]."
- "~*~A is not a large number."
- (numberp n) n)
- (format t "~&Type a large number: ")
- (setq n (read))
- (fresh-line)))
- (assure-large-number 10000)
- @result{} 10000
- (assure-large-number 'a)
- @t{ |> } Correctable error in ASSURE-LARGE-NUMBER: A is not a large number.
- @t{ |> } Restart options:
- @t{ |> } 1: Enter a number.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Type a large number: @b{|>>}@t{88}@b{<<|}
- @result{} 88
- (assure-large-number 37)
- @t{ |> } Correctable error in ASSURE-LARGE-NUMBER: 37 is not a large number.
- @t{ |> } Restart options:
- @t{ |> } 1: Enter a number a bit larger than 37.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Type a large number: @b{|>>}@t{259}@b{<<|}
- @result{} 259
- (define-condition not-a-large-number (error)
- ((argument :reader not-a-large-number-argument :initarg :argument))
- (:report (lambda (condition stream)
- (format stream "~S is not a large number."
- (not-a-large-number-argument condition)))))
- (defun assure-large-number (n)
- (loop (when (and (numberp n) (> n 73)) (return n))
- (cerror "Enter a number~3*~:[~; a bit larger than ~*~D~]."
- 'not-a-large-number
- :argument n
- :ignore (numberp n)
- :ignore n
- :allow-other-keys t)
- (format t "~&Type a large number: ")
- (setq n (read))
- (fresh-line)))
- (assure-large-number 'a)
- @t{ |> } Correctable error in ASSURE-LARGE-NUMBER: A is not a large number.
- @t{ |> } Restart options:
- @t{ |> } 1: Enter a number.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Type a large number: @b{|>>}@t{88}@b{<<|}
- @result{} 88
- (assure-large-number 37)
- @t{ |> } Correctable error in ASSURE-LARGE-NUMBER: A is not a large number.
- @t{ |> } Restart options:
- @t{ |> } 1: Enter a number a bit larger than 37.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Type a large number: @b{|>>}@t{259}@b{<<|}
- @result{} 259
- @end example
- @subsubheading Affected By::
- @b{*break-on-signals*}.
- Existing handler bindings.
- @subsubheading See Also::
- @ref{error}
- ,
- @ref{format}
- ,
- @ref{handler-bind}
- ,
- @b{*break-on-signals*}, @b{simple-type-error}
- @subsubheading Notes::
- If @i{datum} is a @i{condition} @i{type} rather than a
- @i{string}, the @b{format} directive @t{~*} may be especially
- useful in the @i{continue-format-control} in order to ignore the
- @i{keywords} in the @i{initialization argument list}. For example:
- @example
- (cerror "enter a new value to replace ~*~s"
- 'not-a-number
- :argument a)
- @end example
- @node check-type, simple-error, cerror, Conditions Dictionary
- @subsection check-type [Macro]
- @code{check-type} @i{place typespec {@r{[}@i{string}@r{]}}} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{place}---a @i{place}.
- @i{typespec}---a @i{type specifier}.
- @i{string}---a @i{string}; evaluated.
- @subsubheading Description::
- @b{check-type} signals a @i{correctable} @i{error}
- of @i{type} @b{type-error} if the contents of @i{place} are not
- of the type @i{typespec}.
- @b{check-type} can return only if the @b{store-value} @i{restart} is invoked,
- either explicitly from a handler
- or implicitly as one of the options offered by the debugger.
- If the @b{store-value} @i{restart} is invoked,
- @b{check-type} stores the new value
- that is the argument to the @i{restart} invocation
- (or that is prompted for interactively by the debugger)
- in @i{place} and starts over,
- checking the type of the new value
- and signaling another error if it is still not of the desired @i{type}.
- The first time @i{place} is @i{evaluated},
- it is @i{evaluated} by normal evaluation rules.
- It is later @i{evaluated} as a @i{place}
- if the type check fails and the @b{store-value} @i{restart} is used;
- see @ref{Evaluation of Subforms to Places}.
- @i{string} should be an English description of the type,
- starting with an indefinite article (``a'' or ``an'').
- If @i{string} is not supplied,
- it is computed automatically from @i{typespec}.
- The automatically generated message mentions
- @i{place},
- its contents,
- and the desired type.
- An implementation may choose to generate
- a somewhat differently worded error message
- if it recognizes that @i{place} is of a particular form,
- such as one of the arguments to the function that called @b{check-type}.
- @i{string} is allowed because some applications of @b{check-type}
- may require a more specific description of what is wanted
- than can be generated automatically from @i{typespec}.
- @subsubheading Examples::
- @example
- (setq aardvarks '(sam harry fred))
- @result{} (SAM HARRY FRED)
- (check-type aardvarks (array * (3)))
- @t{ |> } Error: The value of AARDVARKS, (SAM HARRY FRED),
- @t{ |> } is not a 3-long array.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a value to use instead.
- @t{ |> } 2: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{:CONTINUE 1}@b{<<|}
- @t{ |> } Use Value: @b{|>>}@t{#(SAM FRED HARRY)}@b{<<|}
- @result{} NIL
- aardvarks
- @result{} #<ARRAY-T-3 13571>
- (map 'list #'identity aardvarks)
- @result{} (SAM FRED HARRY)
- (setq aardvark-count 'foo)
- @result{} FOO
- (check-type aardvark-count (integer 0 *) "A positive integer")
- @t{ |> } Error: The value of AARDVARK-COUNT, FOO, is not a positive integer.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a value to use instead.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:CONTINUE 2}@b{<<|}
- @end example
- @example
- (defmacro define-adder (name amount)
- (check-type name (and symbol (not null)) "a name for an adder function")
- (check-type amount integer)
- `(defun ,name (x) (+ x ,amount)))
- (macroexpand '(define-adder add3 3))
- @result{} (defun add3 (x) (+ x 3))
- (macroexpand '(define-adder 7 7))
- @t{ |> } Error: The value of NAME, 7, is not a name for an adder function.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a value to use instead.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:Continue 1}@b{<<|}
- @t{ |> } Specify a value to use instead.
- @t{ |> } Type a form to be evaluated and used instead: @b{|>>}@t{'ADD7}@b{<<|}
- @result{} (defun add7 (x) (+ x 7))
- (macroexpand '(define-adder add5 something))
- @t{ |> } Error: The value of AMOUNT, SOMETHING, is not an integer.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a value to use instead.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:Continue 1}@b{<<|}
- @t{ |> } Type a form to be evaluated and used instead: @b{|>>}@t{5}@b{<<|}
- @result{} (defun add5 (x) (+ x 5))
- @end example
- Control is transferred to a handler.
- @subsubheading Side Effects::
- The debugger might be entered.
- @subsubheading Affected By::
- @b{*break-on-signals*}
- The implementation.
- @subsubheading See Also::
- @ref{Condition System Concepts}
- @subsubheading Notes::
- @example
- (check-type @i{place} @i{typespec})
- @equiv{} (assert (typep @i{place} '@i{typespec}) (@i{place})
- 'type-error :datum @i{place} :expected-type '@i{typespec})
- @end example
- @node simple-error, invalid-method-error, check-type, Conditions Dictionary
- @subsection simple-error [Condition Type]
- @subsubheading Class Precedence List::
- @b{simple-error},
- @b{simple-condition},
- @b{error},
- @b{serious-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{simple-error} consists of @i{conditions} that
- are signaled by @b{error} or @b{cerror} when a
- @i{format control}
- is supplied as the function's first argument.
- @node invalid-method-error, method-combination-error, simple-error, Conditions Dictionary
- @subsection invalid-method-error [Function]
- @code{invalid-method-error} @i{method format-control {&rest} args} @result{} @i{@i{implementation-dependent}}
- @subsubheading Arguments and Values::
- @i{method}---a @i{method}.
- @i{format-control}---a @i{format control}.
- @i{args}---@i{format arguments} for the @i{format-control}.
- @subsubheading Description::
- The @i{function} @b{invalid-method-error} is used to signal an error of @i{type} @b{error}
- when there is an applicable @i{method} whose @i{qualifiers} are not valid for
- the method combination type. The error message is constructed by
- using the @i{format-control} suitable for @b{format}
- and any @i{args} to it. Because an
- implementation may need to add additional contextual information to
- the error message, @b{invalid-method-error} should be called only
- within the dynamic extent of a method combination function.
- The @i{function} @b{invalid-method-error} is called automatically when a
- @i{method} fails to satisfy every @i{qualifier} pattern and predicate in a
- @b{define-method-combination} @i{form}. A method combination function
- that imposes additional restrictions should call
- @b{invalid-method-error} explicitly if it encounters a @i{method}
- it cannot accept.
- Whether @b{invalid-method-error} returns to its caller or exits via
- @b{throw} is @i{implementation-dependent}.
- @subsubheading Side Effects::
- The debugger might be entered.
- @subsubheading Affected By::
- @b{*break-on-signals*}
- @subsubheading See Also::
- @ref{define-method-combination}
- @node method-combination-error, signal, invalid-method-error, Conditions Dictionary
- @subsection method-combination-error [Function]
- @code{method-combination-error} @i{format-control {&rest} args} @result{} @i{@i{implementation-dependent}}
- @subsubheading Arguments and Values::
- @i{format-control}---a @i{format control}.
- @i{args}---@i{format arguments} for @i{format-control}.
- @subsubheading Description::
- The @i{function} @b{method-combination-error} is used to signal an error
- in method combination.
- The error message is constructed by using a @i{format-control} suitable
- for @b{format} and any @i{args} to it. Because an implementation may
- need to add additional contextual information to the error message,
- @b{method-combination-error} should be called only within the
- dynamic extent of a method combination function.
- Whether @b{method-combination-error} returns to its caller or exits
- via @b{throw} is @i{implementation-dependent}.
- @subsubheading Side Effects::
- The debugger might be entered.
- @subsubheading Affected By::
- @b{*break-on-signals*}
- @subsubheading See Also::
- @ref{define-method-combination}
- @node signal, simple-condition, method-combination-error, Conditions Dictionary
- @subsection signal [Function]
- @code{signal} @i{datum {&rest} arguments} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{datum}, @i{arguments}---@i{designators} for a @i{condition}
- of default type @b{simple-condition}.
- @subsubheading Description::
- @i{Signals} the @i{condition} denoted by the given @i{datum} and @i{arguments}.
- If the @i{condition} is not handled, @b{signal} returns @b{nil}.
- @subsubheading Examples::
- @example
- (defun handle-division-conditions (condition)
- (format t "Considering condition for division condition handling~
- (when (and (typep condition 'arithmetic-error)
- (eq '/ (arithmetic-error-operation condition)))
- (invoke-debugger condition)))
- HANDLE-DIVISION-CONDITIONS
- (defun handle-other-arithmetic-errors (condition)
- (format t "Considering condition for arithmetic condition handling~
- (when (typep condition 'arithmetic-error)
- (abort)))
- HANDLE-OTHER-ARITHMETIC-ERRORS
- (define-condition a-condition-with-no-handler (condition) ())
- A-CONDITION-WITH-NO-HANDLER
- (signal 'a-condition-with-no-handler)
- NIL
- (handler-bind ((condition #'handle-division-conditions)
- (condition #'handle-other-arithmetic-errors))
- (signal 'a-condition-with-no-handler))
- Considering condition for division condition handling
- Considering condition for arithmetic condition handling
- NIL
- (handler-bind ((arithmetic-error #'handle-division-conditions)
- (arithmetic-error #'handle-other-arithmetic-errors))
- (signal 'arithmetic-error :operation '* :operands '(1.2 b)))
- Considering condition for division condition handling
- Considering condition for arithmetic condition handling
- Back to Lisp Toplevel
- @end example
- @subsubheading Side Effects::
- The debugger might be entered due to @b{*break-on-signals*}.
- Handlers for the condition being signaled might transfer control.
- @subsubheading Affected By::
- Existing handler bindings.
- @b{*break-on-signals*}
- @subsubheading See Also::
- @b{*break-on-signals*},
- @ref{error}
- ,
- @b{simple-condition},
- @ref{Signaling and Handling Conditions}
- @subsubheading Notes::
- If @t{(typep @i{datum} *break-on-signals*)} @i{yields} @i{true},
- the debugger is entered prior to beginning the signaling process.
- The @b{continue} @i{restart} can be used to continue with the signaling process.
- This is also true for all other @i{functions} and @i{macros} that
- should, might, or must @i{signal} @i{conditions}.
- @node simple-condition, simple-condition-format-control, signal, Conditions Dictionary
- @subsection simple-condition [Condition Type]
- @subsubheading Class Precedence List::
- @b{simple-condition},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{simple-condition} represents @i{conditions} that are
- signaled by @b{signal} whenever a @i{format-control} is
- supplied as the function's first argument.
- The @i{format control} and @i{format arguments} are initialized with
- the initialization arguments named @t{:format-control}
- and @t{:format-arguments} to @b{make-condition}, and are
- @i{accessed} by the @i{functions}
- @b{simple-condition-format-control}
- and @b{simple-condition-format-arguments}.
- If format arguments are not supplied to @b{make-condition},
- @b{nil} is used as a default.
- @subsubheading See Also::
- @ref{simple-condition-format-control; simple-condition-format-arguments}
- ,
- @b{simple-condition-format-arguments}
- @node simple-condition-format-control, warn, simple-condition, Conditions Dictionary
- @subsection simple-condition-format-control, simple-condition-format-arguments
- @flushright
- @i{[Function]}
- @end flushright
- @code{simple-condition-format-control} @i{condition} @result{} @i{format-control}
- @code{simple-condition-format-arguments} @i{condition} @result{} @i{format-arguments}
- @subsubheading Arguments and Values::
- @i{condition}---a @i{condition} of @i{type} @b{simple-condition}.
- @i{format-control}---a @i{format control}.
- @i{format-arguments}---a @i{list}.
- @subsubheading Description::
- @b{simple-condition-format-control} returns the @i{format control} needed to
- process the @i{condition}'s @i{format arguments}.
- @b{simple-condition-format-arguments} returns a @i{list} of @i{format arguments}
- needed to process the @i{condition}'s @i{format control}.
- @subsubheading Examples::
- @example
- (setq foo (make-condition 'simple-condition
- :format-control "Hi ~S"
- :format-arguments '(ho)))
- @result{} #<SIMPLE-CONDITION 26223553>
- (apply #'format nil (simple-condition-format-control foo)
- (simple-condition-format-arguments foo))
- @result{} "Hi HO"
- @end example
- @subsubheading See Also::
- @ref{simple-condition}
- ,
- @ref{Condition System Concepts}
- @node warn, simple-warning, simple-condition-format-control, Conditions Dictionary
- @subsection warn [Function]
- @code{warn} @i{datum {&rest} arguments} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{datum}, @i{arguments}---@i{designators} for a @i{condition}
- of default type @b{simple-warning}.
- @subsubheading Description::
- @i{Signals} a @i{condition} of @i{type} @b{warning}.
- If the @i{condition} is not @i{handled},
- reports the @i{condition} to @i{error output}.
- The precise mechanism for warning is as follows:
- @table @asis
- @item @b{The warning condition is signaled}
- While the @b{warning} @i{condition} is being signaled,
- the @b{muffle-warning} @i{restart} is established for use by a @i{handler}.
- If invoked, this @i{restart} bypasses further action by @b{warn},
- which in turn causes @b{warn} to immediately return @b{nil}.
- @item @b{If no handler for the warning condition is found}
- If no handlers for the warning condition are found,
- or if all such handlers decline,
- then the @i{condition} is reported to @i{error output}
- by @b{warn} in an @i{implementation-dependent} format.
- @item @b{@b{nil} is returned}
- The value returned by @b{warn} if it returns is @b{nil}.
- @end table
- @subsubheading Examples::
- @example
- (defun foo (x)
- (let ((result (* x 2)))
- (if (not (typep result 'fixnum))
- (warn "You're using very big numbers."))
- result))
- @result{} FOO
- (foo 3)
- @result{} 6
- (foo most-positive-fixnum)
- @t{ |> } Warning: You're using very big numbers.
- @result{} 4294967294
- (setq *break-on-signals* t)
- @result{} T
- (foo most-positive-fixnum)
- @t{ |> } Break: Caveat emptor.
- @t{ |> } To continue, type :CONTINUE followed by an option number.
- @t{ |> } 1: Return from Break.
- @t{ |> } 2: Abort to Lisp Toplevel.
- @t{ |> } Debug> :continue 1
- @t{ |> } Warning: You're using very big numbers.
- @result{} 4294967294
- @end example
- @subsubheading Side Effects::
- A warning is issued. The debugger might be entered.
- @subsubheading Affected By::
- Existing handler bindings.
- @b{*break-on-signals*},
- @b{*error-output*}.
- @subsubheading Exceptional Situations::
- If @i{datum} is a @i{condition}
- and if the @i{condition} is not of @i{type} @b{warning},
- or @i{arguments} is @i{non-nil}, an error of @i{type} @b{type-error} is signaled.
- If @i{datum} is a condition type,
- the result of @t{(apply #'make-condition datum arguments)}
- must be of @i{type} @b{warning} or an error of @i{type} @b{type-error} is signaled.
- @subsubheading See Also::
- @b{*break-on-signals*},
- @ref{muffle-warning}
- ,
- @ref{signal}
- @node simple-warning, invoke-debugger, warn, Conditions Dictionary
- @subsection simple-warning [Condition Type]
- @subsubheading Class Precedence List::
- @b{simple-warning},
- @b{simple-condition},
- @b{warning},
- @b{condition},
- @b{t}
- @subsubheading Description::
- The @i{type} @b{simple-warning} represents @i{conditions} that
- are signaled by @b{warn} whenever a
- @i{format control}
- is supplied as the function's first argument.
- @node invoke-debugger, break, simple-warning, Conditions Dictionary
- @subsection invoke-debugger [Function]
- @code{invoke-debugger} @i{condition}
- @result{} #<NoValue>
- @subsubheading Arguments and Values::
- @i{condition}---a @i{condition} @i{object}.
- @subsubheading Description::
- @b{invoke-debugger} attempts to enter the debugger with @i{condition}.
- If @b{*debugger-hook*} is not @b{nil}, it should be a @i{function}
- (or the name of a @i{function}) to be called prior to entry to
- the standard debugger. The @i{function} is called with
- @b{*debugger-hook*} bound to @b{nil}, and the @i{function}
- must accept two arguments: the @i{condition}
- and the @i{value} of @b{*debugger-hook*} prior to binding it to @b{nil}.
- If the @i{function} returns normally,
- the standard debugger is entered.
- The standard debugger never directly returns. Return can occur only by a
- non-local transfer of control, such as the use of a restart function.
- @subsubheading Examples::
- @example
- (ignore-errors ;Normally, this would suppress debugger entry
- (handler-bind ((error #'invoke-debugger)) ;But this forces debugger entry
- (error "Foo.")))
- Debug: Foo.
- To continue, type :CONTINUE followed by an option number:
- 1: Return to Lisp Toplevel.
- Debug>
- @end example
- @subsubheading Side Effects::
- @b{*debugger-hook*} is bound to @b{nil},
- program execution is discontinued,
- and the debugger is entered.
- @subsubheading Affected By::
- @b{*debug-io*} and @b{*debugger-hook*}.
- @subsubheading See Also::
- @ref{error}
- ,
- @ref{break}
- @node break, *debugger-hook*, invoke-debugger, Conditions Dictionary
- @subsection break [Function]
- @code{break} @i{{&optional} format-control {&rest} format-arguments} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{format-control}---a @i{format control}.
- The default is @i{implementation-dependent}.
- @i{format-arguments}---@i{format arguments} for the @i{format-control}.
- @subsubheading Description::
- @b{break} @i{formats} @i{format-control} and @i{format-arguments}
- and then goes directly into the debugger without allowing any possibility of
- interception by programmed error-handling facilities.
- If the @b{continue} @i{restart} is used while in the debugger,
- @b{break} immediately returns @b{nil} without taking any unusual recovery action.
- @b{break} binds @b{*debugger-hook*} to @b{nil}
- before attempting to enter the debugger.
- @subsubheading Examples::
- @example
- (break "You got here with arguments: ~:S." '(FOO 37 A))
- @t{ |> } BREAK: You got here with these arguments: FOO, 37, A.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return from BREAK.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> :CONTINUE 1
- @t{ |> } Return from BREAK.
- @result{} NIL
- @end example
- @subsubheading Side Effects::
- The debugger is entered.
- @subsubheading Affected By::
- @b{*debug-io*}.
- @subsubheading See Also::
- @ref{error}
- ,
- @ref{invoke-debugger}
- .
- @subsubheading Notes::
- @b{break} is used as a way of inserting temporary debugging
- ``breakpoints'' in a program, not as a way of signaling errors.
- For this reason, @b{break} does not take the @i{continue-format-control}
- @i{argument} that @b{cerror} takes.
- This and the lack of any possibility of interception by
- @i{condition} @i{handling} are the only program-visible
- differences between @b{break} and @b{cerror}.
- The user interface aspects of @b{break} and @b{cerror} are
- permitted to vary more widely, in order to accomodate the interface
- needs of the @i{implementation}. For example, it is permissible for a
- @i{Lisp read-eval-print loop} to be entered by @b{break} rather
- than the conventional debugger.
- @b{break} could be defined by:
- @example
- (defun break (&optional (format-control "Break") &rest format-arguments)
- (with-simple-restart (continue "Return from BREAK.")
- (let ((*debugger-hook* nil))
- (invoke-debugger
- (make-condition 'simple-condition
- :format-control format-control
- :format-arguments format-arguments))))
- nil)
- @end example
- @node *debugger-hook*, *break-on-signals*, break, Conditions Dictionary
- @subsection *debugger-hook* [Variable]
- @subsubheading Value Type::
- a @i{designator} for a @i{function} of two @i{arguments}
- (a @i{condition} and the @i{value} of @b{*debugger-hook*} at the time
- the debugger was entered),
- or @b{nil}.
- @subsubheading Initial Value::
- @b{nil}.
- @subsubheading Description::
- When the @i{value} of @b{*debugger-hook*} is @i{non-nil}, it is called prior to
- normal entry into the debugger, either due to a call to @b{invoke-debugger}
- or due to automatic entry into the debugger from a call to @b{error}
- or @b{cerror} with a condition that is not handled.
- The @i{function} may either handle the @i{condition}
- (transfer control) or return normally (allowing the standard debugger to run).
- To minimize recursive errors while debugging,
- @b{*debugger-hook*} is bound to @b{nil} by @b{invoke-debugger}
- prior to calling the @i{function}.
- @subsubheading Examples::
- @example
- (defun one-of (choices &optional (prompt "Choice"))
- (let ((n (length choices)) (i))
- (do ((c choices (cdr c)) (i 1 (+ i 1)))
- ((null c))
- (format t "~&[~D] ~A~
- (do () ((typep i `(integer 1 ,n)))
- (format t "~&~A: " prompt)
- (setq i (read))
- (fresh-line))
- (nth (- i 1) choices)))
- (defun my-debugger (condition me-or-my-encapsulation)
- (format t "~&Fooey: ~A" condition)
- (let ((restart (one-of (compute-restarts))))
- (if (not restart) (error "My debugger got an error."))
- (let ((*debugger-hook* me-or-my-encapsulation))
- (invoke-restart-interactively restart))))
- (let ((*debugger-hook* #'my-debugger))
- (+ 3 'a))
- @t{ |> } Fooey: The argument to +, A, is not a number.
- @t{ |> } [1] Supply a replacement for A.
- @t{ |> } [2] Return to Cloe Toplevel.
- @t{ |> } Choice: 1
- @t{ |> } Form to evaluate and use: (+ 5 'b)
- @t{ |> } Fooey: The argument to +, B, is not a number.
- @t{ |> } [1] Supply a replacement for B.
- @t{ |> } [2] Supply a replacement for A.
- @t{ |> } [3] Return to Cloe Toplevel.
- @t{ |> } Choice: 1
- @t{ |> } Form to evaluate and use: 1
- @result{} 9
- @end example
- @subsubheading Affected By::
- @b{invoke-debugger}
- @subsubheading Notes::
- When evaluating code typed in by the user interactively, it is sometimes
- useful to have the hook function bind @b{*debugger-hook*} to the
- @i{function} that was its second argument so that recursive errors
- can be handled using the same interactive facility.
- @node *break-on-signals*, handler-bind, *debugger-hook*, Conditions Dictionary
- @subsection *break-on-signals* [Variable]
- @subsubheading Value Type::
- a @i{type specifier}.
- @subsubheading Initial Value::
- @b{nil}.
- @subsubheading Description::
- When @t{(typep @i{condition} *break-on-signals*)} returns @i{true},
- calls to @b{signal}, and to other @i{operators} such as @b{error}
- that implicitly call @b{signal}, enter the debugger prior to
- @i{signaling} the @i{condition}.
- The @b{continue} @i{restart} can be used to continue with the normal
- @i{signaling} process when a break occurs process due to
- @b{*break-on-signals*}.
- @subsubheading Examples::
- @example
- *break-on-signals* @result{} NIL
- (ignore-errors (error 'simple-error :format-control "Fooey!"))
- @result{} NIL, #<SIMPLE-ERROR 32207172>
- (let ((*break-on-signals* 'error))
- (ignore-errors (error 'simple-error :format-control "Fooey!")))
- @t{ |> } Break: Fooey!
- @t{ |> } BREAK entered because of *BREAK-ON-SIGNALS*.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Continue to signal.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:CONTINUE 1}@b{<<|}
- @t{ |> } Continue to signal.
- @result{} NIL, #<SIMPLE-ERROR 32212257>
- (let ((*break-on-signals* 'error))
- (error 'simple-error :format-control "Fooey!"))
- @t{ |> } Break: Fooey!
- @t{ |> } BREAK entered because of *BREAK-ON-SIGNALS*.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Continue to signal.
- @t{ |> } 2: Top level.
- @t{ |> } Debug> @b{|>>}@t{:CONTINUE 1}@b{<<|}
- @t{ |> } Continue to signal.
- @t{ |> } Error: Fooey!
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Top level.
- @t{ |> } Debug> @b{|>>}@t{:CONTINUE 1}@b{<<|}
- @t{ |> } Top level.
- @end example
- @subsubheading See Also::
- @ref{break}
- ,
- @ref{signal}
- ,
- @ref{warn}
- ,
- @ref{error}
- ,
- @ref{typep}
- ,
- @ref{Condition System Concepts}
- @subsubheading Notes::
- @b{*break-on-signals*} is intended primarily for use in debugging code that
- does signaling. When setting @b{*break-on-signals*}, the user is
- encouraged to choose the most restrictive specification that suffices.
- Setting @b{*break-on-signals*} effectively violates the modular handling of
- @i{condition} signaling. In practice, the complete effect of setting
- @b{*break-on-signals*} might be unpredictable in some cases since the user
- might not be aware of the variety or number of calls to @b{signal}
- that are used in code called only incidentally.
- @b{*break-on-signals*} enables an early entry to the debugger but such an
- entry does not preclude an additional entry to the debugger in the case of
- operations such as @b{error} and @b{cerror}.
- @node handler-bind, handler-case, *break-on-signals*, Conditions Dictionary
- @subsection handler-bind [Macro]
- @code{handler-bind} @i{@r{(}@{!@i{binding}@}{*}@r{)}
- @{@i{form}@}{*}} @result{} @i{@{@i{result}@}{*}}
- @w{@i{binding} ::=@r{(}type handler@r{)}}
- @subsubheading Arguments and Values::
- @i{type}---a @i{type specifier}.
- @i{handler}---a @i{form}; evaluated to produce a @i{handler-function}.
- @i{handler-function}---a @i{designator} for a @i{function} of one @i{argument}.
- @i{forms}---an @i{implicit progn}.
- @i{results}---the @i{values} returned by the @i{forms}.
- @subsubheading Description::
- Executes @i{forms} in a @i{dynamic environment} where the indicated
- @i{handler} @i{bindings} are in effect.
- Each @i{handler} should evaluate to a @i{handler-function},
- which is used to handle @i{conditions} of the given @i{type}
- during execution of the @i{forms}. This @i{function} should
- take a single argument, the @i{condition} being signaled.
- If more than one @i{handler} @i{binding} is supplied,
- the @i{handler} @i{bindings} are searched sequentially from
- top to bottom in search of a match (by visual analogy with @b{typecase}).
- If an appropriate @i{type} is found,
- the associated handler is run in a @i{dynamic environment} where none of these
- @i{handler} bindings are visible (to avoid recursive errors).
- If the @i{handler} @i{declines}, the search continues for another @i{handler}.
- If no appropriate @i{handler} is found, other @i{handlers} are sought
- from dynamically enclosing contours. If no @i{handler} is found outside,
- then @b{signal} returns or @b{error} enters the debugger.
- @subsubheading Examples::
- In the following code, if an unbound variable error is
- signaled in the body (and not handled by an intervening handler),
- the first function is called.
- @example
- (handler-bind ((unbound-variable #'(lambda ...))
- (error #'(lambda ...)))
- ...)
- @end example
- If any other kind of error is signaled, the second function is called.
- In either case, neither handler is active while executing the code
- in the associated function.
- @example
- (defun trap-error-handler (condition)
- (format *error-output* "~&~A~&" condition)
- (throw 'trap-errors nil))
- (defmacro trap-errors (&rest forms)
- `(catch 'trap-errors
- (handler-bind ((error #'trap-error-handler))
- ,@@forms)))
- (list (trap-errors (signal "Foo.") 1)
- (trap-errors (error "Bar.") 2)
- (+ 1 2))
- @t{ |> } Bar.
- @result{} (1 NIL 3)
- @end example
- Note that ``Foo.'' is not printed because the condition made
- by @b{signal} is a @i{simple condition}, which is not of @i{type} @b{error},
- so it doesn't trigger the handler for @b{error} set up by @t{trap-errors}.
- @subsubheading See Also::
- @ref{handler-case}
- @node handler-case, ignore-errors, handler-bind, Conditions Dictionary
- @subsection handler-case [Macro]
- @code{handler-case} @i{@i{expression}
- [[@{!@i{error-clause}@}{*} | !@i{no-error-clause}]]} @result{} @i{@{@i{result}@}{*}}
- @w{@i{clause} ::=!@i{error-clause} | !@i{no-error-clause}}
- @w{@i{error-clause} ::=@r{(}typespec @r{(}@t{[}var@t{]}@r{)} @{@i{declaration}@}{*} @{@i{form}@}{*}@r{)}}
- @w{@i{no-error-clause} ::=@r{(}@t{:no-error} @i{lambda-list} @{@i{declaration}@}{*} @{@i{form}@}{*}@r{)}}
- @subsubheading Arguments and Values::
- @i{expression}---a @i{form}.
- @i{typespec}---a @i{type specifier}.
- @i{var}---a @i{variable} @i{name}.
- @i{lambda-list}---an @i{ordinary lambda list}.
- @i{declaration}---a @b{declare} @i{expression}; not evaluated.
- @i{form}---a @i{form}.
- @i{results}---In the normal situation, the values returned are those that result from
- the evaluation of @i{expression};
- in the exceptional situation when control is transferred to a @i{clause},
- the value of the last @i{form} in that @i{clause} is returned.
- @subsubheading Description::
- @b{handler-case} executes @i{expression} in a @i{dynamic environment} where
- various handlers are active. Each @i{error-clause} specifies how to
- handle a @i{condition} matching the indicated @i{typespec}.
- A @i{no-error-clause} allows the specification of a particular action
- if control returns normally.
- If a @i{condition} is signaled for which there is an appropriate
- @i{error-clause} during the execution of @i{expression}
- (@i{i.e.}, one for which @t{(typep @i{condition} '@i{typespec})}
- returns @i{true}) and if there is no intervening handler for a
- @i{condition} of that @i{type}, then control is transferred to
- the body of the relevant @i{error-clause}. In this case, the
- dynamic state is unwound appropriately (so that the handlers established
- around the @i{expression} are no longer active), and @i{var} is bound to
- the @i{condition} that had been signaled.
- If more than one case is provided, those cases are made accessible
- in parallel. That is, in
- @example
- (handler-case @i{form}
- (@i{typespec1} (@i{var1}) @i{form1})
- (@i{typespec2} (@i{var2}) @i{form2}))
- @end example
- if the first @i{clause} (containing @i{form1}) has been selected,
- the handler for the second is no longer visible (or vice versa).
- The @i{clauses}
- are searched sequentially from top to bottom. If there is @i{type}
- overlap between @i{typespecs},
- the earlier of the @i{clauses} is selected.
- If @i{var}
- is not needed, it can be omitted. That is, a @i{clause} such as:
- @example
- (@i{typespec} (@i{var}) (declare (ignore @i{var})) @i{form})
- @end example
- can be written
- @t{(@i{typespec} () @i{form})}.
- If there are no @i{forms} in a selected @i{clause}, the case, and therefore
- @b{handler-case}, returns @b{nil}.
- If execution of @i{expression}
- returns normally and no @i{no-error-clause}
- exists, the values returned by
- @i{expression} are returned by @b{handler-case}.
- If execution of
- @i{expression} returns normally and a @i{no-error-clause}
- does exist, the values returned are used as arguments to the function
- described by constructing
- @t{(lambda @i{lambda-list} @{@i{form}@}{*})}
- from the @i{no-error-clause}, and the @i{values} of that function call are
- returned by @b{handler-case}.
- The handlers which were established around the @i{expression} are no longer active at the time of this call.
- @subsubheading Examples::
- @example
- (defun assess-condition (condition)
- (handler-case (signal condition)
- (warning () "Lots of smoke, but no fire.")
- ((or arithmetic-error control-error cell-error stream-error)
- (condition)
- (format nil "~S looks especially bad." condition))
- (serious-condition (condition)
- (format nil "~S looks serious." condition))
- (condition () "Hardly worth mentioning.")))
- @result{} ASSESS-CONDITION
- (assess-condition (make-condition 'stream-error :stream *terminal-io*))
- @result{} "#<STREAM-ERROR 12352256> looks especially bad."
- (define-condition random-condition (condition) ()
- (:report (lambda (condition stream)
- (declare (ignore condition))
- (princ "Yow" stream))))
- @result{} RANDOM-CONDITION
- (assess-condition (make-condition 'random-condition))
- @result{} "Hardly worth mentioning."
- @end example
- @subsubheading See Also::
- @ref{handler-bind}
- ,
- @ref{ignore-errors}
- ,
- @ref{Condition System Concepts}
- @subsubheading Notes::
- @example
- (handler-case form
- (@i{type1} (@i{var1}) . @i{body1})
- (@i{type2} (@i{var2}) . @i{body2}) ...)
- @end example
- is approximately equivalent to:
- @example
- (block #1=#:g0001
- (let ((#2=#:g0002 nil))
- (tagbody
- (handler-bind ((@i{type1} #'(lambda (temp)
- (setq #1# temp)
- (go #3=#:g0003)))
- (@i{type2} #'(lambda (temp)
- (setq #2# temp)
- (go #4=#:g0004))) ...)
- (return-from #1# form))
- #3# (return-from #1# (let ((@i{var1} #2#)) . @i{body1}))
- #4# (return-from #1# (let ((@i{var2} #2#)) . @i{body2})) ...)))
- @end example
- @example
- (handler-case form
- (@i{type1} @i{(var1)} . @i{body1})
- ...
- (:no-error (@i{varN-1} @i{varN-2} ...) . @i{bodyN}))
- @end example
- is approximately equivalent to:
- @example
- (block #1=#:error-return
- (multiple-value-call #'(lambda (@i{varN-1} @i{varN-2} ...) . @i{bodyN})
- (block #2=#:normal-return
- (return-from #1#
- (handler-case (return-from #2# form)
- (@i{type1} (@i{var1}) . @i{body1}) ...)))))
- @end example
- @node ignore-errors, define-condition, handler-case, Conditions Dictionary
- @subsection ignore-errors [Macro]
- @code{ignore-errors} @i{@{@i{form}@}{*}} @result{} @i{@{@i{result}@}{*}}
- @subsubheading Arguments and Values::
- @i{forms}---an @i{implicit progn}.
- @i{results}---In the normal situation,
- the @i{values} of the @i{forms} are returned;
- in the exceptional situation,
- two values are returned: @b{nil} and the @i{condition}.
- @subsubheading Description::
- @b{ignore-errors} is used to prevent @i{conditions} of @i{type} @b{error}
- from causing entry into the debugger.
- Specifically, @b{ignore-errors} @i{executes} @i{forms}
- in a @i{dynamic environment} where a @i{handler} for
- @i{conditions} of @i{type} @b{error} has been established;
- if invoked, it @i{handles} such @i{conditions} by
- returning two @i{values}, @b{nil} and the @i{condition} that was @i{signaled},
- from the @b{ignore-errors} @i{form}.
- If a @i{normal return} from the @i{forms} occurs,
- any @i{values} returned are returned by @b{ignore-errors}.
- @subsubheading Examples::
- @example
- (defun load-init-file (program)
- (let ((win nil))
- (ignore-errors ;if this fails, don't enter debugger
- (load (merge-pathnames (make-pathname :name program :type :lisp)
- (user-homedir-pathname)))
- (setq win t))
- (unless win (format t "~&Init file failed to load.~
- win))
- (load-init-file "no-such-program")
- @t{ |> } Init file failed to load.
- NIL
- @end example
- @subsubheading See Also::
- @ref{handler-case}
- , @ref{Condition System Concepts}
- @subsubheading Notes::
- @example
- (ignore-errors . @i{forms})
- @end example
- is equivalent to:
- @example
- (handler-case (progn . @i{forms})
- (error (condition) (values nil condition)))
- @end example
- Because the second return value is a @i{condition}
- in the exceptional case, it is common (but not required) to arrange
- for the second return value in the normal case to be missing or @b{nil} so
- that the two situations can be distinguished.
- @node define-condition, make-condition, ignore-errors, Conditions Dictionary
- @subsection define-condition [Macro]
- [Editorial Note by KMP: This syntax stuff is still very confused and needs lots of work.]
- @code{define-condition} @i{name @r{(}@{@i{parent-type}@}{*}@r{)}
- @r{(}@{!@i{slot-spec}@}{*}@r{)}
- @{@i{option}@}{*}}@*
- @result{} @i{name}
- @w{@i{slot-spec} ::=slot-name | @r{(}slot-name !@i{slot-option}@r{)}}
- @w{@i{slot-option} ::=[[ @{{:reader} @i{symbol}@}{*} | }
- @w{ @{{:writer} !@i{function-name}@}{*} | }
- @w{ @{{:accessor} @i{symbol}@}{*} | }
- @w{ @{{:allocation} !@i{allocation-type}@} | }
- @w{ @{{:initarg} @i{symbol}@}{*} | }
- @w{ @{{:initform} @i{form}@} | }
- @w{ @{{:type} @i{type-specifier}@} ]]}
- @w{@i{option} ::=[[ @r{(}@t{:default-initargs} @t{.} @i{initarg-list}@r{)} | }
- @w{ @r{(}@t{:documentation} @i{string}@r{)} | }
- @w{ @r{(}@t{:report} @i{report-name}@r{)} ]]}
- @w{@i{function-name} ::=@{@i{symbol} | @t{(setf @i{symbol})}@}}
- @w{@i{allocation-type} ::=@t{:instance} | @t{:class}}
- @w{@i{report-name} ::=@i{string} | @i{symbol} | @i{lambda expression}}
- @subsubheading Arguments and Values::
- @i{name}---a @i{symbol}.
- @i{parent-type}---a @i{symbol} naming a @i{condition} @i{type}.
- If no @i{parent-types} are supplied,
- the @i{parent-types} default to @t{(condition)}.
- @i{default-initargs}---a @i{list} of @i{keyword/value pairs}.
- [Editorial Note by KMP: This is all mixed up as to which is a slot option and which is
- a main option. I'll sort that out. Also, some of this is implied
- by the bnf and needn't be stated explicitly.]
- @i{Slot-spec} -- the @i{name} of a @i{slot} or a @i{list}
- consisting of the @i{slot-name} followed by zero or more @i{slot-options}.
- @i{Slot-name} -- a slot name (a @i{symbol}),
- the @i{list} of a slot name, or the
- @i{list} of slot name/slot form pairs.
- @i{Option} -- Any of the following:
- @table @asis
- @item @t{:reader}
- @t{:reader} can be supplied more than once for a given @i{slot}
- and cannot be @b{nil}.
- @item @t{:writer}
- @t{:writer} can be supplied more than once for a given @i{slot}
- and must name a @i{generic function}.
- @item @t{:accessor}
- @t{:accessor} can be supplied more than once for a given @i{slot}
- and cannot be @b{nil}.
- @item @t{:allocation}
- @t{:allocation} can be supplied once at most for a given @i{slot}.
- The default if @t{:allocation} is not supplied is @t{:instance}.
- @item @t{:initarg}
- @t{:initarg} can be supplied more than once for a given @i{slot}.
- @item @t{:initform}
- @t{:initform} can be supplied once at most for a given @i{slot}.
- @item @t{:type}
- @t{:type} can be supplied once at most for a given @i{slot}.
- @item @t{:documentation}
- @t{:documentation} can be supplied once at most for a given @i{slot}.
- @item @t{:report}
- @t{:report} can be supplied once at most.
- @end table
- @subsubheading Description::
- @b{define-condition} defines a new condition type called @i{name},
- which is a @i{subtype} of
- the @i{type} or @i{types} named by
- @i{parent-type}.
- Each @i{parent-type} argument specifies a direct @i{supertype}
- of the new @i{condition}. The new @i{condition}
- inherits @i{slots} and @i{methods} from each of its direct
- @i{supertypes}, and so on.
- If a slot name/slot form pair is supplied,
- the slot form is a @i{form} that
- can be evaluated by @b{make-condition} to
- produce a default value when an explicit value is not provided. If no
- slot form
- is supplied, the contents of the @i{slot}
- is initialized in an
- @i{implementation-dependent} way.
- If the @i{type} being defined and some other
- @i{type} from which it inherits
- have a slot by the same name, only one slot is allocated in the
- @i{condition},
- but the supplied slot form overrides any slot form
- that might otherwise have been inherited from a @i{parent-type}. If no
- slot form is supplied, the inherited slot form (if any) is still visible.
- Accessors are created according to the same rules as used by
- @b{defclass}.
- A description of @i{slot-options} follows:
- @table @asis
- @item @t{:reader}
- The @t{:reader} slot option specifies that an @i{unqualified method} is
- to be defined on the @i{generic function} named by the argument
- to @t{:reader} to read the value of the given @i{slot}.
- @item @t{*}
- The @t{:initform} slot option is used to provide a default
- initial value form to be used in the initialization of the @i{slot}. This
- @i{form} is evaluated every time it is used to initialize the
- @i{slot}. The
- @i{lexical environment}
- in which this @i{form} is evaluated is the lexical
- @i{environment} in which the @b{define-condition}
- form was evaluated.
- Note that the @i{lexical environment} refers both to variables and to
- @i{functions}.
- For @i{local slots}, the @i{dynamic environment} is the dynamic
- @i{environment}
- in which @b{make-condition} was called; for
- @i{shared slots}, the @i{dynamic environment}
- is the @i{dynamic environment} in which the
- @b{define-condition} form was evaluated.
- [Reviewer Note by Barmar: Issue CLOS-CONDITIONS doesn't say this.]
- No implementation is permitted to extend the syntax of @b{define-condition}
- to allow @t{(@i{slot-name} @i{form})} as an abbreviation for
- @t{(@i{slot-name} :initform @i{form})}.
- @item @t{:initarg}
- The @t{:initarg} slot option declares an initialization
- argument named by its @i{symbol} argument
- and specifies that this
- initialization argument initializes the given @i{slot}. If the
- initialization argument has a value in the call to
- @b{initialize-instance}, the value is stored into the given @i{slot},
- and the slot's @t{:initform} slot option, if any, is not
- evaluated. If none of the initialization arguments specified for a
- given @i{slot} has a value, the @i{slot} is initialized according to the
- @t{:initform} slot option, if specified.
- @item @t{:type}
- The @t{:type} slot option specifies that the contents of the
- @i{slot} is always of the specified @i{type}. It effectively
- declares the result type of the reader generic function when applied
- to an @i{object} of this @i{condition} type.
- The consequences of attempting to store in a
- @i{slot} a value that
- does not satisfy the type of the @i{slot} is undefined.
- @item @t{:default-initargs}
- [Editorial Note by KMP: This is an option, not a slot option.]
- This option is treated the same as it would be @b{defclass}.
- @item @t{:documentation}
- [Editorial Note by KMP: This is both an option and a slot option.]
- The @t{:documentation} slot option provides a @i{documentation string}
- for the @i{slot}.
- @item @t{:report}
- [Editorial Note by KMP: This is an option, not a slot option.]
- @i{Condition} reporting is mediated through the @b{print-object}
- method for the @i{condition} type in question, with @b{*print-escape*}
- always being @b{nil}. Specifying @t{(:report @i{report-name})}
- in the definition of a condition type @t{C} is equivalent to:
- @example
- (defmethod print-object ((x c) stream)
- (if *print-escape* (call-next-method) (@i{report-name} x stream)))
- @end example
- If the value supplied by the argument to @t{:report} (@i{report-name})
- is a @i{symbol} or a @i{lambda expression},
- it must be acceptable to
- @b{function}. @t{(function @i{report-name})}
- is evaluated
- in the current @i{lexical environment}.
- It should return a @i{function}
- of two
- arguments, a @i{condition} and a @i{stream},
- that prints on the @i{stream} a
- description of the @i{condition}.
- This @i{function} is called whenever the
- @i{condition} is printed while @b{*print-escape*} is @b{nil}.
- If @i{report-name} is a @i{string}, it is a shorthand for
- @example
- (lambda (condition stream)
- (declare (ignore condition))
- (write-string @i{report-name} stream))
- @end example
- This option is processed after the new @i{condition} type has been defined,
- so use of the @i{slot} accessors within the @t{:report} function is permitted.
- If this option is not supplied, information about how to report this
- type of @i{condition} is inherited from the @i{parent-type}.
- @end table
- The consequences are unspecifed if an attempt is made to @i{read} a
- @i{slot} that has not been explicitly initialized and that has not
- been given a default value.
- The consequences are unspecified if an attempt is made to assign the
- @i{slots} by using @b{setf}.
- If a @b{define-condition} @i{form} appears as a @i{top level form},
- the @i{compiler} must make @i{name} recognizable as a valid @i{type} name,
- and it must be possible to reference the @i{condition} @i{type} as the
- @i{parent-type} of another @i{condition} @i{type} in a subsequent
- @b{define-condition} @i{form} in the @i{file} being compiled.
- @subsubheading Examples::
- The following form defines a condition of @i{type}
- @t{peg/hole-mismatch} which inherits from a condition type
- called @t{blocks-world-error}:
- @example
- (define-condition peg/hole-mismatch
- (blocks-world-error)
- ((peg-shape :initarg :peg-shape
- :reader peg/hole-mismatch-peg-shape)
- (hole-shape :initarg :hole-shape
- :reader peg/hole-mismatch-hole-shape))
- (:report (lambda (condition stream)
- (format stream "A ~A peg cannot go in a ~A hole."
- (peg/hole-mismatch-peg-shape condition)
- (peg/hole-mismatch-hole-shape condition)))))
- @end example
- The new type has slots @t{peg-shape} and @t{hole-shape},
- so @b{make-condition} accepts @t{:peg-shape} and @t{:hole-shape} keywords.
- The @i{readers} @t{peg/hole-mismatch-peg-shape} and @t{peg/hole-mismatch-hole-shape}
- apply to objects of this type, as illustrated in the @t{:report} information.
- The following form defines a @i{condition} @i{type} named @t{machine-error}
- which inherits from @b{error}:
- @example
- (define-condition machine-error
- (error)
- ((machine-name :initarg :machine-name
- :reader machine-error-machine-name))
- (:report (lambda (condition stream)
- (format stream "There is a problem with ~A."
- (machine-error-machine-name condition)))))
- @end example
- Building on this definition, a new error condition can be defined which
- is a subtype of @t{machine-error} for use when machines are not available:
- @example
- (define-condition machine-not-available-error (machine-error) ()
- (:report (lambda (condition stream)
- (format stream "The machine ~A is not available."
- (machine-error-machine-name condition)))))
- @end example
- This defines a still more specific condition, built upon
- @t{machine-not-available-error}, which provides a slot initialization form
- for @t{machine-name} but which does not provide any new slots or report
- information. It just gives the @t{machine-name} slot a default initialization:
- @example
- (define-condition my-favorite-machine-not-available-error
- (machine-not-available-error)
- ((machine-name :initform "mc.lcs.mit.edu")))
- @end example
- Note that since no @t{:report} clause was given, the information
- inherited from @t{machine-not-available-error} is used to
- report this type of condition.
- @example
- (define-condition ate-too-much (error)
- ((person :initarg :person :reader ate-too-much-person)
- (weight :initarg :weight :reader ate-too-much-weight)
- (kind-of-food :initarg :kind-of-food
- :reader :ate-too-much-kind-of-food)))
- @result{} ATE-TOO-MUCH
- (define-condition ate-too-much-ice-cream (ate-too-much)
- ((kind-of-food :initform 'ice-cream)
- (flavor :initarg :flavor
- :reader ate-too-much-ice-cream-flavor
- :initform 'vanilla ))
- (:report (lambda (condition stream)
- (format stream "~A ate too much ~A ice-cream"
- (ate-too-much-person condition)
- (ate-too-much-ice-cream-flavor condition)))))
- @result{} ATE-TOO-MUCH-ICE-CREAM
- (make-condition 'ate-too-much-ice-cream
- :person 'fred
- :weight 300
- :flavor 'chocolate)
- @result{} #<ATE-TOO-MUCH-ICE-CREAM 32236101>
- (format t "~A" *)
- @t{ |> } FRED ate too much CHOCOLATE ice-cream
- @result{} NIL
- @end example
- @subsubheading See Also::
- @ref{make-condition}
- ,
- @ref{defclass}
- , @ref{Condition System Concepts}
- @node make-condition, restart, define-condition, Conditions Dictionary
- @subsection make-condition [Function]
- @code{make-condition} @i{type {&rest} slot-initializations} @result{} @i{condition}
- @subsubheading Arguments and Values::
- @i{type}---a @i{type specifier} (for a @i{subtype} of @b{condition}).
- @i{slot-initializations}---an @i{initialization argument list}.
- @i{condition}---a @i{condition}.
- @subsubheading Description::
- Constructs and returns a @i{condition} of type @i{type}
- using @i{slot-initializations} for the initial values of the slots.
- The newly created @i{condition} is returned.
- @subsubheading Examples::
- @example
- (defvar *oops-count* 0)
- (setq a (make-condition 'simple-error
- :format-control "This is your ~:R error."
- :format-arguments (list (incf *oops-count*))))
- @result{} #<SIMPLE-ERROR 32245104>
- (format t "~&~A~
- @t{ |> } This is your first error.
- @result{} NIL
- (error a)
- @t{ |> } Error: This is your first error.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return to Lisp Toplevel.
- @t{ |> } Debug>
- @end example
- @subsubheading Affected By::
- The set of defined @i{condition} @i{types}.
- @subsubheading See Also::
- @ref{define-condition}
- , @ref{Condition System Concepts}
- @node restart, compute-restarts, make-condition, Conditions Dictionary
- @subsection restart [System Class]
- @subsubheading Class Precedence List::
- @b{restart},
- @b{t}
- @subsubheading Description::
- An @i{object} of @i{type} @b{restart} represents a @i{function} that can be
- called to perform some form of recovery action, usually a transfer of control
- to an outer point in the running program.
- An @i{implementation} is free to implement a @i{restart} in whatever
- manner is most convenient; a @i{restart} has only @i{dynamic extent}
- relative to the scope of the binding @i{form} which @i{establishes} it.
- @node compute-restarts, find-restart, restart, Conditions Dictionary
- @subsection compute-restarts [Function]
- @code{compute-restarts} @i{{&optional} condition} @result{} @i{restarts}
- @subsubheading Arguments and Values::
- @i{condition}---a @i{condition} @i{object}, or @b{nil}.
- @i{restarts}---a @i{list} of @i{restarts}.
- @subsubheading Description::
- @b{compute-restarts} uses the dynamic state of the program to compute
- a @i{list} of the @i{restarts} which are currently active.
- The resulting @i{list} is ordered so that the innermost
- (more-recently established) restarts are nearer the head of the @i{list}.
- When @i{condition} is @i{non-nil}, only those @i{restarts}
- are considered that are either explicitly associated with that @i{condition},
- or not associated with any @i{condition}; that is, the excluded @i{restarts}
- are those that are associated with a non-empty set of @i{conditions} of
- which the given @i{condition} is not an @i{element}.
- If @i{condition} is @b{nil}, all @i{restarts} are considered.
- @b{compute-restarts} returns all
- @i{applicable restarts},
- including anonymous ones, even if some of them have the same name as
- others and would therefore not be found by @b{find-restart}
- when given a @i{symbol} argument.
- Implementations are permitted, but not required, to return @i{distinct}
- @i{lists} from repeated calls to @b{compute-restarts} while in
- the same dynamic environment.
- The consequences are undefined if the @i{list} returned by
- @b{compute-restarts} is every modified.
- @subsubheading Examples::
- @example
- ;; One possible way in which an interactive debugger might present
- ;; restarts to the user.
- (defun invoke-a-restart ()
- (let ((restarts (compute-restarts)))
- (do ((i 0 (+ i 1)) (r restarts (cdr r))) ((null r))
- (format t "~&~D: ~A~
- (let ((n nil) (k (length restarts)))
- (loop (when (and (typep n 'integer) (>= n 0) (< n k))
- (return t))
- (format t "~&Option: ")
- (setq n (read))
- (fresh-line))
- (invoke-restart-interactively (nth n restarts)))))
- (restart-case (invoke-a-restart)
- (one () 1)
- (two () 2)
- (nil () :report "Who knows?" 'anonymous)
- (one () 'I)
- (two () 'II))
- @t{ |> } 0: ONE
- @t{ |> } 1: TWO
- @t{ |> } 2: Who knows?
- @t{ |> } 3: ONE
- @t{ |> } 4: TWO
- @t{ |> } 5: Return to Lisp Toplevel.
- @t{ |> } Option: @b{|>>}@t{4}@b{<<|}
- @result{} II
- ;; Note that in addition to user-defined restart points, COMPUTE-RESTARTS
- ;; also returns information about any system-supplied restarts, such as
- ;; the "Return to Lisp Toplevel" restart offered above.
- @end example
- @subsubheading Affected By::
- Existing restarts.
- @subsubheading See Also::
- @ref{find-restart}
- ,
- @ref{invoke-restart}
- ,
- @ref{restart-bind}
- @node find-restart, invoke-restart, compute-restarts, Conditions Dictionary
- @subsection find-restart [Function]
- @code{find-restart} @i{identifier {&optional} condition}
- {restart}
- @subsubheading Arguments and Values::
- @i{identifier}---a @i{non-nil} @i{symbol}, or a @i{restart}.
- @i{condition}---a @i{condition} @i{object}, or @b{nil}.
- @i{restart}---a @i{restart} or @b{nil}.
- @subsubheading Description::
- @b{find-restart} searches for a particular @i{restart} in the
- current @i{dynamic environment}.
- When @i{condition} is @i{non-nil}, only those @i{restarts}
- are considered that are either explicitly associated with that @i{condition},
- or not associated with any @i{condition}; that is, the excluded @i{restarts}
- are those that are associated with a non-empty set of @i{conditions} of
- which the given @i{condition} is not an @i{element}.
- If @i{condition} is @b{nil}, all @i{restarts} are considered.
- If @i{identifier} is a @i{symbol}, then the innermost
- (most recently established) @i{applicable restart} with that @i{name} is returned.
- @b{nil} is returned if no such restart is found.
- If @i{identifier} is a currently active restart, then it is returned.
- Otherwise, @b{nil} is returned.
- @subsubheading Examples::
- @example
- (restart-case
- (let ((r (find-restart 'my-restart)))
- (format t "~S is named ~S" r (restart-name r)))
- (my-restart () nil))
- @t{ |> } #<RESTART 32307325> is named MY-RESTART
- @result{} NIL
- (find-restart 'my-restart)
- @result{} NIL
- @end example
- @subsubheading Affected By::
- Existing restarts.
- @b{restart-case}, @b{restart-bind}, @b{with-condition-restarts}.
- @subsubheading See Also::
- @ref{compute-restarts}
- @subsubheading Notes::
- @example
- (find-restart @i{identifier})
- @equiv{} (find @i{identifier} (compute-restarts) :key :restart-name)
- @end example
- Although anonymous restarts have a name of @b{nil},
- the consequences are unspecified if @b{nil} is given as an @i{identifier}.
- Occasionally, programmers lament that @b{nil} is not permissible as an
- @i{identifier} argument. In most such cases, @b{compute-restarts}
- can probably be used to simulate the desired effect.
- @node invoke-restart, invoke-restart-interactively, find-restart, Conditions Dictionary
- @subsection invoke-restart [Function]
- @code{invoke-restart} @i{restart {&rest} arguments} @result{} @i{@{@i{result}@}{*}}
- @subsubheading Arguments and Values::
- @i{restart}---a @i{restart designator}.
- @i{argument}---an @i{object}.
- @i{results}---the @i{values} returned by the @i{function}
- associated with @i{restart}, if that @i{function} returns.
- @subsubheading Description::
- Calls the @i{function} associated with @i{restart},
- passing @i{arguments} to it.
- @i{Restart} must be valid in the current @i{dynamic environment}.
- @subsubheading Examples::
- @example
- (defun add3 (x) (check-type x number) (+ x 3))
- (foo 'seven)
- @t{ |> } Error: The value SEVEN was not of type NUMBER.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a different value to use.
- @t{ |> } 2: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{(invoke-restart 'store-value 7)}@b{<<|}
- @result{} 10
- @end example
- @subsubheading Side Effects::
- A non-local transfer of control might be done by the restart.
- @subsubheading Affected By::
- Existing restarts.
- @subsubheading Exceptional Situations::
- If @i{restart} is not valid, an error of @i{type} @b{control-error} is signaled.
- @subsubheading See Also::
- @ref{find-restart}
- ,
- @ref{restart-bind}
- ,
- @ref{restart-case}
- ,
- @ref{invoke-restart-interactively}
- @subsubheading Notes::
- The most common use for @b{invoke-restart} is in a @i{handler}.
- It might be used explicitly, or implicitly through @b{invoke-restart-interactively}
- or a @i{restart function}.
- @i{Restart functions} call @b{invoke-restart}, not vice versa. That is,
- @i{invoke-restart} provides primitive functionality, and @i{restart functions}
- are non-essential ``syntactic sugar.''
- @node invoke-restart-interactively, restart-bind, invoke-restart, Conditions Dictionary
- @subsection invoke-restart-interactively [Function]
- @code{invoke-restart-interactively} @i{restart} @result{} @i{@{@i{result}@}{*}}
- @subsubheading Arguments and Values::
- @i{restart}---a @i{restart designator}.
- @i{results}---the @i{values} returned by the @i{function}
- associated with @i{restart}, if that @i{function} returns.
- @subsubheading Description::
- @b{invoke-restart-interactively} calls the @i{function} associated
- with @i{restart}, prompting for any necessary arguments.
- If @i{restart} is a name, it must be valid in the current @i{dynamic environment}.
- @b{invoke-restart-interactively}
- prompts for arguments by executing
- the code provided in the @t{:interactive} keyword to
- @b{restart-case} or
- @t{:interactive-function} keyword to @b{restart-bind}.
- If no such options have been supplied in the corresponding
- @b{restart-bind} or @b{restart-case},
- then the consequences are undefined if the @i{restart} takes
- required arguments. If the arguments are optional, an argument list of
- @b{nil} is used.
- Once the arguments have been determined,
- @b{invoke-restart-interactively}
- executes the following:
- @example
- (apply #'invoke-restart @i{restart} @i{arguments})
- @end example
- @subsubheading Examples::
- @example
- (defun add3 (x) (check-type x number) (+ x 3))
- (add3 'seven)
- @t{ |> } Error: The value SEVEN was not of type NUMBER.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a different value to use.
- @t{ |> } 2: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{(invoke-restart-interactively 'store-value)}@b{<<|}
- @t{ |> } Type a form to evaluate and use: @b{|>>}@t{7}@b{<<|}
- @result{} 10
- @end example
- @subsubheading Side Effects::
- If prompting for arguments is necesary,
- some typeout may occur (on @i{query I/O}).
- A non-local transfer of control might be done by the restart.
- @subsubheading Affected By::
- @b{*query-io*}, active @i{restarts}
- @subsubheading Exceptional Situations::
- If @i{restart} is not valid, an error of @i{type} @b{control-error}
- is signaled.
- @subsubheading See Also::
- @ref{find-restart}
- ,
- @ref{invoke-restart}
- ,
- @ref{restart-case}
- ,
- @ref{restart-bind}
- @subsubheading Notes::
- @b{invoke-restart-interactively} is used internally by the debugger
- and may also be useful in implementing other portable, interactive debugging
- tools.
- @node restart-bind, restart-case, invoke-restart-interactively, Conditions Dictionary
- @subsection restart-bind [Macro]
- @code{restart-bind} @i{@r{(}@{{(}name function
- @{!@i{key-val-pair}@}{*}@r{)}@}{)}
- @{@i{form}@}{*}}@*
- @result{} @i{@{@i{result}@}{*}}
- @w{@i{key-val-pair} ::=@t{:interactive-function} {interactive-function} | }
- @w{ @t{:report-function} {report-function} | }
- @w{ @t{:test-function} {test-function}}
- @subsubheading Arguments and Values::
- @i{name}---a @i{symbol}; not evaluated.
- @i{function}---a @i{form}; evaluated.
- @i{forms}---an @i{implicit progn}.
- @i{interactive-function}---a @i{form}; evaluated.
- @i{report-function}---a @i{form}; evaluated.
- @i{test-function}---a @i{form}; evaluated.
- @i{results}---the @i{values} returned by the @i{forms}.
- @subsubheading Description::
- @b{restart-bind} executes the body of @i{forms}
- in a @i{dynamic environment} where @i{restarts} with the given @i{names} are in effect.
- If a @i{name} is @b{nil}, it indicates an anonymous restart;
- if a @i{name} is a @i{non-nil} @i{symbol}, it indicates a named restart.
- The @i{function}, @i{interactive-function}, and @i{report-function}
- are unconditionally evaluated in the current lexical and dynamic environment
- prior to evaluation of the body. Each of these @i{forms} must evaluate to
- a @i{function}.
- If @b{invoke-restart} is done on that restart,
- the @i{function} which resulted from evaluating @i{function}
- is called, in the @i{dynamic environment} of the @b{invoke-restart},
- with the @i{arguments} given to @b{invoke-restart}.
- The @i{function} may either perform a non-local transfer of control or may return normally.
- If the restart is invoked interactively from the debugger
- (using @b{invoke-restart-interactively}),
- the arguments are defaulted by calling the @i{function}
- which resulted from evaluating @i{interactive-function}.
- That @i{function} may optionally prompt interactively on @i{query I/O},
- and should return a @i{list} of arguments to be used by
- @b{invoke-restart-interactively} when invoking the restart.
- If a restart is invoked interactively but no @i{interactive-function} is used,
- then an argument list of @b{nil} is used. In that case, the @i{function}
- must be compatible with an empty argument list.
- If the restart is presented interactively (@i{e.g.}, by the debugger),
- the presentation is done by calling the @i{function} which resulted
- from evaluating @i{report-function}.
- This @i{function} must be a @i{function} of one argument, a @i{stream}.
- It is expected to print a description of the action that the restart takes
- to that @i{stream}.
- This @i{function} is called any time the restart is printed
- while @b{*print-escape*} is @b{nil}.
- In the case of interactive invocation,
- the result is dependent on the value of @t{:interactive-function}
- as follows.
- @table @asis
- @item @t{:interactive-function}
- @i{Value} is evaluated in the current lexical environment and
- should return a @i{function} of no arguments which constructs a
- @i{list} of arguments to be used by @b{invoke-restart-interactively}
- when invoking this restart. The @i{function} may prompt interactively
- using @i{query I/O} if necessary.
- @item @t{:report-function}
- @i{Value} is evaluated in the current lexical environment and
- should return a @i{function} of one argument, a @i{stream}, which
- prints on the @i{stream} a summary of the action that this restart
- takes. This @i{function} is called whenever the restart is
- reported (printed while @b{*print-escape*} is @b{nil}).
- If no @t{:report-function} option is provided, the manner in which the
- @i{restart} is reported is @i{implementation-dependent}.
- @item @t{:test-function}
- @i{Value} is evaluated in the current lexical environment and
- should return a @i{function} of one argument, a @i{condition}, which
- returns @i{true} if the restart is to be considered visible.
- @end table
- @subsubheading Affected By::
- @b{*query-io*}.
- @subsubheading See Also::
- @ref{restart-case}
- ,
- @ref{with-simple-restart}
- @subsubheading Notes::
- @b{restart-bind} is primarily intended to be used to implement
- @b{restart-case} and might be useful in implementing other
- macros. Programmers who are uncertain about whether to use @b{restart-case}
- or @b{restart-bind} should prefer @b{restart-case} for the cases where
- it is powerful enough, using @b{restart-bind} only in cases where its full
- generality is really needed.
- @node restart-case, restart-name, restart-bind, Conditions Dictionary
- @subsection restart-case [Macro]
- @code{restart-case} @i{restartable-form {@{!@i{clause}@}}} @result{} @i{@{@i{result}@}{*}}
- @w{@i{clause} ::=@r{(} case-name lambda-list }
- @w{ [[@t{:interactive} interactive-expression | @t{:report} report-expression | @t{:test} test-expression]] }
- @w{ @{@i{declaration}@}{*} @{@i{form}@}{*}@r{)}}
- @subsubheading Arguments and Values::
- @i{restartable-form}---a @i{form}.
- @i{case-name}---a @i{symbol} or @b{nil}.
- @i{lambda-list}---an @i{ordinary lambda list}.
- @i{interactive-expression}---a @i{symbol} or a @i{lambda expression}.
- @i{report-expression}---a @i{string},
- a @i{symbol},
- or a @i{lambda expression}.
- @i{test-expression}---a @i{symbol} or a @i{lambda expression}.
- @i{declaration}---a @b{declare} @i{expression}; not evaluated.
- @i{form}---a @i{form}.
- @i{results}---the @i{values} resulting from the @i{evaluation}
- of @i{restartable-form},
- or the @i{values} returned by the last @i{form}
- executed in a chosen @i{clause},
- or @b{nil}.
- @subsubheading Description::
- @b{restart-case} evaluates @i{restartable-form} in a @i{dynamic environment}
- where the clauses have special meanings as points to which control may be transferred.
- If @i{restartable-form} finishes executing and returns any values,
- all values returned are returned by @b{restart-case} and
- processing has completed. While @i{restartable-form} is executing, any code may
- transfer control to one of the clauses (see @b{invoke-restart}).
- If a transfer
- occurs, the forms in the body of that clause is evaluated and any values
- returned by the last such form are returned by
- @b{restart-case}.
- In this case, the
- dynamic state is unwound appropriately (so that the restarts established
- around the @i{restartable-form} are no longer active) prior to execution of the
- clause.
- If there are no @i{forms}
- in a selected clause, @b{restart-case} returns @b{nil}.
- If @i{case-name} is a @i{symbol}, it names this restart.
- It is possible to have more than one clause use the same @i{case-name}.
- In this case, the first clause with that name is found by @b{find-restart}.
- The other clauses are accessible using @b{compute-restarts}.
- Each @i{arglist} is an @i{ordinary lambda list} to be bound during the
- execution of its corresponding @i{forms}. These parameters are used
- by the @b{restart-case} clause to receive any necessary data from a call
- to @b{invoke-restart}.
- By default, @b{invoke-restart-interactively} passes no arguments and
- all arguments must be optional in order to accomodate interactive
- restarting. However, the arguments need not be optional if the
- @t{:interactive}
- keyword has been used to inform @b{invoke-restart-interactively}
- about how to compute a proper argument list.
- @i{Keyword} options have the following meaning.
- @table @asis
- @item @t{:interactive}
- The @i{value} supplied by @t{:interactive @i{value}}
- must be a suitable argument to @b{function}.
- @t{(function @i{value})} is evaluated in the current lexical
- environment. It should return a @i{function} of no arguments which
- returns arguments to be used by
- @b{invoke-restart-interactively} when it is invoked.
- @b{invoke-restart-interactively}
- is called in the dynamic
- environment available prior to any restart attempt, and uses
- @i{query I/O} for user interaction.
- If a restart is invoked interactively but no @t{:interactive} option
- was supplied, the argument list used in the invocation is the empty
- list.
- @item @t{:report}
- If the @i{value} supplied by @t{:report @i{value}}
- is a @i{lambda expression} or a @i{symbol}, it
- must be acceptable to @b{function}.
- @t{(function @i{value})} is evaluated in the current lexical
- environment. It should return a @i{function} of one
- argument, a @i{stream}, which prints on the @i{stream} a
- description of the restart. This @i{function} is called
- whenever the restart is printed while @b{*print-escape*} is @b{nil}.
- If @i{value} is a @i{string}, it is a shorthand for
- @example
- (lambda (stream) (write-string value stream))
- @end example
- If a named restart is asked to report but no report information has been
- supplied, the name of the restart is used in generating default report text.
- When @b{*print-escape*} is @b{nil}, the
- printer uses the report information for
- a restart. For example, a debugger might announce the action of typing
- a ``continue'' command by:
- @example
- (format t "~&~S -- ~A~
- @end example
- which might then display as something like:
- @example
- :CONTINUE -- Return to command level
- @end example
- The consequences are unspecified if an unnamed restart is specified
- but no @t{:report} option is provided.
- @item @t{:test}
- The @i{value} supplied by @t{:test @i{value}}
- must be a suitable argument to @b{function}.
- @t{(function @i{value})} is evaluated in the current lexical
- environment. It should return a @i{function} of one @i{argument}, the
- @i{condition}, that
- returns @i{true} if the restart is to be considered visible.
- The default for this option is equivalent to @t{(lambda (c) (declare (ignore c)) t)}.
- @end table
- If the @i{restartable-form} is a @i{list} whose @i{car} is any of
- the @i{symbols} @b{signal}, @b{error}, @b{cerror},
- or @b{warn} (or is a @i{macro form} which macroexpands into such a
- @i{list}), then @b{with-condition-restarts} is used implicitly
- to associate the indicated @i{restarts} with the @i{condition} to be
- signaled.
- @subsubheading Examples::
- @example
- (restart-case
- (handler-bind ((error #'(lambda (c)
- (declare (ignore condition))
- (invoke-restart 'my-restart 7))))
- (error "Foo."))
- (my-restart (&optional v) v))
- @result{} 7
- (define-condition food-error (error) ())
- @result{} FOOD-ERROR
- (define-condition bad-tasting-sundae (food-error)
- ((ice-cream :initarg :ice-cream :reader bad-tasting-sundae-ice-cream)
- (sauce :initarg :sauce :reader bad-tasting-sundae-sauce)
- (topping :initarg :topping :reader bad-tasting-sundae-topping))
- (:report (lambda (condition stream)
- (format stream "Bad tasting sundae with ~S, ~S, and ~S"
- (bad-tasting-sundae-ice-cream condition)
- (bad-tasting-sundae-sauce condition)
- (bad-tasting-sundae-topping condition)))))
- @result{} BAD-TASTING-SUNDAE
- (defun all-start-with-same-letter (symbol1 symbol2 symbol3)
- (let ((first-letter (char (symbol-name symbol1) 0)))
- (and (eql first-letter (char (symbol-name symbol2) 0))
- (eql first-letter (char (symbol-name symbol3) 0)))))
- @result{} ALL-START-WITH-SAME-LETTER
- (defun read-new-value ()
- (format t "Enter a new value: ")
- (multiple-value-list (eval (read))))
- @result{} READ-NEW-VALUE@page
- (defun verify-or-fix-perfect-sundae (ice-cream sauce topping)
- (do ()
- ((all-start-with-same-letter ice-cream sauce topping))
- (restart-case
- (error 'bad-tasting-sundae
- :ice-cream ice-cream
- :sauce sauce
- :topping topping)
- (use-new-ice-cream (new-ice-cream)
- :report "Use a new ice cream."
- :interactive read-new-value
- (setq ice-cream new-ice-cream))
- (use-new-sauce (new-sauce)
- :report "Use a new sauce."
- :interactive read-new-value
- (setq sauce new-sauce))
- (use-new-topping (new-topping)
- :report "Use a new topping."
- :interactive read-new-value
- (setq topping new-topping))))
- (values ice-cream sauce topping))
- @result{} VERIFY-OR-FIX-PERFECT-SUNDAE
- (verify-or-fix-perfect-sundae 'vanilla 'caramel 'cherry)
- @t{ |> } Error: Bad tasting sundae with VANILLA, CARAMEL, and CHERRY.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Use a new ice cream.
- @t{ |> } 2: Use a new sauce.
- @t{ |> } 3: Use a new topping.
- @t{ |> } 4: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @t{ |> } Use a new ice cream.
- @t{ |> } Enter a new ice cream: @b{|>>}@t{'chocolate}@b{<<|}
- @result{} CHOCOLATE, CARAMEL, CHERRY
- @end example
- @subsubheading See Also::
- @ref{restart-bind}
- ,
- @ref{with-simple-restart}
- .
- @subsubheading Notes::
- @example
- (restart-case @i{expression}
- (@i{name1} @i{arglist1} ...@i{options1}... . @i{body1})
- (@i{name2} @i{arglist2} ...@i{options2}... . @i{body2}))
- @end example
- is essentially equivalent to
- @example
- (block #1=#:g0001
- (let ((#2=#:g0002 nil))
- (tagbody
- (restart-bind ((name1 #'(lambda (&rest temp)
- (setq #2# temp)
- (go #3=#:g0003))
- ...@i{slightly-transformed-options1}...)
- (name2 #'(lambda (&rest temp)
- (setq #2# temp)
- (go #4=#:g0004))
- ...@i{slightly-transformed-options2}...))
- (return-from #1# @i{expression}))
- #3# (return-from #1#
- (apply #'(lambda @i{arglist1} . @i{body1}) #2#))
- #4# (return-from #1#
- (apply #'(lambda @i{arglist2} . @i{body2}) #2#)))))
- @end example
- Unnamed restarts are generally only useful interactively
- and an interactive option which has no description is of little value.
- Implementations are encouraged to warn if
- an unnamed restart is used and no report information
- is provided
- at compilation time.
- At runtime, this error might be noticed when entering
- the debugger. Since signaling an error would probably cause recursive
- entry into the debugger (causing yet another recursive error, etc.) it is
- suggested that the debugger print some indication of such problems when
- they occur but not actually signal errors.
- @example
- (restart-case (signal fred)
- (a ...)
- (b ...))
- @equiv{}
- (restart-case
- (with-condition-restarts fred
- (list (find-restart 'a)
- (find-restart 'b))
- (signal fred))
- (a ...)
- (b ...))
- @end example
- @node restart-name, with-condition-restarts, restart-case, Conditions Dictionary
- @subsection restart-name [Function]
- @code{restart-name} @i{restart} @result{} @i{name}
- @subsubheading Arguments and Values::
- @i{restart}---a @i{restart}.
- @i{name}---a @i{symbol}.
- @subsubheading Description::
- Returns the name of the @i{restart},
- or @b{nil} if the @i{restart} is not named.
- @subsubheading Examples::
- @example
- (restart-case
- (loop for restart in (compute-restarts)
- collect (restart-name restart))
- (case1 () :report "Return 1." 1)
- (nil () :report "Return 2." 2)
- (case3 () :report "Return 3." 3)
- (case1 () :report "Return 4." 4))
- @result{} (CASE1 NIL CASE3 CASE1 ABORT)
- ;; In the example above the restart named ABORT was not created
- ;; explicitly, but was implicitly supplied by the system.
- @end example
- @subsubheading See Also::
- @ref{compute-restarts}
- @ref{find-restart}
- @node with-condition-restarts, with-simple-restart, restart-name, Conditions Dictionary
- @subsection with-condition-restarts [Macro]
- @code{with-condition-restarts} @i{condition-form restarts-form @{@i{form}@}{*}}@*
- @result{} @i{@{@i{result}@}{*}}
- @subsubheading Arguments and Values::
- @i{condition-form}---a @i{form}; @i{evaluated} to produce a @i{condition}.
- @i{condition}---a @i{condition} @i{object} resulting from the
- @i{evaluation} of @i{condition-form}.
- @i{restart-form}---a @i{form}; @i{evaluated} to produce a @i{restart-list}.
- @i{restart-list}---a @i{list} of @i{restart} @i{objects} resulting
- from the @i{evaluation} of @i{restart-form}.
- @i{forms}---an @i{implicit progn}; evaluated.
- @i{results}---the @i{values} returned by @i{forms}.
- @subsubheading Description::
- First, the @i{condition-form} and @i{restarts-form} are @i{evaluated}
- in normal left-to-right order; the @i{primary values} yielded by these
- @i{evaluations} are respectively called the @i{condition}
- and the @i{restart-list}.
- Next, the @i{forms} are @i{evaluated} in a @i{dynamic environment}
- in which each @i{restart} in @i{restart-list} is associated with
- the @i{condition}. See @ref{Associating a Restart with a Condition}.
- @subsubheading See Also::
- @ref{restart-case}
- @subsubheading Notes::
- Usually this @i{macro} is not used explicitly in code,
- since @b{restart-case} handles most of the common cases
- in a way that is syntactically more concise.
- @node with-simple-restart, abort, with-condition-restarts, Conditions Dictionary
- @subsection with-simple-restart [Macro]
- @code{with-simple-restart} @i{@r{(}name format-control @{@i{format-argument}@}{*}@r{)}
- @{@i{form}@}{*}}@*
- @result{} @i{@{@i{result}@}{*}}
- @subsubheading Arguments and Values::
- @i{name}---a @i{symbol}.
- @i{format-control}---a @i{format control}.
- @i{format-argument}---an @i{object} (@i{i.e.}, a @i{format argument}).
- @i{forms}---an @i{implicit progn}.
- @i{results}---in the normal situation,
- the @i{values} returned by the @i{forms};
- in the exceptional situation where the @i{restart} named @i{name} is invoked,
- two values---@b{nil} and @b{t}.
- @subsubheading Description::
- @b{with-simple-restart} establishes a restart.
- If the restart designated by @i{name} is not invoked while executing @i{forms},
- all values returned by the last of @i{forms} are returned.
- If the restart designated by @i{name} is invoked,
- control is transferred to @b{with-simple-restart},
- which returns two values, @b{nil} and @b{t}.
- If @i{name} is @b{nil}, an anonymous restart is established.
- The @i{format-control} and @i{format-arguments} are used
- report the @i{restart}.
- @subsubheading Examples::
- @example
- (defun read-eval-print-loop (level)
- (with-simple-restart (abort "Exit command level ~D." level)
- (loop
- (with-simple-restart (abort "Return to command level ~D." level)
- (let ((form (prog2 (fresh-line) (read) (fresh-line))))
- (prin1 (eval form)))))))
- @result{} READ-EVAL-PRINT-LOOP
- (read-eval-print-loop 1)
- (+ 'a 3)
- @t{ |> } Error: The argument, A, to the function + was of the wrong type.
- @t{ |> } The function expected a number.
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Specify a value to use this time.
- @t{ |> } 2: Return to command level 1.
- @t{ |> } 3: Exit command level 1.
- @t{ |> } 4: Return to Lisp Toplevel.
- @end example
- @example
- (defun compute-fixnum-power-of-2 (x)
- (with-simple-restart (nil "Give up on computing 2{@t{^}}~D." x)
- (let ((result 1))
- (dotimes (i x result)
- (setq result (* 2 result))
- (unless (fixnump result)
- (error "Power of 2 is too large."))))))
- COMPUTE-FIXNUM-POWER-OF-2
- (defun compute-power-of-2 (x)
- (or (compute-fixnum-power-of-2 x) 'something big))
- COMPUTE-POWER-OF-2
- (compute-power-of-2 10)
- 1024
- (compute-power-of-2 10000)
- @t{ |> } Error: Power of 2 is too large.
- @t{ |> } To continue, type :CONTINUE followed by an option number.
- @t{ |> } 1: Give up on computing 2{@t{^}}10000.
- @t{ |> } 2: Return to Lisp Toplevel
- @t{ |> } Debug> @b{|>>}@t{:continue 1}@b{<<|}
- @result{} SOMETHING-BIG
- @end example
- @subsubheading See Also::
- @ref{restart-case}
- @subsubheading Notes::
- @b{with-simple-restart} is shorthand for one of the most
- common uses of @b{restart-case}.
- @b{with-simple-restart} could be defined by:
- @example
- (defmacro with-simple-restart ((restart-name format-control
- &rest format-arguments)
- &body forms)
- `(restart-case (progn ,@@forms)
- (,restart-name ()
- :report (lambda (stream)
- (format stream ,format-control ,@@format-arguments))
- (values nil t))))
- @end example
- Because the second return value is @b{t} in the exceptional case,
- it is common (but not required) to arrange for the second return value
- in the normal case to be missing or @b{nil} so that the two situations
- can be distinguished.
- @node abort, continue, with-simple-restart, Conditions Dictionary
- @subsection abort [Restart]
- @subsubheading Data Arguments Required::
- None.
- @subsubheading Description::
- The intent of the @b{abort} restart is to allow return to the
- innermost ``command level.'' Implementors are encouraged to make
- sure that there is always a restart named @b{abort}
- around any user code so that user code can call @b{abort}
- at any time and expect something reasonable to happen;
- exactly what the reasonable thing is may vary somewhat. Typically,
- in an interactive listener, the invocation of @b{abort}
- returns to the @i{Lisp reader} phase of the @i{Lisp read-eval-print loop},
- though in some batch or multi-processing
- situations there may be situations in which having it kill the running
- process is more appropriate.
- @subsubheading See Also::
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{invoke-restart}
- ,
- @ref{abort}
- (@i{function})
- @node continue, muffle-warning, abort, Conditions Dictionary
- @subsection continue [Restart]
- @subsubheading Data Arguments Required::
- None.
- @subsubheading Description::
- The @b{continue} @i{restart} is generally part of protocols where there is
- a single ``obvious'' way to continue, such as in
- @b{break} and @b{cerror}. Some
- user-defined protocols may also wish to incorporate it for similar reasons.
- In general, however, it is more reliable to design a special purpose restart
- with a name that more directly suits the particular application.
- @subsubheading Examples::
- @example
- (let ((x 3))
- (handler-bind ((error #'(lambda (c)
- (let ((r (find-restart 'continue c)))
- (when r (invoke-restart r))))))
- (cond ((not (floatp x))
- (cerror "Try floating it." "~D is not a float." x)
- (float x))
- (t x)))) @result{} 3.0
- @end example
- @subsubheading See Also::
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{invoke-restart}
- ,
- @ref{continue}
- (@i{function}),
- @ref{assert}
- ,
- @ref{cerror}
- @node muffle-warning, store-value, continue, Conditions Dictionary
- @subsection muffle-warning [Restart]
- @subsubheading Data Arguments Required::
- None.
- @subsubheading Description::
- This @i{restart} is established by @b{warn} so that @i{handlers}
- of @b{warning} @i{conditions} have a way to tell @b{warn}
- that a warning has already been dealt with and that no further action is warranted.
- @subsubheading Examples::
- @example
- (defvar *all-quiet* nil) @result{} *ALL-QUIET*
- (defvar *saved-warnings* '()) @result{} *SAVED-WARNINGS*
- (defun quiet-warning-handler (c)
- (when *all-quiet*
- (let ((r (find-restart 'muffle-warning c)))
- (when r
- (push c *saved-warnings*)
- (invoke-restart r)))))
- @result{} CUSTOM-WARNING-HANDLER
- (defmacro with-quiet-warnings (&body forms)
- `(let ((*all-quiet* t)
- (*saved-warnings* '()))
- (handler-bind ((warning #'quiet-warning-handler))
- ,@@forms
- *saved-warnings*)))
- @result{} WITH-QUIET-WARNINGS
- (setq saved
- (with-quiet-warnings
- (warn "Situation #1.")
- (let ((*all-quiet* nil))
- (warn "Situation #2."))
- (warn "Situation #3.")))
- @t{ |> } Warning: Situation #2.
- @result{} (#<SIMPLE-WARNING 42744421> #<SIMPLE-WARNING 42744365>)
- (dolist (s saved) (format t "~&~A~
- @t{ |> } Situation #3.
- @t{ |> } Situation #1.
- @result{} NIL
- @end example
- @subsubheading See Also::
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{invoke-restart}
- ,
- @ref{muffle-warning}
- (@i{function}),
- @ref{warn}
- @node store-value, use-value, muffle-warning, Conditions Dictionary
- @subsection store-value [Restart]
- @subsubheading Data Arguments Required::
- a value to use instead (on an ongoing basis).
- @subsubheading Description::
- The @b{store-value} @i{restart} is generally used by @i{handlers}
- trying to recover from errors of @i{types} such as @b{cell-error}
- or @b{type-error}, which may wish to supply a replacement datum to
- be stored permanently.
- @subsubheading Examples::
- @example
- (defun type-error-auto-coerce (c)
- (when (typep c 'type-error)
- (let ((r (find-restart 'store-value c)))
- (handler-case (let ((v (coerce (type-error-datum c)
- (type-error-expected-type c))))
- (invoke-restart r v))
- (error ()))))) @result{} TYPE-ERROR-AUTO-COERCE
- (let ((x 3))
- (handler-bind ((type-error #'type-error-auto-coerce))
- (check-type x float)
- x)) @result{} 3.0
- @end example
- @subsubheading See Also::
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{invoke-restart}
- ,
- @ref{store-value}
- (@i{function}),
- @b{ccase},
- @ref{check-type}
- ,
- @b{ctypecase},
- @ref{use-value}
- (@i{function} and @i{restart})
- @node use-value, abort, store-value, Conditions Dictionary
- @subsection use-value [Restart]
- @subsubheading Data Arguments Required::
- a value to use instead (once).
- @subsubheading Description::
- The @b{use-value} @i{restart} is generally used by @i{handlers} trying
- to recover from errors of @i{types} such as @b{cell-error},
- where the handler may wish to supply a replacement datum for one-time use.
- @subsubheading See Also::
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{invoke-restart}
- ,
- @ref{use-value}
- (@i{function}),
- @ref{store-value}
- (@i{function} and @i{restart})
- @node abort, , use-value, Conditions Dictionary
- @subsection abort, continue, muffle-warning, store-value, use-value [Function]
- @IRindex{abort}
- @IRindex{continue}
- @IRindex{muffle-warning}
- @IRindex{store-value}
- @IRindex{use-value}
- @code{abort} @i{{&optional} condition}
- @result{} #<NoValue>
- @code{continue} @i{{&optional} condition} @result{} @i{@b{nil}}
- @code{muffle-warning} @i{{&optional} condition}
- @result{} #<NoValue>
- @code{store-value} @i{value {&optional} condition} @result{} @i{@b{nil}}
- @code{use-value} @i{value {&optional} condition} @result{} @i{@b{nil}}
- @subsubheading Arguments and Values::
- @i{value}---an @i{object}.
- @i{condition}---a @i{condition} @i{object}, or @b{nil}.
- @subsubheading Description::
- Transfers control to the most recently established @i{applicable restart}
- having the same name as the function. That is,
- the @i{function} @b{abort} searches for an @i{applicable} @b{abort} @i{restart},
- the @i{function} @b{continue} searches for an @i{applicable} @b{continue} @i{restart},
- and so on.
- If no such @i{restart} exists,
- the functions
- @b{continue},
- @b{store-value},
- and @b{use-value}
- return @b{nil}, and
- the functions
- @b{abort}
- and @b{muffle-warning}
- signal an error of @i{type} @b{control-error}.
- When @i{condition} is @i{non-nil},
- only those @i{restarts} are considered that are
- either explicitly associated with that @i{condition},
- or not associated with any @i{condition};
- that is, the excluded @i{restarts} are
- those that are associated with a non-empty set of @i{conditions}
- of which the given @i{condition} is not an @i{element}.
- If @i{condition} is @b{nil}, all @i{restarts} are considered.
- @subsubheading Examples::
- @example
- ;;; Example of the ABORT retart
- (defmacro abort-on-error (&body forms)
- `(handler-bind ((error #'abort))
- ,@@forms)) @result{} ABORT-ON-ERROR
- (abort-on-error (+ 3 5)) @result{} 8
- (abort-on-error (error "You lose."))
- @t{ |> } Returned to Lisp Top Level.
- ;;; Example of the CONTINUE restart
- (defun real-sqrt (n)
- (when (minusp n)
- (setq n (- n))
- (cerror "Return sqrt(~D) instead." "Tried to take sqrt(-~D)." n))
- (sqrt n))
- (real-sqrt 4) @result{} 2
- (real-sqrt -9)
- @t{ |> } Error: Tried to take sqrt(-9).
- @t{ |> } To continue, type :CONTINUE followed by an option number:
- @t{ |> } 1: Return sqrt(9) instead.
- @t{ |> } 2: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{(continue)}@b{<<|}
- @t{ |> } Return sqrt(9) instead.
- @result{} 3
- (handler-bind ((error #'(lambda (c) (continue))))
- (real-sqrt -9)) @result{} 3
- ;;; Example of the MUFFLE-WARNING restart
- (defun count-down (x)
- (do ((counter x (1- counter)))
- ((= counter 0) 'done)
- (when (= counter 1)
- (warn "Almost done"))
- (format t "~&~D~
- @result{} COUNT-DOWN
- (count-down 3)
- @t{ |> } 3
- @t{ |> } 2
- @t{ |> } Warning: Almost done
- @t{ |> } 1
- @result{} DONE
- (defun ignore-warnings-while-counting (x)
- (handler-bind ((warning #'ignore-warning))
- (count-down x)))
- @result{} IGNORE-WARNINGS-WHILE-COUNTING
- (defun ignore-warning (condition)
- (declare (ignore condition))
- (muffle-warning))
- @result{} IGNORE-WARNING
- (ignore-warnings-while-counting 3)
- @t{ |> } 3
- @t{ |> } 2
- @t{ |> } 1
- @result{} DONE
- ;;; Example of the STORE-VALUE and USE-VALUE restarts
- (defun careful-symbol-value (symbol)
- (check-type symbol symbol)
- (restart-case (if (boundp symbol)
- (return-from careful-symbol-value
- (symbol-value symbol))
- (error 'unbound-variable
- :name symbol))
- (use-value (value)
- :report "Specify a value to use this time."
- value)
- (store-value (value)
- :report "Specify a value to store and use in the future."
- (setf (symbol-value symbol) value))))
- (setq a 1234) @result{} 1234
- (careful-symbol-value 'a) @result{} 1234
- (makunbound 'a) @result{} A
- (careful-symbol-value 'a)
- @t{ |> } Error: A is not bound.
- @t{ |> } To continue, type :CONTINUE followed by an option number.
- @t{ |> } 1: Specify a value to use this time.
- @t{ |> } 2: Specify a value to store and use in the future.
- @t{ |> } 3: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{(use-value 12)}@b{<<|}
- @result{} 12
- (careful-symbol-value 'a)
- @t{ |> } Error: A is not bound.
- @t{ |> } To continue, type :CONTINUE followed by an option number.
- @t{ |> } 1: Specify a value to use this time.
- @t{ |> } 2: Specify a value to store and use in the future.
- @t{ |> } 3: Return to Lisp Toplevel.
- @t{ |> } Debug> @b{|>>}@t{(store-value 24)}@b{<<|}
- @result{} 24
- (careful-symbol-value 'a)
- @result{} 24
- ;;; Example of the USE-VALUE restart
- (defun add-symbols-with-default (default &rest symbols)
- (handler-bind ((sys:unbound-symbol
- #'(lambda (c)
- (declare (ignore c))
- (use-value default))))
- (apply #'+ (mapcar #'careful-symbol-value symbols))))
- @result{} ADD-SYMBOLS-WITH-DEFAULT
- (setq x 1 y 2) @result{} 2
- (add-symbols-with-default 3 'x 'y 'z) @result{} 6
- @end example
- @subsubheading Side Effects::
- A transfer of control may occur if an appropriate @i{restart} is available,
- or (in the case of the @i{function} @b{abort} or the @i{function} @b{muffle-warning})
- execution may be stopped.
- @subsubheading Affected By::
- Each of these functions can be affected by
- the presence of a @i{restart} having the same name.
- @subsubheading Exceptional Situations::
- If an appropriate @b{abort} @i{restart}
- is not available for the @i{function} @b{abort},
- or an appropriate @b{muffle-warning} @i{restart}
- is not available for the @i{function} @b{muffle-warning},
- an error of @i{type} @b{control-error} is signaled.
- @subsubheading See Also::
- @ref{invoke-restart}
- ,
- @ref{Restarts},
- @ref{Interfaces to Restarts},
- @ref{assert}
- ,
- @b{ccase},
- @ref{cerror}
- ,
- @ref{check-type}
- ,
- @b{ctypecase},
- @ref{use-value}
- ,
- @ref{warn}
- @subsubheading Notes::
- @example
- (abort condition) @equiv{} (invoke-restart 'abort)
- (muffle-warning) @equiv{} (invoke-restart 'muffle-warning)
- (continue) @equiv{} (let ((r (find-restart 'continue))) (if r (invoke-restart r)))
- (use-value @i{x}) @equiv{} (let ((r (find-restart 'use-value))) (if r (invoke-restart r @i{x})))
- (store-value x) @equiv{} (let ((r (find-restart 'store-value))) (if r (invoke-restart r @i{x})))
- @end example
- No functions defined in this specification are required to provide
- a @b{use-value} @i{restart}.
- @c end of including dict-conditions
- @c %**end of chapter
|