1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187 |
- @c -*-texinfo-*-
- @c This is part of the GNU Guile Reference Manual.
- @c Copyright (C) 1996, 1997, 2000-2004, 2006, 2007-2014, 2017, 2018, 2019, 2020
- @c Free Software Foundation, Inc.
- @c See the file guile.texi for copying conditions.
- @node SRFI Support
- @section SRFI Support Modules
- @cindex SRFI
- SRFI is an acronym for Scheme Request For Implementation. The SRFI
- documents define a lot of syntactic and procedure extensions to standard
- Scheme as defined in R5RS.
- Guile has support for a number of SRFIs. This chapter gives an overview
- over the available SRFIs and some usage hints. For complete
- documentation, design rationales and further examples, we advise you to
- get the relevant SRFI documents from the SRFI home page
- @url{http://srfi.schemers.org/}.
- @menu
- * About SRFI Usage:: What to know about Guile's SRFI support.
- * SRFI-0:: cond-expand
- * SRFI-1:: List library.
- * SRFI-2:: and-let*.
- * SRFI-4:: Homogeneous numeric vector datatypes.
- * SRFI-6:: Basic String Ports.
- * SRFI-8:: receive.
- * SRFI-9:: define-record-type.
- * SRFI-10:: Hash-Comma Reader Extension.
- * SRFI-11:: let-values and let*-values.
- * SRFI-13:: String library.
- * SRFI-14:: Character-set library.
- * SRFI-16:: case-lambda
- * SRFI-17:: Generalized set!
- * SRFI-18:: Multithreading support
- * SRFI-19:: Time/Date library.
- * SRFI-23:: Error reporting
- * SRFI-26:: Specializing parameters
- * SRFI-27:: Sources of Random Bits
- * SRFI-28:: Basic format strings.
- * SRFI-30:: Nested multi-line block comments
- * SRFI-31:: A special form `rec' for recursive evaluation
- * SRFI-34:: Exception handling.
- * SRFI-35:: Conditions.
- * SRFI-37:: args-fold program argument processor
- * SRFI-38:: External Representation for Data With Shared Structure
- * SRFI-39:: Parameter objects
- * SRFI-41:: Streams.
- * SRFI-42:: Eager comprehensions
- * SRFI-43:: Vector Library.
- * SRFI-45:: Primitives for expressing iterative lazy algorithms
- * SRFI-46:: Basic syntax-rules Extensions.
- * SRFI-55:: Requiring Features.
- * SRFI-60:: Integers as bits.
- * SRFI-61:: A more general `cond' clause
- * SRFI-62:: S-expression comments.
- * SRFI-64:: A Scheme API for test suites.
- * SRFI-67:: Compare procedures
- * SRFI-69:: Basic hash tables.
- * SRFI-71:: Extended let-syntax for multiple values.
- * SRFI-87:: => in case clauses.
- * SRFI-88:: Keyword objects.
- * SRFI-98:: Accessing environment variables.
- * SRFI-105:: Curly-infix expressions.
- * SRFI-111:: Boxes.
- * SRFI-119:: Wisp: simpler indentation-sensitive Scheme.
- * SRFI-171:: Transducers
- @end menu
- @node About SRFI Usage
- @subsection About SRFI Usage
- @c FIXME::martin: Review me!
- SRFI support in Guile is currently implemented partly in the core
- library, and partly as add-on modules. That means that some SRFIs are
- automatically available when the interpreter is started, whereas the
- other SRFIs require you to use the appropriate support module
- explicitly.
- There are several reasons for this inconsistency. First, the feature
- checking syntactic form @code{cond-expand} (@pxref{SRFI-0}) must be
- available immediately, because it must be there when the user wants to
- check for the Scheme implementation, that is, before she can know that
- it is safe to use @code{use-modules} to load SRFI support modules. The
- second reason is that some features defined in SRFIs had been
- implemented in Guile before the developers started to add SRFI
- implementations as modules (for example SRFI-13 (@pxref{SRFI-13})). In
- the future, it is possible that SRFIs in the core library might be
- factored out into separate modules, requiring explicit module loading
- when they are needed. So you should be prepared to have to use
- @code{use-modules} someday in the future to access SRFI-13 bindings. If
- you want, you can do that already. We have included the module
- @code{(srfi srfi-13)} in the distribution, which currently does nothing,
- but ensures that you can write future-safe code.
- Generally, support for a specific SRFI is made available by using
- modules named @code{(srfi srfi-@var{number})}, where @var{number} is the
- number of the SRFI needed. Another possibility is to use the command
- line option @code{--use-srfi}, which will load the necessary modules
- automatically (@pxref{Invoking Guile}).
- @node SRFI-0
- @subsection SRFI-0 - cond-expand
- @cindex SRFI-0
- This SRFI lets a portable Scheme program test for the presence of
- certain features, and adapt itself by using different blocks of code,
- or fail if the necessary features are not available. There's no
- module to load, this is in the Guile core.
- A program designed only for Guile will generally not need this
- mechanism, such a program can of course directly use the various
- documented parts of Guile.
- @deffn syntax cond-expand (feature body@dots{}) @dots{}
- Expand to the @var{body} of the first clause whose @var{feature}
- specification is satisfied. It is an error if no @var{feature} is
- satisfied.
- Features are symbols such as @code{srfi-1}, and a feature
- specification can use @code{and}, @code{or} and @code{not} forms to
- test combinations. The last clause can be an @code{else}, to be used
- if no other passes.
- For example, define a private version of @code{alist-cons} if SRFI-1
- is not available.
- @example
- (cond-expand (srfi-1
- )
- (else
- (define (alist-cons key val alist)
- (cons (cons key val) alist))))
- @end example
- Or demand a certain set of SRFIs (list operations, string ports,
- @code{receive} and string operations), failing if they're not
- available.
- @example
- (cond-expand ((and srfi-1 srfi-6 srfi-8 srfi-13)
- ))
- @end example
- @end deffn
- @noindent
- The Guile core has the following features,
- @example
- guile
- guile-2 ;; starting from Guile 2.x
- guile-2.2 ;; starting from Guile 2.2
- guile-3 ;; starting from Guile 3.x
- guile-3.0 ;; starting from Guile 3.0
- r5rs
- r6rs
- r7rs
- exact-closed ieee-float full-unicode ratios ;; R7RS features
- srfi-0
- srfi-4
- srfi-6
- srfi-13
- srfi-14
- srfi-16
- srfi-23
- srfi-30
- srfi-39
- srfi-46
- srfi-55
- srfi-61
- srfi-62
- srfi-87
- srfi-105
- @end example
- Other SRFI feature symbols are defined once their code has been loaded
- with @code{use-modules}, since only then are their bindings available.
- The @samp{--use-srfi} command line option (@pxref{Invoking Guile}) is
- a good way to load SRFIs to satisfy @code{cond-expand} when running a
- portable program.
- Testing the @code{guile} feature allows a program to adapt itself to
- the Guile module system, but still run on other Scheme systems. For
- example the following demands SRFI-8 (@code{receive}), but also knows
- how to load it with the Guile mechanism.
- @example
- (cond-expand (srfi-8
- )
- (guile
- (use-modules (srfi srfi-8))))
- @end example
- @cindex @code{guile-2} SRFI-0 feature
- @cindex portability between 2.0 and older versions
- Likewise, testing the @code{guile-2} feature allows code to be portable
- between Guile 2.@var{x} and previous versions of Guile. For instance, it
- makes it possible to write code that accounts for Guile 2.@var{x}'s compiler,
- yet be correctly interpreted on 1.8 and earlier versions:
- @example
- (cond-expand (guile-2 (eval-when (compile)
- ;; This must be evaluated at compile time.
- (fluid-set! current-reader my-reader)))
- (guile
- ;; Earlier versions of Guile do not have a
- ;; separate compilation phase.
- (fluid-set! current-reader my-reader)))
- @end example
- It should be noted that @code{cond-expand} is separate from the
- @code{*features*} mechanism (@pxref{Feature Tracking}), feature
- symbols in one are unrelated to those in the other.
- @node SRFI-1
- @subsection SRFI-1 - List library
- @cindex SRFI-1
- @cindex list
- @c FIXME::martin: Review me!
- The list library defined in SRFI-1 contains a lot of useful list
- processing procedures for construction, examining, destructuring and
- manipulating lists and pairs.
- Since SRFI-1 also defines some procedures which are already contained
- in R5RS and thus are supported by the Guile core library, some list
- and pair procedures which appear in the SRFI-1 document may not appear
- in this section. So when looking for a particular list/pair
- processing procedure, you should also have a look at the sections
- @ref{Lists} and @ref{Pairs}.
- @menu
- * SRFI-1 Constructors:: Constructing new lists.
- * SRFI-1 Predicates:: Testing list for specific properties.
- * SRFI-1 Selectors:: Selecting elements from lists.
- * SRFI-1 Length Append etc:: Length calculation and list appending.
- * SRFI-1 Fold and Map:: Higher-order list processing.
- * SRFI-1 Filtering and Partitioning:: Filter lists based on predicates.
- * SRFI-1 Searching:: Search for elements.
- * SRFI-1 Deleting:: Delete elements from lists.
- * SRFI-1 Association Lists:: Handle association lists.
- * SRFI-1 Set Operations:: Use lists for representing sets.
- @end menu
- @node SRFI-1 Constructors
- @subsubsection Constructors
- @cindex list constructor
- @c FIXME::martin: Review me!
- New lists can be constructed by calling one of the following
- procedures.
- @deffn {Scheme Procedure} xcons d a
- Like @code{cons}, but with interchanged arguments. Useful mostly when
- passed to higher-order procedures.
- @end deffn
- @deffn {Scheme Procedure} list-tabulate n init-proc
- Return an @var{n}-element list, where each list element is produced by
- applying the procedure @var{init-proc} to the corresponding list
- index. The order in which @var{init-proc} is applied to the indices
- is not specified.
- @end deffn
- @deffn {Scheme Procedure} list-copy lst
- Return a new list containing the elements of the list @var{lst}.
- This function differs from the core @code{list-copy} (@pxref{List
- Constructors}) in accepting improper lists too. And if @var{lst} is
- not a pair at all then it's treated as the final tail of an improper
- list and simply returned.
- @end deffn
- @deffn {Scheme Procedure} circular-list elt1 elt2 @dots{}
- Return a circular list containing the given arguments @var{elt1}
- @var{elt2} @dots{}.
- @end deffn
- @deffn {Scheme Procedure} iota count [start step]
- Return a list containing @var{count} numbers, starting from
- @var{start} and adding @var{step} each time. The default @var{start}
- is 0, the default @var{step} is 1. For example,
- @example
- (iota 6) @result{} (0 1 2 3 4 5)
- (iota 4 2.5 -2) @result{} (2.5 0.5 -1.5 -3.5)
- @end example
- This function takes its name from the corresponding primitive in the
- APL language.
- @end deffn
- @node SRFI-1 Predicates
- @subsubsection Predicates
- @cindex list predicate
- @c FIXME::martin: Review me!
- The procedures in this section test specific properties of lists.
- @deffn {Scheme Procedure} proper-list? obj
- Return @code{#t} if @var{obj} is a proper list, or @code{#f}
- otherwise. This is the same as the core @code{list?} (@pxref{List
- Predicates}).
- A proper list is a list which ends with the empty list @code{()} in
- the usual way. The empty list @code{()} itself is a proper list too.
- @example
- (proper-list? '(1 2 3)) @result{} #t
- (proper-list? '()) @result{} #t
- @end example
- @end deffn
- @deffn {Scheme Procedure} circular-list? obj
- Return @code{#t} if @var{obj} is a circular list, or @code{#f}
- otherwise.
- A circular list is a list where at some point the @code{cdr} refers
- back to a previous pair in the list (either the start or some later
- point), so that following the @code{cdr}s takes you around in a
- circle, with no end.
- @example
- (define x (list 1 2 3 4))
- (set-cdr! (last-pair x) (cddr x))
- x @result{} (1 2 3 4 3 4 3 4 ...)
- (circular-list? x) @result{} #t
- @end example
- @end deffn
- @deffn {Scheme Procedure} dotted-list? obj
- Return @code{#t} if @var{obj} is a dotted list, or @code{#f}
- otherwise.
- A dotted list is a list where the @code{cdr} of the last pair is not
- the empty list @code{()}. Any non-pair @var{obj} is also considered a
- dotted list, with length zero.
- @example
- (dotted-list? '(1 2 . 3)) @result{} #t
- (dotted-list? 99) @result{} #t
- @end example
- @end deffn
- It will be noted that any Scheme object passes exactly one of the
- above three tests @code{proper-list?}, @code{circular-list?} and
- @code{dotted-list?}. Non-lists are @code{dotted-list?}, finite lists
- are either @code{proper-list?} or @code{dotted-list?}, and infinite
- lists are @code{circular-list?}.
- @sp 1
- @deffn {Scheme Procedure} null-list? lst
- Return @code{#t} if @var{lst} is the empty list @code{()}, @code{#f}
- otherwise. If something else than a proper or circular list is passed
- as @var{lst}, an error is signaled. This procedure is recommended
- for checking for the end of a list in contexts where dotted lists are
- not allowed.
- @end deffn
- @deffn {Scheme Procedure} not-pair? obj
- Return @code{#t} is @var{obj} is not a pair, @code{#f} otherwise.
- This is shorthand notation @code{(not (pair? @var{obj}))} and is
- supposed to be used for end-of-list checking in contexts where dotted
- lists are allowed.
- @end deffn
- @deffn {Scheme Procedure} list= elt= list1 @dots{}
- Return @code{#t} if all argument lists are equal, @code{#f} otherwise.
- List equality is determined by testing whether all lists have the same
- length and the corresponding elements are equal in the sense of the
- equality predicate @var{elt=}. If no or only one list is given,
- @code{#t} is returned.
- @end deffn
- @node SRFI-1 Selectors
- @subsubsection Selectors
- @cindex list selector
- @c FIXME::martin: Review me!
- @deffn {Scheme Procedure} first pair
- @deffnx {Scheme Procedure} second pair
- @deffnx {Scheme Procedure} third pair
- @deffnx {Scheme Procedure} fourth pair
- @deffnx {Scheme Procedure} fifth pair
- @deffnx {Scheme Procedure} sixth pair
- @deffnx {Scheme Procedure} seventh pair
- @deffnx {Scheme Procedure} eighth pair
- @deffnx {Scheme Procedure} ninth pair
- @deffnx {Scheme Procedure} tenth pair
- These are synonyms for @code{car}, @code{cadr}, @code{caddr}, @dots{}.
- @end deffn
- @deffn {Scheme Procedure} car+cdr pair
- Return two values, the @sc{car} and the @sc{cdr} of @var{pair}.
- @end deffn
- @lisp
- (car+cdr '(0 1 2 3))
- @result{}
- 0
- (1 2 3)
- @end lisp
- @deffn {Scheme Procedure} take lst i
- @deffnx {Scheme Procedure} take! lst i
- Return a list containing the first @var{i} elements of @var{lst}.
- @code{take!} may modify the structure of the argument list @var{lst}
- in order to produce the result.
- @end deffn
- @deffn {Scheme Procedure} drop lst i
- Return a list containing all but the first @var{i} elements of
- @var{lst}.
- @end deffn
- @deffn {Scheme Procedure} take-right lst i
- Return a list containing the @var{i} last elements of @var{lst}.
- The return shares a common tail with @var{lst}.
- @end deffn
- @deffn {Scheme Procedure} drop-right lst i
- @deffnx {Scheme Procedure} drop-right! lst i
- Return a list containing all but the @var{i} last elements of
- @var{lst}.
- @code{drop-right} always returns a new list, even when @var{i} is
- zero. @code{drop-right!} may modify the structure of the argument
- list @var{lst} in order to produce the result.
- @end deffn
- @deffn {Scheme Procedure} split-at lst i
- @deffnx {Scheme Procedure} split-at! lst i
- Return two values, a list containing the first @var{i} elements of the
- list @var{lst} and a list containing the remaining elements.
- @code{split-at!} may modify the structure of the argument list
- @var{lst} in order to produce the result.
- @end deffn
- @deffn {Scheme Procedure} last lst
- Return the last element of the non-empty, finite list @var{lst}.
- @end deffn
- @node SRFI-1 Length Append etc
- @subsubsection Length, Append, Concatenate, etc.
- @c FIXME::martin: Review me!
- @deffn {Scheme Procedure} length+ lst
- Return the length of the argument list @var{lst}. When @var{lst} is a
- circular list, @code{#f} is returned.
- @end deffn
- @deffn {Scheme Procedure} concatenate list-of-lists
- @deffnx {Scheme Procedure} concatenate! list-of-lists
- Construct a list by appending all lists in @var{list-of-lists}.
- @code{concatenate!} may modify the structure of the given lists in
- order to produce the result.
- @code{concatenate} is the same as @code{(apply append
- @var{list-of-lists})}. It exists because some Scheme implementations
- have a limit on the number of arguments a function takes, which the
- @code{apply} might exceed. In Guile there is no such limit.
- @end deffn
- @deffn {Scheme Procedure} append-reverse rev-head tail
- @deffnx {Scheme Procedure} append-reverse! rev-head tail
- Reverse @var{rev-head}, append @var{tail} to it, and return the
- result. This is equivalent to @code{(append (reverse @var{rev-head})
- @var{tail})}, but its implementation is more efficient.
- @example
- (append-reverse '(1 2 3) '(4 5 6)) @result{} (3 2 1 4 5 6)
- @end example
- @code{append-reverse!} may modify @var{rev-head} in order to produce
- the result.
- @end deffn
- @deffn {Scheme Procedure} zip lst1 lst2 @dots{}
- Return a list as long as the shortest of the argument lists, where
- each element is a list. The first list contains the first elements of
- the argument lists, the second list contains the second elements, and
- so on.
- @end deffn
- @deffn {Scheme Procedure} unzip1 lst
- @deffnx {Scheme Procedure} unzip2 lst
- @deffnx {Scheme Procedure} unzip3 lst
- @deffnx {Scheme Procedure} unzip4 lst
- @deffnx {Scheme Procedure} unzip5 lst
- @code{unzip1} takes a list of lists, and returns a list containing the
- first elements of each list, @code{unzip2} returns two lists, the
- first containing the first elements of each lists and the second
- containing the second elements of each lists, and so on.
- @end deffn
- @deffn {Scheme Procedure} count pred lst1 lst2 @dots{}
- Return a count of the number of times @var{pred} returns true when
- called on elements from the given lists.
- @var{pred} is called with @var{N} parameters @code{(@var{pred}
- @var{elem1} @dots{} @var{elemN} )}, each element being from the
- corresponding list. The first call is with the first element of each
- list, the second with the second element from each, and so on.
- Counting stops when the end of the shortest list is reached. At least
- one list must be non-circular.
- @end deffn
- @node SRFI-1 Fold and Map
- @subsubsection Fold, Unfold & Map
- @cindex list fold
- @cindex list map
- @c FIXME::martin: Review me!
- @deffn {Scheme Procedure} fold proc init lst1 lst2 @dots{}
- @deffnx {Scheme Procedure} fold-right proc init lst1 lst2 @dots{}
- Apply @var{proc} to the elements of @var{lst1} @var{lst2} @dots{} to
- build a result, and return that result.
- Each @var{proc} call is @code{(@var{proc} @var{elem1} @var{elem2}
- @dots{} @var{previous})}, where @var{elem1} is from @var{lst1},
- @var{elem2} is from @var{lst2}, and so on. @var{previous} is the return
- from the previous call to @var{proc}, or the given @var{init} for the
- first call. If any list is empty, just @var{init} is returned.
- @code{fold} works through the list elements from first to last. The
- following shows a list reversal and the calls it makes,
- @example
- (fold cons '() '(1 2 3))
- (cons 1 '())
- (cons 2 '(1))
- (cons 3 '(2 1)
- @result{} (3 2 1)
- @end example
- @code{fold-right} works through the list elements from last to first,
- ie.@: from the right. So for example the following finds the longest
- string, and the last among equal longest,
- @example
- (fold-right (lambda (str prev)
- (if (> (string-length str) (string-length prev))
- str
- prev))
- ""
- '("x" "abc" "xyz" "jk"))
- @result{} "xyz"
- @end example
- If @var{lst1} @var{lst2} @dots{} have different lengths, @code{fold}
- stops when the end of the shortest is reached; @code{fold-right}
- commences at the last element of the shortest. Ie.@: elements past the
- length of the shortest are ignored in the other @var{lst}s. At least
- one @var{lst} must be non-circular.
- @code{fold} should be preferred over @code{fold-right} if the order of
- processing doesn't matter, or can be arranged either way, since
- @code{fold} is a little more efficient.
- The way @code{fold} builds a result from iterating is quite general,
- it can do more than other iterations like say @code{map} or
- @code{filter}. The following for example removes adjacent duplicate
- elements from a list,
- @example
- (define (delete-adjacent-duplicates lst)
- (fold-right (lambda (elem ret)
- (if (equal? elem (first ret))
- ret
- (cons elem ret)))
- (list (last lst))
- lst))
- (delete-adjacent-duplicates '(1 2 3 3 4 4 4 5))
- @result{} (1 2 3 4 5)
- @end example
- Clearly the same sort of thing can be done with a @code{for-each} and
- a variable in which to build the result, but a self-contained
- @var{proc} can be re-used in multiple contexts, where a
- @code{for-each} would have to be written out each time.
- @end deffn
- @deffn {Scheme Procedure} pair-fold proc init lst1 lst2 @dots{}
- @deffnx {Scheme Procedure} pair-fold-right proc init lst1 lst2 @dots{}
- The same as @code{fold} and @code{fold-right}, but apply @var{proc} to
- the pairs of the lists instead of the list elements.
- @end deffn
- @deffn {Scheme Procedure} reduce proc default lst
- @deffnx {Scheme Procedure} reduce-right proc default lst
- @code{reduce} is a variant of @code{fold}, where the first call to
- @var{proc} is on two elements from @var{lst}, rather than one element
- and a given initial value.
- If @var{lst} is empty, @code{reduce} returns @var{default} (this is
- the only use for @var{default}). If @var{lst} has just one element
- then that's the return value. Otherwise @var{proc} is called on the
- elements of @var{lst}.
- Each @var{proc} call is @code{(@var{proc} @var{elem} @var{previous})},
- where @var{elem} is from @var{lst} (the second and subsequent elements
- of @var{lst}), and @var{previous} is the return from the previous call
- to @var{proc}. The first element of @var{lst} is the @var{previous}
- for the first call to @var{proc}.
- For example, the following adds a list of numbers, the calls made to
- @code{+} are shown. (Of course @code{+} accepts multiple arguments
- and can add a list directly, with @code{apply}.)
- @example
- (reduce + 0 '(5 6 7)) @result{} 18
- (+ 6 5) @result{} 11
- (+ 7 11) @result{} 18
- @end example
- @code{reduce} can be used instead of @code{fold} where the @var{init}
- value is an ``identity'', meaning a value which under @var{proc}
- doesn't change the result, in this case 0 is an identity since
- @code{(+ 5 0)} is just 5. @code{reduce} avoids that unnecessary call.
- @code{reduce-right} is a similar variation on @code{fold-right},
- working from the end (ie.@: the right) of @var{lst}. The last element
- of @var{lst} is the @var{previous} for the first call to @var{proc},
- and the @var{elem} values go from the second last.
- @code{reduce} should be preferred over @code{reduce-right} if the
- order of processing doesn't matter, or can be arranged either way,
- since @code{reduce} is a little more efficient.
- @end deffn
- @deffn {Scheme Procedure} unfold p f g seed [tail-gen]
- @code{unfold} is defined as follows:
- @lisp
- (unfold p f g seed) =
- (if (p seed) (tail-gen seed)
- (cons (f seed)
- (unfold p f g (g seed))))
- @end lisp
- @table @var
- @item p
- Determines when to stop unfolding.
- @item f
- Maps each seed value to the corresponding list element.
- @item g
- Maps each seed value to next seed value.
- @item seed
- The state value for the unfold.
- @item tail-gen
- Creates the tail of the list; defaults to @code{(lambda (x) '())}.
- @end table
- @var{g} produces a series of seed values, which are mapped to list
- elements by @var{f}. These elements are put into a list in
- left-to-right order, and @var{p} tells when to stop unfolding.
- @end deffn
- @deffn {Scheme Procedure} unfold-right p f g seed [tail]
- Construct a list with the following loop.
- @lisp
- (let lp ((seed seed) (lis tail))
- (if (p seed) lis
- (lp (g seed)
- (cons (f seed) lis))))
- @end lisp
- @table @var
- @item p
- Determines when to stop unfolding.
- @item f
- Maps each seed value to the corresponding list element.
- @item g
- Maps each seed value to next seed value.
- @item seed
- The state value for the unfold.
- @item tail
- The tail of the list; defaults to @code{'()}.
- @end table
- @end deffn
- @deffn {Scheme Procedure} map f lst1 lst2 @dots{}
- Map the procedure over the list(s) @var{lst1}, @var{lst2}, @dots{} and
- return a list containing the results of the procedure applications.
- This procedure is extended with respect to R5RS, because the argument
- lists may have different lengths. The result list will have the same
- length as the shortest argument lists. The order in which @var{f}
- will be applied to the list element(s) is not specified.
- @end deffn
- @deffn {Scheme Procedure} for-each f lst1 lst2 @dots{}
- Apply the procedure @var{f} to each pair of corresponding elements of
- the list(s) @var{lst1}, @var{lst2}, @dots{}. The return value is not
- specified. This procedure is extended with respect to R5RS, because
- the argument lists may have different lengths. The shortest argument
- list determines the number of times @var{f} is called. @var{f} will
- be applied to the list elements in left-to-right order.
- @end deffn
- @deffn {Scheme Procedure} append-map f lst1 lst2 @dots{}
- @deffnx {Scheme Procedure} append-map! f lst1 lst2 @dots{}
- Equivalent to
- @lisp
- (apply append (map f clist1 clist2 ...))
- @end lisp
- and
- @lisp
- (apply append! (map f clist1 clist2 ...))
- @end lisp
- Map @var{f} over the elements of the lists, just as in the @code{map}
- function. However, the results of the applications are appended
- together to make the final result. @code{append-map} uses
- @code{append} to append the results together; @code{append-map!} uses
- @code{append!}.
- The dynamic order in which the various applications of @var{f} are
- made is not specified.
- @end deffn
- @deffn {Scheme Procedure} map! f lst1 lst2 @dots{}
- Linear-update variant of @code{map} -- @code{map!} is allowed, but not
- required, to alter the cons cells of @var{lst1} to construct the
- result list.
- The dynamic order in which the various applications of @var{f} are
- made is not specified. In the n-ary case, @var{lst2}, @var{lst3},
- @dots{} must have at least as many elements as @var{lst1}.
- @end deffn
- @deffn {Scheme Procedure} pair-for-each f lst1 lst2 @dots{}
- Like @code{for-each}, but applies the procedure @var{f} to the pairs
- from which the argument lists are constructed, instead of the list
- elements. The return value is not specified.
- @end deffn
- @deffn {Scheme Procedure} filter-map f lst1 lst2 @dots{}
- Like @code{map}, but only results from the applications of @var{f}
- which are true are saved in the result list.
- @end deffn
- @node SRFI-1 Filtering and Partitioning
- @subsubsection Filtering and Partitioning
- @cindex list filter
- @cindex list partition
- @c FIXME::martin: Review me!
- Filtering means to collect all elements from a list which satisfy a
- specific condition. Partitioning a list means to make two groups of
- list elements, one which contains the elements satisfying a condition,
- and the other for the elements which don't.
- The @code{filter} and @code{filter!} functions are implemented in the
- Guile core, @xref{List Modification}.
- @deffn {Scheme Procedure} partition pred lst
- @deffnx {Scheme Procedure} partition! pred lst
- Split @var{lst} into those elements which do and don't satisfy the
- predicate @var{pred}.
- The return is two values (@pxref{Multiple Values}), the first being a
- list of all elements from @var{lst} which satisfy @var{pred}, the
- second a list of those which do not.
- The elements in the result lists are in the same order as in @var{lst}
- but the order in which the calls @code{(@var{pred} elem)} are made on
- the list elements is unspecified.
- @code{partition} does not change @var{lst}, but one of the returned
- lists may share a tail with it. @code{partition!} may modify
- @var{lst} to construct its return.
- @end deffn
- @deffn {Scheme Procedure} remove pred lst
- @deffnx {Scheme Procedure} remove! pred lst
- Return a list containing all elements from @var{lst} which do not
- satisfy the predicate @var{pred}. The elements in the result list
- have the same order as in @var{lst}. The order in which @var{pred} is
- applied to the list elements is not specified.
- @code{remove!} is allowed, but not required to modify the structure of
- the input list.
- @end deffn
- @node SRFI-1 Searching
- @subsubsection Searching
- @cindex list search
- @c FIXME::martin: Review me!
- The procedures for searching elements in lists either accept a
- predicate or a comparison object for determining which elements are to
- be searched.
- @deffn {Scheme Procedure} find pred lst
- Return the first element of @var{lst} that satisfies the predicate
- @var{pred} and @code{#f} if no such element is found.
- @end deffn
- @deffn {Scheme Procedure} find-tail pred lst
- Return the first pair of @var{lst} whose @sc{car} satisfies the
- predicate @var{pred} and @code{#f} if no such element is found.
- @end deffn
- @deffn {Scheme Procedure} take-while pred lst
- @deffnx {Scheme Procedure} take-while! pred lst
- Return the longest initial prefix of @var{lst} whose elements all
- satisfy the predicate @var{pred}.
- @code{take-while!} is allowed, but not required to modify the input
- list while producing the result.
- @end deffn
- @deffn {Scheme Procedure} drop-while pred lst
- Drop the longest initial prefix of @var{lst} whose elements all
- satisfy the predicate @var{pred}.
- @end deffn
- @deffn {Scheme Procedure} span pred lst
- @deffnx {Scheme Procedure} span! pred lst
- @deffnx {Scheme Procedure} break pred lst
- @deffnx {Scheme Procedure} break! pred lst
- @code{span} splits the list @var{lst} into the longest initial prefix
- whose elements all satisfy the predicate @var{pred}, and the remaining
- tail. @code{break} inverts the sense of the predicate.
- @code{span!} and @code{break!} are allowed, but not required to modify
- the structure of the input list @var{lst} in order to produce the
- result.
- Note that the name @code{break} conflicts with the @code{break}
- binding established by @code{while} (@pxref{while do}). Applications
- wanting to use @code{break} from within a @code{while} loop will need
- to make a new define under a different name.
- @end deffn
- @deffn {Scheme Procedure} any pred lst1 lst2 @dots{}
- Test whether any set of elements from @var{lst1} @var{lst2} @dots{}
- satisfies @var{pred}. If so, the return value is the return value from
- the successful @var{pred} call, or if not, the return value is
- @code{#f}.
- If there are n list arguments, then @var{pred} must be a predicate
- taking n arguments. Each @var{pred} call is @code{(@var{pred}
- @var{elem1} @var{elem2} @dots{} )} taking an element from each
- @var{lst}. The calls are made successively for the first, second, etc.
- elements of the lists, stopping when @var{pred} returns non-@code{#f},
- or when the end of the shortest list is reached.
- The @var{pred} call on the last set of elements (i.e., when the end of
- the shortest list has been reached), if that point is reached, is a
- tail call.
- @end deffn
- @deffn {Scheme Procedure} every pred lst1 lst2 @dots{}
- Test whether every set of elements from @var{lst1} @var{lst2} @dots{}
- satisfies @var{pred}. If so, the return value is the return from the
- final @var{pred} call, or if not, the return value is @code{#f}.
- If there are n list arguments, then @var{pred} must be a predicate
- taking n arguments. Each @var{pred} call is @code{(@var{pred}
- @var{elem1} @var{elem2 @dots{}})} taking an element from each
- @var{lst}. The calls are made successively for the first, second, etc.
- elements of the lists, stopping if @var{pred} returns @code{#f}, or when
- the end of any of the lists is reached.
- The @var{pred} call on the last set of elements (i.e., when the end of
- the shortest list has been reached) is a tail call.
- If one of @var{lst1} @var{lst2} @dots{}is empty then no calls to
- @var{pred} are made, and the return value is @code{#t}.
- @end deffn
- @deffn {Scheme Procedure} list-index pred lst1 lst2 @dots{}
- Return the index of the first set of elements, one from each of
- @var{lst1} @var{lst2} @dots{}, which satisfies @var{pred}.
- @var{pred} is called as @code{(@var{elem1} @var{elem2 @dots{}})}.
- Searching stops when the end of the shortest @var{lst} is reached.
- The return index starts from 0 for the first set of elements. If no
- set of elements pass, then the return value is @code{#f}.
- @example
- (list-index odd? '(2 4 6 9)) @result{} 3
- (list-index = '(1 2 3) '(3 1 2)) @result{} #f
- @end example
- @end deffn
- @deffn {Scheme Procedure} member x lst [=]
- Return the first sublist of @var{lst} whose @sc{car} is equal to
- @var{x}. If @var{x} does not appear in @var{lst}, return @code{#f}.
- Equality is determined by @code{equal?}, or by the equality predicate
- @var{=} if given. @var{=} is called @code{(= @var{x} elem)},
- ie.@: with the given @var{x} first, so for example to find the first
- element greater than 5,
- @example
- (member 5 '(3 5 1 7 2 9) <) @result{} (7 2 9)
- @end example
- This version of @code{member} extends the core @code{member}
- (@pxref{List Searching}) by accepting an equality predicate.
- @end deffn
- @node SRFI-1 Deleting
- @subsubsection Deleting
- @cindex list delete
- @deffn {Scheme Procedure} delete x lst [=]
- @deffnx {Scheme Procedure} delete! x lst [=]
- Return a list containing the elements of @var{lst} but with those
- equal to @var{x} deleted. The returned elements will be in the same
- order as they were in @var{lst}.
- Equality is determined by the @var{=} predicate, or @code{equal?} if
- not given. An equality call is made just once for each element, but
- the order in which the calls are made on the elements is unspecified.
- The equality calls are always @code{(= x elem)}, ie.@: the given @var{x}
- is first. This means for instance elements greater than 5 can be
- deleted with @code{(delete 5 lst <)}.
- @code{delete} does not modify @var{lst}, but the return might share a
- common tail with @var{lst}. @code{delete!} may modify the structure
- of @var{lst} to construct its return.
- These functions extend the core @code{delete} and @code{delete!}
- (@pxref{List Modification}) in accepting an equality predicate. See
- also @code{lset-difference} (@pxref{SRFI-1 Set Operations}) for
- deleting multiple elements from a list.
- @end deffn
- @deffn {Scheme Procedure} delete-duplicates lst [=]
- @deffnx {Scheme Procedure} delete-duplicates! lst [=]
- Return a list containing the elements of @var{lst} but without
- duplicates.
- When elements are equal, only the first in @var{lst} is retained.
- Equal elements can be anywhere in @var{lst}, they don't have to be
- adjacent. The returned list will have the retained elements in the
- same order as they were in @var{lst}.
- Equality is determined by the @var{=} predicate, or @code{equal?} if
- not given. Calls @code{(= x y)} are made with element @var{x} being
- before @var{y} in @var{lst}. A call is made at most once for each
- combination, but the sequence of the calls across the elements is
- unspecified.
- @code{delete-duplicates} does not modify @var{lst}, but the return
- might share a common tail with @var{lst}. @code{delete-duplicates!}
- may modify the structure of @var{lst} to construct its return.
- In the worst case, this is an @math{O(N^2)} algorithm because it must
- check each element against all those preceding it. For long lists it
- is more efficient to sort and then compare only adjacent elements.
- @end deffn
- @node SRFI-1 Association Lists
- @subsubsection Association Lists
- @cindex association list
- @cindex alist
- @c FIXME::martin: Review me!
- Association lists are described in detail in section @ref{Association
- Lists}. The present section only documents the additional procedures
- for dealing with association lists defined by SRFI-1.
- @deffn {Scheme Procedure} assoc key alist [=]
- Return the pair from @var{alist} which matches @var{key}. This
- extends the core @code{assoc} (@pxref{Retrieving Alist Entries}) by
- taking an optional @var{=} comparison procedure.
- The default comparison is @code{equal?}. If an @var{=} parameter is
- given it's called @code{(@var{=} @var{key} @var{alistcar})}, i.e.@: the
- given target @var{key} is the first argument, and a @code{car} from
- @var{alist} is second.
- For example a case-insensitive string lookup,
- @example
- (assoc "yy" '(("XX" . 1) ("YY" . 2)) string-ci=?)
- @result{} ("YY" . 2)
- @end example
- @end deffn
- @deffn {Scheme Procedure} alist-cons key datum alist
- Cons a new association @var{key} and @var{datum} onto @var{alist} and
- return the result. This is equivalent to
- @lisp
- (cons (cons @var{key} @var{datum}) @var{alist})
- @end lisp
- @code{acons} (@pxref{Adding or Setting Alist Entries}) in the Guile
- core does the same thing.
- @end deffn
- @deffn {Scheme Procedure} alist-copy alist
- Return a newly allocated copy of @var{alist}, that means that the
- spine of the list as well as the pairs are copied.
- @end deffn
- @deffn {Scheme Procedure} alist-delete key alist [=]
- @deffnx {Scheme Procedure} alist-delete! key alist [=]
- Return a list containing the elements of @var{alist} but with those
- elements whose keys are equal to @var{key} deleted. The returned
- elements will be in the same order as they were in @var{alist}.
- Equality is determined by the @var{=} predicate, or @code{equal?} if
- not given. The order in which elements are tested is unspecified, but
- each equality call is made @code{(= key alistkey)}, i.e.@: the given
- @var{key} parameter is first and the key from @var{alist} second.
- This means for instance all associations with a key greater than 5 can
- be removed with @code{(alist-delete 5 alist <)}.
- @code{alist-delete} does not modify @var{alist}, but the return might
- share a common tail with @var{alist}. @code{alist-delete!} may modify
- the list structure of @var{alist} to construct its return.
- @end deffn
- @node SRFI-1 Set Operations
- @subsubsection Set Operations on Lists
- @cindex list set operation
- Lists can be used to represent sets of objects. The procedures in
- this section operate on such lists as sets.
- Note that lists are not an efficient way to implement large sets. The
- procedures here typically take time @math{@var{m}@cross{}@var{n}} when
- operating on @var{m} and @var{n} element lists. Other data structures
- like trees, bitsets (@pxref{Bit Vectors}) or hash tables (@pxref{Hash
- Tables}) are faster.
- All these procedures take an equality predicate as the first argument.
- This predicate is used for testing the objects in the list sets for
- sameness. This predicate must be consistent with @code{eq?}
- (@pxref{Equality}) in the sense that if two list elements are
- @code{eq?} then they must also be equal under the predicate. This
- simply means a given object must be equal to itself.
- @deffn {Scheme Procedure} lset<= = list @dots{}
- Return @code{#t} if each list is a subset of the one following it.
- I.e., @var{list1} is a subset of @var{list2}, @var{list2} is a subset of
- @var{list3}, etc., for as many lists as given. If only one list or no
- lists are given, the return value is @code{#t}.
- A list @var{x} is a subset of @var{y} if each element of @var{x} is
- equal to some element in @var{y}. Elements are compared using the
- given @var{=} procedure, called as @code{(@var{=} xelem yelem)}.
- @example
- (lset<= eq?) @result{} #t
- (lset<= eqv? '(1 2 3) '(1)) @result{} #f
- (lset<= eqv? '(1 3 2) '(4 3 1 2)) @result{} #t
- @end example
- @end deffn
- @deffn {Scheme Procedure} lset= = list @dots{}
- Return @code{#t} if all argument lists are set-equal. @var{list1} is
- compared to @var{list2}, @var{list2} to @var{list3}, etc., for as many
- lists as given. If only one list or no lists are given, the return
- value is @code{#t}.
- Two lists @var{x} and @var{y} are set-equal if each element of @var{x}
- is equal to some element of @var{y} and conversely each element of
- @var{y} is equal to some element of @var{x}. The order of the
- elements in the lists doesn't matter. Element equality is determined
- with the given @var{=} procedure, called as @code{(@var{=} xelem
- yelem)}, but exactly which calls are made is unspecified.
- @example
- (lset= eq?) @result{} #t
- (lset= eqv? '(1 2 3) '(3 2 1)) @result{} #t
- (lset= string-ci=? '("a" "A" "b") '("B" "b" "a")) @result{} #t
- @end example
- @end deffn
- @deffn {Scheme Procedure} lset-adjoin = list elem @dots{}
- Add to @var{list} any of the given @var{elem}s not already in the list.
- @var{elem}s are @code{cons}ed onto the start of @var{list} (so the
- return value shares a common tail with @var{list}), but the order that
- the @var{elem}s are added is unspecified.
- The given @var{=} procedure is used for comparing elements, called as
- @code{(@var{=} listelem elem)}, i.e., the second argument is one of
- the given @var{elem} parameters.
- @example
- (lset-adjoin eqv? '(1 2 3) 4 1 5) @result{} (5 4 1 2 3)
- @end example
- @end deffn
- @deffn {Scheme Procedure} lset-union = list @dots{}
- @deffnx {Scheme Procedure} lset-union! = list @dots{}
- Return the union of the argument list sets. The result is built by
- taking the union of @var{list1} and @var{list2}, then the union of
- that with @var{list3}, etc., for as many lists as given. For one list
- argument that list itself is the result, for no list arguments the
- result is the empty list.
- The union of two lists @var{x} and @var{y} is formed as follows. If
- @var{x} is empty then the result is @var{y}. Otherwise start with
- @var{x} as the result and consider each @var{y} element (from first to
- last). A @var{y} element not equal to something already in the result
- is @code{cons}ed onto the result.
- The given @var{=} procedure is used for comparing elements, called as
- @code{(@var{=} relem yelem)}. The first argument is from the result
- accumulated so far, and the second is from the list being union-ed in.
- But exactly which calls are made is otherwise unspecified.
- Notice that duplicate elements in @var{list1} (or the first non-empty
- list) are preserved, but that repeated elements in subsequent lists
- are only added once.
- @example
- (lset-union eqv?) @result{} ()
- (lset-union eqv? '(1 2 3)) @result{} (1 2 3)
- (lset-union eqv? '(1 2 1 3) '(2 4 5) '(5)) @result{} (5 4 1 2 1 3)
- @end example
- @code{lset-union} doesn't change the given lists but the result may
- share a tail with the first non-empty list. @code{lset-union!} can
- modify all of the given lists to form the result.
- @end deffn
- @deffn {Scheme Procedure} lset-intersection = list1 list2 @dots{}
- @deffnx {Scheme Procedure} lset-intersection! = list1 list2 @dots{}
- Return the intersection of @var{list1} with the other argument lists,
- meaning those elements of @var{list1} which are also in all of
- @var{list2} etc. For one list argument, just that list is returned.
- The test for an element of @var{list1} to be in the return is simply
- that it's equal to some element in each of @var{list2} etc. Notice
- this means an element appearing twice in @var{list1} but only once in
- each of @var{list2} etc will go into the return twice. The return has
- its elements in the same order as they were in @var{list1}.
- The given @var{=} procedure is used for comparing elements, called as
- @code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
- and the second is from one of the subsequent lists. But exactly which
- calls are made and in what order is unspecified.
- @example
- (lset-intersection eqv? '(x y)) @result{} (x y)
- (lset-intersection eqv? '(1 2 3) '(4 3 2)) @result{} (2 3)
- (lset-intersection eqv? '(1 1 2 2) '(1 2) '(2 1) '(2)) @result{} (2 2)
- @end example
- The return from @code{lset-intersection} may share a tail with
- @var{list1}. @code{lset-intersection!} may modify @var{list1} to form
- its result.
- @end deffn
- @deffn {Scheme Procedure} lset-difference = list1 list2 @dots{}
- @deffnx {Scheme Procedure} lset-difference! = list1 list2 @dots{}
- Return @var{list1} with any elements in @var{list2}, @var{list3} etc
- removed (ie.@: subtracted). For one list argument, just that list is
- returned.
- The given @var{=} procedure is used for comparing elements, called as
- @code{(@var{=} elem1 elemN)}. The first argument is from @var{list1}
- and the second from one of the subsequent lists. But exactly which
- calls are made and in what order is unspecified.
- @example
- (lset-difference eqv? '(x y)) @result{} (x y)
- (lset-difference eqv? '(1 2 3) '(3 1)) @result{} (2)
- (lset-difference eqv? '(1 2 3) '(3) '(2)) @result{} (1)
- @end example
- The return from @code{lset-difference} may share a tail with
- @var{list1}. @code{lset-difference!} may modify @var{list1} to form
- its result.
- @end deffn
- @deffn {Scheme Procedure} lset-diff+intersection = list1 list2 @dots{}
- @deffnx {Scheme Procedure} lset-diff+intersection! = list1 list2 @dots{}
- Return two values (@pxref{Multiple Values}), the difference and
- intersection of the argument lists as per @code{lset-difference} and
- @code{lset-intersection} above.
- For two list arguments this partitions @var{list1} into those elements
- of @var{list1} which are in @var{list2} and not in @var{list2}. (But
- for more than two arguments there can be elements of @var{list1} which
- are neither part of the difference nor the intersection.)
- One of the return values from @code{lset-diff+intersection} may share
- a tail with @var{list1}. @code{lset-diff+intersection!} may modify
- @var{list1} to form its results.
- @end deffn
- @deffn {Scheme Procedure} lset-xor = list @dots{}
- @deffnx {Scheme Procedure} lset-xor! = list @dots{}
- Return an XOR of the argument lists. For two lists this means those
- elements which are in exactly one of the lists. For more than two
- lists it means those elements which appear in an odd number of the
- lists.
- To be precise, the XOR of two lists @var{x} and @var{y} is formed by
- taking those elements of @var{x} not equal to any element of @var{y},
- plus those elements of @var{y} not equal to any element of @var{x}.
- Equality is determined with the given @var{=} procedure, called as
- @code{(@var{=} e1 e2)}. One argument is from @var{x} and the other
- from @var{y}, but which way around is unspecified. Exactly which
- calls are made is also unspecified, as is the order of the elements in
- the result.
- @example
- (lset-xor eqv? '(x y)) @result{} (x y)
- (lset-xor eqv? '(1 2 3) '(4 3 2)) @result{} (4 1)
- @end example
- The return from @code{lset-xor} may share a tail with one of the list
- arguments. @code{lset-xor!} may modify @var{list1} to form its
- result.
- @end deffn
- @node SRFI-2
- @subsection SRFI-2 - and-let*
- @cindex SRFI-2
- @noindent
- The following syntax can be obtained with
- @lisp
- (use-modules (srfi srfi-2))
- @end lisp
- or alternatively
- @lisp
- (use-modules (ice-9 and-let-star))
- @end lisp
- @deffn {library syntax} and-let* (clause @dots{}) body @dots{}
- A combination of @code{and} and @code{let*}.
- Each @var{clause} is evaluated in turn, and if @code{#f} is obtained
- then evaluation stops and @code{#f} is returned. If all are
- non-@code{#f} then @var{body} is evaluated and the last form gives the
- return value, or if @var{body} is empty then the result is @code{#t}.
- Each @var{clause} should be one of the following,
- @table @code
- @item (symbol expr)
- Evaluate @var{expr}, check for @code{#f}, and bind it to @var{symbol}.
- Like @code{let*}, that binding is available to subsequent clauses.
- @item (expr)
- Evaluate @var{expr} and check for @code{#f}.
- @item symbol
- Get the value bound to @var{symbol} and check for @code{#f}.
- @end table
- Notice that @code{(expr)} has an ``extra'' pair of parentheses, for
- instance @code{((eq? x y))}. One way to remember this is to imagine
- the @code{symbol} in @code{(symbol expr)} is omitted.
- @code{and-let*} is good for calculations where a @code{#f} value means
- termination, but where a non-@code{#f} value is going to be needed in
- subsequent expressions.
- The following illustrates this, it returns text between brackets
- @samp{[...]} in a string, or @code{#f} if there are no such brackets
- (ie.@: either @code{string-index} gives @code{#f}).
- @example
- (define (extract-brackets str)
- (and-let* ((start (string-index str #\[))
- (end (string-index str #\] start)))
- (substring str (1+ start) end)))
- @end example
- The following shows plain variables and expressions tested too.
- @code{diagnostic-levels} is taken to be an alist associating a
- diagnostic type with a level. @code{str} is printed only if the type
- is known and its level is high enough.
- @example
- (define (show-diagnostic type str)
- (and-let* (want-diagnostics
- (level (assq-ref diagnostic-levels type))
- ((>= level current-diagnostic-level)))
- (display str)))
- @end example
- The advantage of @code{and-let*} is that an extended sequence of
- expressions and tests doesn't require lots of nesting as would arise
- from separate @code{and} and @code{let*}, or from @code{cond} with
- @code{=>}.
- @end deffn
- @node SRFI-4
- @subsection SRFI-4 - Homogeneous numeric vector datatypes
- @cindex SRFI-4
- SRFI-4 provides an interface to uniform numeric vectors: vectors whose elements
- are all of a single numeric type. Guile offers uniform numeric vectors for
- signed and unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of
- floating point values, and, as an extension to SRFI-4, complex floating-point
- numbers of these two sizes.
- The standard SRFI-4 procedures and data types may be included via loading the
- appropriate module:
- @example
- (use-modules (srfi srfi-4))
- @end example
- This module is currently a part of the default Guile environment, but it is a
- good practice to explicitly import the module. In the future, using SRFI-4
- procedures without importing the SRFI-4 module will cause a deprecation message
- to be printed. (Of course, one may call the C functions at any time. Would that
- C had modules!)
- @menu
- * SRFI-4 Overview:: The warp and weft of uniform numeric vectors.
- * SRFI-4 API:: Uniform vectors, from Scheme and from C.
- * SRFI-4 and Bytevectors:: SRFI-4 vectors are backed by bytevectors.
- * SRFI-4 Extensions:: Guile-specific extensions to the standard.
- @end menu
- @node SRFI-4 Overview
- @subsubsection SRFI-4 - Overview
- Uniform numeric vectors can be useful since they consume less memory
- than the non-uniform, general vectors. Also, since the types they can
- store correspond directly to C types, it is easier to work with them
- efficiently on a low level. Consider image processing as an example,
- where you want to apply a filter to some image. While you could store
- the pixels of an image in a general vector and write a general
- convolution function, things are much more efficient with uniform
- vectors: the convolution function knows that all pixels are unsigned
- 8-bit values (say), and can use a very tight inner loop.
- This is implemented in Scheme by having the compiler notice calls to the SRFI-4
- accessors, and inline them to appropriate compiled code. From C you have access
- to the raw array; functions for efficiently working with uniform numeric vectors
- from C are listed at the end of this section.
- Uniform numeric vectors are the special case of one dimensional uniform
- numeric arrays.
- There are 12 standard kinds of uniform numeric vectors, and they all have their
- own complement of constructors, accessors, and so on. Procedures that operate on
- a specific kind of uniform numeric vector have a ``tag'' in their name,
- indicating the element type.
- @table @nicode
- @item u8
- unsigned 8-bit integers
- @item s8
- signed 8-bit integers
- @item u16
- unsigned 16-bit integers
- @item s16
- signed 16-bit integers
- @item u32
- unsigned 32-bit integers
- @item s32
- signed 32-bit integers
- @item u64
- unsigned 64-bit integers
- @item s64
- signed 64-bit integers
- @item f32
- the C type @code{float}
- @item f64
- the C type @code{double}
- @end table
- In addition, Guile supports uniform arrays of complex numbers, with the
- nonstandard tags:
- @table @nicode
- @item c32
- complex numbers in rectangular form with the real and imaginary part
- being a @code{float}
- @item c64
- complex numbers in rectangular form with the real and imaginary part
- being a @code{double}
- @end table
- The external representation (ie.@: read syntax) for these vectors is
- similar to normal Scheme vectors, but with an additional tag from the
- tables above indicating the vector's type. For example,
- @lisp
- #u16(1 2 3)
- #f64(3.1415 2.71)
- @end lisp
- Note that the read syntax for floating-point here conflicts with
- @code{#f} for false. In Standard Scheme one can write @code{(1 #f3)}
- for a three element list @code{(1 #f 3)}, but for Guile @code{(1 #f3)}
- is invalid. @code{(1 #f 3)} is almost certainly what one should write
- anyway to make the intention clear, so this is rarely a problem.
- @node SRFI-4 API
- @subsubsection SRFI-4 - API
- Note that the @nicode{c32} and @nicode{c64} functions are only available from
- @nicode{(srfi srfi-4 gnu)}.
- @deffn {Scheme Procedure} u8vector? obj
- @deffnx {Scheme Procedure} s8vector? obj
- @deffnx {Scheme Procedure} u16vector? obj
- @deffnx {Scheme Procedure} s16vector? obj
- @deffnx {Scheme Procedure} u32vector? obj
- @deffnx {Scheme Procedure} s32vector? obj
- @deffnx {Scheme Procedure} u64vector? obj
- @deffnx {Scheme Procedure} s64vector? obj
- @deffnx {Scheme Procedure} f32vector? obj
- @deffnx {Scheme Procedure} f64vector? obj
- @deffnx {Scheme Procedure} c32vector? obj
- @deffnx {Scheme Procedure} c64vector? obj
- @deffnx {C Function} scm_u8vector_p (obj)
- @deffnx {C Function} scm_s8vector_p (obj)
- @deffnx {C Function} scm_u16vector_p (obj)
- @deffnx {C Function} scm_s16vector_p (obj)
- @deffnx {C Function} scm_u32vector_p (obj)
- @deffnx {C Function} scm_s32vector_p (obj)
- @deffnx {C Function} scm_u64vector_p (obj)
- @deffnx {C Function} scm_s64vector_p (obj)
- @deffnx {C Function} scm_f32vector_p (obj)
- @deffnx {C Function} scm_f64vector_p (obj)
- @deffnx {C Function} scm_c32vector_p (obj)
- @deffnx {C Function} scm_c64vector_p (obj)
- Return @code{#t} if @var{obj} is a homogeneous numeric vector of the
- indicated type.
- @end deffn
- @deffn {Scheme Procedure} make-u8vector n [value]
- @deffnx {Scheme Procedure} make-s8vector n [value]
- @deffnx {Scheme Procedure} make-u16vector n [value]
- @deffnx {Scheme Procedure} make-s16vector n [value]
- @deffnx {Scheme Procedure} make-u32vector n [value]
- @deffnx {Scheme Procedure} make-s32vector n [value]
- @deffnx {Scheme Procedure} make-u64vector n [value]
- @deffnx {Scheme Procedure} make-s64vector n [value]
- @deffnx {Scheme Procedure} make-f32vector n [value]
- @deffnx {Scheme Procedure} make-f64vector n [value]
- @deffnx {Scheme Procedure} make-c32vector n [value]
- @deffnx {Scheme Procedure} make-c64vector n [value]
- @deffnx {C Function} scm_make_u8vector (n, value)
- @deffnx {C Function} scm_make_s8vector (n, value)
- @deffnx {C Function} scm_make_u16vector (n, value)
- @deffnx {C Function} scm_make_s16vector (n, value)
- @deffnx {C Function} scm_make_u32vector (n, value)
- @deffnx {C Function} scm_make_s32vector (n, value)
- @deffnx {C Function} scm_make_u64vector (n, value)
- @deffnx {C Function} scm_make_s64vector (n, value)
- @deffnx {C Function} scm_make_f32vector (n, value)
- @deffnx {C Function} scm_make_f64vector (n, value)
- @deffnx {C Function} scm_make_c32vector (n, value)
- @deffnx {C Function} scm_make_c64vector (n, value)
- Return a newly allocated homogeneous numeric vector holding @var{n}
- elements of the indicated type. If @var{value} is given, the vector
- is initialized with that value, otherwise the contents are
- unspecified.
- @end deffn
- @deffn {Scheme Procedure} u8vector value @dots{}
- @deffnx {Scheme Procedure} s8vector value @dots{}
- @deffnx {Scheme Procedure} u16vector value @dots{}
- @deffnx {Scheme Procedure} s16vector value @dots{}
- @deffnx {Scheme Procedure} u32vector value @dots{}
- @deffnx {Scheme Procedure} s32vector value @dots{}
- @deffnx {Scheme Procedure} u64vector value @dots{}
- @deffnx {Scheme Procedure} s64vector value @dots{}
- @deffnx {Scheme Procedure} f32vector value @dots{}
- @deffnx {Scheme Procedure} f64vector value @dots{}
- @deffnx {Scheme Procedure} c32vector value @dots{}
- @deffnx {Scheme Procedure} c64vector value @dots{}
- @deffnx {C Function} scm_u8vector (values)
- @deffnx {C Function} scm_s8vector (values)
- @deffnx {C Function} scm_u16vector (values)
- @deffnx {C Function} scm_s16vector (values)
- @deffnx {C Function} scm_u32vector (values)
- @deffnx {C Function} scm_s32vector (values)
- @deffnx {C Function} scm_u64vector (values)
- @deffnx {C Function} scm_s64vector (values)
- @deffnx {C Function} scm_f32vector (values)
- @deffnx {C Function} scm_f64vector (values)
- @deffnx {C Function} scm_c32vector (values)
- @deffnx {C Function} scm_c64vector (values)
- Return a newly allocated homogeneous numeric vector of the indicated
- type, holding the given parameter @var{value}s. The vector length is
- the number of parameters given.
- @end deffn
- @deffn {Scheme Procedure} u8vector-length vec
- @deffnx {Scheme Procedure} s8vector-length vec
- @deffnx {Scheme Procedure} u16vector-length vec
- @deffnx {Scheme Procedure} s16vector-length vec
- @deffnx {Scheme Procedure} u32vector-length vec
- @deffnx {Scheme Procedure} s32vector-length vec
- @deffnx {Scheme Procedure} u64vector-length vec
- @deffnx {Scheme Procedure} s64vector-length vec
- @deffnx {Scheme Procedure} f32vector-length vec
- @deffnx {Scheme Procedure} f64vector-length vec
- @deffnx {Scheme Procedure} c32vector-length vec
- @deffnx {Scheme Procedure} c64vector-length vec
- @deffnx {C Function} scm_u8vector_length (vec)
- @deffnx {C Function} scm_s8vector_length (vec)
- @deffnx {C Function} scm_u16vector_length (vec)
- @deffnx {C Function} scm_s16vector_length (vec)
- @deffnx {C Function} scm_u32vector_length (vec)
- @deffnx {C Function} scm_s32vector_length (vec)
- @deffnx {C Function} scm_u64vector_length (vec)
- @deffnx {C Function} scm_s64vector_length (vec)
- @deffnx {C Function} scm_f32vector_length (vec)
- @deffnx {C Function} scm_f64vector_length (vec)
- @deffnx {C Function} scm_c32vector_length (vec)
- @deffnx {C Function} scm_c64vector_length (vec)
- Return the number of elements in @var{vec}.
- @end deffn
- @deffn {Scheme Procedure} u8vector-ref vec i
- @deffnx {Scheme Procedure} s8vector-ref vec i
- @deffnx {Scheme Procedure} u16vector-ref vec i
- @deffnx {Scheme Procedure} s16vector-ref vec i
- @deffnx {Scheme Procedure} u32vector-ref vec i
- @deffnx {Scheme Procedure} s32vector-ref vec i
- @deffnx {Scheme Procedure} u64vector-ref vec i
- @deffnx {Scheme Procedure} s64vector-ref vec i
- @deffnx {Scheme Procedure} f32vector-ref vec i
- @deffnx {Scheme Procedure} f64vector-ref vec i
- @deffnx {Scheme Procedure} c32vector-ref vec i
- @deffnx {Scheme Procedure} c64vector-ref vec i
- @deffnx {C Function} scm_u8vector_ref (vec, i)
- @deffnx {C Function} scm_s8vector_ref (vec, i)
- @deffnx {C Function} scm_u16vector_ref (vec, i)
- @deffnx {C Function} scm_s16vector_ref (vec, i)
- @deffnx {C Function} scm_u32vector_ref (vec, i)
- @deffnx {C Function} scm_s32vector_ref (vec, i)
- @deffnx {C Function} scm_u64vector_ref (vec, i)
- @deffnx {C Function} scm_s64vector_ref (vec, i)
- @deffnx {C Function} scm_f32vector_ref (vec, i)
- @deffnx {C Function} scm_f64vector_ref (vec, i)
- @deffnx {C Function} scm_c32vector_ref (vec, i)
- @deffnx {C Function} scm_c64vector_ref (vec, i)
- Return the element at index @var{i} in @var{vec}. The first element
- in @var{vec} is index 0.
- @end deffn
- @deffn {Scheme Procedure} u8vector-set! vec i value
- @deffnx {Scheme Procedure} s8vector-set! vec i value
- @deffnx {Scheme Procedure} u16vector-set! vec i value
- @deffnx {Scheme Procedure} s16vector-set! vec i value
- @deffnx {Scheme Procedure} u32vector-set! vec i value
- @deffnx {Scheme Procedure} s32vector-set! vec i value
- @deffnx {Scheme Procedure} u64vector-set! vec i value
- @deffnx {Scheme Procedure} s64vector-set! vec i value
- @deffnx {Scheme Procedure} f32vector-set! vec i value
- @deffnx {Scheme Procedure} f64vector-set! vec i value
- @deffnx {Scheme Procedure} c32vector-set! vec i value
- @deffnx {Scheme Procedure} c64vector-set! vec i value
- @deffnx {C Function} scm_u8vector_set_x (vec, i, value)
- @deffnx {C Function} scm_s8vector_set_x (vec, i, value)
- @deffnx {C Function} scm_u16vector_set_x (vec, i, value)
- @deffnx {C Function} scm_s16vector_set_x (vec, i, value)
- @deffnx {C Function} scm_u32vector_set_x (vec, i, value)
- @deffnx {C Function} scm_s32vector_set_x (vec, i, value)
- @deffnx {C Function} scm_u64vector_set_x (vec, i, value)
- @deffnx {C Function} scm_s64vector_set_x (vec, i, value)
- @deffnx {C Function} scm_f32vector_set_x (vec, i, value)
- @deffnx {C Function} scm_f64vector_set_x (vec, i, value)
- @deffnx {C Function} scm_c32vector_set_x (vec, i, value)
- @deffnx {C Function} scm_c64vector_set_x (vec, i, value)
- Set the element at index @var{i} in @var{vec} to @var{value}. The
- first element in @var{vec} is index 0. The return value is
- unspecified.
- @end deffn
- @deffn {Scheme Procedure} u8vector->list vec
- @deffnx {Scheme Procedure} s8vector->list vec
- @deffnx {Scheme Procedure} u16vector->list vec
- @deffnx {Scheme Procedure} s16vector->list vec
- @deffnx {Scheme Procedure} u32vector->list vec
- @deffnx {Scheme Procedure} s32vector->list vec
- @deffnx {Scheme Procedure} u64vector->list vec
- @deffnx {Scheme Procedure} s64vector->list vec
- @deffnx {Scheme Procedure} f32vector->list vec
- @deffnx {Scheme Procedure} f64vector->list vec
- @deffnx {Scheme Procedure} c32vector->list vec
- @deffnx {Scheme Procedure} c64vector->list vec
- @deffnx {C Function} scm_u8vector_to_list (vec)
- @deffnx {C Function} scm_s8vector_to_list (vec)
- @deffnx {C Function} scm_u16vector_to_list (vec)
- @deffnx {C Function} scm_s16vector_to_list (vec)
- @deffnx {C Function} scm_u32vector_to_list (vec)
- @deffnx {C Function} scm_s32vector_to_list (vec)
- @deffnx {C Function} scm_u64vector_to_list (vec)
- @deffnx {C Function} scm_s64vector_to_list (vec)
- @deffnx {C Function} scm_f32vector_to_list (vec)
- @deffnx {C Function} scm_f64vector_to_list (vec)
- @deffnx {C Function} scm_c32vector_to_list (vec)
- @deffnx {C Function} scm_c64vector_to_list (vec)
- Return a newly allocated list holding all elements of @var{vec}.
- @end deffn
- @deffn {Scheme Procedure} list->u8vector lst
- @deffnx {Scheme Procedure} list->s8vector lst
- @deffnx {Scheme Procedure} list->u16vector lst
- @deffnx {Scheme Procedure} list->s16vector lst
- @deffnx {Scheme Procedure} list->u32vector lst
- @deffnx {Scheme Procedure} list->s32vector lst
- @deffnx {Scheme Procedure} list->u64vector lst
- @deffnx {Scheme Procedure} list->s64vector lst
- @deffnx {Scheme Procedure} list->f32vector lst
- @deffnx {Scheme Procedure} list->f64vector lst
- @deffnx {Scheme Procedure} list->c32vector lst
- @deffnx {Scheme Procedure} list->c64vector lst
- @deffnx {C Function} scm_list_to_u8vector (lst)
- @deffnx {C Function} scm_list_to_s8vector (lst)
- @deffnx {C Function} scm_list_to_u16vector (lst)
- @deffnx {C Function} scm_list_to_s16vector (lst)
- @deffnx {C Function} scm_list_to_u32vector (lst)
- @deffnx {C Function} scm_list_to_s32vector (lst)
- @deffnx {C Function} scm_list_to_u64vector (lst)
- @deffnx {C Function} scm_list_to_s64vector (lst)
- @deffnx {C Function} scm_list_to_f32vector (lst)
- @deffnx {C Function} scm_list_to_f64vector (lst)
- @deffnx {C Function} scm_list_to_c32vector (lst)
- @deffnx {C Function} scm_list_to_c64vector (lst)
- Return a newly allocated homogeneous numeric vector of the indicated type,
- initialized with the elements of the list @var{lst}.
- @end deffn
- @deftypefn {C Function} SCM scm_take_u8vector (const scm_t_uint8 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_s8vector (const scm_t_int8 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_u16vector (const scm_t_uint16 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_s16vector (const scm_t_int16 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_u32vector (const scm_t_uint32 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_s32vector (const scm_t_int32 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_u64vector (const scm_t_uint64 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_s64vector (const scm_t_int64 *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_f32vector (const float *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_f64vector (const double *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_c32vector (const float *data, size_t len)
- @deftypefnx {C Function} SCM scm_take_c64vector (const double *data, size_t len)
- Return a new uniform numeric vector of the indicated type and length
- that uses the memory pointed to by @var{data} to store its elements.
- This memory will eventually be freed with @code{free}. The argument
- @var{len} specifies the number of elements in @var{data}, not its size
- in bytes.
- The @code{c32} and @code{c64} variants take a pointer to a C array of
- @code{float}s or @code{double}s. The real parts of the complex numbers
- are at even indices in that array, the corresponding imaginary parts are
- at the following odd index.
- @end deftypefn
- @deftypefn {C Function} {const scm_t_uint8 *} scm_u8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_int8 *} scm_s8vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_uint16 *} scm_u16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_int16 *} scm_s16vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_uint32 *} scm_u32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_int32 *} scm_s32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_uint64 *} scm_u64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const scm_t_int64 *} scm_s64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const float *} scm_f32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const double *} scm_f64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const float *} scm_c32vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {const double *} scm_c64vector_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- Like @code{scm_vector_elements} (@pxref{Vector Accessing from C}), but
- returns a pointer to the elements of a uniform numeric vector of the
- indicated kind.
- @end deftypefn
- @deftypefn {C Function} {scm_t_uint8 *} scm_u8vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_int8 *} scm_s8vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_uint16 *} scm_u16vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_int16 *} scm_s16vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_uint32 *} scm_u32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_int32 *} scm_s32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_uint64 *} scm_u64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {scm_t_int64 *} scm_s64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {float *} scm_f32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {double *} scm_f64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {float *} scm_c32vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- @deftypefnx {C Function} {double *} scm_c64vector_writable_elements (SCM vec, scm_t_array_handle *handle, size_t *lenp, ssize_t *incp)
- Like @code{scm_vector_writable_elements} (@pxref{Vector Accessing from C}),
- but returns a pointer to the elements of a uniform numeric vector of the
- indicated kind.
- @end deftypefn
- @node SRFI-4 and Bytevectors
- @subsubsection SRFI-4 - Relation to bytevectors
- Guile implements SRFI-4 vectors using bytevectors (@pxref{Bytevectors}). Often
- when you have a numeric vector, you end up wanting to write its bytes somewhere,
- or have access to the underlying bytes, or read in bytes from somewhere else.
- Bytevectors are very good at this sort of thing. But the SRFI-4 APIs are nicer
- to use when doing number-crunching, because they are addressed by element and
- not by byte.
- So as a compromise, Guile allows all bytevector functions to operate on numeric
- vectors. They address the underlying bytes in the native endianness, as one
- would expect.
- Following the same reasoning, that it's just bytes underneath, Guile also allows
- uniform vectors of a given type to be accessed as if they were of any type. One
- can fill a @nicode{u32vector}, and access its elements with
- @nicode{u8vector-ref}. One can use @nicode{f64vector-ref} on bytevectors. It's
- all the same to Guile.
- In this way, uniform numeric vectors may be written to and read from
- input/output ports using the procedures that operate on bytevectors.
- @xref{Bytevectors}, for more information.
- @node SRFI-4 Extensions
- @subsubsection SRFI-4 - Guile extensions
- Guile defines some useful extensions to SRFI-4, which are not available in the
- default Guile environment. They may be imported by loading the extensions
- module:
- @example
- (use-modules (srfi srfi-4 gnu))
- @end example
- @deffn {Scheme Procedure} srfi-4-vector-type-size obj
- Return the size, in bytes, of each element of SRFI-4 vector
- @var{obj}. For example, @code{(srfi-4-vector-type-size #u32())} returns
- @code{4}.
- @end deffn
- @deffn {Scheme Procedure} any->u8vector obj
- @deffnx {Scheme Procedure} any->s8vector obj
- @deffnx {Scheme Procedure} any->u16vector obj
- @deffnx {Scheme Procedure} any->s16vector obj
- @deffnx {Scheme Procedure} any->u32vector obj
- @deffnx {Scheme Procedure} any->s32vector obj
- @deffnx {Scheme Procedure} any->u64vector obj
- @deffnx {Scheme Procedure} any->s64vector obj
- @deffnx {Scheme Procedure} any->f32vector obj
- @deffnx {Scheme Procedure} any->f64vector obj
- @deffnx {Scheme Procedure} any->c32vector obj
- @deffnx {Scheme Procedure} any->c64vector obj
- @deffnx {C Function} scm_any_to_u8vector (obj)
- @deffnx {C Function} scm_any_to_s8vector (obj)
- @deffnx {C Function} scm_any_to_u16vector (obj)
- @deffnx {C Function} scm_any_to_s16vector (obj)
- @deffnx {C Function} scm_any_to_u32vector (obj)
- @deffnx {C Function} scm_any_to_s32vector (obj)
- @deffnx {C Function} scm_any_to_u64vector (obj)
- @deffnx {C Function} scm_any_to_s64vector (obj)
- @deffnx {C Function} scm_any_to_f32vector (obj)
- @deffnx {C Function} scm_any_to_f64vector (obj)
- @deffnx {C Function} scm_any_to_c32vector (obj)
- @deffnx {C Function} scm_any_to_c64vector (obj)
- Return a (maybe newly allocated) uniform numeric vector of the indicated
- type, initialized with the elements of @var{obj}, which must be a list,
- a vector, or a uniform vector. When @var{obj} is already a suitable
- uniform numeric vector, it is returned unchanged.
- @end deffn
- @deffn {Scheme Procedure} u8vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} s8vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} u16vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} s16vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} u32vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} s32vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} u64vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} s64vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} f32vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} f64vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} c32vector-copy! dst at src [start [end]]
- @deffnx {Scheme Procedure} c64vector-copy! dst at src [start [end]]
- Copy a block of elements from @var{src} to @var{dst}, both of which must
- be vectors of the indicated type, starting in @var{dst} at @var{at} and
- starting in @var{src} at @var{start} and ending at @var{end}. It is an
- error for @var{dst} to have a length less than @var{at} + (@var{end} -
- @var{start}). @var{at} and @var{start} default to 0 and @var{end}
- defaults to the length of @var{src}.
- If source and destination overlap, copying takes place as if the
- source is first copied into a temporary vector and then into the
- destination.
- See also @ref{x-vector-copy!,@code{vector-copy!}}.
- @end deffn
- @deffn {Scheme Procedure} u8vector-copy src [start [end]]
- @deffnx {Scheme Procedure} s8vector-copy src [start [end]]
- @deffnx {Scheme Procedure} u16vector-copy src [start [end]]
- @deffnx {Scheme Procedure} s16vector-copy src [start [end]]
- @deffnx {Scheme Procedure} u32vector-copy src [start [end]]
- @deffnx {Scheme Procedure} s32vector-copy src [start [end]]
- @deffnx {Scheme Procedure} u64vector-copy src [start [end]]
- @deffnx {Scheme Procedure} s64vector-copy src [start [end]]
- @deffnx {Scheme Procedure} f32vector-copy src [start [end]]
- @deffnx {Scheme Procedure} f64vector-copy src [start [end]]
- @deffnx {Scheme Procedure} c32vector-copy src [start [end]]
- @deffnx {Scheme Procedure} c64vector-copy src [start [end]]
- Returns a freshly allocated vector of the indicated type, which must be
- the same as that of @var{src}, containing the elements of @var{src}
- between @var{start} and @var{end}. @var{start} defaults to 0 and
- @var{end} defaults to the length of @var{src}.
- See also @ref{x-vector-copy,@code{vector-copy}}.
- @end deffn
- @node SRFI-6
- @subsection SRFI-6 - Basic String Ports
- @cindex SRFI-6
- SRFI-6 defines the procedures @code{open-input-string},
- @code{open-output-string} and @code{get-output-string}. These
- procedures are included in the Guile core, so using this module does not
- make any difference at the moment. But it is possible that support for
- SRFI-6 will be factored out of the core library in the future, so using
- this module does not hurt, after all.
- @node SRFI-8
- @subsection SRFI-8 - receive
- @cindex SRFI-8
- @code{receive} is a syntax for making the handling of multiple-value
- procedures easier. It is documented in @xref{Multiple Values}.
- @node SRFI-9
- @subsection SRFI-9 - define-record-type
- This SRFI is a syntax for defining new record types and creating
- predicate, constructor, and field getter and setter functions. It is
- documented in the ``Data Types'' section of the manual (@pxref{SRFI-9
- Records}).
- @node SRFI-10
- @subsection SRFI-10 - Hash-Comma Reader Extension
- @cindex SRFI-10
- @cindex hash-comma
- @cindex #,()
- This SRFI implements a reader extension @code{#,()} called hash-comma.
- It allows the reader to give new kinds of objects, for use both in data
- and as constants or literals in source code. This feature is available
- with
- @example
- (use-modules (srfi srfi-10))
- @end example
- @noindent
- The new read syntax is of the form
- @example
- #,(@var{tag} @var{arg}@dots{})
- @end example
- @noindent
- where @var{tag} is a symbol and the @var{arg}s are objects taken as
- parameters. @var{tag}s are registered with the following procedure.
- @deffn {Scheme Procedure} define-reader-ctor tag proc
- Register @var{proc} as the constructor for a hash-comma read syntax
- starting with symbol @var{tag}, i.e.@: @nicode{#,(@var{tag} arg@dots{})}.
- @var{proc} is called with the given arguments @code{(@var{proc}
- arg@dots{})} and the object it returns is the result of the read.
- @end deffn
- @noindent
- For example, a syntax giving a list of @var{N} copies of an object.
- @example
- (define-reader-ctor 'repeat
- (lambda (obj reps)
- (make-list reps obj)))
- (display '#,(repeat 99 3))
- @print{} (99 99 99)
- @end example
- Notice the quote @nicode{'} when the @nicode{#,( )} is used. The
- @code{repeat} handler returns a list and the program must quote to use
- it literally, the same as any other list. Ie.
- @example
- (display '#,(repeat 99 3))
- @result{}
- (display '(99 99 99))
- @end example
- When a handler returns an object which is self-evaluating, like a
- number or a string, then there's no need for quoting, just as there's
- no need when giving those directly as literals. For example an
- addition,
- @example
- (define-reader-ctor 'sum
- (lambda (x y)
- (+ x y)))
- (display #,(sum 123 456)) @print{} 579
- @end example
- Once @code{(srfi srfi-10)} has loaded, @nicode{#,()} is available
- globally, there's no need to use @code{(srfi srfi-10)} in later
- modules. Similarly the tags registered are global and can be used
- anywhere once registered.
- We do not recommend @nicode{#,()} reader extensions, however, and for
- three reasons.
- First of all, this SRFI is not modular: the tag is matched by name, not
- as an identifier within a scope. Defining a reader extension in one
- part of a program can thus affect unrelated parts of a program because
- the tag is not scoped.
- Secondly, reader extensions can be hard to manage from a time
- perspective: when does the reader extension take effect? @xref{Eval
- When}, for more discussion.
- Finally, reader extensions can easily produce objects that can't be
- reified to an object file by the compiler. For example if you define a
- reader extension that makes a hash table (@pxref{Hash Tables}), then it
- will work fine when run with the interpreter, and you think you have a
- neat hack. But then if you try to compile your program, after wrangling
- with the @code{eval-when} concerns mentioned above, the compiler will
- carp that it doesn't know how to serialize a hash table to disk.
- In the specific case of hash tables, it would be possible for Guile to
- know how to pack hash tables into compiled files, but this doesn't work
- in general. What if the object you produce is an instance of a record
- type? Guile would then have to serialize the record type to disk too,
- and then what happens if the program independently loads the code that
- defines the record type? Does it define the same type or a different
- type? Guile's record types are nominal, not structural, so the answer
- is not clear at all.
- For all of these reasons we recommend macros over reader extensions.
- Macros fulfill many of the same needs while preserving modular
- composition, and their interaction with @code{eval-when} is well-known.
- If you need brevity, instead use @code{read-hash-extend} and make your
- reader extension expand to a macro invocation. In that way we preserve
- scoping as much as possible. @xref{Reader Extensions}.
- @node SRFI-11
- @subsection SRFI-11 - let-values
- @cindex SRFI-11
- @findex let-values
- @findex let*-values
- This module implements the binding forms for multiple values
- @code{let-values} and @code{let*-values}. These forms are similar to
- @code{let} and @code{let*} (@pxref{Local Bindings}), but they support
- binding of the values returned by multiple-valued expressions.
- Write @code{(use-modules (srfi srfi-11))} to make the bindings
- available.
- @lisp
- (let-values (((x y) (values 1 2))
- ((z f) (values 3 4)))
- (+ x y z f))
- @result{}
- 10
- @end lisp
- @code{let-values} performs all bindings simultaneously, which means that
- no expression in the binding clauses may refer to variables bound in the
- same clause list. @code{let*-values}, on the other hand, performs the
- bindings sequentially, just like @code{let*} does for single-valued
- expressions.
- @node SRFI-13
- @subsection SRFI-13 - String Library
- @cindex SRFI-13
- The SRFI-13 procedures are always available, @xref{Strings}.
- @node SRFI-14
- @subsection SRFI-14 - Character-set Library
- @cindex SRFI-14
- The SRFI-14 data type and procedures are always available,
- @xref{Character Sets}.
- @node SRFI-16
- @subsection SRFI-16 - case-lambda
- @cindex SRFI-16
- @cindex variable arity
- @cindex arity, variable
- SRFI-16 defines a variable-arity @code{lambda} form,
- @code{case-lambda}. This form is available in the default Guile
- environment. @xref{Case-lambda}, for more information.
- @node SRFI-17
- @subsection SRFI-17 - Generalized set!
- @cindex SRFI-17
- This SRFI implements a generalized @code{set!}, allowing some
- ``referencing'' functions to be used as the target location of a
- @code{set!}. This feature is available from
- @example
- (use-modules (srfi srfi-17))
- @end example
- @noindent
- For example @code{vector-ref} is extended so that
- @example
- (set! (vector-ref vec idx) new-value)
- @end example
- @noindent
- is equivalent to
- @example
- (vector-set! vec idx new-value)
- @end example
- The idea is that a @code{vector-ref} expression identifies a location,
- which may be either fetched or stored. The same form is used for the
- location in both cases, encouraging visual clarity. This is similar
- to the idea of an ``lvalue'' in C.
- The mechanism for this kind of @code{set!} is in the Guile core
- (@pxref{Procedures with Setters}). This module adds definitions of
- the following functions as procedures with setters, allowing them to
- be targets of a @code{set!},
- @quotation
- @nicode{car}, @nicode{cdr}, @nicode{caar}, @nicode{cadr},
- @nicode{cdar}, @nicode{cddr}, @nicode{caaar}, @nicode{caadr},
- @nicode{cadar}, @nicode{caddr}, @nicode{cdaar}, @nicode{cdadr},
- @nicode{cddar}, @nicode{cdddr}, @nicode{caaaar}, @nicode{caaadr},
- @nicode{caadar}, @nicode{caaddr}, @nicode{cadaar}, @nicode{cadadr},
- @nicode{caddar}, @nicode{cadddr}, @nicode{cdaaar}, @nicode{cdaadr},
- @nicode{cdadar}, @nicode{cdaddr}, @nicode{cddaar}, @nicode{cddadr},
- @nicode{cdddar}, @nicode{cddddr}
- @nicode{string-ref}, @nicode{vector-ref}
- @end quotation
- The SRFI specifies @code{setter} (@pxref{Procedures with Setters}) as
- a procedure with setter, allowing the setter for a procedure to be
- changed, eg.@: @code{(set! (setter foo) my-new-setter-handler)}.
- Currently Guile does not implement this, a setter can only be
- specified on creation (@code{getter-with-setter} below).
- @defun getter-with-setter
- The same as the Guile core @code{make-procedure-with-setter}
- (@pxref{Procedures with Setters}).
- @end defun
- @node SRFI-18
- @subsection SRFI-18 - Multithreading support
- @cindex SRFI-18
- This is an implementation of the SRFI-18 threading and synchronization
- library. The functions and variables described here are provided by
- @example
- (use-modules (srfi srfi-18))
- @end example
- SRFI-18 defines facilities for threads, mutexes, condition variables,
- time, and exception handling. Because these facilities are at a higher
- level than Guile's primitives, they are implemented as a layer on top of
- what Guile provides. In particular this means that a Guile mutex is not
- a SRFI-18 mutex, and a Guile thread is not a SRFI-18 thread, and so on.
- Guile provides a set of primitives and SRFI-18 is one of the systems built in terms of those primitives.
- @menu
- * SRFI-18 Threads:: Executing code
- * SRFI-18 Mutexes:: Mutual exclusion devices
- * SRFI-18 Condition variables:: Synchronizing of groups of threads
- * SRFI-18 Time:: Representation of times and durations
- * SRFI-18 Exceptions:: Signaling and handling errors
- @end menu
- @node SRFI-18 Threads
- @subsubsection SRFI-18 Threads
- Threads created by SRFI-18 differ in two ways from threads created by
- Guile's built-in thread functions. First, a thread created by SRFI-18
- @code{make-thread} begins in a blocked state and will not start
- execution until @code{thread-start!} is called on it. Second, SRFI-18
- threads are constructed with a top-level exception handler that
- captures any exceptions that are thrown on thread exit.
- SRFI-18 threads are disjoint from Guile's primitive threads.
- @xref{Threads}, for more on Guile's primitive facility.
- @defun current-thread
- Returns the thread that called this function. This is the same
- procedure as the same-named built-in procedure @code{current-thread}
- (@pxref{Threads}).
- @end defun
- @defun thread? obj
- Returns @code{#t} if @var{obj} is a thread, @code{#f} otherwise. This
- is the same procedure as the same-named built-in procedure
- @code{thread?} (@pxref{Threads}).
- @end defun
- @defun make-thread thunk [name]
- Call @code{thunk} in a new thread and with a new dynamic state,
- returning the new thread and optionally assigning it the object name
- @var{name}, which may be any Scheme object.
- Note that the name @code{make-thread} conflicts with the
- @code{(ice-9 threads)} function @code{make-thread}. Applications
- wanting to use both of these functions will need to refer to them by
- different names.
- @end defun
- @defun thread-name thread
- Returns the name assigned to @var{thread} at the time of its creation,
- or @code{#f} if it was not given a name.
- @end defun
- @defun thread-specific thread
- @defunx thread-specific-set! thread obj
- Get or set the ``object-specific'' property of @var{thread}. In
- Guile's implementation of SRFI-18, this value is stored as an object
- property, and will be @code{#f} if not set.
- @end defun
- @defun thread-start! thread
- Unblocks @var{thread} and allows it to begin execution if it has not
- done so already.
- @end defun
- @defun thread-yield!
- If one or more threads are waiting to execute, calling
- @code{thread-yield!} forces an immediate context switch to one of them.
- Otherwise, @code{thread-yield!} has no effect. @code{thread-yield!}
- behaves identically to the Guile built-in function @code{yield}.
- @end defun
- @defun thread-sleep! timeout
- The current thread waits until the point specified by the time object
- @var{timeout} is reached (@pxref{SRFI-18 Time}). This blocks the
- thread only if @var{timeout} represents a point in the future. it is
- an error for @var{timeout} to be @code{#f}.
- @end defun
- @defun thread-terminate! thread
- Causes an abnormal termination of @var{thread}. If @var{thread} is
- not already terminated, all mutexes owned by @var{thread} become
- unlocked/abandoned. If @var{thread} is the current thread,
- @code{thread-terminate!} does not return. Otherwise
- @code{thread-terminate!} returns an unspecified value; the termination
- of @var{thread} will occur before @code{thread-terminate!} returns.
- Subsequent attempts to join on @var{thread} will cause a ``terminated
- thread exception'' to be raised.
- @code{thread-terminate!} is compatible with the thread cancellation
- procedures in the core threads API (@pxref{Threads}) in that if a
- cleanup handler has been installed for the target thread, it will be
- called before the thread exits and its return value (or exception, if
- any) will be stored for later retrieval via a call to
- @code{thread-join!}.
- @end defun
- @defun thread-join! thread [timeout [timeout-val]]
- Wait for @var{thread} to terminate and return its exit value. When a
- time value @var{timeout} is given, it specifies a point in time where
- the waiting should be aborted. When the waiting is aborted,
- @var{timeout-val} is returned if it is specified; otherwise, a
- @code{join-timeout-exception} exception is raised
- (@pxref{SRFI-18 Exceptions}). Exceptions may also be raised if the
- thread was terminated by a call to @code{thread-terminate!}
- (@code{terminated-thread-exception} will be raised) or if the thread
- exited by raising an exception that was handled by the top-level
- exception handler (@code{uncaught-exception} will be raised; the
- original exception can be retrieved using
- @code{uncaught-exception-reason}).
- @end defun
- @node SRFI-18 Mutexes
- @subsubsection SRFI-18 Mutexes
- SRFI-18 mutexes are disjoint from Guile's primitive mutexes.
- @xref{Mutexes and Condition Variables}, for more on Guile's primitive
- facility.
- @defun make-mutex [name]
- Returns a new mutex, optionally assigning it the object name @var{name},
- which may be any Scheme object. The returned mutex will be created with
- the configuration described above.
- @end defun
- @defun mutex-name mutex
- Returns the name assigned to @var{mutex} at the time of its creation, or
- @code{#f} if it was not given a name.
- @end defun
- @defun mutex-specific mutex
- Return the ``object-specific'' property of @var{mutex}, or @code{#f} if
- none is set.
- @end defun
- @defun mutex-specific-set! mutex obj
- Set the ``object-specific'' property of @var{mutex}.
- @end defun
- @defun mutex-state mutex
- Returns information about the state of @var{mutex}. Possible values
- are:
- @itemize @bullet
- @item
- thread @var{t}: the mutex is in the locked/owned state and thread
- @var{t} is the owner of the mutex
- @item
- symbol @code{not-owned}: the mutex is in the locked/not-owned state
- @item
- symbol @code{abandoned}: the mutex is in the unlocked/abandoned state
- @item
- symbol @code{not-abandoned}: the mutex is in the
- unlocked/not-abandoned state
- @end itemize
- @end defun
- @defun mutex-lock! mutex [timeout [thread]]
- Lock @var{mutex}, optionally specifying a time object @var{timeout}
- after which to abort the lock attempt and a thread @var{thread} giving
- a new owner for @var{mutex} different than the current thread.
- @end defun
- @defun mutex-unlock! mutex [condition-variable [timeout]]
- Unlock @var{mutex}, optionally specifying a condition variable
- @var{condition-variable} on which to wait, either indefinitely or,
- optionally, until the time object @var{timeout} has passed, to be
- signaled.
- @end defun
- @node SRFI-18 Condition variables
- @subsubsection SRFI-18 Condition variables
- SRFI-18 does not specify a ``wait'' function for condition variables.
- Waiting on a condition variable can be simulated using the SRFI-18
- @code{mutex-unlock!} function described in the previous section.
- SRFI-18 condition variables are disjoint from Guile's primitive
- condition variables. @xref{Mutexes and Condition Variables}, for more
- on Guile's primitive facility.
- @defun condition-variable? obj
- Returns @code{#t} if @var{obj} is a condition variable, @code{#f}
- otherwise.
- @end defun
- @defun make-condition-variable [name]
- Returns a new condition variable, optionally assigning it the object
- name @var{name}, which may be any Scheme object.
- @end defun
- @defun condition-variable-name condition-variable
- Returns the name assigned to @var{condition-variable} at the time of its
- creation, or @code{#f} if it was not given a name.
- @end defun
- @defun condition-variable-specific condition-variable
- Return the ``object-specific'' property of @var{condition-variable}, or
- @code{#f} if none is set.
- @end defun
- @defun condition-variable-specific-set! condition-variable obj
- Set the ``object-specific'' property of @var{condition-variable}.
- @end defun
- @defun condition-variable-signal! condition-variable
- @defunx condition-variable-broadcast! condition-variable
- Wake up one thread that is waiting for @var{condition-variable}, in
- the case of @code{condition-variable-signal!}, or all threads waiting
- for it, in the case of @code{condition-variable-broadcast!}.
- @end defun
- @node SRFI-18 Time
- @subsubsection SRFI-18 Time
- The SRFI-18 time functions manipulate time in two formats: a
- ``time object'' type that represents an absolute point in time in some
- implementation-specific way; and the number of seconds since some
- unspecified ``epoch''. In Guile's implementation, the epoch is the
- Unix epoch, 00:00:00 UTC, January 1, 1970.
- @defun current-time
- Return the current time as a time object. This procedure replaces
- the procedure of the same name in the core library, which returns the
- current time in seconds since the epoch.
- @end defun
- @defun time? obj
- Returns @code{#t} if @var{obj} is a time object, @code{#f} otherwise.
- @end defun
- @defun time->seconds time
- @defunx seconds->time seconds
- Convert between time objects and numerical values representing the
- number of seconds since the epoch. When converting from a time object
- to seconds, the return value is the number of seconds between
- @var{time} and the epoch. When converting from seconds to a time
- object, the return value is a time object that represents a time
- @var{seconds} seconds after the epoch.
- @end defun
- @node SRFI-18 Exceptions
- @subsubsection SRFI-18 Exceptions
- SRFI-18 exceptions are identical to the exceptions provided by
- Guile's implementation of SRFI-34. The behavior of exception
- handlers invoked to handle exceptions thrown from SRFI-18 functions,
- however, differs from the conventional behavior of SRFI-34 in that
- the continuation of the handler is the same as that of the call to
- the function. Handlers are called in a tail-recursive manner; the
- exceptions do not ``bubble up''.
- @defun current-exception-handler
- Returns the current exception handler.
- @end defun
- @defun with-exception-handler handler thunk
- Installs @var{handler} as the current exception handler and calls the
- procedure @var{thunk} with no arguments, returning its value as the
- value of the exception. @var{handler} must be a procedure that accepts
- a single argument. The current exception handler at the time this
- procedure is called will be restored after the call returns.
- @end defun
- @defun raise obj
- Raise @var{obj} as an exception. This is the same procedure as the
- same-named procedure defined in SRFI 34.
- @end defun
- @defun join-timeout-exception? obj
- Returns @code{#t} if @var{obj} is an exception raised as the result of
- performing a timed join on a thread that does not exit within the
- specified timeout, @code{#f} otherwise.
- @end defun
- @defun abandoned-mutex-exception? obj
- Returns @code{#t} if @var{obj} is an exception raised as the result of
- attempting to lock a mutex that has been abandoned by its owner thread,
- @code{#f} otherwise.
- @end defun
- @defun terminated-thread-exception? obj
- Returns @code{#t} if @var{obj} is an exception raised as the result of
- joining on a thread that exited as the result of a call to
- @code{thread-terminate!}.
- @end defun
- @defun uncaught-exception? obj
- @defunx uncaught-exception-reason exc
- @code{uncaught-exception?} returns @code{#t} if @var{obj} is an
- exception thrown as the result of joining a thread that exited by
- raising an exception that was handled by the top-level exception
- handler installed by @code{make-thread}. When this occurs, the
- original exception is preserved as part of the exception thrown by
- @code{thread-join!} and can be accessed by calling
- @code{uncaught-exception-reason} on that exception. Note that
- because this exception-preservation mechanism is a side-effect of
- @code{make-thread}, joining on threads that exited as described above
- but were created by other means will not raise this
- @code{uncaught-exception} error.
- @end defun
- @node SRFI-19
- @subsection SRFI-19 - Time/Date Library
- @cindex SRFI-19
- @cindex time
- @cindex date
- This is an implementation of the SRFI-19 time/date library. The
- functions and variables described here are provided by
- @example
- (use-modules (srfi srfi-19))
- @end example
- @menu
- * SRFI-19 Introduction::
- * SRFI-19 Time::
- * SRFI-19 Date::
- * SRFI-19 Time/Date conversions::
- * SRFI-19 Date to string::
- * SRFI-19 String to date::
- @end menu
- @node SRFI-19 Introduction
- @subsubsection SRFI-19 Introduction
- @cindex universal time
- @cindex atomic time
- @cindex UTC
- @cindex TAI
- This module implements time and date representations and calculations,
- in various time systems, including Coordinated Universal Time (UTC)
- and International Atomic Time (TAI).
- For those not familiar with these time systems, TAI is based on a
- fixed length second derived from oscillations of certain atoms. UTC
- differs from TAI by an integral number of seconds, which is increased
- or decreased at announced times to keep UTC aligned to a mean solar
- day (the orbit and rotation of the earth are not quite constant).
- @cindex leap second
- So far, only increases in the TAI
- @tex
- $\leftrightarrow$
- @end tex
- @ifnottex
- <->
- @end ifnottex
- UTC difference have been needed. Such an increase is a ``leap
- second'', an extra second of TAI introduced at the end of a UTC day.
- When working entirely within UTC this is never seen, every day simply
- has 86400 seconds. But when converting from TAI to a UTC date, an
- extra 23:59:60 is present, where normally a day would end at 23:59:59.
- Effectively the UTC second from 23:59:59 to 00:00:00 has taken two TAI
- seconds.
- @cindex system clock
- In the current implementation, the system clock is assumed to be UTC,
- and a table of leap seconds in the code converts to TAI. See comments
- in @file{srfi-19.scm} for how to update this table.
- @cindex julian day
- @cindex modified julian day
- Also, for those not familiar with the terminology, a @dfn{Julian Day}
- represents a point in time as a real number of days since
- -4713-11-24T12:00:00Z, i.e.@: midday UT on 24 November 4714 BC in the
- proleptic Gregorian calendar (1 January 4713 BC in the proleptic Julian
- calendar).
- A @dfn{Modified Julian Day} represents a point in time as a real number
- of days since 1858-11-17T00:00:00Z, i.e.@: midnight UT on Wednesday 17
- November AD 1858. That time is julian day 2400000.5.
- @node SRFI-19 Time
- @subsubsection SRFI-19 Time
- @cindex time
- A @dfn{time} object has type, seconds and nanoseconds fields
- representing a point in time starting from some epoch. This is an
- arbitrary point in time, not just a time of day. Although times are
- represented in nanoseconds, the actual resolution may be lower.
- The following variables hold the possible time types. For instance
- @code{(current-time time-process)} would give the current CPU process
- time.
- @defvar time-utc
- Universal Coordinated Time (UTC).
- @cindex UTC
- @end defvar
- @defvar time-tai
- International Atomic Time (TAI).
- @cindex TAI
- @end defvar
- @defvar time-monotonic
- Monotonic time, meaning a monotonically increasing time starting from
- an unspecified epoch.
- Note that in the current implementation @code{time-monotonic} is the
- same as @code{time-tai}, and unfortunately is therefore affected by
- adjustments to the system clock. Perhaps this will change in the
- future.
- @end defvar
- @defvar time-duration
- A duration, meaning simply a difference between two times.
- @end defvar
- @defvar time-process
- CPU time spent in the current process, starting from when the process
- began.
- @cindex process time
- @end defvar
- @defvar time-thread
- CPU time spent in the current thread. Not currently implemented.
- @cindex thread time
- @end defvar
- @sp 1
- @defun time? obj
- Return @code{#t} if @var{obj} is a time object, or @code{#f} if not.
- @end defun
- @defun make-time type nanoseconds seconds
- Create a time object with the given @var{type}, @var{seconds} and
- @var{nanoseconds}.
- @end defun
- @defun time-type time
- @defunx time-nanosecond time
- @defunx time-second time
- @defunx set-time-type! time type
- @defunx set-time-nanosecond! time nsec
- @defunx set-time-second! time sec
- Get or set the type, seconds or nanoseconds fields of a time object.
- @code{set-time-type!} merely changes the field, it doesn't convert the
- time value. For conversions, see @ref{SRFI-19 Time/Date conversions}.
- @end defun
- @defun copy-time time
- Return a new time object, which is a copy of the given @var{time}.
- @end defun
- @defun current-time [type]
- Return the current time of the given @var{type}. The default
- @var{type} is @code{time-utc}.
- Note that the name @code{current-time} conflicts with the Guile core
- @code{current-time} function (@pxref{Time}) as well as the SRFI-18
- @code{current-time} function (@pxref{SRFI-18 Time}). Applications
- wanting to use more than one of these functions will need to refer to
- them by different names.
- @end defun
- @defun time-resolution [type]
- Return the resolution, in nanoseconds, of the given time @var{type}.
- The default @var{type} is @code{time-utc}.
- @end defun
- @defun time<=? t1 t2
- @defunx time<? t1 t2
- @defunx time=? t1 t2
- @defunx time>=? t1 t2
- @defunx time>? t1 t2
- Return @code{#t} or @code{#f} according to the respective relation
- between time objects @var{t1} and @var{t2}. @var{t1} and @var{t2}
- must be the same time type.
- @end defun
- @defun time-difference t1 t2
- @defunx time-difference! t1 t2
- Return a time object of type @code{time-duration} representing the
- period between @var{t1} and @var{t2}. @var{t1} and @var{t2} must be
- the same time type.
- @code{time-difference} returns a new time object,
- @code{time-difference!} may modify @var{t1} to form its return.
- @end defun
- @defun add-duration time duration
- @defunx add-duration! time duration
- @defunx subtract-duration time duration
- @defunx subtract-duration! time duration
- Return a time object which is @var{time} with the given @var{duration}
- added or subtracted. @var{duration} must be a time object of type
- @code{time-duration}.
- @code{add-duration} and @code{subtract-duration} return a new time
- object. @code{add-duration!} and @code{subtract-duration!} may modify
- the given @var{time} to form their return.
- @end defun
- @node SRFI-19 Date
- @subsubsection SRFI-19 Date
- @cindex date
- A @dfn{date} object represents a date in the Gregorian calendar and a
- time of day on that date in some timezone.
- The fields are year, month, day, hour, minute, second, nanoseconds and
- timezone. A date object is immutable, its fields can be read but they
- cannot be modified once the object is created.
- Historically, the Gregorian calendar was only used from the latter part
- of the year 1582 onwards, and not until even later in many countries.
- Prior to that most countries used the Julian calendar. SRFI-19 does
- not deal with the Julian calendar at all, and so does not reflect this
- historical calendar reform. Instead it projects the Gregorian calendar
- back proleptically as far as necessary. When dealing with historical
- data, especially prior to the British Empire's adoption of the Gregorian
- calendar in 1752, one should be mindful of which calendar is used in
- each context, and apply non-SRFI-19 facilities to convert where necessary.
- @defun date? obj
- Return @code{#t} if @var{obj} is a date object, or @code{#f} if not.
- @end defun
- @defun make-date nsecs seconds minutes hours date month year zone-offset
- Create a new date object.
- @c
- @c FIXME: What can we say about the ranges of the values. The
- @c current code looks it doesn't normalize, but expects then in their
- @c usual range already.
- @c
- @end defun
- @defun date-nanosecond date
- Nanoseconds, 0 to 999999999.
- @end defun
- @defun date-second date
- Seconds, 0 to 59, or 60 for a leap second. 60 is never seen when working
- entirely within UTC, it's only when converting to or from TAI.
- @end defun
- @defun date-minute date
- Minutes, 0 to 59.
- @end defun
- @defun date-hour date
- Hour, 0 to 23.
- @end defun
- @defun date-day date
- Day of the month, 1 to 31 (or less, according to the month).
- @end defun
- @defun date-month date
- Month, 1 to 12.
- @end defun
- @defun date-year date
- Year, eg.@: 2003. Dates B.C.@: are negative, eg.@: @math{-46} is 46
- B.C. There is no year 0, year @math{-1} is followed by year 1.
- @end defun
- @defun date-zone-offset date
- Time zone, an integer number of seconds east of Greenwich.
- @end defun
- @defun date-year-day date
- Day of the year, starting from 1 for 1st January.
- @end defun
- @defun date-week-day date
- Day of the week, starting from 0 for Sunday.
- @end defun
- @defun date-week-number date dstartw
- Week of the year, ignoring a first partial week. @var{dstartw} is the
- day of the week which is taken to start a week, 0 for Sunday, 1 for
- Monday, etc.
- @c
- @c FIXME: The spec doesn't say whether numbering starts at 0 or 1.
- @c The code looks like it's 0, if that's the correct intention.
- @c
- @end defun
- @c The SRFI text doesn't actually give the default for tz-offset, but
- @c the reference implementation has the local timezone and the
- @c conversions functions all specify that, so it should be ok to
- @c document it here.
- @c
- @defun current-date [tz-offset]
- Return a date object representing the current date/time, in UTC offset
- by @var{tz-offset}. @var{tz-offset} is seconds east of Greenwich and
- defaults to the local timezone.
- @end defun
- @defun current-julian-day
- @cindex julian day
- Return the current Julian Day.
- @end defun
- @defun current-modified-julian-day
- @cindex modified julian day
- Return the current Modified Julian Day.
- @end defun
- @node SRFI-19 Time/Date conversions
- @subsubsection SRFI-19 Time/Date conversions
- @cindex time conversion
- @cindex date conversion
- @defun date->julian-day date
- @defunx date->modified-julian-day date
- @defunx date->time-monotonic date
- @defunx date->time-tai date
- @defunx date->time-utc date
- @end defun
- @defun julian-day->date jdn [tz-offset]
- @defunx julian-day->time-monotonic jdn
- @defunx julian-day->time-tai jdn
- @defunx julian-day->time-utc jdn
- @end defun
- @defun modified-julian-day->date jdn [tz-offset]
- @defunx modified-julian-day->time-monotonic jdn
- @defunx modified-julian-day->time-tai jdn
- @defunx modified-julian-day->time-utc jdn
- @end defun
- @defun time-monotonic->date time [tz-offset]
- @defunx time-monotonic->time-tai time
- @defunx time-monotonic->time-tai! time
- @defunx time-monotonic->time-utc time
- @defunx time-monotonic->time-utc! time
- @end defun
- @defun time-tai->date time [tz-offset]
- @defunx time-tai->julian-day time
- @defunx time-tai->modified-julian-day time
- @defunx time-tai->time-monotonic time
- @defunx time-tai->time-monotonic! time
- @defunx time-tai->time-utc time
- @defunx time-tai->time-utc! time
- @end defun
- @defun time-utc->date time [tz-offset]
- @defunx time-utc->julian-day time
- @defunx time-utc->modified-julian-day time
- @defunx time-utc->time-monotonic time
- @defunx time-utc->time-monotonic! time
- @defunx time-utc->time-tai time
- @defunx time-utc->time-tai! time
- @sp 1
- Convert between dates, times and days of the respective types. For
- instance @code{time-tai->time-utc} accepts a @var{time} object of type
- @code{time-tai} and returns an object of type @code{time-utc}.
- The @code{!} variants may modify their @var{time} argument to form
- their return. The plain functions create a new object.
- For conversions to dates, @var{tz-offset} is seconds east of
- Greenwich. The default is the local timezone, at the given time, as
- provided by the system, using @code{localtime} (@pxref{Time}).
- On 32-bit systems, @code{localtime} is limited to a 32-bit
- @code{time_t}, so a default @var{tz-offset} is only available for
- times between Dec 1901 and Jan 2038. For prior dates an application
- might like to use the value in 1902, though some locations have zone
- changes prior to that. For future dates an application might like to
- assume today's rules extend indefinitely. But for correct daylight
- savings transitions it will be necessary to take an offset for the
- same day and time but a year in range and which has the same starting
- weekday and same leap/non-leap (to support rules like last Sunday in
- October).
- @end defun
- @node SRFI-19 Date to string
- @subsubsection SRFI-19 Date to string
- @cindex date to string
- @cindex string, from date
- @defun date->string date [format]
- Convert a date to a string under the control of a format.
- @var{format} should be a string containing @samp{~} escapes, which
- will be expanded as per the following conversion table. The default
- @var{format} is @samp{~c}, a locale-dependent date and time.
- Many of these conversion characters are the same as POSIX
- @code{strftime} (@pxref{Time}), but there are some extras and some
- variations.
- @multitable {MMMM} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
- @item @nicode{~~} @tab literal ~
- @item @nicode{~a} @tab locale abbreviated weekday, eg.@: @samp{Sun}
- @item @nicode{~A} @tab locale full weekday, eg.@: @samp{Sunday}
- @item @nicode{~b} @tab locale abbreviated month, eg.@: @samp{Jan}
- @item @nicode{~B} @tab locale full month, eg.@: @samp{January}
- @item @nicode{~c} @tab locale date and time, eg.@: @*
- @samp{Fri Jul 14 20:28:42-0400 2000}
- @item @nicode{~d} @tab day of month, zero padded, @samp{01} to @samp{31}
- @c Spec says d/m/y, reference implementation says m/d/y.
- @c Apparently the reference code was the intention, but would like to
- @c see an errata published for the spec before contradicting it here.
- @c
- @c @item @nicode{~D} @tab date @nicode{~d/~m/~y}
- @item @nicode{~e} @tab day of month, blank padded, @samp{ 1} to @samp{31}
- @item @nicode{~f} @tab seconds and fractional seconds,
- with locale decimal point, eg.@: @samp{5.2}
- @item @nicode{~h} @tab same as @nicode{~b}
- @item @nicode{~H} @tab hour, 24-hour clock, zero padded, @samp{00} to @samp{23}
- @item @nicode{~I} @tab hour, 12-hour clock, zero padded, @samp{01} to @samp{12}
- @item @nicode{~j} @tab day of year, zero padded, @samp{001} to @samp{366}
- @item @nicode{~k} @tab hour, 24-hour clock, blank padded, @samp{ 0} to @samp{23}
- @item @nicode{~l} @tab hour, 12-hour clock, blank padded, @samp{ 1} to @samp{12}
- @item @nicode{~m} @tab month, zero padded, @samp{01} to @samp{12}
- @item @nicode{~M} @tab minute, zero padded, @samp{00} to @samp{59}
- @item @nicode{~n} @tab newline
- @item @nicode{~N} @tab nanosecond, zero padded, @samp{000000000} to @samp{999999999}
- @item @nicode{~p} @tab locale AM or PM
- @item @nicode{~r} @tab time, 12 hour clock, @samp{~I:~M:~S ~p}
- @item @nicode{~s} @tab number of full seconds since ``the epoch'' in UTC
- @item @nicode{~S} @tab second, zero padded @samp{00} to @samp{60} @*
- (usual limit is 59, 60 is a leap second)
- @item @nicode{~t} @tab horizontal tab character
- @item @nicode{~T} @tab time, 24 hour clock, @samp{~H:~M:~S}
- @item @nicode{~U} @tab week of year, Sunday first day of week,
- @samp{00} to @samp{52}
- @item @nicode{~V} @tab week of year, Monday first day of week,
- @samp{01} to @samp{53}
- @item @nicode{~w} @tab day of week, 0 for Sunday, @samp{0} to @samp{6}
- @item @nicode{~W} @tab week of year, Monday first day of week,
- @samp{00} to @samp{52}
- @c The spec has ~x as an apparent duplicate of ~W, and ~X as a locale
- @c date. The reference code has ~x as the locale date and ~X as a
- @c locale time. The rule is apparently that the code should be
- @c believed, but would like to see an errata for the spec before
- @c contradicting it here.
- @c
- @c @item @nicode{~x} @tab week of year, Monday as first day of week,
- @c @samp{00} to @samp{53}
- @c @item @nicode{~X} @tab locale date, eg.@: @samp{07/31/00}
- @item @nicode{~y} @tab year, two digits, @samp{00} to @samp{99}
- @item @nicode{~Y} @tab year, full, eg.@: @samp{2003}
- @item @nicode{~z} @tab time zone, RFC-822 style
- @item @nicode{~Z} @tab time zone symbol (not currently implemented)
- @item @nicode{~1} @tab ISO-8601 date, @samp{~Y-~m-~d}
- @item @nicode{~2} @tab ISO-8601 time+zone, @samp{~H:~M:~S~z}
- @item @nicode{~3} @tab ISO-8601 time, @samp{~H:~M:~S}
- @item @nicode{~4} @tab ISO-8601 date/time+zone, @samp{~Y-~m-~dT~H:~M:~S~z}
- @item @nicode{~5} @tab ISO-8601 date/time, @samp{~Y-~m-~dT~H:~M:~S}
- @end multitable
- @end defun
- Conversions @samp{~D}, @samp{~x} and @samp{~X} are not currently
- described here, since the specification and reference implementation
- differ.
- Conversion is locale-dependent on systems that support it
- (@pxref{Accessing Locale Information}). @xref{Locales,
- @code{setlocale}}, for information on how to change the current
- locale.
- @node SRFI-19 String to date
- @subsubsection SRFI-19 String to date
- @cindex string to date
- @cindex date, from string
- @c FIXME: Can we say what happens when an incomplete date is
- @c converted? I.e. fields left as 0, or what? The spec seems to be
- @c silent on this.
- @defun string->date input template
- Convert an @var{input} string to a date under the control of a
- @var{template} string. Return a newly created date object.
- Literal characters in @var{template} must match characters in
- @var{input} and @samp{~} escapes must match the input forms described
- in the table below. ``Skip to'' means characters up to one of the
- given type are ignored, or ``no skip'' for no skipping. ``Read'' is
- what's then read, and ``Set'' is the field affected in the date
- object.
- For example @samp{~Y} skips input characters until a digit is reached,
- at which point it expects a year and stores that to the year field of
- the date.
- @multitable {MMMM} {@nicode{char-alphabetic?}} {MMMMMMMMMMMMMMMMMMMMMMMMM} {@nicode{date-zone-offset}}
- @item
- @tab Skip to
- @tab Read
- @tab Set
- @item @nicode{~~}
- @tab no skip
- @tab literal ~
- @tab nothing
- @item @nicode{~a}
- @tab @nicode{char-alphabetic?}
- @tab locale abbreviated weekday name
- @tab nothing
- @item @nicode{~A}
- @tab @nicode{char-alphabetic?}
- @tab locale full weekday name
- @tab nothing
- @c Note that the SRFI spec says that ~b and ~B don't set anything,
- @c but that looks like a mistake. The reference implementation sets
- @c the month field, which seems sensible and is what we describe
- @c here.
- @item @nicode{~b}
- @tab @nicode{char-alphabetic?}
- @tab locale abbreviated month name
- @tab @nicode{date-month}
- @item @nicode{~B}
- @tab @nicode{char-alphabetic?}
- @tab locale full month name
- @tab @nicode{date-month}
- @item @nicode{~d}
- @tab @nicode{char-numeric?}
- @tab day of month
- @tab @nicode{date-day}
- @item @nicode{~e}
- @tab no skip
- @tab day of month, blank padded
- @tab @nicode{date-day}
- @item @nicode{~h}
- @tab same as @samp{~b}
- @item @nicode{~H}
- @tab @nicode{char-numeric?}
- @tab hour
- @tab @nicode{date-hour}
- @item @nicode{~k}
- @tab no skip
- @tab hour, blank padded
- @tab @nicode{date-hour}
- @item @nicode{~m}
- @tab @nicode{char-numeric?}
- @tab month
- @tab @nicode{date-month}
- @item @nicode{~M}
- @tab @nicode{char-numeric?}
- @tab minute
- @tab @nicode{date-minute}
- @item @nicode{~N}
- @tab @nicode{char-numeric?}
- @tab nanosecond
- @tab @nicode{date-nanosecond}
- @item @nicode{~S}
- @tab @nicode{char-numeric?}
- @tab second
- @tab @nicode{date-second}
- @item @nicode{~y}
- @tab no skip
- @tab 2-digit year
- @tab @nicode{date-year} within 50 years
- @item @nicode{~Y}
- @tab @nicode{char-numeric?}
- @tab year
- @tab @nicode{date-year}
- @item @nicode{~z}
- @tab no skip
- @tab time zone
- @tab date-zone-offset
- @end multitable
- Notice that the weekday matching forms don't affect the date object
- returned, instead the weekday will be derived from the day, month and
- year.
- Conversion is locale-dependent on systems that support it
- (@pxref{Accessing Locale Information}). @xref{Locales,
- @code{setlocale}}, for information on how to change the current
- locale.
- @end defun
- @node SRFI-23
- @subsection SRFI-23 - Error Reporting
- @cindex SRFI-23
- The SRFI-23 @code{error} procedure is always available.
- @node SRFI-26
- @subsection SRFI-26 - specializing parameters
- @cindex SRFI-26
- @cindex parameter specialize
- @cindex argument specialize
- @cindex specialize parameter
- This SRFI provides a syntax for conveniently specializing selected
- parameters of a function. It can be used with,
- @example
- (use-modules (srfi srfi-26))
- @end example
- @deffn {library syntax} cut slot1 slot2 @dots{}
- @deffnx {library syntax} cute slot1 slot2 @dots{}
- Return a new procedure which will make a call (@var{slot1} @var{slot2}
- @dots{}) but with selected parameters specialized to given expressions.
- An example will illustrate the idea. The following is a
- specialization of @code{write}, sending output to
- @code{my-output-port},
- @example
- (cut write <> my-output-port)
- @result{}
- (lambda (obj) (write obj my-output-port))
- @end example
- The special symbol @code{<>} indicates a slot to be filled by an
- argument to the new procedure. @code{my-output-port} on the other
- hand is an expression to be evaluated and passed, ie.@: it specializes
- the behavior of @code{write}.
- @table @nicode
- @item <>
- A slot to be filled by an argument from the created procedure.
- Arguments are assigned to @code{<>} slots in the order they appear in
- the @code{cut} form, there's no way to re-arrange arguments.
- The first argument to @code{cut} is usually a procedure (or expression
- giving a procedure), but @code{<>} is allowed there too. For example,
- @example
- (cut <> 1 2 3)
- @result{}
- (lambda (proc) (proc 1 2 3))
- @end example
- @item <...>
- A slot to be filled by all remaining arguments from the new procedure.
- This can only occur at the end of a @code{cut} form.
- For example, a procedure taking a variable number of arguments like
- @code{max} but in addition enforcing a lower bound,
- @example
- (define my-lower-bound 123)
- (cut max my-lower-bound <...>)
- @result{}
- (lambda arglist (apply max my-lower-bound arglist))
- @end example
- @end table
- For @code{cut} the specializing expressions are evaluated each time
- the new procedure is called. For @code{cute} they're evaluated just
- once, when the new procedure is created. The name @code{cute} stands
- for ``@code{cut} with evaluated arguments''. In all cases the
- evaluations take place in an unspecified order.
- The following illustrates the difference between @code{cut} and
- @code{cute},
- @example
- (cut format <> "the time is ~s" (current-time))
- @result{}
- (lambda (port) (format port "the time is ~s" (current-time)))
- (cute format <> "the time is ~s" (current-time))
- @result{}
- (let ((val (current-time)))
- (lambda (port) (format port "the time is ~s" val))
- @end example
- (There's no provision for a mixture of @code{cut} and @code{cute}
- where some expressions would be evaluated every time but others
- evaluated only once.)
- @code{cut} is really just a shorthand for the sort of @code{lambda}
- forms shown in the above examples. But notice @code{cut} avoids the
- need to name unspecialized parameters, and is more compact. Use in
- functional programming style or just with @code{map}, @code{for-each}
- or similar is typical.
- @example
- (map (cut * 2 <>) '(1 2 3 4))
- (for-each (cut write <> my-port) my-list)
- @end example
- @end deffn
- @node SRFI-27
- @subsection SRFI-27 - Sources of Random Bits
- @cindex SRFI-27
- This subsection is based on the
- @uref{http://srfi.schemers.org/srfi-27/srfi-27.html, specification of
- SRFI-27} written by Sebastian Egner.
- @c The copyright notice and license text of the SRFI-27 specification is
- @c reproduced below:
- @c Copyright (C) Sebastian Egner (2002). All Rights Reserved.
- @c Permission is hereby granted, free of charge, to any person obtaining a
- @c copy of this software and associated documentation files (the
- @c "Software"), to deal in the Software without restriction, including
- @c without limitation the rights to use, copy, modify, merge, publish,
- @c distribute, sublicense, and/or sell copies of the Software, and to
- @c permit persons to whom the Software is furnished to do so, subject to
- @c the following conditions:
- @c The above copyright notice and this permission notice shall be included
- @c in all copies or substantial portions of the Software.
- @c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- @c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- @c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- @c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- @c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- @c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- @c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- This SRFI provides access to a (pseudo) random number generator; for
- Guile's built-in random number facilities, which SRFI-27 is implemented
- upon, @xref{Random}. With SRFI-27, random numbers are obtained from a
- @emph{random source}, which encapsulates a random number generation
- algorithm and its state.
- @menu
- * SRFI-27 Default Random Source:: Obtaining random numbers
- * SRFI-27 Random Sources:: Creating and manipulating random sources
- * SRFI-27 Random Number Generators:: Obtaining random number generators
- @end menu
- @node SRFI-27 Default Random Source
- @subsubsection The Default Random Source
- @cindex SRFI-27
- @defun random-integer n
- Return a random number between zero (inclusive) and @var{n} (exclusive),
- using the default random source. The numbers returned have a uniform
- distribution.
- @end defun
- @defun random-real
- Return a random number in (0,1), using the default random source. The
- numbers returned have a uniform distribution.
- @end defun
- @defun default-random-source
- A random source from which @code{random-integer} and @code{random-real}
- have been derived using @code{random-source-make-integers} and
- @code{random-source-make-reals} (@pxref{SRFI-27 Random Number Generators}
- for those procedures). Note that an assignment to
- @code{default-random-source} does not change @code{random-integer} or
- @code{random-real}; it is also strongly recommended not to assign a new
- value.
- @end defun
- @node SRFI-27 Random Sources
- @subsubsection Random Sources
- @cindex SRFI-27
- @defun make-random-source
- Create a new random source. The stream of random numbers obtained from
- each random source created by this procedure will be identical, unless
- its state is changed by one of the procedures below.
- @end defun
- @defun random-source? object
- Tests whether @var{object} is a random source. Random sources are a
- disjoint type.
- @end defun
- @defun random-source-randomize! source
- Attempt to set the state of the random source to a truly random value.
- The current implementation uses a seed based on the current system time.
- @end defun
- @defun random-source-pseudo-randomize! source i j
- Changes the state of the random source s into the initial state of the
- (@var{i}, @var{j})-th independent random source, where @var{i} and
- @var{j} are non-negative integers. This procedure provides a mechanism
- to obtain a large number of independent random sources (usually all
- derived from the same backbone generator), indexed by two integers. In
- contrast to @code{random-source-randomize!}, this procedure is entirely
- deterministic.
- @end defun
- The state associated with a random state can be obtained an reinstated
- with the following procedures:
- @defun random-source-state-ref source
- @defunx random-source-state-set! source state
- Get and set the state of a random source. No assumptions should be made
- about the nature of the state object, besides it having an external
- representation (i.e.@: it can be passed to @code{write} and subsequently
- @code{read} back).
- @end defun
- @node SRFI-27 Random Number Generators
- @subsubsection Obtaining random number generator procedures
- @cindex SRFI-27
- @defun random-source-make-integers source
- Obtains a procedure to generate random integers using the random source
- @var{source}. The returned procedure takes a single argument @var{n},
- which must be a positive integer, and returns the next uniformly
- distributed random integer from the interval @{0, ..., @var{n}-1@} by
- advancing the state of @var{source}.
- If an application obtains and uses several generators for the same
- random source @var{source}, a call to any of these generators advances
- the state of @var{source}. Hence, the generators do not produce the
- same sequence of random integers each but rather share a state. This
- also holds for all other types of generators derived from a fixed random
- sources.
- While the SRFI text specifies that ``Implementations that support
- concurrency make sure that the state of a generator is properly
- advanced'', this is currently not the case in Guile's implementation of
- SRFI-27, as it would cause a severe performance penalty. So in
- multi-threaded programs, you either must perform locking on random
- sources shared between threads yourself, or use different random sources
- for multiple threads.
- @end defun
- @defun random-source-make-reals source
- @defunx random-source-make-reals source unit
- Obtains a procedure to generate random real numbers @math{0 < x < 1}
- using the random source @var{source}. The procedure rand is called
- without arguments.
- The optional parameter @var{unit} determines the type of numbers being
- produced by the returned procedure and the quantization of the output.
- @var{unit} must be a number such that @math{0 < @var{unit} < 1}. The
- numbers created by the returned procedure are of the same numerical type
- as @var{unit} and the potential output values are spaced by at most
- @var{unit}. One can imagine rand to create numbers as @var{x} *
- @var{unit} where @var{x} is a random integer in @{1, ...,
- floor(1/unit)-1@}. Note, however, that this need not be the way the
- values are actually created and that the actual resolution of rand can
- be much higher than unit. In case @var{unit} is absent it defaults to a
- reasonably small value (related to the width of the mantissa of an
- efficient number format).
- @end defun
- @node SRFI-28
- @subsection SRFI-28 - Basic Format Strings
- @cindex SRFI-28
- SRFI-28 provides a basic @code{format} procedure that provides only
- the @code{~a}, @code{~s}, @code{~%}, and @code{~~} format specifiers.
- You can import this procedure by using:
- @lisp
- (use-modules (srfi srfi-28))
- @end lisp
- @deffn {Scheme Procedure} format message arg @dots{}
- Returns a formatted message, using @var{message} as the format string,
- which can contain the following format specifiers:
- @table @code
- @item ~a
- Insert the textual representation of the next @var{arg}, as if printed
- by @code{display}.
- @item ~s
- Insert the textual representation of the next @var{arg}, as if printed
- by @code{write}.
- @item ~%
- Insert a newline.
- @item ~~
- Insert a tilde.
- @end table
- This procedure is the same as calling @code{simple-format}
- (@pxref{Simple Output}) with @code{#f} as the destination.
- @end deffn
- @node SRFI-30
- @subsection SRFI-30 - Nested Multi-line Comments
- @cindex SRFI-30
- Starting from version 2.0, Guile's @code{read} supports SRFI-30/R6RS
- nested multi-line comments by default, @ref{Block Comments}.
- @node SRFI-31
- @subsection SRFI-31 - A special form `rec' for recursive evaluation
- @cindex SRFI-31
- @cindex recursive expression
- @findex rec
- SRFI-31 defines a special form that can be used to create
- self-referential expressions more conveniently. The syntax is as
- follows:
- @example
- @group
- <rec expression> --> (rec <variable> <expression>)
- <rec expression> --> (rec (<variable>+) <body>)
- @end group
- @end example
- The first syntax can be used to create self-referential expressions,
- for example:
- @lisp
- guile> (define tmp (rec ones (cons 1 (delay ones))))
- @end lisp
- The second syntax can be used to create anonymous recursive functions:
- @lisp
- guile> (define tmp (rec (display-n item n)
- (if (positive? n)
- (begin (display n) (display-n (- n 1))))))
- guile> (tmp 42 3)
- 424242
- guile>
- @end lisp
- @node SRFI-34
- @subsection SRFI-34 - Exception handling for programs
- @cindex SRFI-34
- Guile provides an implementation of
- @uref{http://srfi.schemers.org/srfi-34/srfi-34.html, SRFI-34's exception
- handling mechanisms} as an alternative to its own built-in mechanisms
- (@pxref{Exceptions}). It can be made available as follows:
- @lisp
- (use-modules (srfi srfi-34))
- @end lisp
- @xref{Raising and Handling Exceptions}, for more on
- @code{with-exception-handler} and @code{raise} (known as
- @code{raise-exception} in core Guile).
- SRFI-34's @code{guard} form is syntactic sugar over
- @code{with-exception-handler}:
- @deffn {Syntax} guard (var clause @dots{}) body @dots{}
- Evaluate @var{body} with an exception handler that binds the raised
- object to @var{var} and within the scope of that binding evaluates
- @var{clause}@dots{} as if they were the clauses of a cond expression.
- That implicit cond expression is evaluated with the continuation and
- dynamic environment of the guard expression.
- If every @var{clause}'s test evaluates to false and there is no
- @code{else} clause, then @code{raise} is re-invoked on the raised object
- within the dynamic environment of the original call to @code{raise}
- except that the current exception handler is that of the @code{guard}
- expression.
- @end deffn
- @node SRFI-35
- @subsection SRFI-35 - Conditions
- @cindex SRFI-35
- @cindex conditions
- @cindex exceptions
- @uref{http://srfi.schemers.org/srfi-35/srfi-35.html, SRFI-35} defines
- @dfn{conditions}, a data structure akin to records designed to convey
- information about exceptional conditions between parts of a program. It
- is normally used in conjunction with SRFI-34's @code{raise}:
- @lisp
- (raise (condition (&message
- (message "An error occurred"))))
- @end lisp
- Users can define @dfn{condition types} containing arbitrary information.
- Condition types may inherit from one another. This allows the part of
- the program that handles (or ``catches'') conditions to get accurate
- information about the exceptional condition that arose.
- SRFI-35 conditions are made available using:
- @lisp
- (use-modules (srfi srfi-35))
- @end lisp
- The procedures available to manipulate condition types are the
- following:
- @deffn {Scheme Procedure} make-condition-type id parent field-names
- Return a new condition type named @var{id}, inheriting from
- @var{parent}, and with the fields whose names are listed in
- @var{field-names}. @var{field-names} must be a list of symbols and must
- not contain names already used by @var{parent} or one of its supertypes.
- @end deffn
- @deffn {Scheme Procedure} condition-type? obj
- Return true if @var{obj} is a condition type.
- @end deffn
- Conditions can be created and accessed with the following procedures:
- @deffn {Scheme Procedure} make-condition type . field+value
- Return a new condition of type @var{type} with fields initialized as
- specified by @var{field+value}, a sequence of field names (symbols) and
- values as in the following example:
- @lisp
- (let ((&ct (make-condition-type 'foo &condition '(a b c))))
- (make-condition &ct 'a 1 'b 2 'c 3))
- @end lisp
- Note that all fields of @var{type} and its supertypes must be specified.
- @end deffn
- @deffn {Scheme Procedure} make-compound-condition condition1 condition2 @dots{}
- Return a new compound condition composed of @var{condition1}
- @var{condition2} @enddots{}. The returned condition has the type of
- each condition of condition1 condition2 @dots{} (per
- @code{condition-has-type?}).
- @end deffn
- @deffn {Scheme Procedure} condition-has-type? c type
- Return true if condition @var{c} has type @var{type}.
- @end deffn
- @deffn {Scheme Procedure} condition-ref c field-name
- Return the value of the field named @var{field-name} from condition @var{c}.
- If @var{c} is a compound condition and several underlying condition
- types contain a field named @var{field-name}, then the value of the
- first such field is returned, using the order in which conditions were
- passed to @code{make-compound-condition}.
- @end deffn
- @deffn {Scheme Procedure} extract-condition c type
- Return a condition of condition type @var{type} with the field values
- specified by @var{c}.
- If @var{c} is a compound condition, extract the field values from the
- subcondition belonging to @var{type} that appeared first in the call to
- @code{make-compound-condition} that created the condition.
- @end deffn
- Convenience macros are also available to create condition types and
- conditions.
- @deffn {library syntax} define-condition-type type supertype predicate field-spec...
- Define a new condition type named @var{type} that inherits from
- @var{supertype}. In addition, bind @var{predicate} to a type predicate
- that returns true when passed a condition of type @var{type} or any of
- its subtypes. @var{field-spec} must have the form @code{(field
- accessor)} where @var{field} is the name of field of @var{type} and
- @var{accessor} is the name of a procedure to access field @var{field} in
- conditions of type @var{type}.
- The example below defines condition type @code{&foo}, inheriting from
- @code{&condition} with fields @code{a}, @code{b} and @code{c}:
- @lisp
- (define-condition-type &foo &condition
- foo-condition?
- (a foo-a)
- (b foo-b)
- (c foo-c))
- @end lisp
- @end deffn
- @deffn {library syntax} condition type-field-binding1 type-field-binding2 @dots{}
- Return a new condition or compound condition, initialized according to
- @var{type-field-binding1} @var{type-field-binding2} @enddots{}. Each
- @var{type-field-binding} must have the form @code{(type
- field-specs...)}, where @var{type} is the name of a variable bound to a
- condition type; each @var{field-spec} must have the form
- @code{(field-name value)} where @var{field-name} is a symbol denoting
- the field being initialized to @var{value}. As for
- @code{make-condition}, all fields must be specified.
- The following example returns a simple condition:
- @lisp
- (condition (&message (message "An error occurred")))
- @end lisp
- The one below returns a compound condition:
- @lisp
- (condition (&message (message "An error occurred"))
- (&serious))
- @end lisp
- @end deffn
- Finally, SRFI-35 defines a several standard condition types.
- @defvar &condition
- This condition type is the root of all condition types. It has no
- fields.
- @end defvar
- @defvar &message
- A condition type that carries a message describing the nature of the
- condition to humans.
- @end defvar
- @deffn {Scheme Procedure} message-condition? c
- Return true if @var{c} is of type @code{&message} or one of its
- subtypes.
- @end deffn
- @deffn {Scheme Procedure} condition-message c
- Return the message associated with message condition @var{c}.
- @end deffn
- @defvar &serious
- This type describes conditions serious enough that they cannot safely be
- ignored. It has no fields.
- @end defvar
- @deffn {Scheme Procedure} serious-condition? c
- Return true if @var{c} is of type @code{&serious} or one of its
- subtypes.
- @end deffn
- @defvar &error
- This condition describes errors, typically caused by something that has
- gone wrong in the interaction of the program with the external world or
- the user.
- @end defvar
- @deffn {Scheme Procedure} error? c
- Return true if @var{c} is of type @code{&error} or one of its subtypes.
- @end deffn
- As an implementation note, condition objects in Guile are the same as
- ``exception objects''. @xref{Exception Objects}. The
- @code{&condition}, @code{&serious}, and @code{&error} condition types
- are known in core Guile as @code{&exception}, @code{&error}, and
- @code{&external-error}, respectively.
- @node SRFI-37
- @subsection SRFI-37 - args-fold
- @cindex SRFI-37
- This is a processor for GNU @code{getopt_long}-style program
- arguments. It provides an alternative, less declarative interface
- than @code{getopt-long} in @code{(ice-9 getopt-long)}
- (@pxref{getopt-long,,The (ice-9 getopt-long) Module}). Unlike
- @code{getopt-long}, it supports repeated options and any number of
- short and long names per option. Access it with:
- @lisp
- (use-modules (srfi srfi-37))
- @end lisp
- @acronym{SRFI}-37 principally provides an @code{option} type and the
- @code{args-fold} function. To use the library, create a set of
- options with @code{option} and use it as a specification for invoking
- @code{args-fold}.
- Here is an example of a simple argument processor for the typical
- @samp{--version} and @samp{--help} options, which returns a backwards
- list of files given on the command line:
- @lisp
- (args-fold (cdr (program-arguments))
- (let ((display-and-exit-proc
- (lambda (msg)
- (lambda (opt name arg loads)
- (display msg) (quit)))))
- (list (option '(#\v "version") #f #f
- (display-and-exit-proc "Foo version 42.0\n"))
- (option '(#\h "help") #f #f
- (display-and-exit-proc
- "Usage: foo scheme-file ..."))))
- (lambda (opt name arg loads)
- (error "Unrecognized option `~A'" name))
- (lambda (op loads) (cons op loads))
- '())
- @end lisp
- @deffn {Scheme Procedure} option names required-arg? optional-arg? processor
- Return an object that specifies a single kind of program option.
- @var{names} is a list of command-line option names, and should consist of
- characters for traditional @code{getopt} short options and strings for
- @code{getopt_long}-style long options.
- @var{required-arg?} and @var{optional-arg?} are mutually exclusive;
- one or both must be @code{#f}. If @var{required-arg?}, the option
- must be followed by an argument on the command line, such as
- @samp{--opt=value} for long options, or an error will be signaled.
- If @var{optional-arg?}, an argument will be taken if available.
- @var{processor} is a procedure that takes at least 3 arguments, called
- when @code{args-fold} encounters the option: the containing option
- object, the name used on the command line, and the argument given for
- the option (or @code{#f} if none). The rest of the arguments are
- @code{args-fold} ``seeds'', and the @var{processor} should return
- seeds as well.
- @end deffn
- @deffn {Scheme Procedure} option-names opt
- @deffnx {Scheme Procedure} option-required-arg? opt
- @deffnx {Scheme Procedure} option-optional-arg? opt
- @deffnx {Scheme Procedure} option-processor opt
- Return the specified field of @var{opt}, an option object, as
- described above for @code{option}.
- @end deffn
- @deffn {Scheme Procedure} args-fold args options unrecognized-option-proc operand-proc seed @dots{}
- Process @var{args}, a list of program arguments such as that returned by
- @code{(cdr (program-arguments))}, in order against @var{options}, a list
- of option objects as described above. All functions called take the
- ``seeds'', or the last multiple-values as multiple arguments, starting
- with @var{seed} @dots{}, and must return the new seeds. Return the
- final seeds.
- Call @code{unrecognized-option-proc}, which is like an option object's
- processor, for any options not found in @var{options}.
- Call @code{operand-proc} with any items on the command line that are
- not named options. This includes arguments after @samp{--}. It is
- called with the argument in question, as well as the seeds.
- @end deffn
- @node SRFI-38
- @subsection SRFI-38 - External Representation for Data With Shared Structure
- @cindex SRFI-38
- This subsection is based on
- @uref{http://srfi.schemers.org/srfi-38/srfi-38.html, the specification
- of SRFI-38} written by Ray Dillinger.
- @c Copyright (C) Ray Dillinger 2003. All Rights Reserved.
- @c Permission is hereby granted, free of charge, to any person obtaining a
- @c copy of this software and associated documentation files (the
- @c "Software"), to deal in the Software without restriction, including
- @c without limitation the rights to use, copy, modify, merge, publish,
- @c distribute, sublicense, and/or sell copies of the Software, and to
- @c permit persons to whom the Software is furnished to do so, subject to
- @c the following conditions:
- @c The above copyright notice and this permission notice shall be included
- @c in all copies or substantial portions of the Software.
- @c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- @c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- @c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- @c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- @c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- @c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- @c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- This SRFI creates an alternative external representation for data
- written and read using @code{write-with-shared-structure} and
- @code{read-with-shared-structure}. It is identical to the grammar for
- external representation for data written and read with @code{write} and
- @code{read} given in section 7 of R5RS, except that the single
- production
- @example
- <datum> --> <simple datum> | <compound datum>
- @end example
- is replaced by the following five productions:
- @example
- <datum> --> <defining datum> | <nondefining datum> | <defined datum>
- <defining datum> --> #<indexnum>=<nondefining datum>
- <defined datum> --> #<indexnum>#
- <nondefining datum> --> <simple datum> | <compound datum>
- <indexnum> --> <digit 10>+
- @end example
- @deffn {Scheme procedure} write-with-shared-structure obj
- @deffnx {Scheme procedure} write-with-shared-structure obj port
- @deffnx {Scheme procedure} write-with-shared-structure obj port optarg
- Writes an external representation of @var{obj} to the given port.
- Strings that appear in the written representation are enclosed in
- doublequotes, and within those strings backslash and doublequote
- characters are escaped by backslashes. Character objects are written
- using the @code{#\} notation.
- Objects which denote locations rather than values (cons cells, vectors,
- and non-zero-length strings in R5RS scheme; also Guile's structs,
- bytevectors and ports and hash-tables), if they appear at more than one
- point in the data being written, are preceded by @samp{#@var{N}=} the
- first time they are written and replaced by @samp{#@var{N}#} all
- subsequent times they are written, where @var{N} is a natural number
- used to identify that particular object. If objects which denote
- locations occur only once in the structure, then
- @code{write-with-shared-structure} must produce the same external
- representation for those objects as @code{write}.
- @code{write-with-shared-structure} terminates in finite time and
- produces a finite representation when writing finite data.
- @code{write-with-shared-structure} returns an unspecified value. The
- @var{port} argument may be omitted, in which case it defaults to the
- value returned by @code{(current-output-port)}. The @var{optarg}
- argument may also be omitted. If present, its effects on the output and
- return value are unspecified but @code{write-with-shared-structure} must
- still write a representation that can be read by
- @code{read-with-shared-structure}. Some implementations may wish to use
- @var{optarg} to specify formatting conventions, numeric radixes, or
- return values. Guile's implementation ignores @var{optarg}.
- For example, the code
- @lisp
- (begin (define a (cons 'val1 'val2))
- (set-cdr! a a)
- (write-with-shared-structure a))
- @end lisp
- should produce the output @code{#1=(val1 . #1#)}. This shows a cons
- cell whose @code{cdr} contains itself.
- @end deffn
- @deffn {Scheme procedure} read-with-shared-structure
- @deffnx {Scheme procedure} read-with-shared-structure port
- @code{read-with-shared-structure} converts the external representations
- of Scheme objects produced by @code{write-with-shared-structure} into
- Scheme objects. That is, it is a parser for the nonterminal
- @samp{<datum>} in the augmented external representation grammar defined
- above. @code{read-with-shared-structure} returns the next object
- parsable from the given input port, updating @var{port} to point to the
- first character past the end of the external representation of the
- object.
- If an end-of-file is encountered in the input before any characters are
- found that can begin an object, then an end-of-file object is returned.
- The port remains open, and further attempts to read it (by
- @code{read-with-shared-structure} or @code{read} will also return an
- end-of-file object. If an end of file is encountered after the
- beginning of an object's external representation, but the external
- representation is incomplete and therefore not parsable, an error is
- signaled.
- The @var{port} argument may be omitted, in which case it defaults to the
- value returned by @code{(current-input-port)}. It is an error to read
- from a closed port.
- @end deffn
- @node SRFI-39
- @subsection SRFI-39 - Parameters
- @cindex SRFI-39
- This SRFI adds support for dynamically-scoped parameters. SRFI 39 is
- implemented in the Guile core; there's no module needed to get SRFI-39
- itself. Parameters are documented in @ref{Parameters}.
- This module does export one extra function: @code{with-parameters*}.
- This is a Guile-specific addition to the SRFI, similar to the core
- @code{with-fluids*} (@pxref{Fluids and Dynamic States}).
- @defun with-parameters* param-list value-list thunk
- Establish a new dynamic scope, as per @code{parameterize} above,
- taking parameters from @var{param-list} and corresponding values from
- @var{value-list}. A call @code{(@var{thunk})} is made in the new
- scope and the result from that @var{thunk} is the return from
- @code{with-parameters*}.
- @end defun
- @node SRFI-41
- @subsection SRFI-41 - Streams
- @cindex SRFI-41
- This subsection is based on the
- @uref{http://srfi.schemers.org/srfi-41/srfi-41.html, specification of
- SRFI-41} by Philip L.@: Bewig.
- @c The copyright notice and license text of the SRFI-41 specification is
- @c reproduced below:
- @c Copyright (C) Philip L. Bewig (2007). All Rights Reserved.
- @c Permission is hereby granted, free of charge, to any person obtaining a
- @c copy of this software and associated documentation files (the
- @c "Software"), to deal in the Software without restriction, including
- @c without limitation the rights to use, copy, modify, merge, publish,
- @c distribute, sublicense, and/or sell copies of the Software, and to
- @c permit persons to whom the Software is furnished to do so, subject to
- @c the following conditions:
- @c The above copyright notice and this permission notice shall be included
- @c in all copies or substantial portions of the Software.
- @c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- @c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- @c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- @c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- @c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- @c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- @c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- @noindent
- This SRFI implements streams, sometimes called lazy lists, a sequential
- data structure containing elements computed only on demand. A stream is
- either null or is a pair with a stream in its cdr. Since elements of a
- stream are computed only when accessed, streams can be infinite. Once
- computed, the value of a stream element is cached in case it is needed
- again. SRFI-41 can be made available with:
- @example
- (use-modules (srfi srfi-41))
- @end example
- @menu
- * SRFI-41 Stream Fundamentals::
- * SRFI-41 Stream Primitives::
- * SRFI-41 Stream Library::
- @end menu
- @node SRFI-41 Stream Fundamentals
- @subsubsection SRFI-41 Stream Fundamentals
- SRFI-41 Streams are based on two mutually-recursive abstract data types:
- An object of the @code{stream} abstract data type is a promise that,
- when forced, is either @code{stream-null} or is an object of type
- @code{stream-pair}. An object of the @code{stream-pair} abstract data
- type contains a @code{stream-car} and a @code{stream-cdr}, which must be
- a @code{stream}. The essential feature of streams is the systematic
- suspensions of the recursive promises between the two data types.
- The object stored in the @code{stream-car} of a @code{stream-pair} is a
- promise that is forced the first time the @code{stream-car} is accessed;
- its value is cached in case it is needed again. The object may have any
- type, and different stream elements may have different types. If the
- @code{stream-car} is never accessed, the object stored there is never
- evaluated. Likewise, the @code{stream-cdr} is a promise to return a
- stream, and is only forced on demand.
- @node SRFI-41 Stream Primitives
- @subsubsection SRFI-41 Stream Primitives
- This library provides eight operators: constructors for
- @code{stream-null} and @code{stream-pair}s, type predicates for streams
- and the two kinds of streams, accessors for both fields of a
- @code{stream-pair}, and a lambda that creates procedures that return
- streams.
- @defvr {Scheme Variable} stream-null
- A promise that, when forced, is a single object, distinguishable from
- all other objects, that represents the null stream. @code{stream-null}
- is immutable and unique.
- @end defvr
- @deffn {Scheme Syntax} stream-cons object-expr stream-expr
- Creates a newly-allocated stream containing a promise that, when forced,
- is a @code{stream-pair} with @var{object-expr} in its @code{stream-car}
- and @var{stream-expr} in its @code{stream-cdr}. Neither
- @var{object-expr} nor @var{stream-expr} is evaluated when
- @code{stream-cons} is called.
- Once created, a @code{stream-pair} is immutable; there is no
- @code{stream-set-car!} or @code{stream-set-cdr!} that modifies an
- existing stream-pair. There is no dotted-pair or improper stream as
- with lists.
- @end deffn
- @deffn {Scheme Procedure} stream? object
- Returns true if @var{object} is a stream, otherwise returns false. If
- @var{object} is a stream, its promise will not be forced. If
- @code{(stream? obj)} returns true, then one of @code{(stream-null? obj)}
- or @code{(stream-pair? obj)} will return true and the other will return
- false.
- @end deffn
- @deffn {Scheme Procedure} stream-null? object
- Returns true if @var{object} is the distinguished null stream, otherwise
- returns false. If @var{object} is a stream, its promise will be forced.
- @end deffn
- @deffn {Scheme Procedure} stream-pair? object
- Returns true if @var{object} is a @code{stream-pair} constructed by
- @code{stream-cons}, otherwise returns false. If @var{object} is a
- stream, its promise will be forced.
- @end deffn
- @deffn {Scheme Procedure} stream-car stream
- Returns the object stored in the @code{stream-car} of @var{stream}. An
- error is signaled if the argument is not a @code{stream-pair}. This
- causes the @var{object-expr} passed to @code{stream-cons} to be
- evaluated if it had not yet been; the value is cached in case it is
- needed again.
- @end deffn
- @deffn {Scheme Procedure} stream-cdr stream
- Returns the stream stored in the @code{stream-cdr} of @var{stream}. An
- error is signaled if the argument is not a @code{stream-pair}.
- @end deffn
- @deffn {Scheme Syntax} stream-lambda formals body @dots{}
- Creates a procedure that returns a promise to evaluate the @var{body} of
- the procedure. The last @var{body} expression to be evaluated must
- yield a stream. As with normal @code{lambda}, @var{formals} may be a
- single variable name, in which case all the formal arguments are
- collected into a single list, or a list of variable names, which may be
- null if there are no arguments, proper if there are an exact number of
- arguments, or dotted if a fixed number of arguments is to be followed by
- zero or more arguments collected into a list. @var{Body} must contain
- at least one expression, and may contain internal definitions preceding
- any expressions to be evaluated.
- @end deffn
- @example
- (define strm123
- (stream-cons 1
- (stream-cons 2
- (stream-cons 3
- stream-null))))
- (stream-car strm123) @result{} 1
- (stream-car (stream-cdr strm123) @result{} 2
- (stream-pair?
- (stream-cdr
- (stream-cons (/ 1 0) stream-null))) @result{} #f
- (stream? (list 1 2 3)) @result{} #f
- (define iter
- (stream-lambda (f x)
- (stream-cons x (iter f (f x)))))
- (define nats (iter (lambda (x) (+ x 1)) 0))
- (stream-car (stream-cdr nats)) @result{} 1
- (define stream-add
- (stream-lambda (s1 s2)
- (stream-cons
- (+ (stream-car s1) (stream-car s2))
- (stream-add (stream-cdr s1)
- (stream-cdr s2)))))
- (define evens (stream-add nats nats))
- (stream-car evens) @result{} 0
- (stream-car (stream-cdr evens)) @result{} 2
- (stream-car (stream-cdr (stream-cdr evens))) @result{} 4
- @end example
- @node SRFI-41 Stream Library
- @subsubsection SRFI-41 Stream Library
- @deffn {Scheme Syntax} define-stream (name args @dots{}) body @dots{}
- Creates a procedure that returns a stream, and may appear anywhere a
- normal @code{define} may appear, including as an internal definition.
- It may contain internal definitions of its own. The defined procedure
- takes arguments in the same way as @code{stream-lambda}.
- @code{define-stream} is syntactic sugar on @code{stream-lambda}; see
- also @code{stream-let}, which is also a sugaring of
- @code{stream-lambda}.
- A simple version of @code{stream-map} that takes only a single input
- stream calls itself recursively:
- @example
- (define-stream (stream-map proc strm)
- (if (stream-null? strm)
- stream-null
- (stream-cons
- (proc (stream-car strm))
- (stream-map proc (stream-cdr strm))))))
- @end example
- @end deffn
- @deffn {Scheme Procedure} list->stream list
- Returns a newly-allocated stream containing the elements from
- @var{list}.
- @end deffn
- @deffn {Scheme Procedure} port->stream [port]
- Returns a newly-allocated stream containing in its elements the
- characters on the port. If @var{port} is not given it defaults to the
- current input port. The returned stream has finite length and is
- terminated by @code{stream-null}.
- It looks like one use of @code{port->stream} would be this:
- @example
- (define s ;wrong!
- (with-input-from-file filename
- (lambda () (port->stream))))
- @end example
- But that fails, because @code{with-input-from-file} is eager, and closes
- the input port prematurely, before the first character is read. To read
- a file into a stream, say:
- @example
- (define-stream (file->stream filename)
- (let ((p (open-input-file filename)))
- (stream-let loop ((c (read-char p)))
- (if (eof-object? c)
- (begin (close-input-port p)
- stream-null)
- (stream-cons c
- (loop (read-char p)))))))
- @end example
- @end deffn
- @deffn {Scheme Syntax} stream object-expr @dots{}
- Creates a newly-allocated stream containing in its elements the objects,
- in order. The @var{object-expr}s are evaluated when they are accessed,
- not when the stream is created. If no objects are given, as in
- (stream), the null stream is returned. See also @code{list->stream}.
- @example
- (define strm123 (stream 1 2 3))
- ; (/ 1 0) not evaluated when stream is created
- (define s (stream 1 (/ 1 0) -1))
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream->list [n] stream
- Returns a newly-allocated list containing in its elements the first
- @var{n} items in @var{stream}. If @var{stream} has less than @var{n}
- items, all the items in the stream will be included in the returned
- list. If @var{n} is not given it defaults to infinity, which means that
- unless @var{stream} is finite @code{stream->list} will never return.
- @example
- (stream->list 10
- (stream-map (lambda (x) (* x x))
- (stream-from 0)))
- @result{} (0 1 4 9 16 25 36 49 64 81)
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-append stream @dots{}
- Returns a newly-allocated stream containing in its elements those
- elements contained in its input @var{stream}s, in order of input. If
- any of the input streams is infinite, no elements of any of the
- succeeding input streams will appear in the output stream. See also
- @code{stream-concat}.
- @end deffn
- @deffn {Scheme Procedure} stream-concat stream
- Takes a @var{stream} consisting of one or more streams and returns a
- newly-allocated stream containing all the elements of the input streams.
- If any of the streams in the input @var{stream} is infinite, any
- remaining streams in the input stream will never appear in the output
- stream. See also @code{stream-append}.
- @end deffn
- @deffn {Scheme Procedure} stream-constant object @dots{}
- Returns a newly-allocated stream containing in its elements the
- @var{object}s, repeating in succession forever.
- @example
- (stream-constant 1) @result{} 1 1 1 @dots{}
- (stream-constant #t #f) @result{} #t #f #t #f #t #f @dots{}
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-drop n stream
- Returns the suffix of the input @var{stream} that starts at the next
- element after the first @var{n} elements. The output stream shares
- structure with the input @var{stream}; thus, promises forced in one
- instance of the stream are also forced in the other instance of the
- stream. If the input @var{stream} has less than @var{n} elements,
- @code{stream-drop} returns the null stream. See also
- @code{stream-take}.
- @end deffn
- @deffn {Scheme Procedure} stream-drop-while pred stream
- Returns the suffix of the input @var{stream} that starts at the first
- element @var{x} for which @code{(pred x)} returns false. The output
- stream shares structure with the input @var{stream}. See also
- @code{stream-take-while}.
- @end deffn
- @deffn {Scheme Procedure} stream-filter pred stream
- Returns a newly-allocated stream that contains only those elements
- @var{x} of the input @var{stream} which satisfy the predicate
- @code{pred}.
- @example
- (stream-filter odd? (stream-from 0))
- @result{} 1 3 5 7 9 @dots{}
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-fold proc base stream
- Applies a binary procedure @var{proc} to @var{base} and the first
- element of @var{stream} to compute a new @var{base}, then applies the
- procedure to the new @var{base} and the next element of @var{stream} to
- compute a succeeding @var{base}, and so on, accumulating a value that is
- finally returned as the value of @code{stream-fold} when the end of the
- stream is reached. @var{stream} must be finite, or @code{stream-fold}
- will enter an infinite loop. See also @code{stream-scan}, which is
- similar to @code{stream-fold}, but useful for infinite streams. For
- readers familiar with other functional languages, this is a left-fold;
- there is no corresponding right-fold, since right-fold relies on finite
- streams that are fully-evaluated, in which case they may as well be
- converted to a list.
- @end deffn
- @deffn {Scheme Procedure} stream-for-each proc stream @dots{}
- Applies @var{proc} element-wise to corresponding elements of the input
- @var{stream}s for side-effects; it returns nothing.
- @code{stream-for-each} stops as soon as any of its input streams is
- exhausted.
- @end deffn
- @deffn {Scheme Procedure} stream-from first [step]
- Creates a newly-allocated stream that contains @var{first} as its first
- element and increments each succeeding element by @var{step}. If
- @var{step} is not given it defaults to 1. @var{first} and @var{step}
- may be of any numeric type. @code{stream-from} is frequently useful as
- a generator in @code{stream-of} expressions. See also
- @code{stream-range} for a similar procedure that creates finite streams.
- @end deffn
- @deffn {Scheme Procedure} stream-iterate proc base
- Creates a newly-allocated stream containing @var{base} in its first
- element and applies @var{proc} to each element in turn to determine the
- succeeding element. See also @code{stream-unfold} and
- @code{stream-unfolds}.
- @end deffn
- @deffn {Scheme Procedure} stream-length stream
- Returns the number of elements in the @var{stream}; it does not evaluate
- its elements. @code{stream-length} may only be used on finite streams;
- it enters an infinite loop with infinite streams.
- @end deffn
- @deffn {Scheme Syntax} stream-let tag ((var expr) @dots{}) body @dots{}
- Creates a local scope that binds each variable to the value of its
- corresponding expression. It additionally binds @var{tag} to a
- procedure which takes the bound variables as arguments and @var{body} as
- its defining expressions, binding the @var{tag} with
- @code{stream-lambda}. @var{tag} is in scope within body, and may be
- called recursively. When the expanded expression defined by the
- @code{stream-let} is evaluated, @code{stream-let} evaluates the
- expressions in its @var{body} in an environment containing the
- newly-bound variables, returning the value of the last expression
- evaluated, which must yield a stream.
- @code{stream-let} provides syntactic sugar on @code{stream-lambda}, in
- the same manner as normal @code{let} provides syntactic sugar on normal
- @code{lambda}. However, unlike normal @code{let}, the @var{tag} is
- required, not optional, because unnamed @code{stream-let} is
- meaningless.
- For example, @code{stream-member} returns the first @code{stream-pair}
- of the input @var{strm} with a @code{stream-car} @var{x} that satisfies
- @code{(eql? obj x)}, or the null stream if @var{x} is not present in
- @var{strm}.
- @example
- (define-stream (stream-member eql? obj strm)
- (stream-let loop ((strm strm))
- (cond ((stream-null? strm) strm)
- ((eql? obj (stream-car strm)) strm)
- (else (loop (stream-cdr strm))))))
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-map proc stream @dots{}
- Applies @var{proc} element-wise to corresponding elements of the input
- @var{stream}s, returning a newly-allocated stream containing elements
- that are the results of those procedure applications. The output stream
- has as many elements as the minimum-length input stream, and may be
- infinite.
- @end deffn
- @deffn {Scheme Syntax} stream-match stream clause @dots{}
- Provides pattern-matching for streams. The input @var{stream} is an
- expression that evaluates to a stream. Clauses are of the form
- @code{(pattern [fender] expression)}, consisting of a @var{pattern} that
- matches a stream of a particular shape, an optional @var{fender} that
- must succeed if the pattern is to match, and an @var{expression} that is
- evaluated if the pattern matches. There are four types of patterns:
- @itemize @bullet
- @item
- () matches the null stream.
- @item
- (@var{pat0} @var{pat1} @dots{}) matches a finite stream with length
- exactly equal to the number of pattern elements.
- @item
- (@var{pat0} @var{pat1} @dots{} @code{.} @var{pat-rest}) matches an
- infinite stream, or a finite stream with length at least as great as the
- number of pattern elements before the literal dot.
- @item
- @var{pat} matches an entire stream. Should always appear last in the
- list of clauses; it's not an error to appear elsewhere, but subsequent
- clauses could never match.
- @end itemize
- Each pattern element may be either:
- @itemize @bullet
- @item
- An identifier, which matches any stream element. Additionally, the
- value of the stream element is bound to the variable named by the
- identifier, which is in scope in the @var{fender} and @var{expression}
- of the corresponding @var{clause}. Each identifier in a single pattern
- must be unique.
- @item
- A literal underscore (@code{_}), which matches any stream element but
- creates no bindings.
- @end itemize
- The @var{pattern}s are tested in order, left-to-right, until a matching
- pattern is found; if @var{fender} is present, it must evaluate to a true
- value for the match to be successful. Pattern variables are bound in
- the corresponding @var{fender} and @var{expression}. Once the matching
- @var{pattern} is found, the corresponding @var{expression} is evaluated
- and returned as the result of the match. An error is signaled if no
- pattern matches the input @var{stream}.
- @code{stream-match} is often used to distinguish null streams from
- non-null streams, binding @var{head} and @var{tail}:
- @example
- (define (len strm)
- (stream-match strm
- (() 0)
- ((head . tail) (+ 1 (len tail)))))
- @end example
- Fenders can test the common case where two stream elements must be
- identical; the @code{else} pattern is an identifier bound to the entire
- stream, not a keyword as in @code{cond}.
- @example
- (stream-match strm
- ((x y . _) (equal? x y) 'ok)
- (else 'error))
- @end example
- A more complex example uses two nested matchers to match two different
- stream arguments; @code{(stream-merge lt? . strms)} stably merges two or
- more streams ordered by the @code{lt?} predicate:
- @example
- (define-stream (stream-merge lt? . strms)
- (define-stream (merge xx yy)
- (stream-match xx (() yy) ((x . xs)
- (stream-match yy (() xx) ((y . ys)
- (if (lt? y x)
- (stream-cons y (merge xx ys))
- (stream-cons x (merge xs yy))))))))
- (stream-let loop ((strms strms))
- (cond ((null? strms) stream-null)
- ((null? (cdr strms)) (car strms))
- (else (merge (car strms)
- (apply stream-merge lt?
- (cdr strms)))))))
- @end example
- @end deffn
- @deffn {Scheme Syntax} stream-of expr clause @dots{}
- Provides the syntax of stream comprehensions, which generate streams by
- means of looping expressions. The result is a stream of objects of the
- type returned by @var{expr}. There are four types of clauses:
- @itemize @bullet
- @item
- (@var{var} @code{in} @var{stream-expr}) loops over the elements of
- @var{stream-expr}, in order from the start of the stream, binding each
- element of the stream in turn to @var{var}. @code{stream-from} and
- @code{stream-range} are frequently useful as generators for
- @var{stream-expr}.
- @item
- (@var{var} @code{is} @var{expr}) binds @var{var} to the value obtained
- by evaluating @var{expr}.
- @item
- (@var{pred} @var{expr}) includes in the output stream only those
- elements @var{x} which satisfy the predicate @var{pred}.
- @end itemize
- The scope of variables bound in the stream comprehension is the clauses
- to the right of the binding clause (but not the binding clause itself)
- plus the result expression.
- When two or more generators are present, the loops are processed as if
- they are nested from left to right; that is, the rightmost generator
- varies fastest. A consequence of this is that only the first generator
- may be infinite and all subsequent generators must be finite. If no
- generators are present, the result of a stream comprehension is a stream
- containing the result expression; thus, @samp{(stream-of 1)} produces a
- finite stream containing only the element 1.
- @example
- (stream-of (* x x)
- (x in (stream-range 0 10))
- (even? x))
- @result{} 0 4 16 36 64
- (stream-of (list a b)
- (a in (stream-range 1 4))
- (b in (stream-range 1 3)))
- @result{} (1 1) (1 2) (2 1) (2 2) (3 1) (3 2)
- (stream-of (list i j)
- (i in (stream-range 1 5))
- (j in (stream-range (+ i 1) 5)))
- @result{} (1 2) (1 3) (1 4) (2 3) (2 4) (3 4)
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-range first past [step]
- Creates a newly-allocated stream that contains @var{first} as its first
- element and increments each succeeding element by @var{step}. The
- stream is finite and ends before @var{past}, which is not an element of
- the stream. If @var{step} is not given it defaults to 1 if @var{first}
- is less than past and -1 otherwise. @var{first}, @var{past} and
- @var{step} may be of any real numeric type. @code{stream-range} is
- frequently useful as a generator in @code{stream-of} expressions. See
- also @code{stream-from} for a similar procedure that creates infinite
- streams.
- @example
- (stream-range 0 10) @result{} 0 1 2 3 4 5 6 7 8 9
- (stream-range 0 10 2) @result{} 0 2 4 6 8
- @end example
- Successive elements of the stream are calculated by adding @var{step} to
- @var{first}, so if any of @var{first}, @var{past} or @var{step} are
- inexact, the length of the output stream may differ from
- @code{(ceiling (- (/ (- past first) step) 1)}.
- @end deffn
- @deffn {Scheme Procedure} stream-ref stream n
- Returns the @var{n}th element of stream, counting from zero. An error
- is signaled if @var{n} is greater than or equal to the length of stream.
- @example
- (define (fact n)
- (stream-ref
- (stream-scan * 1 (stream-from 1))
- n))
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-reverse stream
- Returns a newly-allocated stream containing the elements of the input
- @var{stream} but in reverse order. @code{stream-reverse} may only be
- used with finite streams; it enters an infinite loop with infinite
- streams. @code{stream-reverse} does not force evaluation of the
- elements of the stream.
- @end deffn
- @deffn {Scheme Procedure} stream-scan proc base stream
- Accumulates the partial folds of an input @var{stream} into a
- newly-allocated output stream. The output stream is the @var{base}
- followed by @code{(stream-fold proc base (stream-take i stream))} for
- each of the first @var{i} elements of @var{stream}.
- @example
- (stream-scan + 0 (stream-from 1))
- @result{} (stream 0 1 3 6 10 15 @dots{})
- (stream-scan * 1 (stream-from 1))
- @result{} (stream 1 1 2 6 24 120 @dots{})
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-take n stream
- Returns a newly-allocated stream containing the first @var{n} elements
- of the input @var{stream}. If the input @var{stream} has less than
- @var{n} elements, so does the output stream. See also
- @code{stream-drop}.
- @end deffn
- @deffn {Scheme Procedure} stream-take-while pred stream
- Takes a predicate and a @code{stream} and returns a newly-allocated
- stream containing those elements @code{x} that form the maximal prefix
- of the input stream which satisfy @var{pred}. See also
- @code{stream-drop-while}.
- @end deffn
- @deffn {Scheme Procedure} stream-unfold map pred gen base
- The fundamental recursive stream constructor. It constructs a stream by
- repeatedly applying @var{gen} to successive values of @var{base}, in the
- manner of @code{stream-iterate}, then applying @var{map} to each of the
- values so generated, appending each of the mapped values to the output
- stream as long as @code{(pred? base)} returns a true value. See also
- @code{stream-iterate} and @code{stream-unfolds}.
- The expression below creates the finite stream @samp{0 1 4 9 16 25 36 49
- 64 81}. Initially the @var{base} is 0, which is less than 10, so
- @var{map} squares the @var{base} and the mapped value becomes the first
- element of the output stream. Then @var{gen} increments the @var{base}
- by 1, so it becomes 1; this is less than 10, so @var{map} squares the
- new @var{base} and 1 becomes the second element of the output stream.
- And so on, until the base becomes 10, when @var{pred} stops the
- recursion and stream-null ends the output stream.
- @example
- (stream-unfold
- (lambda (x) (expt x 2)) ; map
- (lambda (x) (< x 10)) ; pred?
- (lambda (x) (+ x 1)) ; gen
- 0) ; base
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-unfolds proc seed
- Returns @var{n} newly-allocated streams containing those elements
- produced by successive calls to the generator @var{proc}, which takes
- the current @var{seed} as its argument and returns @var{n}+1 values
- (@var{proc} @var{seed}) @result{} @var{seed} @var{result_0} @dots{} @var{result_n-1}
- where the returned @var{seed} is the input @var{seed} to the next call
- to the generator and @var{result_i} indicates how to produce the next
- element of the @var{i}th result stream:
- @itemize @bullet
- @item
- (@var{value}): @var{value} is the next car of the result stream.
- @item
- @code{#f}: no value produced by this iteration of the generator
- @var{proc} for the result stream.
- @item
- (): the end of the result stream.
- @end itemize
- It may require multiple calls of @var{proc} to produce the next element
- of any particular result stream. See also @code{stream-iterate} and
- @code{stream-unfold}.
- @example
- (define (stream-partition pred? strm)
- (stream-unfolds
- (lambda (s)
- (if (stream-null? s)
- (values s '() '())
- (let ((a (stream-car s))
- (d (stream-cdr s)))
- (if (pred? a)
- (values d (list a) #f)
- (values d #f (list a))))))
- strm))
- (call-with-values
- (lambda ()
- (stream-partition odd?
- (stream-range 1 6)))
- (lambda (odds evens)
- (list (stream->list odds)
- (stream->list evens))))
- @result{} ((1 3 5) (2 4))
- @end example
- @end deffn
- @deffn {Scheme Procedure} stream-zip stream @dots{}
- Returns a newly-allocated stream in which each element is a list (not a
- stream) of the corresponding elements of the input @var{stream}s. The
- output stream is as long as the shortest input @var{stream}, if any of
- the input @var{stream}s is finite, or is infinite if all the input
- @var{stream}s are infinite.
- @end deffn
- @node SRFI-42
- @subsection SRFI-42 - Eager Comprehensions
- @cindex SRFI-42
- See @uref{http://srfi.schemers.org/srfi-42/srfi-42.html, the
- specification of SRFI-42}.
- @node SRFI-43
- @subsection SRFI-43 - Vector Library
- @cindex SRFI-43
- This subsection is based on the
- @uref{http://srfi.schemers.org/srfi-43/srfi-43.html, specification of
- SRFI-43} by Taylor Campbell.
- @c The copyright notice and license text of the SRFI-43 specification is
- @c reproduced below:
- @c Copyright (C) Taylor Campbell (2003). All Rights Reserved.
- @c Permission is hereby granted, free of charge, to any person obtaining a
- @c copy of this software and associated documentation files (the
- @c "Software"), to deal in the Software without restriction, including
- @c without limitation the rights to use, copy, modify, merge, publish,
- @c distribute, sublicense, and/or sell copies of the Software, and to
- @c permit persons to whom the Software is furnished to do so, subject to
- @c the following conditions:
- @c The above copyright notice and this permission notice shall be included
- @c in all copies or substantial portions of the Software.
- @c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- @c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- @c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- @c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- @c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- @c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- @c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- @noindent
- SRFI-43 implements a comprehensive library of vector operations. It can
- be made available with:
- @example
- (use-modules (srfi srfi-43))
- @end example
- @menu
- * SRFI-43 Constructors::
- * SRFI-43 Predicates::
- * SRFI-43 Selectors::
- * SRFI-43 Iteration::
- * SRFI-43 Searching::
- * SRFI-43 Mutators::
- * SRFI-43 Conversion::
- @end menu
- @node SRFI-43 Constructors
- @subsubsection SRFI-43 Constructors
- @deffn {Scheme Procedure} make-vector size [fill]
- Create and return a vector of size @var{size}, optionally filling it
- with @var{fill}. The default value of @var{fill} is unspecified.
- @example
- (make-vector 5 3) @result{} #(3 3 3 3 3)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector x @dots{}
- Create and return a vector whose elements are @var{x} @enddots{}.
- @example
- (vector 0 1 2 3 4) @result{} #(0 1 2 3 4)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-unfold f length initial-seed @dots{}
- The fundamental vector constructor. Create a vector whose length
- is @var{length} and iterates across each index k from 0 up to
- @var{length} - 1, applying @var{f} at each iteration to the current
- index and current seeds, in that order, to receive n + 1 values: the
- element to put in the kth slot of the new vector, and n new seeds for
- the next iteration. It is an error for the number of seeds to vary
- between iterations.
- @example
- (vector-unfold (lambda (i x) (values x (- x 1)))
- 10 0)
- @result{} #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
- (vector-unfold values 10)
- @result{} #(0 1 2 3 4 5 6 7 8 9)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-unfold-right f length initial-seed @dots{}
- Like @code{vector-unfold}, but it uses @var{f} to generate elements from
- right-to-left, rather than left-to-right.
- @example
- (vector-unfold-right (lambda (i x) (values x (+ x 1)))
- 10 0)
- @result{} #(9 8 7 6 5 4 3 2 1 0)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-copy vec [start [end [fill]]]
- Allocate a new vector whose length is @var{end} - @var{start} and fills
- it with elements from @var{vec}, taking elements from @var{vec} starting
- at index @var{start} and stopping at index @var{end}. @var{start}
- defaults to 0 and @var{end} defaults to the value of
- @code{(vector-length vec)}. If @var{end} extends beyond the length of
- @var{vec}, the slots in the new vector that obviously cannot be filled
- by elements from @var{vec} are filled with @var{fill}, whose default
- value is unspecified.
- @example
- (vector-copy '#(a b c d e f g h i))
- @result{} #(a b c d e f g h i)
- (vector-copy '#(a b c d e f g h i) 6)
- @result{} #(g h i)
- (vector-copy '#(a b c d e f g h i) 3 6)
- @result{} #(d e f)
- (vector-copy '#(a b c d e f g h i) 6 12 'x)
- @result{} #(g h i x x x)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-reverse-copy vec [start [end]]
- Like @code{vector-copy}, but it copies the elements in the reverse order
- from @var{vec}.
- @example
- (vector-reverse-copy '#(5 4 3 2 1 0) 1 5)
- @result{} #(1 2 3 4)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-append vec @dots{}
- Return a newly allocated vector that contains all elements in order from
- the subsequent locations in @var{vec} @enddots{}.
- @example
- (vector-append '#(a) '#(b c d))
- @result{} #(a b c d)
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-concatenate list-of-vectors
- Append each vector in @var{list-of-vectors}. Equivalent to
- @code{(apply vector-append list-of-vectors)}.
- @example
- (vector-concatenate '(#(a b) #(c d)))
- @result{} #(a b c d)
- @end example
- @end deffn
- @node SRFI-43 Predicates
- @subsubsection SRFI-43 Predicates
- @deffn {Scheme Procedure} vector? obj
- Return true if @var{obj} is a vector, else return false.
- @end deffn
- @deffn {Scheme Procedure} vector-empty? vec
- Return true if @var{vec} is empty, i.e. its length is 0, else return
- false.
- @end deffn
- @deffn {Scheme Procedure} vector= elt=? vec @dots{}
- Return true if the vectors @var{vec} @dots{} have equal lengths and
- equal elements according to @var{elt=?}. @var{elt=?} is always applied
- to two arguments. Element comparison must be consistent with @code{eq?}
- in the following sense: if @code{(eq? a b)} returns true, then
- @code{(elt=? a b)} must also return true. The order in which
- comparisons are performed is unspecified.
- @end deffn
- @node SRFI-43 Selectors
- @subsubsection SRFI-43 Selectors
- @deffn {Scheme Procedure} vector-ref vec i
- Return the element at index @var{i} in @var{vec}. Indexing is based on
- zero.
- @end deffn
- @deffn {Scheme Procedure} vector-length vec
- Return the length of @var{vec}.
- @end deffn
- @node SRFI-43 Iteration
- @subsubsection SRFI-43 Iteration
- @deffn {Scheme Procedure} vector-fold kons knil vec1 vec2 @dots{}
- The fundamental vector iterator. @var{kons} is iterated over each index
- in all of the vectors, stopping at the end of the shortest; @var{kons}
- is applied as
- @smalllisp
- (kons i state (vector-ref vec1 i) (vector-ref vec2 i) ...)
- @end smalllisp
- where @var{state} is the current state value, and @var{i} is the current
- index. The current state value begins with @var{knil}, and becomes
- whatever @var{kons} returned at the respective iteration. The iteration
- is strictly left-to-right.
- @end deffn
- @deffn {Scheme Procedure} vector-fold-right kons knil vec1 vec2 @dots{}
- Similar to @code{vector-fold}, but it iterates right-to-left instead of
- left-to-right.
- @end deffn
- @deffn {Scheme Procedure} vector-map f vec1 vec2 @dots{}
- Return a new vector of the shortest size of the vector arguments. Each
- element at index i of the new vector is mapped from the old vectors by
- @smalllisp
- (f i (vector-ref vec1 i) (vector-ref vec2 i) ...)
- @end smalllisp
- The dynamic order of application of @var{f} is unspecified.
- @end deffn
- @deffn {Scheme Procedure} vector-map! f vec1 vec2 @dots{}
- Similar to @code{vector-map}, but rather than mapping the new elements
- into a new vector, the new mapped elements are destructively inserted
- into @var{vec1}. The dynamic order of application of @var{f} is
- unspecified.
- @end deffn
- @deffn {Scheme Procedure} vector-for-each f vec1 vec2 @dots{}
- Call @code{(f i (vector-ref vec1 i) (vector-ref vec2 i) ...)} for each
- index i less than the length of the shortest vector passed. The
- iteration is strictly left-to-right.
- @end deffn
- @deffn {Scheme Procedure} vector-count pred? vec1 vec2 @dots{}
- Count the number of parallel elements in the vectors that satisfy
- @var{pred?}, which is applied, for each index i less than the length of
- the smallest vector, to i and each parallel element in the vectors at
- that index, in order.
- @example
- (vector-count (lambda (i elt) (even? elt))
- '#(3 1 4 1 5 9 2 5 6))
- @result{} 3
- (vector-count (lambda (i x y) (< x y))
- '#(1 3 6 9) '#(2 4 6 8 10 12))
- @result{} 2
- @end example
- @end deffn
- @node SRFI-43 Searching
- @subsubsection SRFI-43 Searching
- @deffn {Scheme Procedure} vector-index pred? vec1 vec2 @dots{}
- Find and return the index of the first elements in @var{vec1} @var{vec2}
- @dots{} that satisfy @var{pred?}. If no matching element is found by
- the end of the shortest vector, return @code{#f}.
- @example
- (vector-index even? '#(3 1 4 1 5 9))
- @result{} 2
- (vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
- @result{} 1
- (vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
- @result{} #f
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-index-right pred? vec1 vec2 @dots{}
- Like @code{vector-index}, but it searches right-to-left, rather than
- left-to-right. Note that the SRFI 43 specification requires that all
- the vectors must have the same length, but both the SRFI 43 reference
- implementation and Guile's implementation allow vectors with unequal
- lengths, and start searching from the last index of the shortest vector.
- @end deffn
- @deffn {Scheme Procedure} vector-skip pred? vec1 vec2 @dots{}
- Find and return the index of the first elements in @var{vec1} @var{vec2}
- @dots{} that do not satisfy @var{pred?}. If no matching element is
- found by the end of the shortest vector, return @code{#f}. Equivalent
- to @code{vector-index} but with the predicate inverted.
- @example
- (vector-skip number? '#(1 2 a b 3 4 c d)) @result{} 2
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-skip-right pred? vec1 vec2 @dots{}
- Like @code{vector-skip}, but it searches for a non-matching element
- right-to-left, rather than left-to-right. Note that the SRFI 43
- specification requires that all the vectors must have the same length,
- but both the SRFI 43 reference implementation and Guile's implementation
- allow vectors with unequal lengths, and start searching from the last
- index of the shortest vector.
- @end deffn
- @deffn {Scheme Procedure} vector-binary-search vec value cmp [start [end]]
- Find and return an index of @var{vec} between @var{start} and @var{end}
- whose value is @var{value} using a binary search. If no matching
- element is found, return @code{#f}. The default @var{start} is 0 and
- the default @var{end} is the length of @var{vec}.
- @var{cmp} must be a procedure of two arguments such that @code{(cmp a
- b)} returns a negative integer if @math{a < b}, a positive integer if
- @math{a > b}, or zero if @math{a = b}. The elements of @var{vec} must
- be sorted in non-decreasing order according to @var{cmp}.
- Note that SRFI 43 does not document the @var{start} and @var{end}
- arguments, but both its reference implementation and Guile's
- implementation support them.
- @example
- (define (char-cmp c1 c2)
- (cond ((char<? c1 c2) -1)
- ((char>? c1 c2) 1)
- (else 0)))
- (vector-binary-search '#(#\a #\b #\c #\d #\e #\f #\g #\h)
- #\g
- char-cmp)
- @result{} 6
- @end example
- @end deffn
- @deffn {Scheme Procedure} vector-any pred? vec1 vec2 @dots{}
- Find the first parallel set of elements from @var{vec1} @var{vec2}
- @dots{} for which @var{pred?} returns a true value. If such a parallel
- set of elements exists, @code{vector-any} returns the value that
- @var{pred?} returned for that set of elements. The iteration is
- strictly left-to-right.
- @end deffn
- @deffn {Scheme Procedure} vector-every pred? vec1 vec2 @dots{}
- If, for every index i between 0 and the length of the shortest vector
- argument, the set of elements @code{(vector-ref vec1 i)}
- @code{(vector-ref vec2 i)} @dots{} satisfies @var{pred?},
- @code{vector-every} returns the value that @var{pred?} returned for the
- last set of elements, at the last index of the shortest vector.
- Otherwise it returns @code{#f}. The iteration is strictly
- left-to-right.
- @end deffn
- @node SRFI-43 Mutators
- @subsubsection SRFI-43 Mutators
- @deffn {Scheme Procedure} vector-set! vec i value
- Assign the contents of the location at @var{i} in @var{vec} to
- @var{value}.
- @end deffn
- @deffn {Scheme Procedure} vector-swap! vec i j
- Swap the values of the locations in @var{vec} at @var{i} and @var{j}.
- @end deffn
- @deffn {Scheme Procedure} vector-fill! vec fill [start [end]]
- Assign the value of every location in @var{vec} between @var{start} and
- @var{end} to @var{fill}. @var{start} defaults to 0 and @var{end}
- defaults to the length of @var{vec}.
- @end deffn
- @deffn {Scheme Procedure} vector-reverse! vec [start [end]]
- Destructively reverse the contents of @var{vec} between @var{start} and
- @var{end}. @var{start} defaults to 0 and @var{end} defaults to the
- length of @var{vec}.
- @end deffn
- @deffn {Scheme Procedure} vector-copy! target tstart source [sstart [send]]
- Copy a block of elements from @var{source} to @var{target}, both of
- which must be vectors, starting in @var{target} at @var{tstart} and
- starting in @var{source} at @var{sstart}, ending when (@var{send} -
- @var{sstart}) elements have been copied. It is an error for
- @var{target} to have a length less than (@var{tstart} + @var{send} -
- @var{sstart}). @var{sstart} defaults to 0 and @var{send} defaults to
- the length of @var{source}.
- @end deffn
- @deffn {Scheme Procedure} vector-reverse-copy! target tstart source [sstart [send]]
- Like @code{vector-copy!}, but this copies the elements in the reverse
- order. It is an error if @var{target} and @var{source} are identical
- vectors and the @var{target} and @var{source} ranges overlap; however,
- if @var{tstart} = @var{sstart}, @code{vector-reverse-copy!} behaves as
- @code{(vector-reverse! target tstart send)} would.
- @end deffn
- @node SRFI-43 Conversion
- @subsubsection SRFI-43 Conversion
- @deffn {Scheme Procedure} vector->list vec [start [end]]
- Return a newly allocated list containing the elements in @var{vec}
- between @var{start} and @var{end}. @var{start} defaults to 0 and
- @var{end} defaults to the length of @var{vec}.
- @end deffn
- @deffn {Scheme Procedure} reverse-vector->list vec [start [end]]
- Like @code{vector->list}, but the resulting list contains the specified
- range of elements of @var{vec} in reverse order.
- @end deffn
- @deffn {Scheme Procedure} list->vector proper-list [start [end]]
- Return a newly allocated vector of the elements from @var{proper-list}
- with indices between @var{start} and @var{end}. @var{start} defaults to
- 0 and @var{end} defaults to the length of @var{proper-list}. Note that
- SRFI 43 does not document the @var{start} and @var{end} arguments, but
- both its reference implementation and Guile's implementation support
- them.
- @end deffn
- @deffn {Scheme Procedure} reverse-list->vector proper-list [start [end]]
- Like @code{list->vector}, but the resulting vector contains the specified
- range of elements of @var{proper-list} in reverse order. Note that SRFI
- 43 does not document the @var{start} and @var{end} arguments, but both
- its reference implementation and Guile's implementation support them.
- @end deffn
- @node SRFI-45
- @subsection SRFI-45 - Primitives for Expressing Iterative Lazy Algorithms
- @cindex SRFI-45
- This subsection is based on @uref{http://srfi.schemers.org/srfi-45/srfi-45.html, the
- specification of SRFI-45} written by Andr@'e van Tonder.
- @c Copyright (C) André van Tonder (2003). All Rights Reserved.
- @c Permission is hereby granted, free of charge, to any person obtaining a
- @c copy of this software and associated documentation files (the
- @c "Software"), to deal in the Software without restriction, including
- @c without limitation the rights to use, copy, modify, merge, publish,
- @c distribute, sublicense, and/or sell copies of the Software, and to
- @c permit persons to whom the Software is furnished to do so, subject to
- @c the following conditions:
- @c The above copyright notice and this permission notice shall be included
- @c in all copies or substantial portions of the Software.
- @c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- @c OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- @c MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- @c NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- @c LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- @c OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- @c WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Lazy evaluation is traditionally simulated in Scheme using @code{delay}
- and @code{force}. However, these primitives are not powerful enough to
- express a large class of lazy algorithms that are iterative. Indeed, it
- is folklore in the Scheme community that typical iterative lazy
- algorithms written using delay and force will often require unbounded
- memory.
- This SRFI provides set of three operations: @{@code{lazy}, @code{delay},
- @code{force}@}, which allow the programmer to succinctly express lazy
- algorithms while retaining bounded space behavior in cases that are
- properly tail-recursive. A general recipe for using these primitives is
- provided. An additional procedure @code{eager} is provided for the
- construction of eager promises in cases where efficiency is a concern.
- Although this SRFI redefines @code{delay} and @code{force}, the
- extension is conservative in the sense that the semantics of the subset
- @{@code{delay}, @code{force}@} in isolation (i.e., as long as the
- program does not use @code{lazy}) agrees with that in R5RS. In other
- words, no program that uses the R5RS definitions of delay and force will
- break if those definition are replaced by the SRFI-45 definitions of
- delay and force.
- Guile also adds @code{promise?} to the list of exports, which is not
- part of the official SRFI-45.
- @deffn {Scheme Procedure} promise? obj
- Return true if @var{obj} is an SRFI-45 promise, otherwise return false.
- @end deffn
- @deffn {Scheme Syntax} delay expression
- Takes an expression of arbitrary type @var{a} and returns a promise of
- type @code{(Promise @var{a})} which at some point in the future may be
- asked (by the @code{force} procedure) to evaluate the expression and
- deliver the resulting value.
- @end deffn
- @deffn {Scheme Syntax} lazy expression
- Takes an expression of type @code{(Promise @var{a})} and returns a
- promise of type @code{(Promise @var{a})} which at some point in the
- future may be asked (by the @code{force} procedure) to evaluate the
- expression and deliver the resulting promise.
- @end deffn
- @deffn {Scheme Procedure} force expression
- Takes an argument of type @code{(Promise @var{a})} and returns a value
- of type @var{a} as follows: If a value of type @var{a} has been computed
- for the promise, this value is returned. Otherwise, the promise is
- first evaluated, then overwritten by the obtained promise or value, and
- then force is again applied (iteratively) to the promise.
- @end deffn
- @deffn {Scheme Procedure} eager expression
- Takes an argument of type @var{a} and returns a value of type
- @code{(Promise @var{a})}. As opposed to @code{delay}, the argument is
- evaluated eagerly. Semantically, writing @code{(eager expression)} is
- equivalent to writing
- @lisp
- (let ((value expression)) (delay value)).
- @end lisp
- However, the former is more efficient since it does not require
- unnecessary creation and evaluation of thunks. We also have the
- equivalence
- @lisp
- (delay expression) = (lazy (eager expression))
- @end lisp
- @end deffn
- The following reduction rules may be helpful for reasoning about these
- primitives. However, they do not express the memoization and memory
- usage semantics specified above:
- @lisp
- (force (delay expression)) -> expression
- (force (lazy expression)) -> (force expression)
- (force (eager value)) -> value
- @end lisp
- @subsubheading Correct usage
- We now provide a general recipe for using the primitives @{@code{lazy},
- @code{delay}, @code{force}@} to express lazy algorithms in Scheme. The
- transformation is best described by way of an example: Consider the
- stream-filter algorithm, expressed in a hypothetical lazy language as
- @lisp
- (define (stream-filter p? s)
- (if (null? s) '()
- (let ((h (car s))
- (t (cdr s)))
- (if (p? h)
- (cons h (stream-filter p? t))
- (stream-filter p? t)))))
- @end lisp
- This algorithm can be expressed as follows in Scheme:
- @lisp
- (define (stream-filter p? s)
- (lazy
- (if (null? (force s)) (delay '())
- (let ((h (car (force s)))
- (t (cdr (force s))))
- (if (p? h)
- (delay (cons h (stream-filter p? t)))
- (stream-filter p? t))))))
- @end lisp
- In other words, we
- @itemize @bullet
- @item
- wrap all constructors (e.g., @code{'()}, @code{cons}) with @code{delay},
- @item
- apply @code{force} to arguments of deconstructors (e.g., @code{car},
- @code{cdr} and @code{null?}),
- @item
- wrap procedure bodies with @code{(lazy ...)}.
- @end itemize
- @node SRFI-46
- @subsection SRFI-46 Basic syntax-rules Extensions
- @cindex SRFI-46
- Guile's core @code{syntax-rules} supports the extensions specified by
- SRFI-46/R7RS. Tail patterns have been supported since at least Guile
- 2.0, and custom ellipsis identifiers have been supported since Guile
- 2.0.10. @xref{Syntax Rules}.
- @node SRFI-55
- @subsection SRFI-55 - Requiring Features
- @cindex SRFI-55
- SRFI-55 provides @code{require-extension} which is a portable
- mechanism to load selected SRFI modules. This is implemented in the
- Guile core, there's no module needed to get SRFI-55 itself.
- @deffn {library syntax} require-extension clause1 clause2 @dots{}
- Require the features of @var{clause1} @var{clause2} @dots{} , throwing
- an error if any are unavailable.
- A @var{clause} is of the form @code{(@var{identifier} arg...)}. The
- only @var{identifier} currently supported is @code{srfi} and the
- arguments are SRFI numbers. For example to get SRFI-1 and SRFI-6,
- @example
- (require-extension (srfi 1 6))
- @end example
- @code{require-extension} can only be used at the top-level.
- A Guile-specific program can simply @code{use-modules} to load SRFIs
- not already in the core, @code{require-extension} is for programs
- designed to be portable to other Scheme implementations.
- @end deffn
- @node SRFI-60
- @subsection SRFI-60 - Integers as Bits
- @cindex SRFI-60
- @cindex integers as bits
- @cindex bitwise logical
- This SRFI provides various functions for treating integers as bits and
- for bitwise manipulations. These functions can be obtained with,
- @example
- (use-modules (srfi srfi-60))
- @end example
- Integers are treated as infinite precision twos-complement, the same
- as in the core logical functions (@pxref{Bitwise Operations}). And
- likewise bit indexes start from 0 for the least significant bit. The
- following functions in this SRFI are already in the Guile core,
- @quotation
- @code{logand},
- @code{logior},
- @code{logxor},
- @code{lognot},
- @code{logtest},
- @code{logcount},
- @code{integer-length},
- @code{logbit?},
- @code{ash}
- @end quotation
- @sp 1
- @defun bitwise-and n1 ...
- @defunx bitwise-ior n1 ...
- @defunx bitwise-xor n1 ...
- @defunx bitwise-not n
- @defunx any-bits-set? j k
- @defunx bit-set? index n
- @defunx arithmetic-shift n count
- @defunx bit-field n start end
- @defunx bit-count n
- Aliases for @code{logand}, @code{logior}, @code{logxor},
- @code{lognot}, @code{logtest}, @code{logbit?}, @code{ash},
- @code{bit-extract} and @code{logcount} respectively.
- Note that the name @code{bit-count} conflicts with @code{bit-count} in
- the core (@pxref{Bit Vectors}).
- @end defun
- @defun bitwise-if mask n1 n0
- @defunx bitwise-merge mask n1 n0
- Return an integer with bits selected from @var{n1} and @var{n0}
- according to @var{mask}. Those bits where @var{mask} has 1s are taken
- from @var{n1}, and those where @var{mask} has 0s are taken from
- @var{n0}.
- @example
- (bitwise-if 3 #b0101 #b1010) @result{} 9
- @end example
- @end defun
- @defun log2-binary-factors n
- @defunx first-set-bit n
- Return a count of how many factors of 2 are present in @var{n}. This
- is also the bit index of the lowest 1 bit in @var{n}. If @var{n} is
- 0, the return is @math{-1}.
- @example
- (log2-binary-factors 6) @result{} 1
- (log2-binary-factors -8) @result{} 3
- @end example
- @end defun
- @defun copy-bit index n newbit
- Return @var{n} with the bit at @var{index} set according to
- @var{newbit}. @var{newbit} should be @code{#t} to set the bit to 1,
- or @code{#f} to set it to 0. Bits other than at @var{index} are
- unchanged in the return.
- @example
- (copy-bit 1 #b0101 #t) @result{} 7
- @end example
- @end defun
- @defun copy-bit-field n newbits start end
- Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
- (exclusive) changed to the value @var{newbits}.
- The least significant bit in @var{newbits} goes to @var{start}, the
- next to @math{@var{start}+1}, etc. Anything in @var{newbits} past the
- @var{end} given is ignored.
- @example
- (copy-bit-field #b10000 #b11 1 3) @result{} #b10110
- @end example
- @end defun
- @defun rotate-bit-field n count start end
- Return @var{n} with the bit field from @var{start} (inclusive) to
- @var{end} (exclusive) rotated upwards by @var{count} bits.
- @var{count} can be positive or negative, and it can be more than the
- field width (it'll be reduced modulo the width).
- @example
- (rotate-bit-field #b0110 2 1 4) @result{} #b1010
- @end example
- @end defun
- @defun reverse-bit-field n start end
- Return @var{n} with the bits from @var{start} (inclusive) to @var{end}
- (exclusive) reversed.
- @example
- (reverse-bit-field #b101001 2 4) @result{} #b100101
- @end example
- @end defun
- @defun integer->list n [len]
- Return bits from @var{n} in the form of a list of @code{#t} for 1 and
- @code{#f} for 0. The least significant @var{len} bits are returned,
- and the first list element is the most significant of those bits. If
- @var{len} is not given, the default is @code{(integer-length @var{n})}
- (@pxref{Bitwise Operations}).
- @example
- (integer->list 6) @result{} (#t #t #f)
- (integer->list 1 4) @result{} (#f #f #f #t)
- @end example
- @end defun
-
- @defun list->integer lst
- @defunx booleans->integer bool@dots{}
- Return an integer formed bitwise from the given @var{lst} list of
- booleans, or for @code{booleans->integer} from the @var{bool}
- arguments.
- Each boolean is @code{#t} for a 1 and @code{#f} for a 0. The first
- element becomes the most significant bit in the return.
- @example
- (list->integer '(#t #f #t #f)) @result{} 10
- @end example
- @end defun
- @node SRFI-61
- @subsection SRFI-61 - A more general @code{cond} clause
- This SRFI extends RnRS @code{cond} to support test expressions that
- return multiple values, as well as arbitrary definitions of test
- success. SRFI 61 is implemented in the Guile core; there's no module
- needed to get SRFI-61 itself. Extended @code{cond} is documented in
- @ref{Conditionals,, Simple Conditional Evaluation}.
- @node SRFI-62
- @subsection SRFI-62 - S-expression comments.
- @cindex SRFI-62
- Starting from version 2.0, Guile's @code{read} supports SRFI-62/R7RS
- S-expression comments by default.
- @node SRFI-64
- @subsection SRFI-64 - A Scheme API for test suites.
- @cindex SRFI-64
- See @uref{http://srfi.schemers.org/srfi-64/srfi-64.html, the
- specification of SRFI-64}.
- @node SRFI-67
- @subsection SRFI-67 - Compare procedures
- @cindex SRFI-67
- See @uref{http://srfi.schemers.org/srfi-67/srfi-67.html, the
- specification of SRFI-67}.
- @node SRFI-69
- @subsection SRFI-69 - Basic hash tables
- @cindex SRFI-69
- This is a portable wrapper around Guile's built-in hash table and weak
- table support. @xref{Hash Tables}, for information on that built-in
- support. Above that, this hash-table interface provides association
- of equality and hash functions with tables at creation time, so
- variants of each function are not required, as well as a procedure
- that takes care of most uses for Guile hash table handles, which this
- SRFI does not provide as such.
- Access it with:
- @lisp
- (use-modules (srfi srfi-69))
- @end lisp
- @menu
- * SRFI-69 Creating hash tables::
- * SRFI-69 Accessing table items::
- * SRFI-69 Table properties::
- * SRFI-69 Hash table algorithms::
- @end menu
- @node SRFI-69 Creating hash tables
- @subsubsection Creating hash tables
- @deffn {Scheme Procedure} make-hash-table [equal-proc hash-proc #:weak weakness start-size]
- Create and answer a new hash table with @var{equal-proc} as the
- equality function and @var{hash-proc} as the hashing function.
- By default, @var{equal-proc} is @code{equal?}. It can be any
- two-argument procedure, and should answer whether two keys are the
- same for this table's purposes.
- By default @var{hash-proc} assumes that @code{equal-proc} is no
- coarser than @code{equal?} unless it is literally @code{string-ci=?}.
- If provided, @var{hash-proc} should be a two-argument procedure that
- takes a key and the current table size, and answers a reasonably good
- hash integer between 0 (inclusive) and the size (exclusive).
- @var{weakness} should be @code{#f} or a symbol indicating how ``weak''
- the hash table is:
- @table @code
- @item #f
- An ordinary non-weak hash table. This is the default.
- @item key
- When the key has no more non-weak references at GC, remove that entry.
- @item value
- When the value has no more non-weak references at GC, remove that
- entry.
- @item key-or-value
- When either has no more non-weak references at GC, remove the
- association.
- @end table
- As a legacy of the time when Guile couldn't grow hash tables,
- @var{start-size} is an optional integer argument that specifies the
- approximate starting size for the hash table, which will be rounded to
- an algorithmically-sounder number.
- @end deffn
- By @dfn{coarser} than @code{equal?}, we mean that for all @var{x} and
- @var{y} values where @code{(@var{equal-proc} @var{x} @var{y})},
- @code{(equal? @var{x} @var{y})} as well. If that does not hold for
- your @var{equal-proc}, you must provide a @var{hash-proc}.
- In the case of weak tables, remember that @dfn{references} above
- always refers to @code{eq?}-wise references. Just because you have a
- reference to some string @code{"foo"} doesn't mean that an association
- with key @code{"foo"} in a weak-key table @emph{won't} be collected;
- it only counts as a reference if the two @code{"foo"}s are @code{eq?},
- regardless of @var{equal-proc}. As such, it is usually only sensible
- to use @code{eq?} and @code{hashq} as the equivalence and hash
- functions for a weak table. @xref{Weak References}, for more
- information on Guile's built-in weak table support.
- @deffn {Scheme Procedure} alist->hash-table alist [equal-proc hash-proc #:weak weakness start-size]
- As with @code{make-hash-table}, but initialize it with the
- associations in @var{alist}. Where keys are repeated in @var{alist},
- the leftmost association takes precedence.
- @end deffn
- @node SRFI-69 Accessing table items
- @subsubsection Accessing table items
- @deffn {Scheme Procedure} hash-table-ref table key [default-thunk]
- @deffnx {Scheme Procedure} hash-table-ref/default table key default
- Answer the value associated with @var{key} in @var{table}. If
- @var{key} is not present, answer the result of invoking the thunk
- @var{default-thunk}, which signals an error instead by default.
- @code{hash-table-ref/default} is a variant that requires a third
- argument, @var{default}, and answers @var{default} itself instead of
- invoking it.
- @end deffn
- @deffn {Scheme Procedure} hash-table-set! table key new-value
- Set @var{key} to @var{new-value} in @var{table}.
- @end deffn
- @deffn {Scheme Procedure} hash-table-delete! table key
- Remove the association of @var{key} in @var{table}, if present. If
- absent, do nothing.
- @end deffn
- @deffn {Scheme Procedure} hash-table-exists? table key
- Answer whether @var{key} has an association in @var{table}.
- @end deffn
- @deffn {Scheme Procedure} hash-table-update! table key modifier [default-thunk]
- @deffnx {Scheme Procedure} hash-table-update!/default table key modifier default
- Replace @var{key}'s associated value in @var{table} by invoking
- @var{modifier} with one argument, the old value.
- If @var{key} is not present, and @var{default-thunk} is provided,
- invoke it with no arguments to get the ``old value'' to be passed to
- @var{modifier} as above. If @var{default-thunk} is not provided in
- such a case, signal an error.
- @code{hash-table-update!/default} is a variant that requires the
- fourth argument, which is used directly as the ``old value'' rather
- than as a thunk to be invoked to retrieve the ``old value''.
- @end deffn
- @node SRFI-69 Table properties
- @subsubsection Table properties
- @deffn {Scheme Procedure} hash-table-size table
- Answer the number of associations in @var{table}. This is guaranteed
- to run in constant time for non-weak tables.
- @end deffn
- @deffn {Scheme Procedure} hash-table-keys table
- Answer an unordered list of the keys in @var{table}.
- @end deffn
- @deffn {Scheme Procedure} hash-table-values table
- Answer an unordered list of the values in @var{table}.
- @end deffn
- @deffn {Scheme Procedure} hash-table-walk table proc
- Invoke @var{proc} once for each association in @var{table}, passing
- the key and value as arguments.
- @end deffn
- @deffn {Scheme Procedure} hash-table-fold table proc init
- Invoke @code{(@var{proc} @var{key} @var{value} @var{previous})} for
- each @var{key} and @var{value} in @var{table}, where @var{previous} is
- the result of the previous invocation, using @var{init} as the first
- @var{previous} value. Answer the final @var{proc} result.
- @end deffn
- @deffn {Scheme Procedure} hash-table->alist table
- Answer an alist where each association in @var{table} is an
- association in the result.
- @end deffn
- @node SRFI-69 Hash table algorithms
- @subsubsection Hash table algorithms
- Each hash table carries an @dfn{equivalence function} and a @dfn{hash
- function}, used to implement key lookups. Beginning users should
- follow the rules for consistency of the default @var{hash-proc}
- specified above. Advanced users can use these to implement their own
- equivalence and hash functions for specialized lookup semantics.
- @deffn {Scheme Procedure} hash-table-equivalence-function hash-table
- @deffnx {Scheme Procedure} hash-table-hash-function hash-table
- Answer the equivalence and hash function of @var{hash-table}, respectively.
- @end deffn
- @deffn {Scheme Procedure} hash obj [size]
- @deffnx {Scheme Procedure} string-hash obj [size]
- @deffnx {Scheme Procedure} string-ci-hash obj [size]
- @deffnx {Scheme Procedure} hash-by-identity obj [size]
- Answer a hash value appropriate for equality predicate @code{equal?},
- @code{string=?}, @code{string-ci=?}, and @code{eq?}, respectively.
- @end deffn
- @code{hash} is a backwards-compatible replacement for Guile's built-in
- @code{hash}.
- @node SRFI-71
- @subsection SRFI-71 - Extended let-syntax for multiple values
- @cindex SRFI-71
- This SRFI shadows the forms for @code{let}, @code{let*}, and @code{letrec}
- so that they may accept multiple values. For example:
- @example
- (use-modules (srfi srfi-71))
- (let* ((x y (values 1 2))
- (z (+ x y)))
- (* z 2))
- @result{} 6
- @end example
- See @uref{http://srfi.schemers.org/srfi-71/srfi-71.html, the
- specification of SRFI-71}.
- @node SRFI-87
- @subsection SRFI-87 => in case clauses
- @cindex SRFI-87
- Starting from version 2.0.6, Guile's core @code{case} syntax supports
- @code{=>} in clauses, as specified by SRFI-87/R7RS.
- @xref{Conditionals}.
- @node SRFI-88
- @subsection SRFI-88 Keyword Objects
- @cindex SRFI-88
- @cindex keyword objects
- @uref{http://srfi.schemers.org/srfi-88/srfi-88.html, SRFI-88} provides
- @dfn{keyword objects}, which are equivalent to Guile's keywords
- (@pxref{Keywords}). SRFI-88 keywords can be entered using the
- @dfn{postfix keyword syntax}, which consists of an identifier followed
- by @code{:} (@pxref{Scheme Read, @code{postfix} keyword syntax}).
- SRFI-88 can be made available with:
- @example
- (use-modules (srfi srfi-88))
- @end example
- Doing so installs the right reader option for keyword syntax, using
- @code{(read-set! keywords 'postfix)}. It also provides the procedures
- described below.
- @deffn {Scheme Procedure} keyword? obj
- Return @code{#t} if @var{obj} is a keyword. This is the same procedure
- as the same-named built-in procedure (@pxref{Keyword Procedures,
- @code{keyword?}}).
- @example
- (keyword? foo:) @result{} #t
- (keyword? 'foo:) @result{} #t
- (keyword? "foo") @result{} #f
- @end example
- @end deffn
- @deffn {Scheme Procedure} keyword->string kw
- Return the name of @var{kw} as a string, i.e., without the trailing
- colon. The returned string may not be modified, e.g., with
- @code{string-set!}.
- @example
- (keyword->string foo:) @result{} "foo"
- @end example
- @end deffn
- @deffn {Scheme Procedure} string->keyword str
- Return the keyword object whose name is @var{str}.
- @example
- (keyword->string (string->keyword "a b c")) @result{} "a b c"
- @end example
- @end deffn
- @node SRFI-98
- @subsection SRFI-98 Accessing environment variables.
- @cindex SRFI-98
- @cindex environment variables
- This is a portable wrapper around Guile's built-in support for
- interacting with the current environment, @xref{Runtime Environment}.
- @deffn {Scheme Procedure} get-environment-variable name
- Returns a string containing the value of the environment variable
- given by the string @code{name}, or @code{#f} if the named
- environment variable is not found. This is equivalent to
- @code{(getenv name)}.
- @end deffn
- @deffn {Scheme Procedure} get-environment-variables
- Returns the names and values of all the environment variables as an
- association list in which both the keys and the values are strings.
- @end deffn
- @node SRFI-105
- @subsection SRFI-105 Curly-infix expressions.
- @cindex SRFI-105
- @cindex curly-infix
- @cindex curly-infix-and-bracket-lists
- Guile's built-in reader includes support for SRFI-105 curly-infix
- expressions. See @uref{http://srfi.schemers.org/srfi-105/srfi-105.html,
- the specification of SRFI-105}. Some examples:
- @example
- @{n <= 5@} @result{} (<= n 5)
- @{a + b + c@} @result{} (+ a b c)
- @{a * @{b + c@}@} @result{} (* a (+ b c))
- @{(- a) / b@} @result{} (/ (- a) b)
- @{-(a) / b@} @result{} (/ (- a) b) as well
- @{(f a b) + (g h)@} @result{} (+ (f a b) (g h))
- @{f(a b) + g(h)@} @result{} (+ (f a b) (g h)) as well
- @{f[a b] + g(h)@} @result{} (+ ($bracket-apply$ f a b) (g h))
- '@{a + f(b) + x@} @result{} '(+ a (f b) x)
- @{length(x) >= 6@} @result{} (>= (length x) 6)
- @{n-1 + n-2@} @result{} (+ n-1 n-2)
- @{n * factorial@{n - 1@}@} @result{} (* n (factorial (- n 1)))
- @{@{a > 0@} and @{b >= 1@}@} @result{} (and (> a 0) (>= b 1))
- @{f@{n - 1@}(x)@} @result{} ((f (- n 1)) x)
- @{a . z@} @result{} ($nfx$ a . z)
- @{a + b - c@} @result{} ($nfx$ a + b - c)
- @end example
- To enable curly-infix expressions within a file, place the reader
- directive @code{#!curly-infix} before the first use of curly-infix
- notation. To globally enable curly-infix expressions in Guile's reader,
- set the @code{curly-infix} read option.
- Guile also implements the following non-standard extension to SRFI-105:
- if @code{curly-infix} is enabled and there is no other meaning assigned
- to square brackets (i.e. the @code{square-brackets} read option is
- turned off), then lists within square brackets are read as normal lists
- but with the special symbol @code{$bracket-list$} added to the front.
- To enable this combination of read options within a file, use the reader
- directive @code{#!curly-infix-and-bracket-lists}. For example:
- @example
- [a b] @result{} ($bracket-list$ a b)
- [a . b] @result{} ($bracket-list$ a . b)
- @end example
- For more information on reader options, @xref{Scheme Read}.
- @node SRFI-111
- @subsection SRFI-111 Boxes.
- @cindex SRFI-111
- @uref{http://srfi.schemers.org/srfi-111/srfi-111.html, SRFI-111}
- provides boxes: objects with a single mutable cell.
- @deffn {Scheme Procedure} box value
- Return a newly allocated box whose contents is initialized to
- @var{value}.
- @end deffn
- @deffn {Scheme Procedure} box? obj
- Return true if @var{obj} is a box, otherwise return false.
- @end deffn
- @deffn {Scheme Procedure} unbox box
- Return the current contents of @var{box}.
- @end deffn
- @deffn {Scheme Procedure} set-box! box value
- Set the contents of @var{box} to @var{value}.
- @end deffn
- @node SRFI-119
- @subsection SRFI-119 Wisp: simpler indentation-sensitive Scheme.
- @cindex SRFI-119
- @cindex wisp
- The languages shipped in Guile include SRFI-119, also referred to as
- @dfn{Wisp} (for ``Whitespace to Lisp''), an encoding of Scheme that
- allows replacing parentheses with equivalent indentation and inline
- colons. See
- @uref{http://srfi.schemers.org/srfi-119/srfi-119.html, the specification
- of SRFI-119}. Some examples:
- @example
- display "Hello World!" @result{} (display "Hello World!")
- @end example
- @example
- define : factorial n @result{} (define (factorial n)
- if : zero? n @result{} (if (zero? n)
- . 1 @result{} 1
- * n : factorial @{n - 1@} @result{} (* n (factorial @{n - 1@}))))
- @end example
- To execute a file with Wisp code, select the language and filename
- extension @code{.w} vie @code{guile --language=wisp -x .w}.
- In files using Wisp, @xref{SRFI-105} (Curly Infix) is always activated.
- @node SRFI-171
- @subsection Transducers
- @cindex SRFI-171
- @cindex transducers
- Some of the most common operations used in the Scheme language are those
- transforming lists: map, filter, take and so on. They work well, are well
- understood, and are used daily by most Scheme programmers. They are however not
- general because they only work on lists, and they do not compose very well
- since combining N of them builds @code{(- N 1)} intermediate lists.
- Transducers are oblivious to what kind of process they are used in, and
- are composable without building intermediate collections. This means we
- can create a transducer that squares all odd numbers:
- @example
- (compose (tfilter odd?) (tmap (lambda (x) (* x x))))
- @end example
- and reuse it with lists, vectors, or in just about any context where
- data flows in one direction. We could use it as a processing step for
- asynchronous channels, with an event framework as a pre-processing step,
- or even in lazy contexts where you pass a lazy collection and a
- transducer to a function and get a new lazy collection back.
- The traditional Scheme approach of having collection-specific procedures
- is not changed. We instead specify a general form of transformations
- that complement these procedures. The benefits are obvious: a clear,
- well-understood way of describing common transformations in a way that
- is faster than just chaining the collection-specific counterparts. For
- guile in particular this means a lot better GC performance.
- Notice however that @code{(compose @dots{})} composes transducers
- left-to-right, due to how transducers are initiated.
- @menu
- * SRFI-171 General Discussion:: General information about transducers
- * SRFI-171 Applying Transducers:: Documentation of collection-specific forms
- * SRFI-171 Reducers:: Reducers specified by the SRFI
- * SRFI-171 Transducers:: Transducers specified by the SRFI
- * SRFI-171 Helpers:: Utilities for writing your own transducers
- @end menu
- @node SRFI-171 General Discussion
- @subsubsection SRFI-171 General Discussion
- @cindex transducers discussion
- @subheading The concept of reducers
- The central part of transducers are 3-arity reducing procedures.
- @itemize
- @item
- no arguments: Produces the identity of the reducer.
- @item
- (result-so-far): completion. Returns @code{result-so-far} either with or
- without transforming it first.
- @item
- (result-so-far input) combines @code{result-so-far} and @code{input} to produce
- a new @code{result-so-far}.
- @end itemize
- In the case of a summing @code{+} reducer, the reducer would produce, in
- arity order: @code{0}, @code{result-so-far}, @code{(+ result-so-far
- input)}. This happens to be exactly what the regular @code{+} does.
- @subheading The concept of transducers
- A transducer is a one-arity procedure that takes a reducer and produces a
- reducing function that behaves as follows:
- @itemize
- @item
- no arguments: calls reducer with no arguments (producing its identity)
- @item
- (result-so-far): Maybe transform the result-so-far and call reducer with it.
- @item
- (result-so-far input) Maybe do something to input and maybe call the
- reducer with result-so-far and the maybe-transformed input.
- @end itemize
- A simple example is as following:
- @example
- (list-transduce (tfilter odd?) + '(1 2 3 4 5))
- @end example
- This first returns a transducer filtering all odd
- elements, then it runs @code{+} without arguments to retrieve its
- identity. It then starts the transduction by passing @code{+} to the
- transducer returned by @code{(tfilter odd?)} which returns a reducing
- function. It works not unlike reduce from SRFI 1, but also checks
- whether one of the intermediate transducers returns a "reduced" value
- (implemented as a SRFI 9 record), which means the reduction finished
- early.
- Because transducers compose and the final reduction is only executed in
- the last step, composed transducers will not build any intermediate
- result or collections. Although the normal way of thinking about
- application of composed functions is right to left, due to how the
- transduction is built it is applied left to right. @code{(compose
- (tfilter odd?) (tmap sqrt))} will create a transducer that first filters
- out any odd values and then computes the square root of the rest.
- @subheading State
- Even though transducers appear to be somewhat of a generalisation of
- @code{map} and friends, this is not really true. Since transducers don't
- know in which context they are being used, some transducers must keep
- state where their collection-specific counterparts do not. The
- transducers that keep state do so using hidden mutable state, and as
- such all the caveats of mutation, parallelism, and multi-shot
- continuations apply. Each transducer keeping state is clearly described
- as doing so in the documentation.
- @subheading Naming
- Reducers exported from the transducers module are named as in their
- SRFI-1 counterpart, but prepended with an r. Transducers also follow
- that naming, but are prepended with a t.
- @node SRFI-171 Applying Transducers
- @subsubsection Applying Transducers
- @cindex transducers applying
- @deffn {Scheme Procedure} list-transduce xform f lst
- @deffnx {Scheme Procedure} list-transduce xform f identity lst
- Initialize the transducer @var{xform} by passing the reducer @var{f}
- to it. If no identity is provided, @var{f} runs without arguments to
- return the reducer identity. It then reduces over @var{lst} using the
- identity as the seed.
- If one of the transducers finishes early (such as @code{ttake} or
- @code{tdrop}), it communicates this by returning a reduced value, which
- in the guile implementation is just a value wrapped in a SRFI 9 record
- type named ``reduced''. If such a value is returned by the transducer,
- @code{list-transduce} must stop execution and return an unreduced value
- immediately.
- @end deffn
- @deffn {Scheme Procedure} vector-transduce xform f vec
- @deffnx {Scheme Procedure} vector-transduce xform f identity vec
- @deffnx {Scheme Procedure} string-transduce xform f str
- @deffnx {Scheme Procedure} string-transduce xform f identity str
- @deffnx {Scheme Procedure} bytevector-u8-transduce xform f bv
- @deffnx {Scheme Procedure} bytevector-u8-transduce xform f identity bv
- @deffnx {Scheme Procedure} generator-transduce xform f gen
- @deffnx {Scheme Procedure} generator-transduce xform f identity gen
- Same as @code{list-transduce}, but for vectors, strings, u8-bytevectors
- and SRFI-158-styled generators respectively.
- @end deffn
- @deffn {Scheme Procedure} port-transduce xform f reader
- @deffnx {Scheme Procedure} port-transduce xform f reader port
- @deffnx {Scheme Procedure} port-transduce xform f identity reader port
- Same as @code{list-transduce} but for ports. Called without a port, it
- reduces over the results of applying @var{reader} until the EOF-object
- is returned, presumably to read from @code{current-input-port}. With a
- port @var{reader} is applied to @var{port} instead of without any
- arguments. If @var{identity} is provided, that is used as the initial
- identity in the reduction.
- @end deffn
- @node SRFI-171 Reducers
- @subsubsection Reducers
- @cindex transducers reducers
- @deffn {Scheme Procedure} rcons
- a simple consing reducer. When called without values, it returns its
- identity, @code{'()}. With one value, which will be a list, it reverses
- the list (using @code{reverse!}). When called with two values, it conses
- the second value to the first.
- @example
- (list-transduce (tmap (lambda (x) (+ x 1)) rcons (list 0 1 2 3))
- @result{} (1 2 3 4)
- @end example
- @end deffn
- @deffn {Scheme Procedure} reverse-rcons
- same as rcons, but leaves the values in their reversed order.
- @example
- (list-transduce (tmap (lambda (x) (+ x 1))) reverse-rcons (list 0 1 2 3))
- @result{} (4 3 2 1)
- @end example
- @end deffn
- @deffn {Scheme Procedure} rany pred?
- The reducer version of any. Returns @code{(reduced (pred? value))} if
- any @code{(pred? value)} returns non-#f. The identity is #f.
- @example
- (list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 5))
- @result{} #f
- (list-transduce (tmap (lambda (x) (+ x 1))) (rany odd?) (list 1 3 4 5))
- @result{} #t
- @end example
- @end deffn
- @deffn {Scheme Procedure} revery pred?
- The reducer version of every. Stops the transduction and returns
- @code{(reduced #f)} if any @code{(pred? value)} returns #f. If every
- @code{(pred? value)} returns true, it returns the result of the last
- invocation of @code{(pred? value)}. The identity is #t.
- @example
- (list-transduce
- (tmap (lambda (x) (+ x 1)))
- (revery (lambda (v) (if (odd? v) v #f)))
- (list 2 4 6))
- @result{} 7
- (list-transduce (tmap (lambda (x) (+ x 1)) (revery odd?) (list 2 4 5 6))
- @result{} #f
- @end example
- @end deffn
- @deffn {Scheme Procedure} rcount
- A simple counting reducer. Counts the values that pass through the
- transduction.
- @example
- (list-transduce (tfilter odd?) rcount (list 1 2 3 4)) @result{} 2.
- @end example
- @end deffn
- @node SRFI-171 Transducers
- @subsubsection Transducers
- @cindex transducers transducers
- @deffn {Scheme Procedure} tmap proc
- Returns a transducer that applies @var{proc} to all values. Stateless.
- @end deffn
- @deffn {Scheme Procedure} tfilter pred?
- Returns a transducer that removes values for which @var{pred?} returns #f.
- Stateless.
- @end deffn
- @deffn {Scheme Procedure} tremove pred?
- Returns a transducer that removes values for which @var{pred?} returns non-#f.
- Stateless
- @end deffn
- @deffn {Scheme Procedure} tfilter-map proc
- The same as @code{(compose (tmap proc) (tfilter values))}. Stateless.
- @end deffn
- @deffn {Scheme Procedure} treplace mapping
- The argument @var{mapping} is an association list (using @code{equal?}
- to compare keys), a hash-table, a one-argument procedure taking one
- argument and either producing that same argument or a replacement value.
- Returns a transducer which checks for the presence of any value passed
- through it in mapping. If a mapping is found, the value of that mapping
- is returned, otherwise it just returns the original value.
- Does not keep internal state, but modifying the mapping while it's in
- use by treplace is an error.
- @end deffn
- @deffn {Scheme Procedure} tdrop n
- Returns a transducer that discards the first @var{n} values.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} ttake n
- Returns a transducer that discards all values and stops the transduction
- after the first @var{n} values have been let through. Any subsequent values
- are ignored.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tdrop-while pred?
- Returns a transducer that discards the first values for which
- @var{pred?} returns true.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} ttake-while pred?
- @deffnx {Scheme Procedure} ttake-while pred? retf
- Returns a transducer that stops the transduction after @var{pred?} has
- returned #f. Any subsequent values are ignored and the last successful
- value is returned. @var{retf} is a function that gets called whenever
- @var{pred?} returns false. The arguments passed are the result so far
- and the input for which pred? returns @code{#f}. The default function is
- @code{(lambda (result input) result)}.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tconcatenate
- tconcatenate @emph{is} a transducer that concatenates the content of
- each value (that must be a list) into the reduction.
- @example
- (list-transduce tconcatenate rcons '((1 2) (3 4 5) (6 (7 8) 9)))
- @result{} (1 2 3 4 5 6 (7 8) 9)
- @end example
- @end deffn
- @deffn {Scheme Procedure} tappend-map proc
- The same as @code{(compose (tmap proc) tconcatenate)}.
- @end deffn
- @deffn {Scheme Procedure} tflatten
- tflatten @emph{is} a transducer that flattens an input consisting of lists.
- @example
- (list-transduce tflatten rcons '((1 2) 3 (4 (5 6) 7 8) 9)
- @result{} (1 2 3 4 5 6 7 8 9)
- @end example
- @end deffn
- @deffn {Scheme Procedure} tdelete-neighbor-duplicates
- @deffnx {Scheme Procedure} tdelete-neighbor-duplicates equality-predicate
- Returns a transducer that removes any directly following duplicate
- elements. The default @var{equality-predicate} is @code{equal?}.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tdelete-duplicates
- @deffnx {Scheme Procedure} tdelete-duplicates equality-predicate
- Returns a transducer that removes any subsequent duplicate elements
- compared using @var{equality-predicate}. The default
- @var{equality-predicate} is @code{equal?}.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tsegment n
- Returns a transducer that groups inputs into lists of @var{n} elements.
- When the transduction stops, it flushes any remaining collection, even
- if it contains fewer than @var{n} elements.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tpartition pred?
- Returns a transducer that groups inputs in lists by whenever
- @code{(pred? input)} changes value.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tadd-between value
- Returns a transducer which interposes @var{value} between each value
- and the next. This does not compose gracefully with transducers like
- @code{ttake}, as you might end up ending the transduction on
- @code{value}.
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tenumerate
- @deffnx {Scheme Procedure} tenumerate start
- Returns a transducer that indexes values passed through it, starting at
- @var{start}, which defaults to 0. The indexing is done through cons
- pairs like @code{(index . input)}.
- @example
- (list-transduce (tenumerate 1) rcons (list 'first 'second 'third))
- @result{} ((1 . first) (2 . second) (3 . third))
- @end example
- Stateful.
- @end deffn
- @deffn {Scheme Procedure} tlog
- @deffnx {Scheme Procedure} tlog logger
- Returns a transducer that can be used to log or print values and
- results. The result of the @var{logger} procedure is discarded. The
- default @var{logger} is @code{(lambda (result input) (write input)
- (newline))}.
- Stateless.
- @end deffn
- @subheading Guile-specific transducers
- These transducers are available in the @code{(srfi srfi-171 gnu)}
- library, and are provided outside the standard described by the SRFI-171
- document.
- @deffn {Scheme Procedure} tbatch reducer
- @deffnx {Scheme Procedure} tbatch transducer reducer
- A batching transducer that accumulates results using @var{reducer} or
- @code{((transducer) reducer)} until it returns a reduced value. This can
- be used to generalize something like @code{tsegment}:
- @example
- ;; This behaves exactly like (tsegment 4).
- (list-transduce (tbatch (ttake 4) rcons) rcons (iota 10))
- @result{} ((0 1 2 3) (4 5 6 7) (8 9))
- @end example
- @end deffn
- @deffn {Scheme Procedure} tfold reducer
- @deffnx {Scheme Procedure} tfold reducer seed
- A folding transducer that yields the result of @code{(reducer seed
- value)}, saving its result between iterations.
- @example
- (list-transduce (tfold +) rcons (iota 10))
- @result{} (0 1 3 6 10 15 21 28 36 45)
- @end example
- @end deffn
- @node SRFI-171 Helpers
- @subsubsection Helper functions for writing transducers
- @cindex transducers helpers
- These functions are in the @code{(srfi srfi-171 meta)} module and are only
- usable when you want to write your own transducers.
- @deffn {Scheme Procedure} reduced value
- Wraps a value in a @code{<reduced>} container, signaling that the
- reduction should stop.
- @end deffn
- @deffn {Scheme Procedure} reduced? value
- Returns #t if value is a @code{<reduced>} record.
- @end deffn
- @deffn {Scheme Procedure} unreduce reduced-container
- Returns the value in reduced-container.
- @end deffn
- @deffn {Scheme Procedure} ensure-reduced value
- Wraps value in a @code{<reduced>} container if it is not already reduced.
- @end deffn
- @deffn {Scheme Procedure} preserving-reduced reducer
- Wraps @code{reducer} in another reducer that encapsulates any returned
- reduced value in another reduced container. This is useful in places
- where you re-use a reducer with [collection]-reduce. If the reducer
- returns a reduced value, [collection]-reduce unwraps it. Unless handled,
- this leads to the reduction continuing.
- @end deffn
- @deffn {Scheme Procedure} list-reduce f identity lst
- The reducing function used internally by @code{list-transduce}. @var{f}
- is a reducer as returned by a transducer. @var{identity} is the
- identity (sometimes called "seed") of the reduction. @var{lst} is a
- list. If @var{f} returns a reduced value, the reduction stops
- immediately and the unreduced value is returned.
- @end deffn
- @deffn {Scheme Procedure} vector-reduce f identity vec
- The vector version of list-reduce.
- @end deffn
- @deffn {Scheme Procedure} string-reduce f identity str
- The string version of list-reduce.
- @end deffn
- @deffn {Scheme Procedure} bytevector-u8-reduce f identity bv
- The bytevector-u8 version of list-reduce.
- @end deffn
- @deffn {Scheme Procedure} port-reduce f identity reader port
- The port version of list-reduce. It reduces over port using reader
- until reader returns the EOF object.
- @end deffn
- @deffn {Scheme Procedure} generator-reduce f identity gen
- The generator version of list-reduce. It reduces over @code{gen} until
- it returns the EOF object
- @end deffn
- @c srfi-modules.texi ends here
- @c Local Variables:
- @c TeX-master: "guile.texi"
- @c End:
|