1 Star 0 Fork 0

jacklisp/Learning-SICP

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
lec6b.srt 123.11 KB
一键复制 编辑 原始数据 按行查看 历史
DeathKing 提交于 2017-09-13 19:41 +08:00 . 2nd checked finished. ready to produce video
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787
1
00:00:00,032 --> 00:00:03,728
Learning-SICP学习小组
倾情制作
2
00:00:03,984 --> 00:00:07,264
翻译&&时间轴:张大伟(DreamAndDead)
压制&&特效:邓雄飞(Dysprosium)
校对:邓雄飞(Dysprosium)
3
00:00:07,408 --> 00:00:10,272
特别感谢:裘宗燕教授
4
00:00:10,400 --> 00:00:14,928
计算机程序的构造和解释
5
00:00:15,056 --> 00:00:19,408
流 II
Stream
6
00:00:20,970 --> 00:00:24,080
教授:上节课 我们介绍了流
PROFESSOR: OK, well, we've been looking at streams,
7
00:00:24,080 --> 00:00:27,824
按照信号处理的方式来组织系统
this signal processing way of putting systems together.
8
00:00:28,870 --> 00:00:31,424
要记住的是 关键点在于
And remember, the key idea is that
9
00:00:31,904 --> 00:00:32,960
我们分离开
we decouple
10
00:00:34,208 --> 00:00:37,312
程序中 事件表面上的顺序
the apparent order of events in our programs
11
00:00:37,584 --> 00:00:40,176
与机器中的实际计算顺序
from the actual order of events in the computer.
12
00:00:41,072 --> 00:00:42,288
那就意味着 我们可以
And that means that we can start
13
00:00:42,576 --> 00:00:44,144
着手处理非常长的流
dealing with very long streams
14
00:00:44,896 --> 00:00:47,392
并且只有在需要的时候才生成其中的元素
and only having to generate the elements on demand.
15
00:00:47,536 --> 00:00:49,392
这种按需计算的方式
That sort of on-demand computation
16
00:00:49,520 --> 00:00:51,408
是内建在流的数据结构中的
is built into the stream's data structure.
17
00:00:54,110 --> 00:00:55,648
即使这个流非常之长
So if we have a very long stream,
18
00:00:55,664 --> 00:00:57,080
我们只计算所需要的
we only compute what we need.
19
00:00:58,040 --> 00:01:00,750
只有当我们要求的时候 新的数据才会生成
The things only get computed when we actually ask for them.
20
00:01:00,750 --> 00:01:01,744
要举个什么样的例子呢?
Well, what are examples?
21
00:01:02,110 --> 00:01:03,600
这个“按需”是什么个情况呢?
Are they actually asking for them?
22
00:01:05,024 --> 00:01:06,016
举个例子
For instance, we might
23
00:01:09,216 --> 00:01:11,376
我们可能会想要一个流中的第N个元素
might ask for the n-th element of a stream.
24
00:01:15,360 --> 00:01:18,928
这个过程可以用于计算流的第N个元素
Here's a procedure that computes the n-th element of a stream.
25
00:01:20,090 --> 00:01:21,232
一个参数为索引N
An integer n,
26
00:01:21,248 --> 00:01:22,848
另一个参数是流S
the n-th element of some stream s,
27
00:01:23,408 --> 00:01:25,424
递归遍历这个流即可求解
and we just recursively walk down the stream.
28
00:01:25,570 --> 00:01:27,392
如果N为0 我们就计算头部分
And if n is 0, we compute the head.
29
00:01:27,960 --> 00:01:30,992
否则 就在流的尾部分
Otherwise, it's the n-th the minus 1 element
30
00:01:31,744 --> 00:01:32,800
查找第N-1个元素
of the stream.
31
00:01:34,310 --> 00:01:36,432
看起来是Lisp中很普通的编程方式 但是不同的是
Those two are just like for Lisp, but the difference
32
00:01:36,624 --> 00:01:38,768
直到我们不断遍历 取得相继的N个元素
is those elements aren't going to get computed
33
00:01:38,864 --> 00:01:40,992
这些元素才被计算出来
until we walk down, taking successive n-ths.
34
00:01:41,520 --> 00:01:44,784
这是这些流元素可能被FORCE的一种方式
So that's one way that the stream elements might get forced.
35
00:01:45,776 --> 00:01:46,640
另外一种方式则是
And another way,
36
00:01:47,184 --> 00:01:48,928
这里有个简单的过程 用来打印一个流
here's a little procedure that prints a stream.
37
00:01:49,300 --> 00:01:50,384
它的定义是
We say print a stream,
38
00:01:51,904 --> 00:01:53,280
过程PRINT-STREAM的定义是
so to print a stream s.
39
00:01:54,150 --> 00:01:55,120
我们要怎么做呢?
Well, what do we do? We'll
40
00:01:55,744 --> 00:01:56,864
先打印流的头部分
We print the head of the stream,
41
00:01:57,744 --> 00:01:59,328
流的头部分在这时就被计算出来
and that will cause the head to be computed.
42
00:01:59,720 --> 00:02:02,848
然后我们再递归地打印流的尾部分
And then we recursively print stream the tail of the stream.
43
00:02:04,990 --> 00:02:06,032
完成以后
And if we're already done,
44
00:02:06,048 --> 00:02:08,576
就返回一个的表示完成的消息 “DONE”
maybe we have to return something about the message done.
45
00:02:09,660 --> 00:02:11,392
如果你构造了一个流
OK, and then so if you make a stream,
46
00:02:11,648 --> 00:02:13,648
这个流非常的长
you could say here's the stream, this very long stream.
47
00:02:14,310 --> 00:02:16,336
当你调用这个过程
And then you say print the stream,
48
00:02:16,416 --> 00:02:19,776
流中的元素会随着PRINT-STREAM的调用
and the elements of the stream will get computed successively
49
00:02:19,872 --> 00:02:21,120
而被依次计算出来
as that print calls them.
50
00:02:21,320 --> 00:02:22,816
不会在一开始就全部计算出来
They won't get all computed initially.
51
00:02:24,300 --> 00:02:25,664
正因为如此 我们能够
So in this way, we can
52
00:02:27,504 --> 00:02:29,610
我们能够处理非常长的流
So in this way, we can deal with some very long streams.
53
00:02:30,190 --> 00:02:31,920
多长呢?
Well, how long can a stream be?
54
00:02:33,744 --> 00:02:35,120
可以是无限长
Well, it can be infinitely long.
55
00:02:35,904 --> 00:02:38,048
我们在计算机上实践一下
Let's look at an example here on the computer.
56
00:02:38,920 --> 00:02:41,968
我可以在计算机前输入
I could walk up to this computer, and I could say--
57
00:02:43,488 --> 00:02:53,312
我先定义一个函数 (INTEGERS-FROM N)
how about we'll define the stream of integers starting with some number N,
58
00:02:54,240 --> 00:02:57,136
用于生成一个从N开始的正整数流
the stream of positive integers starting with some number n.
59
00:03:00,360 --> 00:03:19,168
也就是 (CONS-STREAM N (INTEGERS-FROM (+ N 1))))
And that's cons-stream of n onto the integers from one more.
60
00:03:24,416 --> 00:03:25,616
这样就我们要的全部整数
So there are the integers.
61
00:03:28,992 --> 00:03:31,500
现在我来尝试得到所有的整数
Then I could say let's get all the integers.
62
00:03:34,570 --> 00:03:44,336
(DEFINE INTEGERS (INTEGERS-FROM 1))
define the stream of integers to be the integers starting with 1.
63
00:03:48,840 --> 00:03:50,944
如果现在我执行 (NTH-STREAM 20 INTEGERS)
And now if I say something like
64
00:03:54,416 --> 00:03:55,800
来查看第20个元素
what's the what's the 20th integer.
65
00:04:03,424 --> 00:04:05,536
得到21 因为索引是从0开始的
So it's 21 because we start counting at 0.
66
00:04:06,848 --> 00:04:08,880
或者我们来点更复杂的
Or I can do more complicated things.
67
00:04:09,450 --> 00:04:10,840
我再来定义一个谓词
Let me to define a little predicate here.
68
00:04:11,776 --> 00:04:18,512
谓词NO-SEVEN用来检测是否为7的倍数
How about define no-seven.
69
00:04:19,580 --> 00:04:20,752
它的判定方法是这样的:
It's going to test an integer,
70
00:04:21,792 --> 00:04:23,168
如果整数X不是7的倍数
and it's going to say it's not.
71
00:04:28,820 --> 00:04:33,968
我取X除7的余数
I take the remainder of x by 7,
72
00:04:36,624 --> 00:04:38,352
余数不应该为0
I don't get 0.
73
00:04:43,808 --> 00:04:49,776
这时用NO-SEVEN这个谓词
And then I could say define the integers with no sevens
74
00:04:50,224 --> 00:04:59,120
过滤全部的整数
take all the integers and filter them to have no sevens.
75
00:05:11,570 --> 00:05:13,344
这样我就得到了所有的
So now I've got the stream of all the integers
76
00:05:13,632 --> 00:05:15,056
不是7的倍数的整数构成的流
that are not divisible by seven.
77
00:05:16,490 --> 00:05:23,440
如果我问 这些不是7的倍数的整数中
So if I say what's the 100th integer
78
00:05:24,704 --> 00:05:26,480
的第100个数是多少?
and the list not divisible by seven,
79
00:05:26,864 --> 00:05:28,112
结果是117
I get 117.
80
00:05:28,320 --> 00:05:30,672
或者我也可以问
Or if I'd like to say well, I could say ah.
81
00:05:32,304 --> 00:05:34,384
这个流的所有元素都是些什么?
well, gee, what are all of them?
82
00:05:35,270 --> 00:05:40,352
我可以用(PRINT-STREAM NS)来尝试打印这个流
So I could say print stream all these integers with no seven,
83
00:05:40,832 --> 00:05:41,792
它就会输出个不停
it goes off printing.
84
00:05:45,100 --> 00:05:47,070
你可能需要等上很久才能得到全部结果
You may have to wait a very long time to see them all.
85
00:05:52,670 --> 00:05:53,840
你可能会问了
Well, you can start asking, gee,
86
00:05:54,816 --> 00:05:57,008
这个数据结构
you know, is it really true that this data structure
87
00:05:58,288 --> 00:06:00,656
真的全部是由整数构成的吗?
with the integers is really all the integers?
88
00:06:01,100 --> 00:06:04,053
现在我画一个图来演示下刚写的那个程序
And let me draw a picture of that program I just wrote.
89
00:06:04,960 --> 00:06:10,570
这是我刚才键入的整数定义
Here's the, right, here's the definition of the integers again that I just typed in,
90
00:06:12,336 --> 00:06:15,984
它是一个由第一个整数和由下一个整数生成的流 所构成的序对
Right it's a cons of the first integer under the integer starting with the rest.
91
00:06:17,616 --> 00:06:19,770
现在我们画个图来看看它到底是什么样
Now, we can make a picture of that and see what it looks like.
92
00:06:22,720 --> 00:06:24,320
从概念上来说 这应该是一个盒子
Conceptually, what I have is a box
93
00:06:25,536 --> 00:06:27,184
这个盒子是(INTEGER-FROM N)
that's the integer starting with n.
94
00:06:27,420 --> 00:06:29,088
它接受一个参数N
It takes in some number n,
95
00:06:31,424 --> 00:06:32,976
然后返回一个流
and it's going to return a stream of--
96
00:06:35,024 --> 00:06:37,360
这个无穷流表示从N开始的所有整数
this infinite stream of all integers starting with n.
97
00:06:38,080 --> 00:06:38,736
我要做什么呢?
And what do I do?
98
00:06:38,752 --> 00:06:42,384
呃 这个是INT-FROM盒子
Well, this is an integers-from box.
99
00:06:45,070 --> 00:06:45,800
里面是什么样子呢?
What's it got in it?
100
00:06:45,800 --> 00:06:48,608
取得参数N之后
Well, it takes in this n,
101
00:06:52,272 --> 00:06:53,920
将其 +1
and it increments it.
102
00:06:57,952 --> 00:07:03,150
然后把结果递归地传递给另一个INT-FROM盒子
And then it puts the result into recursively another integer's from box.
103
00:07:06,870 --> 00:07:09,600
把这个盒子的结果和最初的N
It takes the result of that and the original n
104
00:07:10,240 --> 00:07:12,784
用CONS组合起来
and puts those together with a cons
105
00:07:13,392 --> 00:07:14,360
就形成了一个流
and forms a stream.
106
00:07:14,576 --> 00:07:17,264
我刚才写的那个过程 画出来就是这样子
So that's a picture of that program I wrote. And this is a ...
107
00:07:18,528 --> 00:07:20,320
我们看到的这类图像
Let's see. These kind of diagrams we first saw
108
00:07:20,784 --> 00:07:21,740
首先是由Peter Henderson提出的
drawn by Peter Henderson,
109
00:07:21,760 --> 00:07:23,320
也就是前面课程中绘图语言的发明者
the same guy who did the Escher language.
110
00:07:23,320 --> 00:07:24,752
我们把这种图叫做Henderson图
We call them Henderson diagrams.
111
00:07:25,376 --> 00:07:27,904
画这种图需要遵守一定的约定
And the convention here is that you put these things together.
112
00:07:28,530 --> 00:07:32,512
这些实线代表输出的流
And the solid lines are things coming out are streams,
113
00:07:33,024 --> 00:07:36,208
这些虚线则是初始的输入值
and dotted lines are initial values going in.
114
00:07:37,270 --> 00:07:39,024
而这个图描述的形状是——
So this one has the shape of--
115
00:07:39,408 --> 00:07:41,600
它会取一个整数作为初始值
it takes in some integer, some initial value,
116
00:07:41,808 --> 00:07:42,912
然后输出一个流
and outputs a stream.
117
00:07:46,352 --> 00:07:48,224
现在 你可能又要问了
Again, you can ask. You know it's really
118
00:07:48,380 --> 00:07:50,880
那个INTEGERS的数据结构真的全部都是整数吗?
Is that data structure integers really all the integers?
119
00:07:52,090 --> 00:07:54,912
或者它只是经过了精心组织
Alright? Or is it is something that's cleverly arranged
120
00:07:54,940 --> 00:07:56,432
以至于总可以在其中找到
so that whenever you look for an integer
121
00:07:56,448 --> 00:07:57,240
我们需要的那个整数?
you find it there?
122
00:07:57,950 --> 00:07:59,744
这有点像个哲学问题 不是么?
That's sort of a philosophical question, right?
123
00:07:59,780 --> 00:08:01,696
如果有一个东西
If something is there
124
00:08:02,144 --> 00:08:03,968
你不去观测它 能否知道它“存在”呢?
whenever you look, is it really there or not?
125
00:08:04,450 --> 00:08:07,344
这就有点像
It's sort of the same sense in which
126
00:08:07,360 --> 00:08:09,420
你在银行中的存款那样
the money in your savings account is in the bank.
127
00:08:12,380 --> 00:08:12,640
好吧
Well
128
00:08:16,352 --> 00:08:17,488
我们再来看一个例子
let me do another example.
129
00:08:18,680 --> 00:08:20,704
这门课的第一节课
Umm, Gee, we started the course
130
00:08:20,720 --> 00:08:22,720
我们就讲了一个来自于亚历山大的算法
with an algorithm from Alexandria,
131
00:08:23,296 --> 00:08:25,800
来自亚历山大的Heron提出的
which was Heron of Alexandria's algorithm
132
00:08:25,824 --> 00:08:26,944
一个用于计算平方根的算法
for computing the square root.
133
00:08:28,470 --> 00:08:32,030
现在再来看一个 同样来自于亚力山大的算法
Let's take a look at another Alexandrian algorithm.
134
00:08:32,030 --> 00:08:35,088
这个被称为Eratosthenes算法的方法
This one is Eratosthenes method for
135
00:08:36,192 --> 00:08:38,448
用于计算所有的质数
for computing all of the primes.
136
00:08:41,169 --> 00:08:42,830
它被称为Eratosthenes筛法
It is called the Sieve of Eratosthenes.
137
00:08:42,830 --> 00:08:49,728
它是这样的 一开始
And what you do is you start out,
138
00:08:50,992 --> 00:08:52,288
先列举所有的整数
and you list all the integers,
139
00:08:52,608 --> 00:08:53,536
从2开始
say, starting with 2.
140
00:08:53,880 --> 00:08:55,040
然后取第一个整数
And then you take the first integer, and you say,
141
00:08:55,088 --> 00:08:56,670
然后你发现 哦 2是一个质数
and you say, oh, that's prime.
142
00:08:57,310 --> 00:08:58,352
然后你考察剩余的整数
And then you go look at the rest,
143
00:08:58,688 --> 00:09:00,880
划掉其中可以被2整除的数
and you cross out all the things divisible by 2.
144
00:09:01,520 --> 00:09:04,736
我把这个划掉 还有这个 这个
So I cross out this and this and this.
145
00:09:05,250 --> 00:09:06,352
有点费时
This takes a long time
146
00:09:06,368 --> 00:09:08,912
我要对所有的整数进行这样的操作
because I have to do it for all of the integers.
147
00:09:11,160 --> 00:09:15,392
我遍历整个整数表
So I go through the entire list of integers,
148
00:09:18,272 --> 00:09:20,944
划掉所有被2整除的数
crossing the ones divisible by 2.
149
00:09:22,112 --> 00:09:24,384
所有的整数都操作完后
And now when I finish with all of the integers,
150
00:09:24,784 --> 00:09:26,720
回过头再来看还剩些什么
I go back and look and say what am I left with?
151
00:09:27,040 --> 00:09:28,800
好的 下一个数就是3了
Well, the first thing that starts there is 3.
152
00:09:29,330 --> 00:09:30,336
3也是一个质数
So 3 is a prime.
153
00:09:30,770 --> 00:09:33,056
现在 我会继续在剩下的数中
And now I go back through what I'm left with,
154
00:09:33,360 --> 00:09:35,072
划掉所有被3整除的数
and I cross out all the things divisible by 3.
155
00:09:35,080 --> 00:09:43,808
划掉 9、15、21、27、33 等等
So let's see, 9 and 15 and 21 and 27 and 33 and so on.
156
00:09:44,336 --> 00:09:45,120
我就不往下划了
I won't finish.
157
00:09:45,350 --> 00:09:46,528
然后看看我们还剩下什么
Then I see what I'm left with.
158
00:09:47,250 --> 00:09:49,840
而下一个就是5了
And the next one I have is 5.
159
00:09:50,496 --> 00:09:52,048
我又遍历剩下的数
Now I can through the rest,
160
00:09:52,432 --> 00:09:54,512
找到第一个能被5整除的数
and I find the first one that's divisible by 5.
161
00:09:54,540 --> 00:09:57,616
把剩下的能被5整除的数都划掉
I cross out from the remainder all the ones that are divisible by 5.
162
00:09:58,352 --> 00:09:59,248
做完这个之后
And I did that,
163
00:09:59,824 --> 00:10:01,890
下一个数就是7
and then I go through and find 7.
164
00:10:01,890 --> 00:10:02,720
再遍历剩下的数
Go through all the rest,
165
00:10:02,760 --> 00:10:03,952
划掉所有被7整除的数
cross out things divisible 7,
166
00:10:03,984 --> 00:10:05,470
然后一直这样下去
and I keep doing that forever.
167
00:10:06,810 --> 00:10:07,408
全部结束的时候
And when I'm done,
168
00:10:07,408 --> 00:10:09,104
我也就得到了所有的质数
what I'm left with is a list of all the primes.
169
00:10:09,904 --> 00:10:13,312
这就是Eratosthenes筛法
So that's the Sieve of Eratosthenes.
170
00:10:15,430 --> 00:10:17,696
我们来看下实际代码
Let's look at it as a computer program.
171
00:10:17,930 --> 00:10:19,856
这个过程命名为SIEVE
It's a procedure called sieve.
172
00:10:27,910 --> 00:10:29,408
这是对应的代码
Now, I just write what I did.
173
00:10:30,336 --> 00:10:34,480
SIEVE过程 以一个流S为参数
I'll say to sieve some stream s.
174
00:10:38,770 --> 00:10:39,936
返回一个新的流
I'm going to build a stream
175
00:10:40,272 --> 00:10:41,840
新的流的头部分 就是流S的头部分
whose first element is the head of this.
176
00:10:41,870 --> 00:10:44,432
回忆一下 我总是取剩下的数中的第一个
Remember, I always found the first thing I was left with,
177
00:10:44,912 --> 00:10:48,752
而尾部分则是把流S的尾部分
and the rest of it is the result of taking the tail of S,
178
00:10:51,080 --> 00:10:53,728
过滤掉所有
filtering it to throw away all the things
179
00:10:53,744 --> 00:10:55,320
能被S头部分整除的数
that are divisible by the head of S,
180
00:10:56,416 --> 00:10:57,568
然后再对结果筛选
and now sieving the result.
181
00:10:59,020 --> 00:11:00,096
这个代码就是这样
That's just what I did.
182
00:11:01,980 --> 00:11:04,688
现在 为了得到由质数构成的无穷流
And now to get the infinite stream of times,
183
00:11:05,024 --> 00:11:06,900
我们对从2开始的整数流进行SIEVE
we just sieve all the integers starting from 2.
184
00:11:14,920 --> 00:11:15,568
我们来实践一下
Let's try that.
185
00:11:16,300 --> 00:11:18,304
实际上 我们可以在计算机中运行
We can actually do it.
186
00:11:19,760 --> 00:11:22,128
我希望我已经预先输入过SIEVE的定义了
I typed in the definition of sieve before, I hope,
187
00:11:22,864 --> 00:11:24,064
所以我可以定义
so I can say something like
188
00:11:24,928 --> 00:11:33,456
我可以把PRIMES定义为
define the primes to be
189
00:11:34,640 --> 00:11:41,456
(SIEVE (INTEGERS-FROM 2))
the result of sieving the integers starting with 2.
190
00:11:46,760 --> 00:11:48,100
现在我就得到了质数构成的表
So now I've got this list of primes.
191
00:11:48,100 --> 00:11:50,990
这样就得到了所有的质数 对吧?
That's all of the primes, right?
192
00:11:50,990 --> 00:11:53,520
比如我可以问 第20个质数是什么?
So, if for example, what's the 20th prime in that list?
193
00:12:00,736 --> 00:12:01,680
结果是73
73.
194
00:12:02,540 --> 00:12:03,344
那个短促的停顿
See, and that little pause,
195
00:12:03,360 --> 00:12:04,928
这是因为
it was only at the point
196
00:12:04,940 --> 00:12:06,432
在我询问第20个元素时
when I started asking for the 20th prime
197
00:12:06,464 --> 00:12:07,680
它才进行实际的计算
is that it started computing.
198
00:12:10,370 --> 00:12:11,296
在这里 我也可以要求
Or I can say here
199
00:12:13,808 --> 00:12:14,880
打印所有的质数
Or I can say here let's look at all of the primes.
200
00:12:22,640 --> 00:12:24,400
解释器就开始计算并打印所有的质数
And there it goes computing all of the primes.
201
00:12:25,350 --> 00:12:26,288
得花上好一会儿
Of course, it will take a while
202
00:12:26,288 --> 00:12:27,610
才能打赢完整
again if I want to look at all of them,
203
00:12:27,792 --> 00:12:28,570
所以先把它停掉
so let's stop it.
204
00:12:32,030 --> 00:12:33,130
让我来画图演示一下
Let me draw you a picture of that.
205
00:12:33,130 --> 00:12:34,176
我已经画好了
Well, I've got a picture of that.
206
00:12:34,890 --> 00:12:36,192
这个过程的图形应该是什么样子呢?
What's that program really look like?
207
00:12:37,900 --> 00:12:39,776
用这类图形的约定来说
Again, some practice with these diagrams,
208
00:12:39,824 --> 00:12:40,544
我有一个叫SIEVE的盒子
I have a sieve box.
209
00:12:42,610 --> 00:12:43,560
它是如何运作的呢?
How does sieve work?
210
00:12:43,560 --> 00:12:44,810
它以一个流作为输入
It takes in a stream.
211
00:12:48,850 --> 00:12:50,592
分离流的头、尾部分
It splits off the head from the tail.
212
00:12:50,870 --> 00:12:53,264
从SIEVE盒子出来的第一个东西
And the first thing that's going to come out of the sieve
213
00:12:53,488 --> 00:12:54,976
就是原来流的头部分
is the head of the original stream.
214
00:12:58,208 --> 00:13:00,928
头部分同样也用于这个盒子
Then it also takes the head and uses that.
215
00:13:02,550 --> 00:13:05,104
这个盒子会过滤流的尾部分
It takes the stream. It filters the tail
216
00:13:05,552 --> 00:13:08,336
过滤的依据是 能否被头部分整除
It filters the tail and uses the head to filter for nondivisibility.
217
00:13:09,536 --> 00:13:11,184
过滤得到的不可整除的那些数
It takes the result of nondivisibility
218
00:13:11,248 --> 00:13:13,120
再放入另一个SIEVE盒子
and puts it through another sieve box
219
00:13:13,904 --> 00:13:15,130
然后把它们组合输出
and puts the result together.
220
00:13:15,130 --> 00:13:16,896
你可以把SIEVE想象为一个过滤器
So you can think of this sieve a filter,
221
00:13:17,200 --> 00:13:19,232
只不过它是一个无穷递归的过滤器
but notice that it's an infinitely recursive filter.
222
00:13:19,650 --> 00:13:20,880
这是因为在SIEVE盒子中
Because inside the sieve box
223
00:13:21,520 --> 00:13:22,608
还有另外一个SIEVE盒子
is another sieve box,
224
00:13:23,376 --> 00:13:25,856
内部的盒子里面还有另外一个SIEVE盒子
and inside that is another sieve box and another sieve box.
225
00:13:27,130 --> 00:13:28,960
我们现在逐渐有了非常厉害的能力
So you see we start getting some very powerful things.
226
00:13:28,960 --> 00:13:32,848
我们开始把 信号处理的方法
We're starting to mix this signal processing view of the world
227
00:13:33,904 --> 00:13:36,416
和计算中的递归结合在一起 来建模世界
with things like recursion that come from computation.
228
00:13:37,424 --> 00:13:39,824
还有很多像是这样的事
And there are all sorts of interesting things you can do that are like this.
229
00:13:40,970 --> 00:13:42,096
好的 有什么问题吗?
All right, any questions?
230
00:13:48,190 --> 00:13:49,168
好吧 那我们休息一下
OK, let's take a break.
231
00:13:49,640 --> 00:14:04,128
[音乐]
[JESU, JOY OF MAN'S DESIRING]
232
00:14:04,464 --> 00:14:08,120
《计算机程序的构造和解释》
233
00:14:12,080 --> 00:14:16,384
讲师:哈罗德·艾伯森教授 及 格兰德·杰·萨斯曼教授
234
00:14:16,448 --> 00:14:20,220
《计算机程序的构造和解释》
235
00:14:20,352 --> 00:14:25,056
流 II
236
00:14:28,650 --> 00:14:30,368
我们已经看了
Well, we've been looking at a couple
237
00:14:30,368 --> 00:14:32,090
好几个流式程序设计的例子
of examples of stream programming.
238
00:14:34,790 --> 00:14:39,216
我们目前接触到的流过程
All the stream procedures that we've looked at so far
239
00:14:39,728 --> 00:14:41,328
都有一个共同的特征
have the same kind of character.
240
00:14:41,490 --> 00:14:43,632
这些过程总是递归地
We've been writing these recursive procedures
241
00:14:44,160 --> 00:14:46,496
一次生成一个元素
that kind of generate these stream elements one at a time
242
00:14:46,510 --> 00:14:48,720
再用CONS-STREAM连接起来
and put them together in cons-streams.
243
00:14:49,152 --> 00:14:50,864
因此 我们一直把它当作是生成器
So we've been thinking a lot about generators.
244
00:14:50,928 --> 00:14:53,632
还有一种思考流式程序设计的方式
There's another way to think about stream processing,
245
00:14:53,790 --> 00:14:56,960
我们不认为程序是
and that's to focus not on programs that sort of
246
00:14:57,360 --> 00:14:59,930
沿着流逐一处理元素
process these elements as you walk down the stream,
247
00:15:00,256 --> 00:15:05,680
而是一下子处理了整个流
but on things that kind of process the streams all at once.
248
00:15:07,180 --> 00:15:09,168
我先来定义两个非常有用的过程
To show you what I mean, let me start by defining
249
00:15:09,232 --> 00:15:11,500
来帮助我说明
two procedures that will come in handy.
250
00:15:12,410 --> 00:15:13,600
第一个过程是ADD-STREAMS
The first one's called add streams.
251
00:15:15,360 --> 00:15:18,256
它接受两个流作为参数
Add streams takes two streams:
252
00:15:18,816 --> 00:15:20,880
S1和S2
s1 and s2.
253
00:15:22,300 --> 00:15:24,672
它生成一个新的流
And it's going to produce a stream
254
00:15:24,992 --> 00:15:28,176
其元素是两个流相应位置元素的和
whose elements are the are the corresponding sums
255
00:15:30,224 --> 00:15:31,888
相当于是“按元素”的加
We just sort of add them element-wise.
256
00:15:32,970 --> 00:15:33,952
如果其中一个流是空的
If either stream is empty,
257
00:15:33,968 --> 00:15:35,390
我们就返回另一个
we just return the other one.
258
00:15:36,810 --> 00:15:38,960
否则 我们就构建一个新的流
Otherwise, we're going to make a new stream
259
00:15:39,904 --> 00:15:42,960
新流的头部分是两个流头部分之和
whose head is the sum of the two heads
260
00:15:44,000 --> 00:15:44,880
而新流的尾部分
whose tail
261
00:15:46,000 --> 00:15:48,624
则是递归地加和尾部分
is the result of recursively adding the tails.
262
00:15:50,090 --> 00:15:52,736
这就会产生“按元素”地加的效果
So that will produce the element-wise sum of two streams.
263
00:15:53,150 --> 00:15:57,040
另一个过程是SCALE-STREAM
And then another useful thing to have around is scale stream.
264
00:15:57,500 --> 00:16:01,664
SCALE-STREAM有两个参数 常数C和流S
Scale stream takes some constant number in a stream s
265
00:16:04,112 --> 00:16:06,624
结果生成的流
and is going to produce the stream
266
00:16:07,184 --> 00:16:09,504
就是将流S的所有元素乘上了C
of elements of s multiplied by this constant.
267
00:16:09,710 --> 00:16:11,216
这很简单 就是一个MAP
And that's easy, that's just a map
268
00:16:12,208 --> 00:16:16,224
用到的函数是 X*C
of the function of an element that multiplies it by the constant,
269
00:16:16,352 --> 00:16:17,808
把这个函数MAP于整个流
and we map that down the stream.
270
00:16:20,064 --> 00:16:21,472
有了这两个过程
So given those two,
271
00:16:22,640 --> 00:16:24,368
我来给你们解释 什么叫做
let me show you what I mean by programs that
272
00:16:24,704 --> 00:16:27,008
“一下子处理整个流”
that operate on streams all at once.
273
00:16:28,128 --> 00:16:28,736
我们来看这个
Let's look at this.
274
00:16:30,200 --> 00:16:30,928
假设这样
Suppose I write this.
275
00:16:31,680 --> 00:16:52,352
(DEFINE ONES (CONS-STREAM 1 ONES))
I say define-- I'll call it ones-- to be cons-stream of 1 onto ones.
276
00:16:54,860 --> 00:16:55,520
这是什么?
What's that?
277
00:16:56,950 --> 00:16:58,944
这是一个表示无穷个1的流
That's going to be an infinite stream of ones
278
00:16:59,968 --> 00:17:01,440
因为第一个元素是1
because the first thing is 1.
279
00:17:03,330 --> 00:17:05,152
尾部分则是这样的
And the tail of it is a thing
280
00:17:05,552 --> 00:17:06,832
它的头部分是1
whose first thing is 1
281
00:17:07,630 --> 00:17:09,024
它的尾部分
whose tail is a thing
282
00:17:09,120 --> 00:17:10,240
的头部分又为1
whose first thing is 1
283
00:17:10,528 --> 00:17:11,780
以此类推
and so on and so on.
284
00:17:11,780 --> 00:17:13,328
这就是无穷个1的流
So that's an infinite stream of ones.
285
00:17:15,130 --> 00:17:15,936
现在根据ONES
And now using that,
286
00:17:16,128 --> 00:17:18,032
我再给出另一种定义整数的方式
let me give you another definition of the integers.
287
00:17:19,472 --> 00:17:27,360
(DEFINE INTEGERS
We can define the integers to be--
288
00:17:28,240 --> 00:17:30,768
当然 第一个数是1
well, the first integer we'll take to be 1,
289
00:17:32,752 --> 00:17:38,576
(CONS-STREAM 1 (ADD-STREAM
his cons-stream of 1 onto the element-wise sum
290
00:17:40,224 --> 00:17:48,270
INTEGERS ONES)))
onto add streams of the integers to ones.
291
00:17:55,100 --> 00:17:56,352
整数流是这样的:
The integers are a thing
292
00:17:57,248 --> 00:17:59,984
它的第一个元素是1
whose first element is 1,
293
00:18:00,880 --> 00:18:02,320
而其余部分则是
and the rest of them you get
294
00:18:03,120 --> 00:18:06,144
依次把每个整数加1
by taking those integers and incrementing each one by one.
295
00:18:06,640 --> 00:18:08,192
因此 整数流的第二个元素则是
So the second element of the integers
296
00:18:08,512 --> 00:18:11,968
整数流的第一个元素加1
is the first element of the integers incremented by one.
297
00:18:13,920 --> 00:18:15,184
下一个数又要加1
And the rest of that is the next one,
298
00:18:15,200 --> 00:18:16,480
第三个元素则是
and the third element of that
299
00:18:16,620 --> 00:18:20,416
INTEGER流尾部分的第一个元素
is the same as the first element of the tail of the integers
300
00:18:20,848 --> 00:18:21,960
加1
incremented by one,
301
00:18:22,512 --> 00:18:23,760
这也就相当于
which is the same as the
302
00:18:25,088 --> 00:18:28,656
最初整数流的第一个元素加1
first element of the original integers incremented by one
303
00:18:28,864 --> 00:18:31,250
然后再加1 以此类推
and incremented by one again and so on.
304
00:18:35,240 --> 00:18:36,310
这看起来有点匪夷所思
That looks pretty suspicious.
305
00:18:36,310 --> 00:18:37,472
这样的过程可以正常运行
See, notice that it works
306
00:18:38,128 --> 00:18:38,990
关键在于延时求值
because of delay.
307
00:18:40,150 --> 00:18:43,328
我们来看这个ONES
See, this looks like-- let's take a look at ones.
308
00:18:43,870 --> 00:18:45,920
这看起来根本不可能
This looks like it couldn't even be processed
309
00:18:46,256 --> 00:18:47,632
因为它突然说
because it's suddenly saying
310
00:18:47,792 --> 00:18:48,960
在定义ONES的时候
in order to know what ones is,
311
00:18:49,008 --> 00:18:50,912
发现它依赖于它本身
I say it's cons-stream of something onto ones.
312
00:18:51,130 --> 00:18:52,080
它之所以可以运行是因为
The reason that works
313
00:18:52,096 --> 00:18:54,040
这里暗中隐藏着延时求值
because of that very sneaky hidden delay in there.
314
00:18:55,250 --> 00:18:56,560
这个代码实际上是
Because what this really is,
315
00:18:57,792 --> 00:18:59,696
回忆下 CONS-STREAM是只是一个缩写
remember, cons-stream is just an abbreviation.
316
00:19:00,290 --> 00:19:01,152
实际上则是
This really is
317
00:19:01,856 --> 00:19:08,992
(CONS 1 (DELAY ONES))
cons of 1 onto delay of ones.
318
00:19:12,140 --> 00:19:13,216
它又是怎么运作的呢?
So how does that work?
319
00:19:15,500 --> 00:19:16,880
你想要定义ONES
You say I'm going to define ones.
320
00:19:18,020 --> 00:19:20,240
我来看看ONES要被定义成什么样
First I see what ones is supposed to be defined as.
321
00:19:20,700 --> 00:19:23,408
ONES被定义为一个序对
Well, ones is supposed to be defined as
322
00:19:24,896 --> 00:19:28,112
其CAR部分为1
a cons whose first part is 1
323
00:19:28,320 --> 00:19:29,456
而CDR部分则是
and the second part is,
324
00:19:29,450 --> 00:19:30,736
是一个计算某物的PROMISE
well, it's a promise to compute something
325
00:19:30,752 --> 00:19:31,690
我现在还不用关心
that I don't worry about yet.
326
00:19:32,710 --> 00:19:34,256
所以虽然这时ONES还没有定义
So it doesn't bother me that at the point
327
00:19:34,288 --> 00:19:36,300
但对我并不造成什么影响
I do this definition, ones isn't defined.
328
00:19:37,270 --> 00:19:39,456
一旦运行了整个定义 ONES就被定义了
Having run the definition, now ones is defined.
329
00:19:40,670 --> 00:19:42,832
所以 访问它尾部的时候 它就有定义了
So that when I go and look at the tail of it, it's defined.
330
00:19:44,920 --> 00:19:46,064
这一点非常隐讳
It's very sneaky.
331
00:19:46,590 --> 00:19:47,904
整数流的定义也是如此
And an integer is the same way.
332
00:19:48,470 --> 00:19:50,464
我可以在这里引用INTEGERS是因为
I can refer to integers here because
333
00:19:51,136 --> 00:19:53,210
是因为这个CONS-STREAM的缘故
hidden way down-- because of this cons-stream.
334
00:19:53,850 --> 00:19:55,248
用CONS-STREAM把1
It's the cons-stream of 1
335
00:19:55,376 --> 00:19:57,050
和一个不立即需要的东西组合起来
onto something that I don't worry that yet.
336
00:19:57,050 --> 00:19:59,600
所以我在运行INTEGERS的定义的时候
So I don't look at it, and I don't notice that integers isn't defined
337
00:20:00,224 --> 00:20:01,904
并不会发现INTEGER没有定义过
at the point where I try and run the definition.
338
00:20:06,320 --> 00:20:08,272
听上去非常玄乎
OK, let me draw a picture of that integers thing
339
00:20:08,448 --> 00:20:11,504
让我用图像来演示一下INTEGERS的原理
because it still maybe seems a little bit shaky.
340
00:20:12,430 --> 00:20:14,720
怎么画呢?
What do I do? Uh...
341
00:20:15,020 --> 00:20:16,304
首先是ONES这个流
I've got the stream of ones,
342
00:20:20,510 --> 00:20:21,888
它作为参数输入
and that sort of comes in
343
00:20:23,260 --> 00:20:24,928
进入一个加法器
comes in and goes into an adder
344
00:20:24,960 --> 00:20:26,590
进行流的加法运算
that's going to be this add streams thing.
345
00:20:29,310 --> 00:20:35,872
输出则是整数流INTEGERS
And that goes in-- that's going to put out the integers.
346
00:20:40,760 --> 00:20:42,704
这里 这个整数流又重新进入加法器
And the other thing that goes into the adder here
347
00:20:44,944 --> 00:20:46,976
形成了一个小型的反馈回路
is the integer, so there's a little feedback loop.
348
00:20:48,060 --> 00:20:49,424
我需要在某处接入最初的ONES
And all I need to start it off
349
00:20:50,096 --> 00:20:52,880
才能让它生效
is someplace I've got a stick that initial 1.
350
00:20:57,100 --> 00:20:58,640
在真实的信号处理中
In a real signal processing thing,
351
00:20:58,720 --> 00:21:02,480
这里是一个被初始化为1的延时元件
this might be a delay element with that was initialized to 1.
352
00:21:02,910 --> 00:21:05,904
这就是ONES程序的图示
But there's a picture of that ones program.
353
00:21:07,860 --> 00:21:09,632
事实上 这个非常像
And in fact, that looks a lot like--
354
00:21:09,808 --> 00:21:13,776
如果你见过真正的信号方块图的话
if you've seen real signal block diagram things,
355
00:21:13,776 --> 00:21:16,304
这个图形非常像累加器
that looks a lot like accumulators,
356
00:21:16,352 --> 00:21:17,488
有穷状态累加器
finite state accumulators.
357
00:21:17,980 --> 00:21:20,064
事实上 我们可以稍加修改
And in fact, we can modify this a little bit
358
00:21:21,184 --> 00:21:23,968
就可以让它对一个流做积分
to change this into something that integrates a stream
359
00:21:25,370 --> 00:21:26,976
或者说是有穷状态累加器
or a finite state accumulator,
360
00:21:27,008 --> 00:21:28,040
你怎么认为都可以
however you like to think about it.
361
00:21:28,440 --> 00:21:30,864
现在 不再是输入ONES 输出INTEGERS
So instead of the ones coming in and getting out the integers,
362
00:21:31,680 --> 00:21:32,384
我们要做的是
what we'll do is
363
00:21:32,912 --> 00:21:34,832
这里有一个流S为输入
say there's a stream s coming in,
364
00:21:35,760 --> 00:21:40,560
我们要计算这个流的积分
and we're going to get out the integral of this.
365
00:21:42,600 --> 00:21:44,096
也就是累加这个流的值
successive values of that,
366
00:21:44,448 --> 00:21:45,630
这看起来几乎就是一样的
and it looks almost the same.
367
00:21:45,660 --> 00:21:46,848
我们要做的就是
The only thing we're going to do is
368
00:21:47,024 --> 00:21:48,080
当S从这里输入时
when s comes in here,
369
00:21:49,216 --> 00:21:50,640
在把它求和之前
before we just add it in
370
00:21:50,912 --> 00:21:54,260
先将其乘以dt
we're going to multiply it by some number dt.
371
00:21:57,680 --> 00:22:00,000
剩下的就不用改了
And now what we have here, this is exactly the same thing.
372
00:22:00,000 --> 00:22:00,912
我们就得到了一个盒子
We have a box,
373
00:22:03,360 --> 00:22:04,560
一个积分器
which is an integrator.
374
00:22:09,790 --> 00:22:11,264
对一个流S进行积分
And it takes in a stream s,
375
00:22:11,904 --> 00:22:14,512
把这里的1替换为
and instead of 1 here,
376
00:22:14,944 --> 00:22:18,352
该积分的初始值
we can put the additional value for the integral.
377
00:22:19,980 --> 00:22:21,600
这个看起来就非常像
And that one looks very much like a
378
00:22:22,352 --> 00:22:24,860
信号处理中的方框图了
a signal processing block diagram program.
379
00:22:25,270 --> 00:22:28,112
事实上 这个图示对应的是这样一个过程
In fact, here's the procedure that looks exactly like that.
380
00:22:31,490 --> 00:22:33,616
对一个流进行积分
Find the integral of a stream.
381
00:22:34,010 --> 00:22:35,488
INTEGRAL函数接收一个流
So an integral's going to take a stream
382
00:22:35,680 --> 00:22:36,864
返回一个新的流
Sand produce a new stream,
383
00:22:37,530 --> 00:22:40,672
它还接收一个初始值和某个时间常量
and it takes in an initial value and some time constant.
384
00:22:42,230 --> 00:22:42,976
然后呢?
And what do we do?
385
00:22:43,040 --> 00:22:45,056
首先在内部定义一个流INT
Well, we internally define this thing int,
386
00:22:45,200 --> 00:22:46,320
之所以要给它一个内部名字
and we make this internal name
387
00:22:46,336 --> 00:22:48,860
原因在于可以使它反馈 以形成循环
so we can feed it back, loop it around itself.
388
00:22:49,400 --> 00:22:50,800
INT的定义是
And int is defined to be
389
00:22:51,104 --> 00:22:53,328
一个以INITIA-VALUE开始的流
something that starts out at the initial value,
390
00:22:54,976 --> 00:23:00,144
而其余的元素则是把它们加起来
and the rest of it is gotten by adding together.
391
00:23:01,280 --> 00:23:03,616
我们把输入流乘以dt
We take our input stream, scale it by dt,
392
00:23:03,872 --> 00:23:04,928
然后和INT相加
and add that to int.
393
00:23:06,880 --> 00:23:09,664
整个INTEGRAL函数的结果就是这个INT
And now we'll return from all that the value of integral is this thing int.
394
00:23:10,690 --> 00:23:12,944
我们使用这种内部定义的语法
And we use this internal definition syntax so we could
395
00:23:13,344 --> 00:23:15,664
是为了可以在内部引用它自己
write a little internal definition that refers to itself.
396
00:23:21,880 --> 00:23:23,710
我们还可以做更多的事情
Well, there are all sorts of things we can do.
397
00:23:23,710 --> 00:23:24,512
来看这个
Let's try this one.
398
00:23:25,632 --> 00:23:26,890
斐波那契数
how about the Fibonacci numbers.
399
00:23:26,895 --> 00:23:32,625
(DEFINE FIBS
You can say define fibs.
400
00:23:36,350 --> 00:23:37,632
斐波那契数是什么呢?
Well, what are the Fibonacci numbers?
401
00:23:37,980 --> 00:23:46,544
它从0开始
They're something that starts out with 0,
402
00:23:48,656 --> 00:23:50,090
下一个是1
and the next one is 1.
403
00:23:56,260 --> 00:23:59,168
的其余的斐波那契数是通过
And the rest of the Fibonacci numbers are gotten by
404
00:23:59,872 --> 00:24:11,000
把它们的尾部分求和而得来
adding the Fibonacci numbers to their own tail.
405
00:24:17,570 --> 00:24:19,280
这样来定义斐波那契数
There's a definition of the Fibonacci numbers.
406
00:24:20,580 --> 00:24:21,430
这是如何运作的呢?
How does that work?
407
00:24:21,430 --> 00:24:24,192
我们来试试
Well, we start off,
408
00:24:24,208 --> 00:24:26,490
假如开始计算斐波那契数
and someone says compute for us the Fibonacci numbers,
409
00:24:29,648 --> 00:24:31,920
首先告诉你 它以0和1开始
and we're going to tell you it starts out with 0 and 1.
410
00:24:35,790 --> 00:24:38,224
而0和1之后的数则是
And everything after the 0 and 1
411
00:24:39,184 --> 00:24:40,864
通过加和两个流而得
is gotten by summing two streams.
412
00:24:41,120 --> 00:24:42,592
一个流是FIBS本身
One is the fibs themselves,
413
00:24:44,064 --> 00:24:45,696
另一个是FIBS的尾部分
and the other one is the tail of the fibs.
414
00:24:49,120 --> 00:24:51,168
如果我知道这是以0和1起始的
So if I know that these start out with 0 and 1,
415
00:24:51,790 --> 00:24:55,424
我就能知道 FIBS是以0和1起始的
I know that the fibs now start out with 0 and 1,
416
00:24:55,744 --> 00:24:57,408
那么 FIBS的尾部分则应该以1开始
and the tail of the fibs start out with 1.
417
00:24:58,360 --> 00:24:59,456
一旦我知道了这点
So as soon as I know that,
418
00:24:59,664 --> 00:25:02,112
我就知道 FIBS的下一个数就是0+1=1
I know that the next one here is 0 plus 1 is 1,
419
00:25:02,960 --> 00:25:04,608
它也同样告诉我这里是1
and that tells me that the next one here is 1
420
00:25:04,624 --> 00:25:05,728
这里也是1
and the next one here is 1.
421
00:25:06,300 --> 00:25:07,280
知道了这些之后
And as soon as I know that,
422
00:25:07,296 --> 00:25:08,760
我就知道下一个是2
I know that the next one is 2.
423
00:25:09,390 --> 00:25:11,700
这里是2 这里也是2
So the next one here is 2 and the next one here is 2.
424
00:25:11,700 --> 00:25:12,560
下一个是3
And this is 3.
425
00:25:14,720 --> 00:25:15,792
这里是3
This one goes to 3,
426
00:25:16,192 --> 00:25:17,136
这里是5
and this is 5.
427
00:25:18,672 --> 00:25:19,968
这个定义完全说得通
So it's a perfectly sensible definition.
428
00:25:21,500 --> 00:25:22,784
这个定义只有一行
It's a one-line definition.
429
00:25:22,830 --> 00:25:25,008
当然 我也可以在计算机中
And again, I could walk over to the computer
430
00:25:25,008 --> 00:25:26,624
原原本本地键入计算机中
and type that in, exactly that,
431
00:25:27,040 --> 00:25:28,944
然后要求输出斐波那契数
and then say print stream the Fibonacci numbers,
432
00:25:28,944 --> 00:25:30,150
然后它就会不断输出
and they all come flying out.
433
00:25:32,790 --> 00:25:35,200
这又像是在学习递归
See, this is a lot like learning about recursion again.
434
00:25:36,810 --> 00:25:39,792
过程可以被递归定义
Instead of thinking that recursive procedures,
435
00:25:40,992 --> 00:25:43,504
我们也可以递归地定义数据对象
we have recursively defined data objects.
436
00:25:45,160 --> 00:25:46,928
但你们一点儿不应该感到吃惊
But that shouldn't surprise you at all,
437
00:25:47,120 --> 00:25:49,504
因为现在 你们应该真正相信
because by now, you should be coming to really believe
438
00:25:49,520 --> 00:25:53,056
过程与数据之间没有区别
that there's no difference really between procedures and data.
439
00:25:53,090 --> 00:25:53,920
事实上 就某种意义上来说
In fact, in some sense,
440
00:25:53,936 --> 00:25:56,416
流也是由过程来实现的
the underlying streams are procedures sitting there,
441
00:25:56,432 --> 00:25:57,790
只不过我们不把它看做过程而已
although we don't think of them that way.
442
00:25:58,210 --> 00:26:00,384
因此既然我们有递归过程
So the fact that we have recursive procedures,
443
00:26:00,704 --> 00:26:03,630
那么 有递归数据也就不足为奇了
well, then it should be natural that we have recursive data, too.
444
00:26:07,728 --> 00:26:09,696
虽然流非常简洁
OK, well, this is all pretty neat.
445
00:26:09,720 --> 00:26:13,920
但不幸的是 有些问题流无法解决
Unfortunately, there are problems that streams aren't going to solve.
446
00:26:14,990 --> 00:26:16,480
我来举个例子
Let me show you one of them.
447
00:26:17,580 --> 00:26:20,352
同样地 我们来想象一下
See, in the same way, let's imagine that we're
448
00:26:20,768 --> 00:26:23,616
我们正在构建求解微分方程的模拟计算机
building an analog computer to solve some differential equation
449
00:26:25,200 --> 00:26:34,304
比如求解方程 y' = y^2
like, say, we want to solve the equation y prime dy dt is y squared,
450
00:26:34,760 --> 00:26:36,160
我会给你一个初值
and I'm going to give you some initial value.
451
00:26:36,390 --> 00:26:38,030
y(0) = 1
I'll tell you y of 0 equals 1.
452
00:26:41,488 --> 00:26:44,064
dt = .0001
Let's say dt is equal to something.
453
00:26:46,770 --> 00:26:47,536
很久之前
Now, in the old days,
454
00:26:48,000 --> 00:26:50,650
就有人构建模拟计算机 来解决这类问题
people built analog computers to solve these kinds of things.
455
00:26:51,360 --> 00:26:53,020
原理非常简单
And the way you do that is really simple.
456
00:26:53,020 --> 00:26:54,416
你首先需要一个积分器
You get yourself an integrator,
457
00:27:00,048 --> 00:27:01,696
比如这个INT盒子
like that one, an integrator box.
458
00:27:03,050 --> 00:27:06,480
我们设定初始值 y(0) = 1
And we put in the initial value y of 0 is 1.
459
00:27:08,530 --> 00:27:10,928
现在如果我们送入一个输入 就会得到输出
And now if we feed something in and get something out,
460
00:27:10,960 --> 00:27:13,168
输出的结果就是y
we'll say, gee, what we're getting out is the answer.
461
00:27:14,256 --> 00:27:16,960
输入的是y的导数
And what we're going to feed in is the derivative,
462
00:27:17,520 --> 00:27:20,528
在这里 导数 y' = y^2
and the derivative is supposed to be the square of the answer.
463
00:27:21,490 --> 00:27:27,072
如果我们用MAP把SQUARE映射在这些值上
So if we take these values and map using square,
464
00:27:30,736 --> 00:27:32,096
然后把这个引过来
and if I feed this around,
465
00:27:36,280 --> 00:27:38,480
这个方块图
that's how I build a block diagram
466
00:27:38,576 --> 00:27:41,088
就是用于求解这个微分方程的模拟计算机
for an analog computer that solves this differential equation.
467
00:27:42,910 --> 00:27:44,800
现在我们用代码
Now, what we'd like to do is write a stream
468
00:27:44,800 --> 00:27:46,780
来表示下这个过程
program that looks exactly like that.
469
00:27:47,230 --> 00:27:48,720
这个图究竟表示的是什么呢?
And what do I mean exactly like that?
470
00:27:49,390 --> 00:27:58,304
(DEFINE Y
Well, I'd say define y to be the integral
471
00:28:04,288 --> 00:28:11,680
(INTEGRAL DY 1 .001))
of dy starting at 1 with 0.001 as a time step.
472
00:28:13,790 --> 00:28:15,456
接下来
And I'd like to say that says this.
473
00:28:16,805 --> 00:28:20,850
通过MAP SQUARE 来表示dy
And then I'd like to say, well, dy is gotten by mapping the square along y.
474
00:28:20,850 --> 00:28:32,816
(DEFINE DY (MAP SQUARE Y))
So define dy to be map square along y.
475
00:28:33,510 --> 00:28:36,800
这就是这个模拟计算机的流式描述
So there's a stream description of this analog computer,
476
00:28:38,624 --> 00:28:40,320
不幸的是 它并不起效
and unfortunately, it doesn't work.
477
00:28:41,410 --> 00:28:42,672
你也可以发现这是为什么
And you can see why it doesn't work
478
00:28:42,970 --> 00:28:44,992
因为我把Y定义为
because when I come in and say define y
479
00:28:46,432 --> 00:28:47,850
DY 的积分
to be the integral of dy
480
00:28:49,040 --> 00:28:50,656
它会问 对什么的积分?
it says, oh, the integral of what-- huh?
481
00:28:51,190 --> 00:28:52,128
没定义啊
Oh, that's undefined.
482
00:28:53,710 --> 00:28:57,632
所以这个定义必须写在这个定义的后面
So I can't write this definition before I've written this one.
483
00:28:58,770 --> 00:29:00,512
另一方面 如果先定义了dy
On the other hand, if I try and write this one first,
484
00:29:00,512 --> 00:29:03,024
定义为 (MAP SQUARE 某个东西)
it says, oh, I define y to be the map of square along what?
485
00:29:03,580 --> 00:29:04,640
这个也还没有定义
Oh, that's not defined yet.
486
00:29:05,770 --> 00:29:08,176
我既不能先写这个 又不能先写那个
So I can't write this one first, and I can't write that one first.
487
00:29:09,088 --> 00:29:11,580
这个游戏就没法玩了
So I can't quite play this game.
488
00:29:17,560 --> 00:29:18,512
怎样来解决呢?
Well, is there a way out?
489
00:29:20,608 --> 00:29:21,840
我们可以用ONES来解决
See, we can do that with ones.
490
00:29:22,200 --> 00:29:25,824
所以 我们在这里定义的ONES
See, over here, we did this thing ones,
491
00:29:27,248 --> 00:29:29,904
我们之所以可以使用ONES来定义ONES
and we were able to define ones in terms of ones because
492
00:29:30,400 --> 00:29:32,032
这是因为其中的延时求值
of this delay that was built inside
493
00:29:32,432 --> 00:29:34,128
CONS-STREAM是延时求值的
because cons-stream had a delay.
494
00:29:34,770 --> 00:29:35,792
那么 这又为什么说得通呢?
Now, why's it sensible?
495
00:29:35,920 --> 00:29:38,512
为什么CONS-STREAM是延时求值的是合理的呢?
Why's it sensible for cons-stream to be built with this delay?
496
00:29:40,730 --> 00:29:43,136
原因在于 CONS-STREAM不需要其尾部分
The reason is that cons-stream can do a useful thing
497
00:29:43,488 --> 00:29:44,880
就可以完成有意义的事
without looking at its tail.
498
00:29:45,950 --> 00:29:46,848
比如我说
See, if I say
499
00:29:47,488 --> 00:29:49,648
这个是1和某个东西组成的流
this is cons-stream of 1 onto something
500
00:29:49,920 --> 00:29:51,696
虽然我对它一无所知
without knowing anything about something,
501
00:29:52,160 --> 00:29:54,032
但我却知道整个流是以1开始的
I know that the stream starts off with 1.
502
00:29:54,870 --> 00:29:57,296
所以用CONS-STREAM来构造是有意义的
That's why it was sensible to build something like cons-stream.
503
00:29:59,960 --> 00:30:01,248
我们在这里放了一个DELAY
So we put a delay in there,
504
00:30:01,424 --> 00:30:04,656
这就使得我们能够进行某种自引用的定义
and that allows us to have this sort of self-referential definition.
505
00:30:06,320 --> 00:30:07,952
INTEGRAL也可以用这种方式来解决
Well, integral is a little bit the same way.
506
00:30:08,190 --> 00:30:12,528
注意 对于INTEGRAL来说 我可以
See, notice for an integral, I can--
507
00:30:14,608 --> 00:30:16,080
让我们回过头来再看看INTEGRAL的定义
let's go back and look at integral for a second.
508
00:30:17,580 --> 00:30:18,560
求积分的时候
See, notice integral,
509
00:30:21,392 --> 00:30:25,008
知道INTEGRAL的第一个元素是合理的
it makes sense to say what's the first thing in the integral
510
00:30:26,048 --> 00:30:27,872
尽管还不知道整个流是什么样的
without knowing the stream that you're integrating.
511
00:30:28,970 --> 00:30:30,176
这是因为INTEGRAL中第一个元素
Because the first thing in the integral
512
00:30:30,200 --> 00:30:32,160
总会是你传递过来的INITIAL-VALUE
is always going to be the initial value that you're handed.
513
00:30:33,140 --> 00:30:36,112
所以INTEGRAL可以用CONS-STREAM来实现
So integral could be a procedure like cons-stream.
514
00:30:37,090 --> 00:30:37,984
我们可以定义它
You could define it,
515
00:30:38,256 --> 00:30:40,880
甚至不用知道要积分的流是什么
and then even before it knows what it's supposed to be integrating,
516
00:30:42,848 --> 00:30:45,184
只需要知道初始值是什么就行了
it knows enough to say what its initial value is.
517
00:30:46,710 --> 00:30:48,176
INTEGRAL还可以修改得更为智能
So we can make a smarter integral,
518
00:30:48,416 --> 00:30:50,688
我们给它一个待积分的流
which is aha, you're going to give me a stream to integrate
519
00:30:50,832 --> 00:30:51,920
以及一个初值
and an initial value,
520
00:30:52,112 --> 00:30:54,992
直到你要求沿着这个流求解积分时
but I really don't have to look at that stream that I'm supposed to integrate
521
00:30:55,216 --> 00:30:56,976
我才关心这个流是什么
until you ask me to work down the stream.
522
00:30:58,430 --> 00:31:00,512
换句话说INTEGRAL可以像CONS-STREAM一样
In other words, integral can be like cons-stream,
523
00:31:00,570 --> 00:31:03,744
你可以认为INTEGRAL被放在DELAY之中
and you can expect that there's going to be a delay around its integrand.
524
00:31:03,760 --> 00:31:04,864
我们这样修改
And we can write that.
525
00:31:05,610 --> 00:31:07,024
这个过程是像这样的
Here's a procedure that does that.
526
00:31:07,650 --> 00:31:08,752
这是另一个版本的INTEGRAL
Another version of integral,
527
00:31:08,896 --> 00:31:10,544
这个跟之前的版本非常相似
and this is almost like the previous one,
528
00:31:11,104 --> 00:31:13,344
只不过作为参数的流
except the stream it's going to get in
529
00:31:13,776 --> 00:31:15,696
必须要是一个延时对象
is going to expect to be a delayed object.
530
00:31:17,110 --> 00:31:18,432
这个INTEGRAL又是如何运作的呢?
And how does this integral work?
531
00:31:18,850 --> 00:31:21,792
我们在内部定义的INT则是
Well, the little thing it's going to define inside of itself
532
00:31:22,144 --> 00:31:24,192
用CONS-STREAM构造一个流
says on the cons-stream,
533
00:31:24,736 --> 00:31:26,448
初值还是INITIAL-VALUE
the initial value is the initial value,
534
00:31:27,160 --> 00:31:29,680
但是在CONS-STREAM中
but only inside of that cons-stream,
535
00:31:29,744 --> 00:31:32,300
要注意 这里面有个隐藏的DELAY
and remember, there's going to be a hidden delay inside here.
536
00:31:34,950 --> 00:31:39,072
只有在这个CONS-STREAM的内部
Only inside of that cons-stream will I start looking at
537
00:31:39,824 --> 00:31:42,110
我才会查看延时对象的实际内容
what the actual delayed object is.
538
00:31:43,180 --> 00:31:45,792
所以 答案的第一个元素将会是初值
So my answer is the first thing's the initial value.
539
00:31:45,970 --> 00:31:47,904
如果有人想访问我的尾部分
If anybody now asks me for my tail,
540
00:31:48,400 --> 00:31:49,424
此时
at that point,
541
00:31:50,000 --> 00:31:51,728
我会FORCE该延迟对象
I'm going to force that delayed object--
542
00:31:52,624 --> 00:31:53,600
把结果记作S
and I'll call that s--
543
00:31:54,448 --> 00:31:55,600
然后再进行ADD-STREAMS
and I do the add streams.
544
00:31:56,368 --> 00:31:59,260
这个INTEGRAL就有点像CONS-STREAM
So this is an integral which is sort of like cons-stream.
545
00:31:59,260 --> 00:32:02,592
直到你确实需要知道第一个元素的时候
It's not going to actually try and see what you handed it
546
00:32:03,888 --> 00:32:07,136
它才会去查看DELAYED-S是什么
as the thing to integrate until you look past the first element.
547
00:32:10,120 --> 00:32:11,024
如果这样的话
And if we do that
548
00:32:11,520 --> 00:32:12,832
也就能求解 y' = y^2 了
and we can make this work,
549
00:32:13,360 --> 00:32:15,200
这里我们只需要
all we have to do here is
550
00:32:16,000 --> 00:32:25,312
把Y定义为对延时对象DY的积分
define y to the integral of delay of y, of delay of dy.
551
00:32:27,090 --> 00:32:28,224
所以Y的定义就变成了
So y is going to be
552
00:32:28,400 --> 00:32:34,368
(INTEGRAL (DELAY DY) 1 .001)
the integral of delay of dy starting at 1,
553
00:32:34,384 --> 00:32:35,130
这样一来就可以了
and now this will work.
554
00:32:35,280 --> 00:32:37,440
因为我输入Y的定义
Because I type in the definition of y,
555
00:32:38,000 --> 00:32:39,680
它是某个东西的积分
and that says, oh, I'm supposed to use the integral of
556
00:32:40,208 --> 00:32:42,688
但这是个延迟对象 我现在还不用关心
something I don't care about right now because it's a delay.
557
00:32:44,600 --> 00:32:46,320
这之后 再定义DY
And these things, now you define dy.
558
00:32:46,320 --> 00:32:47,376
现在Y就有定义了
Now, y is defined.
559
00:32:47,550 --> 00:32:48,896
所以我在定义DY时
So when I define dy,
560
00:32:49,136 --> 00:32:50,672
它可以知道Y的定义
it can see that definition for y.
561
00:32:51,700 --> 00:32:52,840
一切都正常了
Everything is now started up.
562
00:32:52,840 --> 00:32:54,336
两个流都有第一个元素
Both streams have their first element.
563
00:32:54,920 --> 00:32:56,256
当我不断取得下一个元素
And then when I start mapping down,
564
00:32:56,272 --> 00:32:57,312
沿着流做MAP运算时
looking at successive elements,
565
00:32:57,376 --> 00:32:58,880
Y和DY都被定义过了
both y and dy are defined.
566
00:33:00,590 --> 00:33:04,240
所以为了继续这个游戏 我们不能仅仅
So there's a little game you can play that goes a little bit beyond
567
00:33:04,670 --> 00:33:07,136
只使用隐藏在流中的DELAY
just using the delay that's hidden inside streams.
568
00:33:08,368 --> 00:33:08,976
有问题么?
Questions?
569
00:33:13,520 --> 00:33:14,272
休息一下吧
OK, let's take a break.
570
00:33:14,720 --> 00:33:26,864
[音乐]
[JESU, JOY OF MAN'S DESIRING]
571
00:33:27,370 --> 00:33:30,944
《计算机程序的构造和解释》
572
00:33:52,160 --> 00:33:55,264
讲师:哈罗德·艾伯森教授 及 格兰德·杰·萨斯曼教授
573
00:33:55,420 --> 00:33:59,264
《计算机程序的构造和解释》
574
00:34:00,384 --> 00:34:03,930
流 II
575
00:34:07,300 --> 00:34:10,048
上节课的最后
Well, just before the break, um..
576
00:34:10,890 --> 00:34:11,808
不知道你们注意到没有
I'm not sure if you noticed it,
577
00:34:11,824 --> 00:34:13,550
事情正变得糟糕起来
but something nasty started to happen.
578
00:34:14,832 --> 00:34:18,400
我们讲了很多关于 流
We've been going along with the streams
579
00:34:19,168 --> 00:34:22,688
以及分离程序中的时间和计算机中的时间
and divorcing time in the programs from time in the computers,
580
00:34:22,864 --> 00:34:26,288
这些分离都被隐藏在流中了
and all that divorcing got hidden inside the streams.
581
00:34:27,280 --> 00:34:29,504
上节课快结束时我们发现
And then at the very end, we saw that sometimes
582
00:34:29,710 --> 00:34:32,192
为了真正发挥这种方法的优势
in order to really take advantage of this method,
583
00:34:32,224 --> 00:34:34,380
我们需要另外的DELAY
you have to pull out other delays.
584
00:34:34,380 --> 00:34:35,856
不只需要隐藏在CONS-STREAM中的DELAY
You have to write some explicit delays
585
00:34:36,096 --> 00:34:37,950
还需要显式地使用DELAY
that are not hidden inside that cons-stream.
586
00:34:39,030 --> 00:34:41,888
我只是用微分方程举了一个很简单的例子
And I did a very simple example with differential equations,
587
00:34:42,350 --> 00:34:44,080
但是如果你有一个非常复杂的系统
but if you have some very complicated system
588
00:34:44,128 --> 00:34:45,408
里面充斥着各种各样的自循环
with all kinds of self-loops,
589
00:34:45,950 --> 00:34:47,840
那就很难再发现
it becomes very, very difficult to
590
00:34:47,904 --> 00:34:49,310
在什么地方需要额外的DELAY了
see where you need those delays.
591
00:34:49,920 --> 00:34:51,184
假如你一不小心漏了一个
And if you leave them out by mistake,
592
00:34:51,456 --> 00:34:54,368
就很难发现程序为什么不起效
it becomes very, very difficult to see why the thing maybe isn't working.
593
00:34:55,550 --> 00:34:57,152
这是一种混乱
So that's kind of mess,
594
00:34:57,792 --> 00:35:01,712
让我们能够使用DELAY
that by getting this power and allowing us to use delay,
595
00:35:02,080 --> 00:35:04,704
有时却会让程序设计变得非常复杂
we end up with some very complicated programming sometimes,
596
00:35:04,720 --> 00:35:06,800
因为它们不能完全隐藏在流中
because it can't all be hidden inside the streams.
597
00:35:08,512 --> 00:35:09,792
那么 有没有什么解决方案呢?
Well, is there a way out of that?
598
00:35:11,136 --> 00:35:12,672
所幸的是 有
Yeah, there is a way out of that.
599
00:35:13,480 --> 00:35:16,080
我们可以修改整个语言
We could change the language so that
600
00:35:16,144 --> 00:35:18,192
使得所有的过程都表现得像CONS-STREAM一样
all procedures acted like cons-stream,
601
00:35:19,104 --> 00:35:21,488
这样所有的过程都会
so that every procedure automatically
602
00:35:22,320 --> 00:35:25,450
自动、隐式地为它的参数加上DELAY
has an implicit delay around its arguments.
603
00:35:25,450 --> 00:35:26,432
这是什么意思呢?
And what would that mean?
604
00:35:27,520 --> 00:35:29,536
就是说 当你调用一个过程时
That would mean when you call a procedure,
605
00:35:30,160 --> 00:35:31,888
参数并不会立即求值
the arguments wouldn't get evaluated.
606
00:35:32,210 --> 00:35:34,704
只有在需要被求值的时候 它们才会被求值
Instead, they'd only be evaluated when you need them,
607
00:35:34,896 --> 00:35:36,720
它们也可能被传递给其它的过程
so they might be passed off to some other procedure,
608
00:35:36,768 --> 00:35:38,128
而这个过程也不会求值这些参数
which wouldn't evaluate them either.
609
00:35:39,260 --> 00:35:41,904
因此这些过程间传递的是PROMISE
So all these procedures would be passing promises around.
610
00:35:42,150 --> 00:35:44,464
直到最后
And then finally maybe when you finally got down
611
00:35:44,656 --> 00:35:47,344
你需要查看某个值的时候
to having to look at the value of something
612
00:35:47,360 --> 00:35:48,992
可能是因为一个基本运算所需要
that was handed to a primitive operator
613
00:35:49,376 --> 00:35:51,488
这是你才实际求值这些PROMISE
which you actually start calling in all those promises.
614
00:35:52,380 --> 00:35:53,168
像这样修改语言之后
If we did that,
615
00:35:53,360 --> 00:35:55,376
由于所有的东西都是统一被延时的
since everything would have a uniform delay,
616
00:35:57,168 --> 00:35:59,008
就不需要任何显式的DELAY了
then you wouldn't have to write any explicit delays,
617
00:35:59,040 --> 00:36:01,552
因为它自动地内建在语言之中了
because it would be automatically built into the way the language works.
618
00:36:03,248 --> 00:36:04,384
换句话来说
Or another way to say that,
619
00:36:05,100 --> 00:36:08,144
从技术上来说 我所描述的
technically what I'm describing is what's called
620
00:36:09,024 --> 00:36:10,768
如果修改后的语言被称作
if we did that, our language would be
621
00:36:12,192 --> 00:36:16,576
所谓的“正则序求值”语言
so-called normal-order evaluation language
622
00:36:20,208 --> 00:36:23,470
这个跟我们一直使用的语言不同
versus what we've actually been working with,
623
00:36:23,872 --> 00:36:33,792
我们所用的是“应用序求值”语言
which is called applicative order-- versus applicative-order evaluation.
624
00:36:34,560 --> 00:36:36,835
还记得应用序求值的代换模型吧
And remember the substitution model for applicative order.
625
00:36:36,830 --> 00:36:40,496
当你求值一个组合式的时候
It says when you go and evaluate a combination,
626
00:36:40,512 --> 00:36:42,112
你需要先计算出每一个元素的值
you find the values of all the pieces.
627
00:36:43,590 --> 00:36:45,408
先求值所有的参数
You evaluate the arguments and then you
628
00:36:45,720 --> 00:36:47,424
再把它们代换入过程的体
substitute them in the body of the procedure.
629
00:36:47,600 --> 00:36:49,552
正则序则不是这样
Normal order says no, don't do that.
630
00:36:49,890 --> 00:36:51,904
你所做的则是
What you do is effectively
631
00:36:52,768 --> 00:36:54,416
直接将参数代换入过程的体
substitute in the body of the procedure,
632
00:36:54,448 --> 00:36:56,192
而不先对参数求值
but instead of evaluating the arguments,
633
00:36:56,544 --> 00:36:58,080
只是代换入了一个计算参数的PROMISE
you just put a promise to compute them there.
634
00:36:58,816 --> 00:36:59,904
换句话说就是
Or another way to say that
635
00:36:59,920 --> 00:37:02,096
把作为参数的整个表达式
you take the expressions for the arguments, if you like,
636
00:37:02,288 --> 00:37:04,848
直接代入过程的体进行代换
and substitute them in the body of the procedure and go on,
637
00:37:05,168 --> 00:37:06,880
在此之间从不进行任何化简
and never really simplify anything
638
00:37:07,168 --> 00:37:08,768
直到遇到一个基本运算符
until you get down to a primitive operator.
639
00:37:09,472 --> 00:37:10,992
这就是所谓的正则序求值语言
So that would be a normal-order language.
640
00:37:12,176 --> 00:37:13,120
我们为什么不这样做呢?
Well, why don't we do that?
641
00:37:13,824 --> 00:37:14,608
这样做了之后
Because if we did,
642
00:37:15,008 --> 00:37:17,344
我们就获得了延时求值的所有优点
we'd get all the advantages of delayed evaluation
643
00:37:17,904 --> 00:37:18,800
而不会一片混乱
with none of the mess.
644
00:37:18,940 --> 00:37:20,192
事实上 如果我们这样做了之后
In fact, if we did that
645
00:37:20,432 --> 00:37:22,672
CONS也会是延时求值的
and cons was just a delayed procedure,
646
00:37:22,688 --> 00:37:24,570
就和CONS-STREAM一样
that would make cons the same as cons-stream.
647
00:37:24,710 --> 00:37:25,824
我们就不再需要流了
We wouldn't need streams at all
648
00:37:26,368 --> 00:37:28,544
因为表自动成为了流
because lists would automatically be streams.
649
00:37:29,552 --> 00:37:30,704
表和流有一样的行为
That's how lists would behave,
650
00:37:30,752 --> 00:37:32,350
所有的数据结构也会像那样
all data structures would behave that way.
651
00:37:32,350 --> 00:37:33,648
所有的都是
Everything would behave that way.
652
00:37:35,070 --> 00:37:37,632
直到需要答案的时候
Right, You'd never really do any computation
653
00:37:37,664 --> 00:37:39,424
才会去实际的求值
until you actually needed the answer.
654
00:37:40,800 --> 00:37:43,584
不必再担心 什么时候需要显式地标注DELAY
You wouldn't have to worry about all these explicit annoying delays.
655
00:37:44,790 --> 00:37:46,160
为什么不这样做呢?
Well, why don't we do that?
656
00:37:47,160 --> 00:37:48,816
首先 已经有人这样做过了
First of all, I should say people do do that.
657
00:37:49,230 --> 00:37:51,850
有一些十分优雅的语言
There's some very beautiful languages.
658
00:37:51,850 --> 00:37:55,216
其中最为人称道的是一门名为 Miranda 的语言
One of the very nicest is a language called Miranda,
659
00:37:55,776 --> 00:37:56,768
它是由
which is, um..
660
00:37:57,440 --> 00:37:59,808
肯特大学的 David Turner 开发的
developed by David Turner at the University of Kent.
661
00:38:00,710 --> 00:38:01,930
它就是用这样的原理实现的
And that's how this language works.
662
00:38:01,930 --> 00:38:03,344
Miranda是正则序求值语言
It's a normal-order language
663
00:38:04,272 --> 00:38:05,552
它的数据结构
and its data structures,
664
00:38:06,160 --> 00:38:08,416
看起来像表 实际上确实流
which look like lists, are actually streams.
665
00:38:08,960 --> 00:38:10,912
你不需要任何特殊的功能
And you write ordinary procedures in Miranda,
666
00:38:11,280 --> 00:38:13,280
就可以在Miranda中编写普通的过程
and they do these prime things and eight queens things,
667
00:38:13,328 --> 00:38:14,970
来解决质数、八皇后这样的问题
just without anything special.
668
00:38:14,970 --> 00:38:16,352
这些都是语言的内建功能
It's all built in there.
669
00:38:17,936 --> 00:38:18,912
但这样做也要付出代价
But there's a price.
670
00:38:21,190 --> 00:38:22,368
还记得我们为什么引入流了吗?
Remember how we got here.
671
00:38:23,170 --> 00:38:27,480
我们分离了程序的时间和它实际执行的时间
We're decoupling time in the programs from time in the machines.
672
00:38:27,968 --> 00:38:28,880
如果我们引入了DELAY
And if we put delay,
673
00:38:29,040 --> 00:38:30,336
这样就在所有的地方完成了解耦
that sort of decouples it everywhere,
674
00:38:30,400 --> 00:38:31,424
而不单单是在流中
not just in streams.
675
00:38:32,192 --> 00:38:33,140
我们的初衷是什么?
Remember what we're trying to do.
676
00:38:33,140 --> 00:38:38,112
我们把程序设计看做是指定计算过程
We're trying to think about programming as a way to specify processes.
677
00:38:39,300 --> 00:38:40,624
如果我们放弃了对时间的控制
And if we give up too much time,
678
00:38:40,656 --> 00:38:42,416
尽管语言变得优雅起来
our language becomes more elegant,
679
00:38:43,744 --> 00:38:45,872
但是它的表达力却有所下降
but it becomes a little bit less expressive.
680
00:38:47,030 --> 00:38:49,840
这里面还有一些我们无法消除的区别
There are certain distinctions that we can't draw.
681
00:38:51,480 --> 00:38:53,152
其中之一就是迭代
One of them, for instance, is iteration.
682
00:38:53,980 --> 00:38:56,448
还记得这个程序吗?
Remember this old procedure,
683
00:38:56,960 --> 00:38:58,288
迭代式的阶乘
iterative factorial,
684
00:38:58,448 --> 00:39:00,480
这是我们很早之前就研究过的
that we looked at quite a long time ago.
685
00:39:01,230 --> 00:39:02,976
过程FACT-ITER
Iterative factorial had a thing,
686
00:39:03,040 --> 00:39:04,912
有一个内部过程ITER
and it said there was an internal procedure,
687
00:39:05,184 --> 00:39:07,504
它含有两个状态PRODUCT和COUNTER
and there was a state which was a product and a counter,
688
00:39:08,704 --> 00:39:10,960
它们随着循环不断迭代
and we iterate that going around the loop.
689
00:39:12,120 --> 00:39:13,680
之所以说这个过程是迭代的
And we said that was an iterative procedure
690
00:39:13,712 --> 00:39:14,832
是因为它没有创建新状态
because it didn't build up state.
691
00:39:15,730 --> 00:39:17,456
之所以没有创建新状态
And the reason it didn't build up state is
692
00:39:17,472 --> 00:39:20,256
是因为在调用ITER时
because this iter that's called
693
00:39:20,304 --> 00:39:22,864
作为参数传递给它自己的始终是这些东西
is just passing these things around to itself.
694
00:39:23,900 --> 00:39:25,392
在代换模型中
Or in the substitution model that,
695
00:39:25,552 --> 00:39:27,792
Gerald教授给你们讲解过
you could see in the substitution model that Jerry did,
696
00:39:28,720 --> 00:39:30,016
在迭代过程中
that in an iterative procedure,
697
00:39:30,032 --> 00:39:31,440
状态并不需要增长
that state doesn't have to grow.
698
00:39:31,824 --> 00:39:34,224
因此这是一个迭代过程
And in fact, we said it doesn't, so this is an iteration.
699
00:39:34,992 --> 00:39:37,472
但是如果用正则序语言
But now think about this exact same text
700
00:39:37,472 --> 00:39:39,104
来运行这段程序
if we had a normal-order language.
701
00:39:41,150 --> 00:39:42,176
这就会导致
What would happen is
702
00:39:42,880 --> 00:39:44,960
这个过程不再是迭代式了
this would no longer be an iterative procedure
703
00:39:45,650 --> 00:39:48,672
如果你仔细地思考代换模型
And if you really think about the details of the substitution model,
704
00:39:48,672 --> 00:39:49,904
在这里我就不细说了
which I'm not going to do here,
705
00:39:51,200 --> 00:39:52,352
这个表达式会不断增长
this expression would grow.
706
00:39:52,368 --> 00:39:53,184
为什么会这样?
Why would it grow?
707
00:39:53,280 --> 00:39:55,200
因为当ITER调用自己时
It's because when iter calls itself,
708
00:39:55,856 --> 00:39:57,312
参数是这个乘法表达式
it calls itself with this product.
709
00:39:58,080 --> 00:39:59,360
而在正则序语言中
If it's a normal-order language,
710
00:39:59,392 --> 00:40:01,168
这个乘法并不会在这里求值
that multiplication is not going to get done.
711
00:40:02,510 --> 00:40:03,824
传递给自己并代换的
That's going to say I'm to call myself
712
00:40:03,936 --> 00:40:05,680
只是这个乘法计算的PROMISE
with a promise to compute this product.
713
00:40:06,670 --> 00:40:08,032
然后继续代换下去
And now iter goes around again.
714
00:40:09,760 --> 00:40:11,552
我调用自己
And I'm going to call myself
715
00:40:11,840 --> 00:40:14,048
用的是计算这个乘法的PROMISE
with a promise to compute this product
716
00:40:14,048 --> 00:40:17,820
但其中的一个因数也是个PROMISE
where now one of the one factors is a promise.
717
00:40:18,400 --> 00:40:19,430
然后我又自调用
And I call myself again.
718
00:40:19,430 --> 00:40:21,136
如果你用代换模型
And if you write out the substitution model
719
00:40:21,984 --> 00:40:23,600
来推演这个迭代步骤
for that iterative process,
720
00:40:23,776 --> 00:40:26,832
你会发现同样的状态增长
you'll see exactly the same growth in state,
721
00:40:27,160 --> 00:40:28,960
所有的PROMISE都需要被记住
all those promises that are getting remembered
722
00:40:28,976 --> 00:40:30,760
以便在最后被调用
that have to get called in at the very end.
723
00:40:31,790 --> 00:40:35,024
所以 正则序的缺点之一
So one of the disadvantages
724
00:40:35,056 --> 00:40:36,864
就是无法有效地表达迭代
is that you can't really express iteration.
725
00:40:36,980 --> 00:40:39,600
也许这个理由有点偏理论
Maybe that's a little theoretical reason why not,
726
00:40:39,616 --> 00:40:43,904
但事实上 那些使用这类语言来编写
but in fact, people who are trying to write real operating systems
727
00:40:44,272 --> 00:40:47,568
实际操作系统的人 也都遇到了这类问题
in these languages are running into exactly these types of problems.
728
00:40:48,208 --> 00:40:50,752
当然 完全可以
Like it's perfectly possible to
729
00:40:51,648 --> 00:40:54,384
用这类语言实现一个文本编辑器
implement a text editor in languages like these.
730
00:40:54,610 --> 00:40:56,080
但是你才用了一会儿
But after you work a while,
731
00:40:56,720 --> 00:40:59,392
就发现已经占用了3MB空间
you suddenly have 3 megabytes of stuff,
732
00:40:59,440 --> 00:41:02,048
我想 那些遇到这类问题的人
which is-- I guess they call them
733
00:41:02,160 --> 00:41:05,600
把它叫做 “拖尾问题”
the dragging tail problem who are looking at these,
734
00:41:05,824 --> 00:41:08,208
由于不能有效地表达迭代计算
of stuff of promises that sort of haven't been called in
735
00:41:08,240 --> 00:41:10,464
导致堆积了一堆没有被调用的PROMISE
because you couldn't quite express an iteration.
736
00:41:10,720 --> 00:41:14,816
针对这类语言的一个研究方向就是
And one of the research questions in these kinds of languages
737
00:41:14,832 --> 00:41:17,488
找出一种有效的编译器技术
are figuring out the right compiler technology
738
00:41:17,824 --> 00:41:19,856
来避免这种所谓的“拖尾问题”
to get rid of the so-called dragging tails.
739
00:41:20,176 --> 00:41:21,616
这并不简单
It's not simple.
740
00:41:23,940 --> 00:41:27,312
但是 还有一个很突出的问题
But there's another kind of more striking issue
741
00:41:27,968 --> 00:41:31,040
使你的语言不能变成正则序
about why you just don't go ahead and make your language normal order.
742
00:41:32,512 --> 00:41:33,296
问题就在于
And the reason is
743
00:41:35,056 --> 00:41:38,096
正则序和副作用
that normal-order evaluation and side effects
744
00:41:38,896 --> 00:41:40,192
是不相容的
just don't mix.
745
00:41:42,000 --> 00:41:43,968
它们不能很好地相互配合
They just don't go together very well.
746
00:41:45,440 --> 00:41:46,656
这是因为 你不能
Somehow, you can't-
747
00:41:48,288 --> 00:41:50,800
你不能一边
it's sort of you can't simultaneously
748
00:41:51,008 --> 00:41:54,336
建模具有局部状态的对象
go around trying to model objects with local state and change
749
00:41:55,728 --> 00:41:56,960
同时又
at the same time
750
00:41:57,184 --> 00:41:59,552
使用正则序的技巧来解耦时间
do these normal-order tricks of de-coupling time.
751
00:42:00,400 --> 00:42:03,552
我来举一个非常简单的例子
Let me just show you a really simple example, very, very simple.
752
00:42:03,790 --> 00:42:05,504
假设语言是正则序求值
Suppose we had a normal-order language.
753
00:42:07,520 --> 00:42:09,550
例子是这样的
And I'm going to start out in this language.
754
00:42:09,550 --> 00:42:10,520
注意现在是正则序求值
This is now normal order.
755
00:42:10,520 --> 00:42:12,224
(DEFINE X 0)
I'm going to define x to be 0.
756
00:42:13,570 --> 00:42:15,568
这只是变量的初始化
It's just some variable I'll initialize.
757
00:42:15,750 --> 00:42:17,696
现在我要定义一个有趣的函数
And now I'm going to define this little funny function,
758
00:42:18,576 --> 00:42:20,448
它就是恒等函数ID
which is an identity function.
759
00:42:22,640 --> 00:42:23,904
它所做的就是
And what it does,
760
00:42:24,112 --> 00:42:26,608
用X来记录上一次调用它时N的值
it keeps track of the last time you called it using x.
761
00:42:31,400 --> 00:42:34,160
因此(ID N)就返回N
Right? So the identity of n just returns n,
762
00:42:34,176 --> 00:42:35,390
但还要把X赋值为N
but it sets x to be n.
763
00:42:36,760 --> 00:42:38,544
最后再定义一个过程INC
And now I'll define a little increment function,
764
00:42:39,552 --> 00:42:42,304
也非常简单
which is a very little, simple scenario.
765
00:42:42,580 --> 00:42:45,344
假设在正则序求值的语言里
Now, imagine I'm interacting with this in the normal-order language,
766
00:42:46,272 --> 00:42:47,230
求值下面的表达式
and I type the following.
767
00:42:47,230 --> 00:42:52,832
我输入 (DEFINE Y (INC (ID 3)))
I say define y to be increment the identity function of 3,
768
00:42:52,832 --> 00:42:53,968
因此Y的值应该是4
so y is going to be 4.
769
00:42:57,410 --> 00:42:58,352
X应该是多少呢?
Now, I say what's x?
770
00:42:59,520 --> 00:43:02,160
X应该是最后一次被记住的值
Well, x should have been the value that was remembered last
771
00:43:02,640 --> 00:43:04,016
也就是我调用函数ID的时候
when I called the identity function.
772
00:43:04,710 --> 00:43:06,736
你可能会想 这里X应该是3
So you'd expect to say, well, x is 3 at this point,
773
00:43:06,912 --> 00:43:07,520
但是并不是这样
but it's not.
774
00:43:08,530 --> 00:43:11,152
这是因为当我在这里定义Y的时候
Because when I defined here, y here,
775
00:43:11,792 --> 00:43:13,456
Y的真正定义却是
what I really defined y to be
776
00:43:13,472 --> 00:43:15,712
一个调用函数ID的PROMISE的增量
increment of a promise to do this thing.
777
00:43:17,000 --> 00:43:18,176
因为我没有访问Y
So I didn't look at y,
778
00:43:18,368 --> 00:43:20,256
所以ID没有运行
so that identity function didn't get run.
779
00:43:21,560 --> 00:43:23,200
我输入这个定义之后
So if I type in this definition
780
00:43:23,312 --> 00:43:24,800
然后查询X得到的结果是0
and look at x, I'm going to get 0.
781
00:43:28,360 --> 00:43:31,200
现在 我输入Y查询它的值
Now, if I go look at y and say what's y,
782
00:43:31,520 --> 00:43:32,432
就会得到结果4
say y is 4,
783
00:43:32,670 --> 00:43:35,168
对Y的主动查询
looking at y, that very active looking at y
784
00:43:35,296 --> 00:43:37,424
会导致ID运行
caused the identity function to be run.
785
00:43:38,720 --> 00:43:40,480
现在X=3就被记住
And now x will get remembered as 3.
786
00:43:40,740 --> 00:43:41,872
所以上面这里的X就应该是0
So here x will be 0.
787
00:43:41,936 --> 00:43:42,960
下面这里是3
Here, x will be 3.
788
00:43:43,280 --> 00:43:46,160
这是一个非常简单的场景
That's a tiny, little, simple scenario,
789
00:43:46,304 --> 00:43:49,280
但你会发现 调试正则序语言
but you can see what kind of a mess that's going to make
790
00:43:50,368 --> 00:43:53,344
的交互式程序
for debugging interactive programs
791
00:43:54,128 --> 00:43:55,888
会变得相当混乱
when you have normal-order evaluation.
792
00:43:57,100 --> 00:43:58,128
很令人迷惑
It's very confusing.
793
00:43:59,690 --> 00:44:02,048
导致这样的深层次的原因
But it's very confusing for a very deep reason,
794
00:44:02,800 --> 00:44:06,416
也就是引入DELAY的根本理念
which is that the whole idea of putting in delays
795
00:44:06,928 --> 00:44:08,432
是因为我们抛弃了时间的概念
is that you throw away time.
796
00:44:09,780 --> 00:44:11,750
也因为如此我们可以处理一些无穷的情况
That's why we can have these infinite processes.
797
00:44:11,750 --> 00:44:12,976
我们抛弃了时间
Since we've thrown away time,
798
00:44:12,992 --> 00:44:14,270
就没有必要等它们运行
we don't have to wait for them to run,
799
00:44:17,550 --> 00:44:20,448
我们把计算机中事件发生的顺序
Right? We decouple the order of events in the computer
800
00:44:20,832 --> 00:44:22,112
与程序中的顺序 分离开来
from what we write in our programs.
801
00:44:22,352 --> 00:44:25,280
但是当我们谈及状态、赋值和改变的时候
But when we talk about state and set and change,
802
00:44:25,488 --> 00:44:27,424
这些又都是我们想要控制的
that's exactly what we do want control of.
803
00:44:28,760 --> 00:44:33,824
我们的目的有着根本性的矛盾
So it's almost as if there's this fundamental contradiction in what you want.
804
00:44:34,570 --> 00:44:39,120
这又让我们进入了一个哲学问题
And that brings us back to these sort of philosophical mutterings
805
00:44:39,136 --> 00:44:40,752
用什么样的模型
what is it that you're trying to model
806
00:44:40,784 --> 00:44:41,776
和从什么角度来看这个世界
and how do you look at the world.
807
00:44:42,410 --> 00:44:44,304
有时这也被称为
Or sometimes this is called the
808
00:44:44,768 --> 00:44:46,608
“函数式程序设计的争论”
the debate over functional programming.
809
00:44:54,192 --> 00:44:56,608
所谓的“纯函数式语言”
A so-called purely functional language
810
00:44:57,072 --> 00:44:59,200
是完全没有副作用的
is one that just doesn't have any side effects.
811
00:45:00,440 --> 00:45:01,632
不需要副作用
Since you have no side effects,
812
00:45:01,648 --> 00:45:03,020
也就不需要赋值运算符
there's no assignment operator,
813
00:45:03,344 --> 00:45:05,728
也就没有什么糟糕的后果
so there are no terrible consequences of it.
814
00:45:06,360 --> 00:45:07,930
可以使用类似代换模型
You can use a substitution-like thing.
815
00:45:07,930 --> 00:45:10,480
程序更像是数学
Programs really are like mathematics and not like
816
00:45:10,768 --> 00:45:13,824
而不像现实世界中的模型和对象
not like models in the real world, not like objects in the real world.
817
00:45:15,050 --> 00:45:17,170
函数式语言有很多了不起的特性
There are a lot of wonderful things about functional languages.
818
00:45:17,170 --> 00:45:19,632
没有时间的概念 所以完全不用担心同步的问题
Since there's no time, you never have any synchronization problems.
819
00:45:20,640 --> 00:45:23,728
如果你想在并行算法中应用一些东西
And if you want to put something into a parallel algorithm,
820
00:45:24,720 --> 00:45:28,208
你可以在这些并行过程中随心所欲地使用
you can run the pieces of that parallel processing any way you want.
821
00:45:29,408 --> 00:45:31,440
从来不担心同步问题
There's just never any synchronization to worry that,
822
00:45:31,504 --> 00:45:33,344
在这种环境下这样做是非常方便的
and it's a very congenial environment for doing this.
823
00:45:33,640 --> 00:45:35,712
代价则是 放弃了赋值
The price is you give up assignment.
824
00:45:39,104 --> 00:45:41,328
函数式语言的支持者会认为
So an advocate of a functional language would say,
825
00:45:41,344 --> 00:45:43,040
这点代价算不了什么
gee, that's just a tiny price to pay.
826
00:45:44,520 --> 00:45:46,510
在大部分情况下 你都不应该使用赋值
You probably shouldn't use assignment most of the time anyway.
827
00:45:46,880 --> 00:45:48,272
如果用你放弃了赋值
And if you just give up assignment,
828
00:45:48,432 --> 00:45:51,408
你可以得到一个比对象世界
you can be in this much, much nicer world
829
00:45:51,968 --> 00:45:53,248
好得多的世界
than this place with objects.
830
00:45:54,190 --> 00:45:56,300
怎么来反驳这个观点呢?
Well, what's the rejoinder to that?
831
00:45:56,300 --> 00:45:58,592
想想 我们如何走到这一步的
Remember how we got into this mess.
832
00:46:00,064 --> 00:46:03,792
我们尝试建模具有局部状态的对象
We started trying to model things that had local state.
833
00:46:04,440 --> 00:46:06,496
想一想Gerald教授给你们讲的随机数生成器
So remember Gerry's random number generator.
834
00:46:07,168 --> 00:46:08,672
这里有一个随机数生成器
There was this random number generator
835
00:46:09,280 --> 00:46:10,624
它内部有一些状态
that had some little state in it
836
00:46:10,830 --> 00:46:12,080
用来计算下一个随机数
to compute the next random number
837
00:46:12,128 --> 00:46:14,080
下下一个 以及再下一个
and the next random number and the next random number.
838
00:46:14,288 --> 00:46:16,144
我们想要把这些状态跟
And we wanted to hide that state away from the
839
00:46:16,432 --> 00:46:18,960
计算π的Cesaro算法分离开来
the Cesaro compute pi process,
840
00:46:19,840 --> 00:46:20,928
这就是我们为什么需要赋值
and that's why we needed set!
841
00:46:20,976 --> 00:46:22,912
我们想要把状态封装在模块中
We wanted to package that stated modularly.
842
00:46:24,070 --> 00:46:26,368
函数式语言程序员可能会说
Well, a functional programming person would say,
843
00:46:26,384 --> 00:46:27,560
“你搞错了”
well, you're just all wet.
844
00:46:27,560 --> 00:46:29,840
“我的意思是 你能写出另一种更具模块化的程序”
I mean, you can write a perfectly good modular program.
845
00:46:29,840 --> 00:46:32,464
“你对模块化的认识并不正确”
It's just you're thinking about modularity wrong.
846
00:46:33,080 --> 00:46:35,024
你太执着于 “生成一个随机数
You're hung up in this next random number
847
00:46:35,072 --> 00:46:36,880
再生成一个 再生成一个” 这种范式了
and the next random number and the next random number.
848
00:46:36,880 --> 00:46:39,424
为什么不写一个这样的程序
Why don't you just say let's write a program.
849
00:46:40,090 --> 00:46:41,296
构造一个枚举器
Let's write an enumerator
850
00:46:41,952 --> 00:46:44,480
它会生成一个随机数的无穷流
which just generates an infinite stream of random numbers.
851
00:46:49,010 --> 00:46:50,912
我们可以立即生成这个流
We can sort of have that stream all at once,
852
00:46:52,640 --> 00:46:54,540
这样就可以用作随机数的源泉
and that's going to be our source of random numbers.
853
00:46:54,540 --> 00:46:55,248
如果有需要的话
And then if you like,
854
00:46:55,536 --> 00:46:57,472
你可以把它跟某个处理过程相连
you can put that through some sort of processor,
855
00:46:57,776 --> 00:47:01,168
比如说Cesaro测试
which is-- I don't know-- a Cesaro test,
856
00:47:04,944 --> 00:47:06,224
然后这个处理过程进行自己的计算
and that can do what it wants.
857
00:47:06,880 --> 00:47:08,560
从这里出来的则是
And what would come out of there
858
00:47:08,720 --> 00:47:27,456
其中是一串的对π的估计值组成的流
would be a stream of successive approximations to pi.
859
00:47:28,140 --> 00:47:30,656
随着我们深入访问这个流
So as we looked further down this stream,
860
00:47:30,768 --> 00:47:32,384
相当于去拽这个Cesaro盒子
we'd tug on this Cesaro thing,
861
00:47:33,120 --> 00:47:35,360
它就会拉取出许多随机数
and it would pull out more and more random numbers.
862
00:47:35,540 --> 00:47:37,216
随着我们对流的深入访问
And the further and further we look down the stream,
863
00:47:37,232 --> 00:47:38,960
得到的对π的估计值就越准
the better an approximation we'd get to pi.
864
00:47:39,720 --> 00:47:41,664
具体的计算过程还是一样的
And it would do exactly the same as the other computation,
865
00:47:41,664 --> 00:47:43,792
只不过使用了另一种模块化的方式
except we're thinking about the modularity different.
866
00:47:43,890 --> 00:47:45,552
我们可以想象成一下子
We're saying imagine we had all that
867
00:47:45,560 --> 00:47:47,472
就有了这所有的随机数
infinite streams of random numbers all at once.
868
00:47:49,280 --> 00:47:52,240
这个过程的细节在书上有
You can see the details of this procedure in the book.
869
00:47:53,610 --> 00:47:57,856
我们同样也陷于另外一些类似的事情中
But similarly, there are other things that we tend to get locked into
870
00:47:58,272 --> 00:48:01,200
这种关于 这个、下一个以及再下一个的范式
on this one and that one and the next one and the next one,
871
00:48:01,376 --> 00:48:02,816
完全可以不这么来做
which don't have to be that way.
872
00:48:03,280 --> 00:48:06,544
我们来思考一下银行系统
Like you might think about like a banking system,
873
00:48:07,680 --> 00:48:08,900
有个非常简单的场景
which is a very simple idea.
874
00:48:08,900 --> 00:48:12,210
我们假设这个程序代表了银行帐户
Imagine we have a program that sort of represents a bank account.
875
00:48:18,810 --> 00:48:20,848
银行账户中可能有
The bank account might have in it--
876
00:48:22,784 --> 00:48:26,224
如果我们以消息传递的角度来看
if we looked at this in a sort of message-passing view of the world,
877
00:48:26,448 --> 00:48:28,128
我们认为银行账户是一个对象
we'd say a bank account is an object
878
00:48:28,592 --> 00:48:31,510
内部保存着标识余额的局部状态BALANCE
that has some local state in there, which is the balance, say.
879
00:48:34,110 --> 00:48:36,000
如果一个用户使用这个系统
And a user using this system comes
880
00:48:36,448 --> 00:48:38,144
发出交易请求
and sends a transaction request.
881
00:48:39,312 --> 00:48:41,056
用户发出的交易请求可能是
So the user sends a transaction request,
882
00:48:41,072 --> 00:48:42,208
存一些钱
like deposit some money,
883
00:48:42,288 --> 00:48:43,536
银行账户就会
and the bank account maybe--
884
00:48:43,920 --> 00:48:46,784
我们假设银行账户总是以当前余额作为回应
let's say the bank account always responds with what the current balance is.
885
00:48:48,220 --> 00:48:50,048
用户存了一些钱
The user says let's deposits some money,
886
00:48:50,064 --> 00:48:53,210
银行账户就会返回一个消息指明当前余额
and the bank account sends back a message which is the balance.
887
00:48:54,350 --> 00:48:57,424
用户再存一些钱
And the user says deposit some more,
888
00:48:57,456 --> 00:48:58,816
银行就再返回消息
and the bank account sends back a message.
889
00:48:59,150 --> 00:49:00,752
就像生成随机数一样
And just like the random number generating
890
00:49:00,784 --> 00:49:02,128
我们想使用赋值来实现
you'd say, gee, we would like to use set.
891
00:49:03,200 --> 00:49:06,880
帐户的内部保存了局部状态BALANCE
We'd like to have balance be a piece of local state inside this bank account
892
00:49:06,880 --> 00:49:08,400
因为我们想要把用户状态
because we want to separate the state of the user
893
00:49:08,416 --> 00:49:09,570
和银行账户的状态分离开来
from the state of the bank account.
894
00:49:13,280 --> 00:49:16,420
这是从消息传递的角度来看
Well, that's the message-processing view.
895
00:49:16,420 --> 00:49:18,208
如果从流的角度来看
There's a stream view with that thing,
896
00:49:19,488 --> 00:49:22,192
不需要赋值或副作用就可以达到同样的效果
which does the same thing without any set or side effects.
897
00:49:22,740 --> 00:49:26,736
再次强调 想法是这样的
And the idea is again
898
00:49:27,376 --> 00:49:30,256
我们认为它们都没有局部状态
we don't think about anything having local state.
899
00:49:31,180 --> 00:49:33,088
我们把银行账户看作是
We think about the bank account as something
900
00:49:33,408 --> 00:49:37,712
能够处理一系列交易请求的东西
that's going to process a stream of transaction requests.
901
00:49:38,640 --> 00:49:40,160
不把银行账户看做
So think about this bank account not
902
00:49:40,224 --> 00:49:42,000
逐个消息地处理
as something that goes message by message,
903
00:49:42,448 --> 00:49:45,856
而是处理某种交易请求流的东西
but something that takes in a stream of transaction requests
904
00:49:45,872 --> 00:49:48,496
这个请求流可能是一些列的存款声明
like maybe successive deposit announced.
905
00:49:49,490 --> 00:49:54,944
比如 1 2 2 4 这样的连续存钱请求
1, 2, 2, 4, those might be successive amounts to deposit.
906
00:49:55,940 --> 00:50:02,448
从帐户出来的流应该是 1 3 5 9
And then coming out of it is the successive balances 1, 3, 5, 9.
907
00:50:03,770 --> 00:50:06,144
我们不把银行账户看做某种具有状态的东西
So we think of the bank account not as something that has state,
908
00:50:06,400 --> 00:50:07,264
而是某种能够处理
but something that acts
909
00:50:08,928 --> 00:50:10,820
有关请求的无穷流的东西
sort of on the infinite stream of requests.
910
00:50:10,820 --> 00:50:12,304
但要注意 我们抛弃了时间
But remember, we've thrown away time.
911
00:50:12,370 --> 00:50:14,272
如果这里有一个用户
So what we can do is if the user's here,
912
00:50:16,120 --> 00:50:19,136
这个无穷请求流的元素
we can have this infinite stream of requests
913
00:50:19,184 --> 00:50:22,540
我们可以一次生成一个
being generated one at a time coming from the user
914
00:50:24,064 --> 00:50:26,576
而这个交易流
and this transaction stream
915
00:50:26,570 --> 00:50:28,800
则会逐个打印在屏幕上
coming back on a printer being printed one at a time.
916
00:50:30,010 --> 00:50:31,376
如果在这里画一条线
And if we drew a little line here,
917
00:50:32,560 --> 00:50:33,088
就在这里
right there to the user,
918
00:50:33,280 --> 00:50:34,912
对用户来说 他根本无法分辨
the user couldn't tell that this system doesn't have state.
919
00:50:36,192 --> 00:50:37,712
这个系统是否有内部状态
that this system doesn't have state.
920
00:50:39,560 --> 00:50:41,136
这个跟消息传递那种是一样的
It looks just like the other one,
921
00:50:41,296 --> 00:50:42,464
只不过这个没有状态
but there's no state in there.
922
00:50:42,848 --> 00:50:45,872
哦 顺便提一下
And by the way,
923
00:50:46,720 --> 00:50:49,472
这是具体的代码实现
just to show you, here's an actual implementation
924
00:50:50,528 --> 00:50:52,304
我们把它叫做MAKE-DEPOSIT-ACCOUNT
of this-- we'll call it make deposit account
925
00:50:52,320 --> 00:50:53,328
因为它只能够存钱
because you can only deposit.
926
00:50:54,176 --> 00:50:55,776
这个过程接受一个初始余额
It takes an initial balance
927
00:50:56,096 --> 00:50:58,096
以及一个可能发起的存款流
and then a stream of deposits you might make.
928
00:51:00,020 --> 00:51:00,820
具体怎么做呢?
And what is it?
929
00:51:00,820 --> 00:51:02,544
它只是用CONS-STREAM把余额BALANCE
Well, it's just cons-stream of the balance
930
00:51:03,232 --> 00:51:05,312
和一个新的存款账户流组合在一起
onto make a new account stream
931
00:51:06,240 --> 00:51:07,328
新存款流的初始余额
whose initial balance
932
00:51:07,488 --> 00:51:10,272
就是之前BALANCE的值加上存款流的第一个元素
is the old balance plus the first thing in the deposit stream
933
00:51:10,864 --> 00:51:13,408
而其余部分则是
whose rest, right and,
934
00:51:13,760 --> 00:51:17,376
存款流的尾部分
make deposit account works on the rest of which is the tail of the deposit stream.
935
00:51:18,300 --> 00:51:23,840
因此这种非常典型的消息传递式、面向对象的问题
So there's sort of a very typical message-passing,
936
00:51:23,952 --> 00:51:27,552
完全可以不用副作用来解决
message-passing, object-oriented thing that's done without side effects at all.
937
00:51:29,056 --> 00:51:30,768
很多地方都可以这样做
There are very many things you can do this way.
938
00:51:32,250 --> 00:51:35,232
那么 我们可以完全不用赋值么?
Well, can you do everything without assignment?
939
00:51:36,400 --> 00:51:39,008
可以只用纯函数式语言吗?
Can everybody go over to purely functional languages?
940
00:51:40,050 --> 00:51:42,048
这个问题谁也说不清
Well, we don't know,
941
00:51:42,272 --> 00:51:43,440
好像有些地方
but there seem to be places
942
00:51:43,920 --> 00:51:46,032
纯函数式语言无法派上用场
where purely functional programming breaks down.
943
00:51:48,100 --> 00:51:50,272
当遇到像这样的系统时 问题就变得棘手起来
Where it starts hurting is when you have things like this,
944
00:51:50,432 --> 00:51:52,320
特别是当你
but you also mix it up with
945
00:51:52,608 --> 00:51:54,272
还需要考虑其它因素的时候
the other things that we had to worry that,
946
00:51:54,304 --> 00:51:55,648
有关对象和共享
which are objects and sharing
947
00:51:55,904 --> 00:51:58,528
以及两个独立的主体共享同一个东西
and two independent agents being the same.
948
00:51:58,850 --> 00:51:59,936
举一个典型的例子
So under a typical one,
949
00:51:59,968 --> 00:52:01,632
假如你来扩展这个帐户
suppose you want to extend this bank account.
950
00:52:03,248 --> 00:52:04,272
这是一个帐户
So here's a bank account.
951
00:52:12,220 --> 00:52:14,752
帐户接受一个交易请求流
Bank accounts take in a stream of transaction requests
952
00:52:15,200 --> 00:52:18,448
输出的流则是关于余额的回复
and put out streams of, say, balances or responses to that.
953
00:52:18,780 --> 00:52:20,160
假设你所建模的是联合账户
But suppose you want to model the fact
954
00:52:20,176 --> 00:52:24,368
而由两个独立用户共享
that this is a joint bank account between two independent people.
955
00:52:25,680 --> 00:52:28,656
我们假设 假设有两个人
Right? I don't know. So suppose there are two people,
956
00:52:28,976 --> 00:52:30,960
比如说Bill和Dave
say, Bill and Dave,
957
00:52:31,776 --> 00:52:33,140
他们俩共享一个帐户
who have a joint bank account.
958
00:52:35,960 --> 00:52:36,850
怎么来建模呢?
How would you model this?
959
00:52:36,880 --> 00:52:39,800
你或许会让Bill输出一个交易请求流
Well, you might, Bill puts out a stream of transaction requests,
960
00:52:40,240 --> 00:52:42,256
Dave也产生一个这样的流
and Dave puts out a stream of transaction requests,
961
00:52:42,256 --> 00:52:45,168
这两个流需要以某种方式合并到银行账户中
and somehow, they have to merge into this bank account.
962
00:52:45,880 --> 00:52:47,856
因此你需要编写一个MERGE过程
So what you might do is write a little stream
963
00:52:47,904 --> 00:52:50,650
来处理这些流
processing thing called merge,
964
00:52:57,232 --> 00:52:59,136
它把这些流合并在一起
which sort of takes these, merges them together,
965
00:52:59,344 --> 00:53:01,190
形成单个流 送入银行账户
produces a single stream for the bank account.
966
00:53:01,190 --> 00:53:02,992
现在他们就共享一个帐户了
Now they're both talking to the same bank account.
967
00:53:03,610 --> 00:53:05,488
看起来不错 问题是怎么来实现MERGE
That's all great, but how do you write merge?
968
00:53:05,936 --> 00:53:08,240
MERGE怎么来合并?
What, What's this procedure merge?
969
00:53:09,730 --> 00:53:11,424
需要合理的合并依据
You want to do something that's reasonable.
970
00:53:12,380 --> 00:53:13,808
你可能首先会想
Your first guess might be to say,
971
00:53:13,808 --> 00:53:16,688
我们从Bill和Dave中选一个请求来处理
well, we'll take alternate requests from Bill and Dave.
972
00:53:18,190 --> 00:53:20,976
但是如果在这中途
But what happens if But what happens if suddenly in the middle thing
973
00:53:21,184 --> 00:53:23,088
Dave突然外出度假两年 会怎么样?
Dave goes away on vacation for two years?
974
00:53:24,150 --> 00:53:25,408
Bill的交易就完全被阻塞了
Then Bill's sort of stuck.
975
00:53:27,690 --> 00:53:29,750
你想要的是
So what you want to do is-- well, it's hard to describe.
976
00:53:29,750 --> 00:53:33,648
是一种公平的合并
What you want to do is what people call fair merge.
977
00:53:38,410 --> 00:53:40,176
这个所谓公平的合并
The idea of fair merge is
978
00:53:40,736 --> 00:53:42,464
应该是交替地一次处理一个
is it sort of should do them alternately,
979
00:53:42,496 --> 00:53:43,920
但是如果一个人没有了交易
but if there's nothing waiting here,
980
00:53:43,968 --> 00:53:44,912
应该继续去处理另一个人的交易
it should take one twice.
981
00:53:46,010 --> 00:53:48,450
但是没有时间 我就不能这样做
Notice I can't even say that without talking about time.
982
00:53:51,300 --> 00:53:56,416
函数式语言的另一个活跃研究领域就是
So one of the other active researcher areas in functional languages
983
00:53:56,432 --> 00:53:59,488
发明类似于“公平合并”的算法
is inventing little things like fair merge
984
00:54:00,350 --> 00:54:01,312
又或者是其它的东西
maybe some others,
985
00:54:01,568 --> 00:54:06,256
用于取代原来需要副作用和对象的地方
which will take the places where I used to need side effects and objects
986
00:54:06,800 --> 00:54:10,528
用一种良好定义的模块化系统来隐藏它们
and sort of hide them away in some very well-defined modules of the system
987
00:54:10,860 --> 00:54:13,504
这样 系统中就不会到处产生
so that all the problems of assignment
988
00:54:13,520 --> 00:54:15,344
赋值所带来的问题
don't sort of leak out all over the system but
989
00:54:15,408 --> 00:54:17,880
因为它可以被理解透彻的概念所描述
are captured in some fairly well-understood things.
990
00:54:20,780 --> 00:54:22,704
推而广之 我想你们也发现了
More generally, I think what you're seeing
991
00:54:23,120 --> 00:54:24,064
我们正面对 我所认为的
is that we're running across
992
00:54:24,080 --> 00:54:26,670
计算机科学中最基本的问题
what I think is a very basic problem in computer science,
993
00:54:26,976 --> 00:54:27,824
也就是
which is how to
994
00:54:28,240 --> 00:54:32,032
我们如何定义一门支持延迟求值的语言
how to define languages that somehow can talk about delayed evaluation
995
00:54:34,144 --> 00:54:35,088
但同时又能够
But also
996
00:54:35,872 --> 00:54:38,256
又能够把事物看做对象来操作
be able to reflect this view that there are objects in the world.
997
00:54:38,360 --> 00:54:40,368
怎么样才能两者兼有之?
How do we somehow get both?
998
00:54:41,230 --> 00:54:43,040
我认为这个问题很困难
And I think that's a very hard problem.
999
00:54:43,040 --> 00:54:45,520
但是这个很困难的问题
And it may be that it's a very hard problem
1000
00:54:45,856 --> 00:54:48,176
却和计算机科学的关系不大
that has almost nothing to do with computer science,
1001
00:54:48,590 --> 00:54:50,240
它真正涉及的是
that it really is a problem having to do with
1002
00:54:50,272 --> 00:54:52,736
两种不相容的看待世界的方式
two very incompatible ways of looking at the world.
1003
00:54:54,144 --> 00:54:54,720
有问题吗?
OK, questions?
1004
00:55:17,550 --> 00:55:19,200
学生:你之前提到过
AUDIENCE: You mentioned earlier that
1005
00:55:20,112 --> 00:55:21,328
一旦引入了赋值
once you introduce assignment,
1006
00:55:21,328 --> 00:55:25,890
就不能使用代换模型了
the general rule for using the substitution model is you can't.
1007
00:55:25,890 --> 00:55:27,570
除非你非常小心
Unless you're very careful, you can't.
1008
00:55:27,570 --> 00:55:27,968
教授:对的
PROFESSOR: Right.
1009
00:55:28,260 --> 00:55:33,280
学生:有什么技术或者指导方针
AUDIENCE: Is there a set of techniques or a set of guidelines
1010
00:55:33,424 --> 00:55:35,920
来确定赋值的影响
for localizing the effects of assignment
1011
00:55:36,528 --> 00:55:40,300
以便说清楚这个“很小心”是怎么回事吗?
so that the very careful becomes defined?
1012
00:55:40,300 --> 00:55:42,608
教授:我不知道
PROFESSOR: I don't know. Um...
1013
00:55:42,890 --> 00:55:43,584
我想想
Let me think.
1014
00:55:45,430 --> 00:55:48,944
当然 实现MEM-PROC也使用了赋值
Well, certainly, there was an assignment inside memo proc,
1015
00:55:50,128 --> 00:55:51,480
但是它被隐藏了起来
but that was sort of hidden away.
1016
00:55:51,480 --> 00:55:53,008
因为它没有对结果造成影响
It ended up not making any difference.
1017
00:55:53,480 --> 00:55:56,448
部分原因之一在于 一旦触发这个过程
Part of the reason for that is once this thing triggered
1018
00:55:57,152 --> 00:55:58,832
它被求值并得到结果
that it had run and gotten an answer,
1019
00:55:58,832 --> 00:56:00,064
这个结果不会再变化
that answer will never change.
1020
00:56:00,608 --> 00:56:02,336
有点像单次赋值
So that was sort of a one-time assignment.
1021
00:56:02,350 --> 00:56:03,856
一个一般性原则就是
So one very general thing you can do
1022
00:56:04,304 --> 00:56:06,352
如果你只用这种单次赋值
is if you only do what's called a one-time assignment
1023
00:56:08,040 --> 00:56:09,248
并且它不再改变
and never change anything,
1024
00:56:09,632 --> 00:56:10,540
我想应该不会有太大问题
then you can do better.
1025
00:56:11,250 --> 00:56:14,128
还有一个问题在于MERGE --
One of the problems in this merge thing, people have--
1026
00:56:14,672 --> 00:56:18,320
让我想想对不对
people have-- let me see if this is right.
1027
00:56:18,490 --> 00:56:21,552
我认为有了公平合并这一技术
I think it's true that with fair merge,
1028
00:56:22,256 --> 00:56:26,096
你可以在语言的其它地方
with just fair merge, you can begin effectively simulating
1029
00:56:27,024 --> 00:56:28,896
有效地模拟赋值
assignment in the rest of the language.
1030
00:56:30,820 --> 00:56:33,296
这就像为了解决问题你会引入一些东西
It seems like anything you do to go outside--
1031
00:56:33,504 --> 00:56:35,504
我不清楚对公平合并来说是否成立
I'm not quite sure that's true for fair merge,
1032
00:56:35,536 --> 00:56:39,312
但是对人们正在尝试的一些一般性事情是成立的
but it's true of a little bit more general things that people have been doing.
1033
00:56:39,520 --> 00:56:41,344
所以 这可能是你引入的这一点点东西
So it might be that any little bit you put in,
1034
00:56:41,616 --> 00:56:44,144
突然间 使你能构建任何东西
suddenly if they allow you to build arbitrary stuff,
1035
00:56:44,160 --> 00:56:46,512
这就几乎跟有了赋值一样糟糕了
it's almost as bad as having assignment altogether.
1036
00:56:47,970 --> 00:56:50,672
这也是人们在研究的一个领域
But that's an area that people are thinking about now.
1037
00:56:51,590 --> 00:56:54,304
学生:我还没有太明白MERGE的问题
AUDIENCE: I guess I don't see the problem here with merge
1038
00:56:54,830 --> 00:56:59,200
如果我调用Bill它是个过程
if, you know the sense, I call Bill, if Bill is a procedure,
1039
00:56:59,216 --> 00:57:02,416
那么Bill就会增加银行账户
then Bill is going to increment the bank account
1040
00:57:02,448 --> 00:57:04,730
或者创建一个表 用于放置下一个存款
or build the list that 's going to put in the next element.
1041
00:57:04,730 --> 00:57:06,848
如果我连续调用Dave两次 他肯定也会那样
If I call Dave twice in a row, that will do that.
1042
00:57:07,170 --> 00:57:09,350
我并不清楚为什么需要公平合并
I'm not sure where fair merge has to be involved.
1043
00:57:09,350 --> 00:57:11,200
教授:关键在于你得把这些当作真人一样
PROFESSOR: The problem is imagine these really as people.
1044
00:57:11,200 --> 00:57:14,208
这里有一个用户在操作帐户
See, here I have the user who's interacting with this bank account.
1045
00:57:14,850 --> 00:57:17,070
请求一次 得到结果
Put in a request, get an answer. Put in a request, get an answer.
1046
00:57:17,200 --> 00:57:17,568
学生:对
AUDIENCE: Right.
1047
00:57:18,200 --> 00:57:20,624
教授:如果我只能通过从两个流中选择一个
PROFESSOR: But if the only way I can process request
1048
00:57:20,656 --> 00:57:22,250
来处理请求的话
is to alternate them from two people--
1049
00:57:22,912 --> 00:57:24,220
学生:为什么要二选一呢?
AUDIENCE: Well, why would you alternate them?
1050
00:57:24,220 --> 00:57:25,232
教授:为什么不呢?
PROFESSOR: Why don't I?
1051
00:57:25,456 --> 00:57:25,808
学生:对啊 为什么要这样呢?
AUDIENCE: Yes. Why do you?
1052
00:57:26,608 --> 00:57:27,728
教授:假设这些是现实中的人 对吗?
PROFESSOR: Think of them as real people, right?
1053
00:57:27,760 --> 00:57:28,976
这个人外出一年
This guy might go away for a year.
1054
00:57:29,280 --> 00:57:31,744
你只能在银行账户窗口旁边等待
And you're sitting here at the bank account window,
1055
00:57:32,430 --> 00:57:33,728
就是不能处理两个请求
and you can't put in two requests
1056
00:57:33,744 --> 00:57:34,944
因为你还得等这个人
because it's waiting for this guy.
1057
00:57:35,480 --> 00:57:37,072
学生:为什么非得等他呢?
AUDIENCE: Why does it have to be waiting for one?
1058
00:57:37,380 --> 00:57:39,110
教授:因为这里是在计算一个函数
PROFESSOR: Because it's trying to compute a function.
1059
00:57:39,110 --> 00:57:40,928
我必须定义一个函数
I have to define a function.
1060
00:57:41,720 --> 00:57:42,608
换种方式来说
Another way to say that
1061
00:57:42,848 --> 00:57:44,992
这个MERGE盒子的输出
is the answer to what comes out of this merge box
1062
00:57:46,240 --> 00:57:49,488
并不是输入的函数
is not a function of what goes in.
1063
00:57:51,690 --> 00:57:53,490
明白了吗?再来看看这个MERGE是怎么运行的
Because, see, what would the function be?
1064
00:57:53,490 --> 00:57:58,864
假设Bill输入 1 1 1 1
Suppose he puts in 1, 1, 1, 1,
1065
00:57:59,824 --> 00:58:02,784
Dave输入2 2 2 2
and he puts in 2, 2, 2, 2.
1066
00:58:03,470 --> 00:58:04,800
MERGE应该输出什么呢?
What's the answer supposed to be?
1067
00:58:05,584 --> 00:58:08,740
这里并不一定是 1 2 1 2 1 2
It's not good enough to say it's 1, 2, 1, 2, 1, 2.
1068
00:58:08,740 --> 00:58:09,390
学生:我明白了
AUDIENCE: I understand.
1069
00:58:09,390 --> 00:58:11,560
当Bill输入1 1也就进去了
But when Bill puts in 1, 1 goes in.
1070
00:58:11,560 --> 00:58:13,950
Dave再输入两个2 MERGE就输出两个2
When Dave puts in 2, twice 2 goes in twice.
1071
00:58:13,950 --> 00:58:14,736
学生:当Bill输入
AUDIENCE: When Bill puts in--
1072
00:58:14,768 --> 00:58:15,088
教授:对的
PROFESSOR: Right.
1073
00:58:15,130 --> 00:58:18,432
学生:为什么不能在输入的数据上
AUDIENCE: Why can't it be hooked to the time of the input--
1074
00:58:18,592 --> 00:58:20,064
加上时间信息呢?
the actual procedural--
1075
00:58:20,128 --> 00:58:21,840
教授:因为这里没有时间这个概念
PROFESSOR: Because I don't have time.
1076
00:58:23,980 --> 00:58:26,900
我只是定义一个函数
See, all I can say is I'm going to define a function.
1077
00:58:26,900 --> 00:58:28,150
没有时间概念
I don't have time.
1078
00:58:32,000 --> 00:58:34,192
如果是二选一的话
There's no concept if it's going to alternate,
1079
00:58:34,192 --> 00:58:36,544
如果选中的流没有人 就得等待它
except if nobody's there, it's going to wait a while for him.
1080
00:58:38,420 --> 00:58:41,360
它只会说 我有一个请求流
It's just going to say I have the stream of requests,
1081
00:58:41,740 --> 00:58:43,344
这是是Dave生成的
the timeless infinite streams
1082
00:58:43,360 --> 00:58:45,296
没有时刻的、无穷长度的请求流
of all the requests that Dave would have made, right?
1083
00:58:47,550 --> 00:58:50,416
Bill可能生成 没有时刻的无穷请求流
And the timeless infinite stream of all the requests Bill would have made,
1084
00:58:50,544 --> 00:58:51,690
我想对这些东西做运算
and I want to operate on them.
1085
00:58:51,690 --> 00:58:53,510
这就是银行帐户的工作原理
See, that's how this bank account is working.
1086
00:58:56,710 --> 00:58:57,584
问题是
And the problem is
1087
00:58:57,610 --> 00:59:00,752
这些坐在银行窗口前的倒霉蛋们
that these poor people who are sitting at the bank account windows
1088
00:59:00,768 --> 00:59:03,824
来得并不是时候
have the misfortune to exist in time.
1089
00:59:05,296 --> 00:59:07,136
它们才看不到这个无穷流
They don't see their infinite stream
1090
00:59:07,696 --> 00:59:09,536
什么时候其中会有请求
of all the requests they would have ever made.
1091
00:59:10,070 --> 00:59:11,550
他们只是等着 等待帐户的响应
They're waiting now, and they want an answer.
1092
00:59:14,480 --> 00:59:15,760
假设你坐在屏幕前
So if you're sitting there--
1093
00:59:16,240 --> 00:59:20,864
操作着一台分时系统的计算机
if this is the screen operation on some time-sharing system
1094
00:59:21,520 --> 00:59:22,608
而且它还是函数式的
and it's working functionally,
1095
00:59:22,640 --> 00:59:24,592
输入指令后你就希望看到结果
you want an answer then when you talk the character.
1096
00:59:25,290 --> 00:59:27,424
但是你并不想主机在处理完所有其它人的命令
You don't want it to have to wait for everybody in the whole system
1097
00:59:27,456 --> 00:59:29,920
之后再来处理你的命令
to have typed one character before it can get around to service you.
1098
00:59:30,910 --> 00:59:31,920
这就是问题所在
So that's the problem.
1099
00:59:34,000 --> 00:59:36,384
我的意思就是 用户的世界当然是存在时间概念的
I mean, the fact that people live in time, apparently.
1100
00:59:37,216 --> 00:59:38,620
如果没有 这就不构成问题
If they didn't, it wouldn't be a problem.
1101
00:59:49,100 --> 00:59:51,024
学生:我想我还是不太理解
AUDIENCE: I'm afraid I miss the point of
1102
00:59:51,088 --> 00:59:54,240
银行交易中为什么没有时间概念这一要点
having no time in this banking transaction.
1103
00:59:54,740 --> 00:59:56,656
难道时间不是非常重要吗?
Isn't time very important?
1104
00:59:56,880 --> 00:59:59,056
举例说 有一系列事件
For instance, the sequence of events.
1105
00:59:59,950 --> 01:00:05,024
比如Dave取款$100
As if, If Dave take out $100, and then
1106
01:00:06,304 --> 01:00:08,400
这些顺序应该很重要才对
then the timing sequence should be important.
1107
01:00:08,400 --> 01:00:10,864
你怎么能把它们看作是流呢?
How do you treat transactions as streams?
1108
01:00:11,260 --> 01:00:14,260
教授:这就是我一直在强调的
PROFESSOR: Well, that's the thing I'm saying.
1109
01:00:14,260 --> 01:00:15,616
在这个例子中确实做不到那一点
This is an example where you can't.
1110
01:00:17,510 --> 01:00:18,128
做不到
You can't.
1111
01:00:18,160 --> 01:00:20,080
关键在于 这里的输出
What goes, The point is what comes out of here
1112
01:00:20,240 --> 01:00:21,888
并不是这两个输入流
is simply not a function of the stream going in here
1113
01:00:21,920 --> 01:00:23,600
的函数
going in here and the stream going in here.
1114
01:00:24,170 --> 01:00:25,984
这个函数跟这个输入流有关
It's a function of the stream going in here
1115
01:00:26,192 --> 01:00:27,264
还跟这个输入流有关
and the stream going in here
1116
01:00:27,360 --> 01:00:29,072
还包括某种有关时间的信息
and some kind of information about time,
1117
01:00:29,376 --> 01:00:32,368
这也正是正则序语言不想让你知道的
which is precisely what a normal-order language won't let you say.
1118
01:00:34,810 --> 01:00:37,952
学生:为了让这个系统更加函数式
AUDIENCE: In order to brings this back into a more functional perspective,
1119
01:00:38,544 --> 01:00:42,048
我们能不能把Bill和Dave的交易请求附上时间戳
could we just explicitly time stamp all the inputs from Bill and Dave
1120
01:00:42,544 --> 01:00:46,400
而使用时间戳作为公平合并的依据?
and define fair merge to just be the sort on those time stamps?
1121
01:00:48,416 --> 01:00:49,550
教授:当然 当然可以
PROFESSOR: Yeah, you can do that.
1122
01:00:49,550 --> 01:00:50,600
你可以那样做
You can do that sort of thing.
1123
01:00:50,600 --> 01:00:52,560
或者 我们可以这样来想象
Another thing you could say is imagine
1124
01:00:52,768 --> 01:00:54,448
我们把这个函数看作是
that really what this function is,
1125
01:00:54,784 --> 01:00:56,880
MERGE每毫秒读一次输入
is that it does a read every microsecond,
1126
01:00:58,860 --> 01:00:59,936
如果没有读到东西
and then if there's none there,
1127
01:00:59,936 --> 01:01:00,970
就认为没有请求
that's considered an empty one.
1128
01:01:00,970 --> 01:01:03,392
这和你刚刚说的那种方式是等价的
That's about equivalent to what you said.
1129
01:01:03,610 --> 01:01:06,080
当然可以这样做 但有点旁门左道
And yes, you can do that, but that's a glitch.
1130
01:01:07,110 --> 01:01:10,144
我们不只是关心函数的具体实现
So it's not quite only implementation we're worried about.
1131
01:01:10,768 --> 01:01:12,736
我们关心的是语言的表达力
We're worried about expressive power in the language,
1132
01:01:12,752 --> 01:01:14,672
我们遇到的困难是
and what we're running across is a real mismatch
1133
01:01:14,992 --> 01:01:17,440
我们不能很容易地表达我们想要表达的东西
between what we can say easily and what we'd like to say.
1134
01:01:19,880 --> 01:01:22,016
学生:听起来好像如果两个人同时发出请求
AUDIENCE: It sounds like where we're getting hung up with that
1135
01:01:22,064 --> 01:01:26,090
这个方法就会出问题
one input from both Bill and Dave at the same time.
1136
01:01:26,120 --> 01:01:28,432
教授:并不只是这个 只要是你定义的都可能出问题
PROFESSOR: It's not quite one, but it's anything you define.
1137
01:01:28,530 --> 01:01:30,576
你当然可以说Dave经常发起两个请求
So you can say Dave can go twice as often,
1138
01:01:30,720 --> 01:01:32,320
但是你如果预先定义了什么
but if anything you predefine,
1139
01:01:32,688 --> 01:01:33,872
这样做也不正确
it's not the right thing.
1140
01:01:36,110 --> 01:01:40,704
你不能确定某些特定函数的输入请求
You can't decide at some particular function of their input requests.
1141
01:01:41,930 --> 01:01:43,376
但是还有更坏的情况
Worse yet, I mean, worse yet,
1142
01:01:44,128 --> 01:01:45,728
有一些情况甚至MERGE也处理不了
there are things that even merge can't do.
1143
01:01:47,290 --> 01:01:49,696
比如突然有一天你想要
One thing you might want to do that's even more general is suddenly
1144
01:01:50,240 --> 01:01:52,470
把另一个人关联在这个银行帐户上
you add somebody else to this bank account system.
1145
01:01:52,470 --> 01:01:54,512
假如这个人是John
You go and you add John to this bank account system.
1146
01:01:56,030 --> 01:01:58,896
现在图上就要多一个流
And now there's yet another stream that's going to come into the picture
1147
01:01:58,912 --> 01:02:00,704
在一个我们未曾指定的时候
at some time which we haven't prespecified.
1148
01:02:02,040 --> 01:02:04,000
这种情况甚至公平合并也无法给出合理的合并
So that's something even fair merge can't do,
1149
01:02:04,000 --> 01:02:08,256
还需要有MANAGER一类的东西
and they're things called-- I forget-- manager or something.
1150
01:02:08,860 --> 01:02:11,790
需要一种更一般性的公平合并来解决
That's a generalization of fair merge to allow that.
1151
01:02:11,790 --> 01:02:13,984
有很多研究都在讨论
There's a whole sort of research discipline saying
1152
01:02:14,000 --> 01:02:16,300
通过不断引入新机制
how far can you push this functional perspective
1153
01:02:16,592 --> 01:02:18,720
函数式思维能应用到哪种程度?
by adding more and more mechanism?
1154
01:02:19,580 --> 01:02:21,792
在我们不得不使用赋值之前
And how far does that go before the whole thing breaks down
1155
01:02:21,824 --> 01:02:23,408
函数式程序设计能干成什么样?
and you might as well been using set anyway.
1156
01:02:25,984 --> 01:02:28,000
学生:看来自动存款就不行
AUDIENCE: But not automatic deposit.
1157
01:02:39,328 --> 01:02:40,496
教授:好的 下课
PROFESSOR: OK, thank you.
1158
01:02:41,328 --> 01:02:51,088
MIT OpenCourseWare
http://ocw.mit.edu
1159
01:02:51,080 --> 01:03:00,080
本项目主页
https://github.com/DeathKing/Learning-SICP
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Ruby
1
https://gitee.com/jacklisp/Learning-SICP.git
git@gitee.com:jacklisp/Learning-SICP.git
jacklisp
Learning-SICP
Learning-SICP
master

搜索帮助