1 Star 0 Fork 0

jacklisp/Learning-SICP

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
lec6a_512kb.mp4.srt 89.89 KB
一键复制 编辑 原始数据 按行查看 历史
DeathKing 提交于 2015-11-17 13:32 +08:00 . add original English subtitles.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752
0
00:00:00,000 --> 00:00:18,550
1
00:00:18,550 --> 00:00:21,230
PROFESSOR: Well, last time Gerry
really let the cat out
2
00:00:21,230 --> 00:00:22,230
of the bag.
3
00:00:22,230 --> 00:00:26,350
He introduced the idea
of assignment.
4
00:00:26,350 --> 00:00:33,405
Assignment and state.
5
00:00:33,405 --> 00:00:37,620
6
00:00:37,620 --> 00:00:41,500
And as we started to see, the
implications of introducing
7
00:00:41,500 --> 00:00:43,860
assignment and state into the
language are absolutely
8
00:00:43,860 --> 00:00:45,350
frightening.
9
00:00:45,350 --> 00:00:47,240
First of all, the substitution
model of
10
00:00:47,240 --> 00:00:48,865
evaluation breaks down.
11
00:00:48,865 --> 00:00:52,210
And we have to use this much
more complicated environment
12
00:00:52,210 --> 00:00:53,780
model and this very mechanistic
thing with
13
00:00:53,780 --> 00:00:56,530
diagrams, even to say what
statements in the programming
14
00:00:56,530 --> 00:00:58,130
language mean.
15
00:00:58,130 --> 00:01:00,260
And that's not a mere
technical point.
16
00:01:00,260 --> 00:01:03,090
See, it's not that we had this
particular substitution model
17
00:01:03,090 --> 00:01:05,200
and, well, it doesn't quite
work, so we have to do
18
00:01:05,200 --> 00:01:05,870
something else.
19
00:01:05,870 --> 00:01:10,730
It's that nothing like the
substitution model can work.
20
00:01:10,730 --> 00:01:15,950
Because suddenly, a variable
is not just something that
21
00:01:15,950 --> 00:01:18,080
stands for a value.
22
00:01:18,080 --> 00:01:22,390
A variable now has to somehow
specify a place
23
00:01:22,390 --> 00:01:23,630
that holds a value.
24
00:01:23,630 --> 00:01:25,885
And the value that's in
that place can change.
25
00:01:25,885 --> 00:01:30,280
26
00:01:30,280 --> 00:01:39,110
Or for instance, an expression
like f of x might have a side
27
00:01:39,110 --> 00:01:40,410
effect in it.
28
00:01:40,410 --> 00:01:44,160
So if we say f of x and it has
some value, and then later we
29
00:01:44,160 --> 00:01:48,890
say f of x again, we might
get a different value
30
00:01:48,890 --> 00:01:49,730
depending on the order.
31
00:01:49,730 --> 00:01:52,780
So suddenly, we have to think
not only about values but
32
00:01:52,780 --> 00:01:54,030
about time.
33
00:01:54,030 --> 00:01:57,970
34
00:01:57,970 --> 00:02:02,070
And then things like pairs are
no longer just their CARs and
35
00:02:02,070 --> 00:02:02,520
their CDRs.
36
00:02:02,520 --> 00:02:06,310
A pair now is not quite its CAR
and its CDR. It's rather
37
00:02:06,310 --> 00:02:08,449
its identity.
38
00:02:08,449 --> 00:02:11,650
So a pair has identity.
39
00:02:11,650 --> 00:02:12,900
It's an object.
40
00:02:12,900 --> 00:02:21,330
41
00:02:21,330 --> 00:02:26,280
And two pairs that have the same
CAR and CDR might be the
42
00:02:26,280 --> 00:02:29,650
same or different, because
suddenly we have to worry
43
00:02:29,650 --> 00:02:30,900
about sharing.
44
00:02:30,900 --> 00:02:34,960
45
00:02:34,960 --> 00:02:38,910
So all of these things enter
as soon as we introduce
46
00:02:38,910 --> 00:02:40,480
assignment.
47
00:02:40,480 --> 00:02:43,340
See, this is a really far cry
from where we started with
48
00:02:43,340 --> 00:02:45,400
substitution.
49
00:02:45,400 --> 00:02:50,420
It's a technically harder way
of looking at things because
50
00:02:50,420 --> 00:02:52,710
we have to think more
mechanistically about our
51
00:02:52,710 --> 00:02:53,540
programming language.
52
00:02:53,540 --> 00:02:55,960
We can't just think about
it as mathematics.
53
00:02:55,960 --> 00:02:59,860
It's philosophically harder,
because suddenly there are all
54
00:02:59,860 --> 00:03:02,020
these funny issues about what
does it mean that something
55
00:03:02,020 --> 00:03:04,050
changes or that two things
are the same.
56
00:03:04,050 --> 00:03:07,910
And also, it's programming
harder, because as Gerry
57
00:03:07,910 --> 00:03:10,070
showed last time, there are all
these bugs having to do
58
00:03:10,070 --> 00:03:14,420
with bad sequencing and aliasing
that just don't exist
59
00:03:14,420 --> 00:03:18,210
in a language where we don't
worry about objects.
60
00:03:18,210 --> 00:03:23,635
Well, how'd we get
into this mess?
61
00:03:23,635 --> 00:03:27,500
Remember what we did, the reason
we got into this is
62
00:03:27,500 --> 00:03:35,750
because we were looking to
build modular systems. We
63
00:03:35,750 --> 00:03:40,250
wanted to build systems that
fall apart into chunks that
64
00:03:40,250 --> 00:03:42,760
seem natural.
65
00:03:42,760 --> 00:03:46,260
So for instance, we want to take
a random number generator
66
00:03:46,260 --> 00:03:48,660
and package up the state of that
random number generator
67
00:03:48,660 --> 00:03:52,840
inside of it so that we can
separate the idea of picking
68
00:03:52,840 --> 00:03:56,640
random numbers from the general
Monte Carlo strategy
69
00:03:56,640 --> 00:03:59,740
of estimating something and
separate that from the
70
00:03:59,740 --> 00:04:03,060
particular way that you work
with random numbers in that
71
00:04:03,060 --> 00:04:06,980
formula developed by
Cesaro for pi.
72
00:04:06,980 --> 00:04:11,400
And similarly, when we go off
and construct some models of
73
00:04:11,400 --> 00:04:15,440
things, if we go off and model
a system that we see in the
74
00:04:15,440 --> 00:04:19,050
real world, we'd like our
program to break into natural
75
00:04:19,050 --> 00:04:22,310
pieces, pieces that mirror the
parts of the system that we
76
00:04:22,310 --> 00:04:24,900
see in the real world.
77
00:04:24,900 --> 00:04:28,780
So for example, if we look at
a digital circuit, we say,
78
00:04:28,780 --> 00:04:33,910
gee, there's a circuit and
it has a piece and
79
00:04:33,910 --> 00:04:35,160
it has another piece.
80
00:04:35,160 --> 00:04:40,100
81
00:04:40,100 --> 00:04:43,580
And these different pieces
sort of have identity.
82
00:04:43,580 --> 00:04:45,550
They have state.
83
00:04:45,550 --> 00:04:48,580
And the state sits
on these wires.
84
00:04:48,580 --> 00:04:51,020
And we think of this piece as
an object that's different
85
00:04:51,020 --> 00:04:52,610
from that as an object.
86
00:04:52,610 --> 00:04:54,400
And when we watch the system
change, we think about a
87
00:04:54,400 --> 00:04:57,500
signal coming in here and
changing a state that might be
88
00:04:57,500 --> 00:04:59,860
here and going here and
interacting with a state that
89
00:04:59,860 --> 00:05:02,170
might be stored there,
and so on and so on.
90
00:05:02,170 --> 00:05:06,860
91
00:05:06,860 --> 00:05:12,760
So what we'd like is we'd like
to build in the computer
92
00:05:12,760 --> 00:05:17,340
systems that fall into pieces
that mirror our view of
93
00:05:17,340 --> 00:05:19,870
reality, of the way that the
actual systems we're modeling
94
00:05:19,870 --> 00:05:23,365
seem to fall into pieces.
95
00:05:23,365 --> 00:05:28,970
Well, maybe the reason that
building systems like this
96
00:05:28,970 --> 00:05:31,600
seems to introduce such
technical complications has
97
00:05:31,600 --> 00:05:33,610
nothing to do with computers.
98
00:05:33,610 --> 00:05:37,960
See, maybe the real reason that
we pay such a price to
99
00:05:37,960 --> 00:05:41,910
write programs that mirror our
view of reality is that we
100
00:05:41,910 --> 00:05:44,550
have the wrong view
of reality.
101
00:05:44,550 --> 00:05:47,460
See, maybe time is just
an illusion, and
102
00:05:47,460 --> 00:05:50,150
nothing ever changes.
103
00:05:50,150 --> 00:05:52,910
See, for example, if I take this
chalk, and we say, gee,
104
00:05:52,910 --> 00:05:55,820
this is an object and
it has a state.
105
00:05:55,820 --> 00:05:59,710
At each moment it has a position
and a velocity.
106
00:05:59,710 --> 00:06:01,240
And if we do something,
that state can change.
107
00:06:01,240 --> 00:06:04,340
108
00:06:04,340 --> 00:06:07,900
But if you studied any
relativity, for instance, you
109
00:06:07,900 --> 00:06:09,760
know that you don't think of
the path of that chalk as
110
00:06:09,760 --> 00:06:11,340
something that goes on
instant by instant.
111
00:06:11,340 --> 00:06:13,870
It's more insightful to think
of that whole chalk's
112
00:06:13,870 --> 00:06:16,020
existence as a path
in space-time.
113
00:06:16,020 --> 00:06:18,040
that's all splayed out.
114
00:06:18,040 --> 00:06:19,840
There aren't individual
positions and velocities.
115
00:06:19,840 --> 00:06:24,640
There's just its unchanging
existence in space-time.
116
00:06:24,640 --> 00:06:28,080
Similarly, if we look at this
electrical system, if we
117
00:06:28,080 --> 00:06:32,450
imagine this electrical system
is implementing some sort of
118
00:06:32,450 --> 00:06:35,730
signal processing system, the
signal processing engineer who
119
00:06:35,730 --> 00:06:39,010
put that thing together doesn't
think of it as, well,
120
00:06:39,010 --> 00:06:41,490
at each instance there's
a voltage coming in.
121
00:06:41,490 --> 00:06:43,340
And that translates
into something.
122
00:06:43,340 --> 00:06:46,400
And that affects the state over
here, which changes the
123
00:06:46,400 --> 00:06:46,810
state over here.
124
00:06:46,810 --> 00:06:49,060
Nobody putting together a
signal processing system
125
00:06:49,060 --> 00:06:50,420
thinks about it like that.
126
00:06:50,420 --> 00:06:56,830
Instead, you say there's
this signal that's
127
00:06:56,830 --> 00:06:58,060
splayed out over time.
128
00:06:58,060 --> 00:07:01,100
And if this is acting as a
filter, this whole thing
129
00:07:01,100 --> 00:07:09,570
transforms this whole thing for
some sort of other output.
130
00:07:09,570 --> 00:07:11,790
You don't think of it as what's
happening instant by
131
00:07:11,790 --> 00:07:14,160
instant as the state
of these things.
132
00:07:14,160 --> 00:07:17,990
And somehow you think of this
box as a whole thing, not as
133
00:07:17,990 --> 00:07:20,980
little pieces sending messages
of state to each other at
134
00:07:20,980 --> 00:07:22,230
particular instants.
135
00:07:22,230 --> 00:07:28,250
136
00:07:28,250 --> 00:07:30,130
Well, today we're going to
look at another way to
137
00:07:30,130 --> 00:07:34,260
decompose systems that's more
like the signal processing
138
00:07:34,260 --> 00:07:37,050
engineer's view of the world
than it is like thinking about
139
00:07:37,050 --> 00:07:41,130
objects that communicate
sending messages.
140
00:07:41,130 --> 00:07:43,310
That's called stream
processing.
141
00:07:43,310 --> 00:07:54,570
142
00:07:54,570 --> 00:08:01,790
And we're going to start by
showing how we can make our
143
00:08:01,790 --> 00:08:08,550
programs more uniform and see
a lot more commonality if we
144
00:08:08,550 --> 00:08:12,490
throw out of these programs
what you might say is an
145
00:08:12,490 --> 00:08:17,210
inordinate concern with
worrying about time.
146
00:08:17,210 --> 00:08:19,910
Let me start by comparing
two procedures.
147
00:08:19,910 --> 00:08:23,260
148
00:08:23,260 --> 00:08:25,690
The first one does this.
149
00:08:25,690 --> 00:08:27,770
We imagine that there's
a tree.
150
00:08:27,770 --> 00:08:30,400
151
00:08:30,400 --> 00:08:33,179
Say there's a tree
of integers.
152
00:08:33,179 --> 00:08:34,429
It's a binary tree.
153
00:08:34,429 --> 00:08:39,100
154
00:08:39,100 --> 00:08:40,230
So it looks like this.
155
00:08:40,230 --> 00:08:44,990
And there's integers in
each of the nodes.
156
00:08:44,990 --> 00:08:51,000
And what we would like to
compute is for each odd number
157
00:08:51,000 --> 00:08:54,210
sitting here, we'd like to find
the square and then sum
158
00:08:54,210 --> 00:08:57,210
up all those squares.
159
00:08:57,210 --> 00:08:59,480
Well, that should be a familiar
kind of thing.
160
00:08:59,480 --> 00:09:02,930
There's a recursive strategy
for doing it.
161
00:09:02,930 --> 00:09:04,880
We look at each leaf, and
either it's going to
162
00:09:04,880 --> 00:09:06,690
contribute the square of
the number if it's odd
163
00:09:06,690 --> 00:09:08,680
or 0 if it's even.
164
00:09:08,680 --> 00:09:13,280
And then recursively, we can say
at each tree, the sum of
165
00:09:13,280 --> 00:09:15,330
all of them is the sum coming
from the right branch and the
166
00:09:15,330 --> 00:09:17,640
left branch, and recursively
down through the nodes.
167
00:09:17,640 --> 00:09:20,360
And that's a familiar way of
thinking about programming.
168
00:09:20,360 --> 00:09:23,960
Let's actually look at
that on the slide.
169
00:09:23,960 --> 00:09:27,960
We say to sum the odd squares
in a tree, well, there's a
170
00:09:27,960 --> 00:09:30,520
test. Either it's a leaf node,
and we're going to check to
171
00:09:30,520 --> 00:09:34,710
see if it's an integer, and then
either it's odd, in which
172
00:09:34,710 --> 00:09:37,160
we take the square,
or else it's 0.
173
00:09:37,160 --> 00:09:40,260
And then the sum of the whole
thing is the sum coming from
174
00:09:40,260 --> 00:09:42,120
the left branch and
the right branch.
175
00:09:42,120 --> 00:09:46,340
176
00:09:46,340 --> 00:09:51,560
OK, well, let me contrast that
with a second problem.
177
00:09:51,560 --> 00:09:55,810
Suppose I give you an integer
n, and then some function to
178
00:09:55,810 --> 00:09:59,270
compute of the first of each
integer in 1 through n.
179
00:09:59,270 --> 00:10:01,810
And then I want to collect
together in a list all those
180
00:10:01,810 --> 00:10:05,600
function values that satisfy
some property.
181
00:10:05,600 --> 00:10:06,880
That's a general
kind of thing.
182
00:10:06,880 --> 00:10:09,750
Let's say to be specific, let's
imagine that for each
183
00:10:09,750 --> 00:10:11,270
integer, k, we're
going to compute
184
00:10:11,270 --> 00:10:14,210
the k Fibonacci number.
185
00:10:14,210 --> 00:10:17,550
And then we'll see which of
those are odd and assemble
186
00:10:17,550 --> 00:10:19,050
those into a list.
187
00:10:19,050 --> 00:10:20,710
So here's a procedure
that does that.
188
00:10:20,710 --> 00:10:23,730
189
00:10:23,730 --> 00:10:26,240
Find the odd Fibonacci numbers
among the first n.
190
00:10:26,240 --> 00:10:28,910
And here is a standard loop the
way we've been writing it.
191
00:10:28,910 --> 00:10:30,800
This is a recursion.
192
00:10:30,800 --> 00:10:33,740
It's a loop on k, and says if
k is bigger than n, it's the
193
00:10:33,740 --> 00:10:36,990
empty list. Otherwise we compute
the k-th Fibonacci
194
00:10:36,990 --> 00:10:40,370
number, call that f.
195
00:10:40,370 --> 00:10:45,180
If it's odd, we CONS it on
to the list starting
196
00:10:45,180 --> 00:10:47,690
with the next one.
197
00:10:47,690 --> 00:10:50,390
And otherwise, we just
take the next one.
198
00:10:50,390 --> 00:10:52,000
And this is the standard
way we've been
199
00:10:52,000 --> 00:10:53,000
writing iterative loops.
200
00:10:53,000 --> 00:10:57,600
And we start off calling
that loop with 1.
201
00:10:57,600 --> 00:11:01,600
OK, so there are
two procedures.
202
00:11:01,600 --> 00:11:02,900
Those procedures look
very different.
203
00:11:02,900 --> 00:11:04,390
They have very different
structures.
204
00:11:04,390 --> 00:11:07,740
Yet from a certain point of
view, those procedures are
205
00:11:07,740 --> 00:11:11,330
really doing very much
the same thing.
206
00:11:11,330 --> 00:11:14,930
So if I was talking like a
signal processing engineer,
207
00:11:14,930 --> 00:11:25,730
what I might say is that the
first procedure enumerates the
208
00:11:25,730 --> 00:11:26,980
leaves of a tree.
209
00:11:26,980 --> 00:11:31,160
210
00:11:31,160 --> 00:11:33,510
And then we can think of a
signal coming out of that,
211
00:11:33,510 --> 00:11:35,330
which is all the leaves.
212
00:11:35,330 --> 00:11:43,970
We'll filter them to see which
ones are odd, put them through
213
00:11:43,970 --> 00:11:45,190
some kind of filter.
214
00:11:45,190 --> 00:11:49,000
We'll then put them through
a kind of transducer.
215
00:11:49,000 --> 00:11:51,420
And for each one of those
things, we'll take the square.
216
00:11:51,420 --> 00:11:54,200
217
00:11:54,200 --> 00:11:58,290
And then we'll accumulate
all of those.
218
00:11:58,290 --> 00:12:00,570
We'll accumulate them by
sticking them together with
219
00:12:00,570 --> 00:12:03,340
addition starting from 0.
220
00:12:03,340 --> 00:12:07,140
221
00:12:07,140 --> 00:12:08,210
That's the first program.
222
00:12:08,210 --> 00:12:10,620
The second program, I can
describe in a very, very
223
00:12:10,620 --> 00:12:11,780
similar way.
224
00:12:11,780 --> 00:12:17,450
I'll say, we'll enumerate the
numbers on this interval, for
225
00:12:17,450 --> 00:12:19,080
the interval 1 through n.
226
00:12:19,080 --> 00:12:22,500
227
00:12:22,500 --> 00:12:28,080
We'll, for each one, compute the
Fibonacci number, put them
228
00:12:28,080 --> 00:12:29,270
through a transducer.
229
00:12:29,270 --> 00:12:31,780
We'll then take the result
of that, and we'll
230
00:12:31,780 --> 00:12:35,976
filter it for oddness.
231
00:12:35,976 --> 00:12:39,350
And then we'll take those and
put them into an accumulator.
232
00:12:39,350 --> 00:12:41,730
This time we'll build up a list,
so we'll accumulate with
233
00:12:41,730 --> 00:12:47,110
CONS starting from
the empty list.
234
00:12:47,110 --> 00:12:50,940
So this way of looking at the
program makes the two seem
235
00:12:50,940 --> 00:12:51,900
very, very similar.
236
00:12:51,900 --> 00:12:55,880
The problem is that that
commonality is completely
237
00:12:55,880 --> 00:12:58,050
obscured when we look at the
procedures we wrote.
238
00:12:58,050 --> 00:13:02,670
Let's go back and look at some
odd squares again, and say
239
00:13:02,670 --> 00:13:06,300
things like, where's
the enumerator?
240
00:13:06,300 --> 00:13:08,140
Where's the enumerator
in this program?
241
00:13:08,140 --> 00:13:11,230
Well, it's not in one place.
242
00:13:11,230 --> 00:13:15,990
It's a little bit in this
leaf-node test,
243
00:13:15,990 --> 00:13:17,160
which is going to stop.
244
00:13:17,160 --> 00:13:19,380
It's a little bit in the
recursive structure of the
245
00:13:19,380 --> 00:13:20,630
thing itself.
246
00:13:20,630 --> 00:13:23,150
247
00:13:23,150 --> 00:13:24,120
Where's the accumulator?
248
00:13:24,120 --> 00:13:25,680
The accumulator isn't
in one place either.
249
00:13:25,680 --> 00:13:32,180
It's partly in this 0 and
partly in this plus.
250
00:13:32,180 --> 00:13:34,510
It's not there as a thing
that we can look at.
251
00:13:34,510 --> 00:13:40,550
Similarly, if we look at odd
Fibs, that's also, in some
252
00:13:40,550 --> 00:13:42,940
sense, an enumerator and
an accumulator, but
253
00:13:42,940 --> 00:13:44,470
it looks very different.
254
00:13:44,470 --> 00:13:49,260
Because partly, the enumerator
is here in this greater than
255
00:13:49,260 --> 00:13:52,100
sign in the test. And partly
it's in this whole recursive
256
00:13:52,100 --> 00:13:55,680
structure in the loop, and
the way that we call it.
257
00:13:55,680 --> 00:13:58,100
And then similarly, that's also
mixed up in there with
258
00:13:58,100 --> 00:14:01,010
the accumulator, which is partly
over there and partly
259
00:14:01,010 --> 00:14:03,600
over there.
260
00:14:03,600 --> 00:14:09,790
So these very, very natural
pieces, these very natural
261
00:14:09,790 --> 00:14:13,770
boxes here don't appear in our
programs. Because they're kind
262
00:14:13,770 --> 00:14:14,360
of mixed up.
263
00:14:14,360 --> 00:14:16,290
The programs don't chop things
up in the right way.
264
00:14:16,290 --> 00:14:19,450
265
00:14:19,450 --> 00:14:22,240
Going back to this fundamental
principle of computer science
266
00:14:22,240 --> 00:14:24,620
that in order to control
something, you need the name
267
00:14:24,620 --> 00:14:27,820
of it, we don't really have
control over thinking about
268
00:14:27,820 --> 00:14:30,500
things this way because we don't
have our hands in them
269
00:14:30,500 --> 00:14:31,060
explicitly.
270
00:14:31,060 --> 00:14:35,510
We don't have a good language
for talking about them.
271
00:14:35,510 --> 00:14:42,850
Well, let's invent an
appropriate language in which
272
00:14:42,850 --> 00:14:44,515
we can build these pieces.
273
00:14:44,515 --> 00:14:48,650
The key to the language is these
guys, is what is these
274
00:14:48,650 --> 00:14:50,480
things I called signals?
275
00:14:50,480 --> 00:14:52,070
What are these things that
are flying on the
276
00:14:52,070 --> 00:14:53,320
arrows between the boxes?
277
00:14:53,320 --> 00:14:56,880
278
00:14:56,880 --> 00:15:02,840
Well, those things are going to
be data structures called
279
00:15:02,840 --> 00:15:04,770
streams. That's going
to be the key to
280
00:15:04,770 --> 00:15:07,980
inventing this language.
281
00:15:07,980 --> 00:15:08,600
What's a stream?
282
00:15:08,600 --> 00:15:10,820
Well, a stream is, like
anything else, a data
283
00:15:10,820 --> 00:15:12,220
abstraction.
284
00:15:12,220 --> 00:15:15,000
So I should tell you what
its selectors and
285
00:15:15,000 --> 00:15:16,870
constructors are.
286
00:15:16,870 --> 00:15:20,185
For a stream, we're going to
have one constructor that's
287
00:15:20,185 --> 00:15:21,435
called CONS-stream.
288
00:15:21,435 --> 00:15:25,690
289
00:15:25,690 --> 00:15:29,060
CONS-stream is going to put two
things together to form a
290
00:15:29,060 --> 00:15:32,040
thing called a stream.
291
00:15:32,040 --> 00:15:34,250
And then to extract things from
the stream, we're going
292
00:15:34,250 --> 00:15:38,010
to have a selector called
the head of the stream.
293
00:15:38,010 --> 00:15:41,340
So if I have a stream, I
can take its head or I
294
00:15:41,340 --> 00:15:44,720
can take its tail.
295
00:15:44,720 --> 00:15:48,290
And remember, I have to tell you
George's contract here to
296
00:15:48,290 --> 00:15:53,160
tell you what the axioms
are that relate these.
297
00:15:53,160 --> 00:16:04,080
And it's going to be for any
x and y, if I form the
298
00:16:04,080 --> 00:16:11,420
CONS-stream and take the head,
the head of CONS-stream of x
299
00:16:11,420 --> 00:16:26,590
and y is going to be x and the
tail of CONS-stream of x and y
300
00:16:26,590 --> 00:16:28,440
is going to be y.
301
00:16:28,440 --> 00:16:31,180
So those are the constructor,
two selectors for
302
00:16:31,180 --> 00:16:34,750
streams, and an axiom.
303
00:16:34,750 --> 00:16:36,980
There's something fishy here.
304
00:16:36,980 --> 00:16:41,060
So you might notice that these
are exactly the axioms for
305
00:16:41,060 --> 00:16:46,100
CONS, CAR, and CDR. If instead
of writing CONS-stream I wrote
306
00:16:46,100 --> 00:16:50,810
CONS and I said head was the
CAR and tail was the CDR,
307
00:16:50,810 --> 00:16:52,810
those are exactly the
axioms for pairs.
308
00:16:52,810 --> 00:16:55,130
And in fact, there's
another thing here.
309
00:16:55,130 --> 00:17:02,930
We're going to have a thing
called the-empty-stream, which
310
00:17:02,930 --> 00:17:08,319
is like the-empty-list.
311
00:17:08,319 --> 00:17:10,030
So why am I introducing
this terminology?
312
00:17:10,030 --> 00:17:12,780
Why don't I just keep talking
about pairs and lists?
313
00:17:12,780 --> 00:17:15,510
Well, we'll see.
314
00:17:15,510 --> 00:17:18,440
For now, if you like, why don't
you just pretend that
315
00:17:18,440 --> 00:17:21,560
streams really are just a
terminology for lists.
316
00:17:21,560 --> 00:17:24,890
And we'll see in a little while
why we want to keep this
317
00:17:24,890 --> 00:17:28,150
extra abstraction layer and
not just call them lists.
318
00:17:28,150 --> 00:17:32,300
319
00:17:32,300 --> 00:17:34,860
OK, now that we have streams, we
can start constructing the
320
00:17:34,860 --> 00:17:38,990
pieces of the language to
operate on streams. And there
321
00:17:38,990 --> 00:17:41,330
are a whole bunch of very useful
things that we could
322
00:17:41,330 --> 00:17:42,120
start making.
323
00:17:42,120 --> 00:17:54,850
For instance, we'll make our map
box to take a stream, s,
324
00:17:54,850 --> 00:18:00,400
and a procedure, and to generate
a new stream which
325
00:18:00,400 --> 00:18:03,640
has as its elements the
procedure applied to all the
326
00:18:03,640 --> 00:18:05,666
successive elements of s.
327
00:18:05,666 --> 00:18:07,400
In fact, we've seen
this before.
328
00:18:07,400 --> 00:18:10,950
This is the procedure map
that we did with lists.
329
00:18:10,950 --> 00:18:14,000
And you see it's exactly map,
except we're testing for
330
00:18:14,000 --> 00:18:14,650
empty-stream.
331
00:18:14,650 --> 00:18:15,560
Oh, I forgot to mention that.
332
00:18:15,560 --> 00:18:19,420
Empty-stream is like the null
test. So if it's empty, we
333
00:18:19,420 --> 00:18:20,510
generate the empty stream.
334
00:18:20,510 --> 00:18:24,700
Otherwise, we form a new stream
whose first element is
335
00:18:24,700 --> 00:18:28,950
the procedure applied to the
head of the stream, and whose
336
00:18:28,950 --> 00:18:31,570
rest is gotten by mapping along
with the procedure down
337
00:18:31,570 --> 00:18:33,140
the tail of the stream.
338
00:18:33,140 --> 00:18:34,920
So that looks exactly like
the map procedure
339
00:18:34,920 --> 00:18:37,030
we looked at before.
340
00:18:37,030 --> 00:18:38,350
Here's another useful thing.
341
00:18:38,350 --> 00:18:40,460
Filter, this is our
filter box.
342
00:18:40,460 --> 00:18:43,890
We're going to have a predicate
and a stream.
343
00:18:43,890 --> 00:18:46,720
We're going to make a new stream
that consists of all
344
00:18:46,720 --> 00:18:48,310
the elements of the
original one
345
00:18:48,310 --> 00:18:50,160
that satisfy the predicate.
346
00:18:50,160 --> 00:18:51,270
That's case analysis.
347
00:18:51,270 --> 00:18:53,140
When there's nothing
in the stream, we
348
00:18:53,140 --> 00:18:56,280
return the empty stream.
349
00:18:56,280 --> 00:19:00,060
We test the predicate on
the head of the stream.
350
00:19:00,060 --> 00:19:03,520
And if it's true, we add the
head of the stream onto the
351
00:19:03,520 --> 00:19:08,220
result of filtering the
tail of the stream.
352
00:19:08,220 --> 00:19:10,870
And otherwise, if that predicate
was false, we just
353
00:19:10,870 --> 00:19:13,500
filter the tail of the stream.
354
00:19:13,500 --> 00:19:16,595
Right, so there's filter.
355
00:19:16,595 --> 00:19:18,560
Let me run through a couple
more rather quickly.
356
00:19:18,560 --> 00:19:20,880
They're all in the book and
you can look at them.
357
00:19:20,880 --> 00:19:22,110
Let me just flash through.
358
00:19:22,110 --> 00:19:23,260
Here's accumulate.
359
00:19:23,260 --> 00:19:27,690
Accumulate takes a way of
combining things and an
360
00:19:27,690 --> 00:19:31,560
initial value in a stream and
sticks them all together.
361
00:19:31,560 --> 00:19:33,970
If the stream's empty, it's
just the initial value.
362
00:19:33,970 --> 00:19:36,930
Otherwise, we combine the head
of the stream with the result
363
00:19:36,930 --> 00:19:39,550
of accumulating the tail of the
stream starting from the
364
00:19:39,550 --> 00:19:40,900
initial value.
365
00:19:40,900 --> 00:19:42,830
So that's what I'd use to add
up everything in the stream.
366
00:19:42,830 --> 00:19:45,830
I'd accumulate with plus.
367
00:19:45,830 --> 00:19:48,060
How would I enumerate the
leaves of a tree?
368
00:19:48,060 --> 00:19:54,530
Well, if the tree is just a leaf
itself, I make something
369
00:19:54,530 --> 00:19:56,640
which only has that
node in it.
370
00:19:56,640 --> 00:20:01,100
Otherwise, I append together the
stuff of enumerating the
371
00:20:01,100 --> 00:20:04,340
left branch and the
right branch.
372
00:20:04,340 --> 00:20:08,130
And then append here is like the
ordinary append on lists.
373
00:20:08,130 --> 00:20:13,190
374
00:20:13,190 --> 00:20:13,850
You can look at that.
375
00:20:13,850 --> 00:20:16,410
That's analogous to the
ordinary procedure for
376
00:20:16,410 --> 00:20:19,150
appending two lists.
377
00:20:19,150 --> 00:20:21,810
How would I enumerate
an interval?
378
00:20:21,810 --> 00:20:24,500
This will take two integers, low
and high, and generate a
379
00:20:24,500 --> 00:20:28,106
stream of the integers going
from low to high.
380
00:20:28,106 --> 00:20:31,890
And we can make a whole
bunch of pieces.
381
00:20:31,890 --> 00:20:34,860
So that's a little language of
talking about streams. Once we
382
00:20:34,860 --> 00:20:37,670
have streams, we can build
things for manipulating them.
383
00:20:37,670 --> 00:20:40,200
Again, we're making
a language.
384
00:20:40,200 --> 00:20:41,270
And now we can start expressing
385
00:20:41,270 --> 00:20:43,060
things in this language.
386
00:20:43,060 --> 00:20:46,590
Here's our original procedure
for summing the odd
387
00:20:46,590 --> 00:20:47,310
squares in a tree.
388
00:20:47,310 --> 00:20:52,210
And you'll notice it looks
exactly now like the block
389
00:20:52,210 --> 00:20:54,590
diagram, like the signal
processing block diagram.
390
00:20:54,590 --> 00:21:00,230
So to sum the odd squares in a
tree, we enumerate the leaves
391
00:21:00,230 --> 00:21:01,320
of the tree.
392
00:21:01,320 --> 00:21:04,830
We filter that for oddness.
393
00:21:04,830 --> 00:21:06,220
We map that for squareness.
394
00:21:06,220 --> 00:21:09,320
395
00:21:09,320 --> 00:21:12,460
And we accumulate the result
of that using addition,
396
00:21:12,460 --> 00:21:14,760
starting from 0.
397
00:21:14,760 --> 00:21:17,290
So we can see the pieces
that we wanted.
398
00:21:17,290 --> 00:21:22,050
Similarly, the Fibonacci one,
how do we get the odd Fibs?
399
00:21:22,050 --> 00:21:27,900
Well, we enumerate the interval
from 1 to n, we map
400
00:21:27,900 --> 00:21:30,920
along that, computing the
Fibonacci of each one.
401
00:21:30,920 --> 00:21:34,810
We filter the result of
those for oddness.
402
00:21:34,810 --> 00:21:38,460
And we accumulate all of that
stuff using CONS starting from
403
00:21:38,460 --> 00:21:43,650
the empty-list.
404
00:21:43,650 --> 00:21:47,680
OK, what's the advantage
of this?
405
00:21:47,680 --> 00:21:50,260
Well, for one thing, we now have
pieces that we can start
406
00:21:50,260 --> 00:21:51,880
mixing and matching.
407
00:21:51,880 --> 00:21:58,230
So for instance, if I wanted to
change this, if I wanted to
408
00:21:58,230 --> 00:22:00,400
compute the squares of the
integers and then filter them,
409
00:22:00,400 --> 00:22:03,810
all I need to do is pick up a
standard piece like this in
410
00:22:03,810 --> 00:22:06,210
that square and put it in.
411
00:22:06,210 --> 00:22:10,150
Or if we wanted to do this whole
Fibonacci computation on
412
00:22:10,150 --> 00:22:12,980
the leaves of a tree rather than
a sequence, all I need to
413
00:22:12,980 --> 00:22:18,030
do is replace this enumerator
with that one.
414
00:22:18,030 --> 00:22:20,650
See, the advantage of this
stream processing is that
415
00:22:20,650 --> 00:22:21,995
we're establishing--
416
00:22:21,995 --> 00:22:25,330
this is one of the big themes
of the course--
417
00:22:25,330 --> 00:22:35,570
we're establishing conventional
interfaces that
418
00:22:35,570 --> 00:22:38,130
allow us to glue things
together.
419
00:22:38,130 --> 00:22:41,730
Things like map and filter are
a standard set of components
420
00:22:41,730 --> 00:22:43,900
that we can start using for
pasting together programs in
421
00:22:43,900 --> 00:22:45,750
all sorts of ways.
422
00:22:45,750 --> 00:22:50,090
It allows us to see the
commonality of programs.
423
00:22:50,090 --> 00:22:52,390
I just ought to mention, I've
only showed you two
424
00:22:52,390 --> 00:22:53,860
procedures.
425
00:22:53,860 --> 00:22:57,800
But let me emphasize that this
way of putting things together
426
00:22:57,800 --> 00:22:59,780
with maps, filters,
and accumulators
427
00:22:59,780 --> 00:23:01,410
is very, very general.
428
00:23:01,410 --> 00:23:08,010
It's the generate and test
paradigm for programs. And as
429
00:23:08,010 --> 00:23:11,970
an example of that, Richard
Waters, who was at MIT when he
430
00:23:11,970 --> 00:23:14,060
was a graduate student, as part
of his thesis research
431
00:23:14,060 --> 00:23:17,700
went and analyzed a large chunk
of the IBM scientific
432
00:23:17,700 --> 00:23:22,340
subroutine library, and
discovered that about 60% of
433
00:23:22,340 --> 00:23:26,830
the programs in it could be
expressed exactly in terms
434
00:23:26,830 --> 00:23:28,940
using no more than what
we've put here--
435
00:23:28,940 --> 00:23:30,710
map, filter, and accumulate.
436
00:23:30,710 --> 00:23:31,960
All right, let's take a break.
437
00:23:31,960 --> 00:23:36,620
438
00:23:36,620 --> 00:23:37,870
Questions?
439
00:23:37,870 --> 00:23:40,470
440
00:23:40,470 --> 00:23:43,033
AUDIENCE: It seems like the
essence of this whole thing is
441
00:23:43,033 --> 00:23:45,980
just that you have a very
uniform, simple data structure
442
00:23:45,980 --> 00:23:48,380
to work with, the stream.
443
00:23:48,380 --> 00:23:48,920
PROFESSOR: Right.
444
00:23:48,920 --> 00:23:51,670
The essence is that you, again,
it's this sense of
445
00:23:51,670 --> 00:23:53,710
conventional interfaces.
446
00:23:53,710 --> 00:23:55,610
So you can start putting a
lot of things together.
447
00:23:55,610 --> 00:23:59,830
And the stream is as you say,
the uniform data structure
448
00:23:59,830 --> 00:24:00,890
that supports that.
449
00:24:00,890 --> 00:24:03,600
This is very much like
APL, by the way.
450
00:24:03,600 --> 00:24:06,330
APL is very much the same idea,
except in APL, instead
451
00:24:06,330 --> 00:24:09,560
of this stream, you have
arrays and vectors.
452
00:24:09,560 --> 00:24:13,565
And a lot of the power of APL is
exactly the same reason of
453
00:24:13,565 --> 00:24:14,815
the power of this.
454
00:24:14,815 --> 00:24:19,910
455
00:24:19,910 --> 00:24:20,910
OK, thank you.
456
00:24:20,910 --> 00:24:22,160
Let's take a break.
457
00:24:22,160 --> 00:24:57,470
458
00:24:57,470 --> 00:24:57,610
All right.
459
00:24:57,610 --> 00:25:02,830
We've been looking at ways of
organizing computations using
460
00:25:02,830 --> 00:25:07,560
streams. What I want to do now
is just show you two somewhat
461
00:25:07,560 --> 00:25:10,810
more complicated examples
of that.
462
00:25:10,810 --> 00:25:15,000
Let's start by thinking about
the following kind of utility
463
00:25:15,000 --> 00:25:16,810
procedure that will
come in useful.
464
00:25:16,810 --> 00:25:19,960
Suppose I've got a stream.
465
00:25:19,960 --> 00:25:23,730
And the elements of this stream
are themselves streams.
466
00:25:23,730 --> 00:25:26,530
So the first thing
might be 1, 2, 3.
467
00:25:26,530 --> 00:25:32,600
468
00:25:32,600 --> 00:25:33,880
So I've got a stream.
469
00:25:33,880 --> 00:25:40,100
And each element of the stream
is itself a stream.
470
00:25:40,100 --> 00:25:45,580
And what I'd like to do is build
a stream that collects
471
00:25:45,580 --> 00:25:47,870
together all of the elements,
pulls all of the elements out
472
00:25:47,870 --> 00:25:50,840
of these sub-streams and
strings them all
473
00:25:50,840 --> 00:25:52,080
together in one thing.
474
00:25:52,080 --> 00:25:56,220
So just to show you the use of
this language, how easy it is,
475
00:25:56,220 --> 00:25:56,960
call that flatten.
476
00:25:56,960 --> 00:26:13,020
And I can define to flatten this
stream of streams. Well,
477
00:26:13,020 --> 00:26:13,960
what is that?
478
00:26:13,960 --> 00:26:16,240
That's just an accumulation.
479
00:26:16,240 --> 00:26:25,240
I want to accumulate
using append, by
480
00:26:25,240 --> 00:26:26,450
successively appending.
481
00:26:26,450 --> 00:26:36,590
So I accumulate using append
streams, starting with
482
00:26:36,590 --> 00:26:54,370
the-empty-stream down that
stream of streams.
483
00:26:54,370 --> 00:26:58,290
OK, so there's an example of how
you can start using these
484
00:26:58,290 --> 00:27:00,830
higher order things to do some
interesting operations.
485
00:27:00,830 --> 00:27:04,230
In fact, there's another
useful thing
486
00:27:04,230 --> 00:27:05,100
that I want to do.
487
00:27:05,100 --> 00:27:18,700
I want to define a procedure
called flat-map, flat map of
488
00:27:18,700 --> 00:27:21,840
some function and a stream.
489
00:27:21,840 --> 00:27:23,920
And what this is going
to do is f will
490
00:27:23,920 --> 00:27:25,720
be a stream of elements.
491
00:27:25,720 --> 00:27:28,930
f is going to be a function that
for each element in the
492
00:27:28,930 --> 00:27:31,950
stream produces another
stream.
493
00:27:31,950 --> 00:27:33,950
And what I want to do is take
all of the elements and all of
494
00:27:33,950 --> 00:27:36,000
those streams and combine
them together.
495
00:27:36,000 --> 00:27:51,350
So that's just going to be the
flatten of map f down s.
496
00:27:51,350 --> 00:27:54,290
Each time I apply f to an
element of s, I get a stream.
497
00:27:54,290 --> 00:27:56,690
If I map it all the way down, I
get a stream of streams, and
498
00:27:56,690 --> 00:27:58,385
I'll flatten that.
499
00:27:58,385 --> 00:28:04,670
Well, I want to use that to
show you a new way to do a
500
00:28:04,670 --> 00:28:06,360
familiar kind of problem.
501
00:28:06,360 --> 00:28:12,310
The problem's going to be like a
lot of problems you've seen,
502
00:28:12,310 --> 00:28:14,190
although maybe not this
particular one.
503
00:28:14,190 --> 00:28:15,490
I'm going to give you
an integer, n.
504
00:28:15,490 --> 00:28:18,480
505
00:28:18,480 --> 00:28:31,020
And the problem is going to be
find all pairs and integers i
506
00:28:31,020 --> 00:28:42,740
and j, between 0 and i, with j
less than i, up to n, such
507
00:28:42,740 --> 00:28:51,910
that i plus j is prime.
508
00:28:51,910 --> 00:28:55,740
509
00:28:55,740 --> 00:29:00,520
So for example, if n equals 6,
let's make a little table
510
00:29:00,520 --> 00:29:06,640
here, i and j and i plus j.
511
00:29:06,640 --> 00:29:09,700
512
00:29:09,700 --> 00:29:15,520
So for, say, i equals 2 and
j equals 1, I'd get 3.
513
00:29:15,520 --> 00:29:18,940
And for i equals 3, I could
have j equals 2, and that
514
00:29:18,940 --> 00:29:21,210
would be 5.
515
00:29:21,210 --> 00:29:28,400
And 4 and 1 would be 5 and so
on, up until i goes to 6.
516
00:29:28,400 --> 00:29:33,640
And what I'd like to return is
to produce a stream of all the
517
00:29:33,640 --> 00:29:37,350
triples like this, let's
say i, j, and i plus j.
518
00:29:37,350 --> 00:29:41,530
So for each n, I want to
generate this stream.
519
00:29:41,530 --> 00:29:43,680
OK, well, that's easy.
520
00:29:43,680 --> 00:29:47,230
Let's build it up.
521
00:29:47,230 --> 00:29:50,150
We start like this.
522
00:29:50,150 --> 00:29:55,510
We're going to say for
each i, we're going
523
00:29:55,510 --> 00:29:56,440
to generate a stream.
524
00:29:56,440 --> 00:29:58,830
For each i in the interval 1
through n, we're going to
525
00:29:58,830 --> 00:30:00,660
generate a stream.
526
00:30:00,660 --> 00:30:02,230
What's that stream
going to be?
527
00:30:02,230 --> 00:30:04,180
We're going to start by
generating all the pairs.
528
00:30:04,180 --> 00:30:11,840
So for each i, we're going to
generate, for each j in the
529
00:30:11,840 --> 00:30:19,450
interval 1 to i minus 1, we'll
generate the pair, or the list
530
00:30:19,450 --> 00:30:20,710
with two elements i and j.
531
00:30:20,710 --> 00:30:23,780
532
00:30:23,780 --> 00:30:30,712
So we map along the interval,
generating the pairs.
533
00:30:30,712 --> 00:30:33,170
And for each i, that generates
a stream of pairs.
534
00:30:33,170 --> 00:30:34,590
And we flatmap it.
535
00:30:34,590 --> 00:30:37,390
Now we have all the pairs
i and j, such that i
536
00:30:37,390 --> 00:30:38,730
is less than j.
537
00:30:38,730 --> 00:30:39,850
So that builds that.
538
00:30:39,850 --> 00:30:42,990
Now we're got to test them.
539
00:30:42,990 --> 00:30:47,160
Well, we take that thing we just
built, the flatmap, and
540
00:30:47,160 --> 00:30:50,090
we filter it to see
whether the i--
541
00:30:50,090 --> 00:30:51,660
see, we had an i and a j.
542
00:30:51,660 --> 00:30:55,180
i was the first thing in the
list, j was the second thing
543
00:30:55,180 --> 00:30:59,030
in the list. So we have a
predicate which says in that
544
00:30:59,030 --> 00:31:00,870
list of two elements
is the sum of the
545
00:31:00,870 --> 00:31:02,070
CAR and the CDR prime.
546
00:31:02,070 --> 00:31:06,540
And we filter that collection
of pairs we just built.
547
00:31:06,540 --> 00:31:09,420
So those are the
pairs we want.
548
00:31:09,420 --> 00:31:13,340
Now we go ahead and we take the
result of that filter and
549
00:31:13,340 --> 00:31:19,610
we map along it, generating the
list i and j and i plus j.
550
00:31:19,610 --> 00:31:22,910
And that's our procedure
prime-sum-pairs.
551
00:31:22,910 --> 00:31:24,480
And then just to flash it up,
here's the whole procedure.
552
00:31:24,480 --> 00:31:27,945
553
00:31:27,945 --> 00:31:30,750
A map, a filter, a flatmap.
554
00:31:30,750 --> 00:31:34,850
555
00:31:34,850 --> 00:31:36,350
There's the whole thing,
even though this isn't
556
00:31:36,350 --> 00:31:37,120
particularly readable.
557
00:31:37,120 --> 00:31:40,000
It's just expanding
that flatmap.
558
00:31:40,000 --> 00:31:45,090
So there's an example which
illustrates the general point
559
00:31:45,090 --> 00:31:49,350
that nested loops in this
procedure start looking like
560
00:31:49,350 --> 00:31:52,370
compositions of flatmaps of
flatmaps of flatmaps of maps
561
00:31:52,370 --> 00:31:54,200
and things.
562
00:31:54,200 --> 00:31:57,900
So not only can we enumerate
individual things, but by
563
00:31:57,900 --> 00:32:00,890
using flatmaps, we can do what
would correspond to nested
564
00:32:00,890 --> 00:32:03,230
loops in most other languages.
565
00:32:03,230 --> 00:32:06,870
Of course, it's pretty awful to
keep writing these flatmaps
566
00:32:06,870 --> 00:32:08,410
of flatmaps of flatmaps.
567
00:32:08,410 --> 00:32:13,830
Prime-sum-pairs you saw looked
fairly complicated, even
568
00:32:13,830 --> 00:32:15,480
though the individual
pieces were easy.
569
00:32:15,480 --> 00:32:17,800
So what you can do, if you
like, is introduced some
570
00:32:17,800 --> 00:32:21,040
syntactic sugar that's
called collect.
571
00:32:21,040 --> 00:32:23,570
And collect is just an
abbreviation for that nest of
572
00:32:23,570 --> 00:32:26,160
flatmaps and filters arranged
in that particular way.
573
00:32:26,160 --> 00:32:29,620
Here's prime-sum-pairs again,
written using collect.
574
00:32:29,620 --> 00:32:32,670
It says to find all those pairs,
I'm going to collect
575
00:32:32,670 --> 00:32:40,910
together a result, which is the
list i, j, and i plus j,
576
00:32:40,910 --> 00:32:44,510
that's going to be generated as
i runs through the interval
577
00:32:44,510 --> 00:32:51,440
from 1 to n and as j runs
through the interval from 1 to
578
00:32:51,440 --> 00:32:58,040
i minus 1, such that
i plus j is prime.
579
00:32:58,040 --> 00:33:00,690
So I'm not going to say what
collect does in general.
580
00:33:00,690 --> 00:33:03,420
You can look at that by looking
at it in the book.
581
00:33:03,420 --> 00:33:06,010
But pretty much, you can see
that the pieces of this are
582
00:33:06,010 --> 00:33:08,820
the pieces of that original
procedure I wrote.
583
00:33:08,820 --> 00:33:11,550
And this collect is just some
syntactic sugar for
584
00:33:11,550 --> 00:33:16,310
automatically generating that
nest of flatmaps and flatmaps.
585
00:33:16,310 --> 00:33:21,120
OK, well, let me do one more
example that shows you the
586
00:33:21,120 --> 00:33:22,120
same kind of thing.
587
00:33:22,120 --> 00:33:25,740
Here's a very famous problem
that's used to illustrate a
588
00:33:25,740 --> 00:33:28,980
lot of so-called backtracking
computer algorithms. This is
589
00:33:28,980 --> 00:33:30,200
the eight queens problem.
590
00:33:30,200 --> 00:33:32,370
This is a chess board.
591
00:33:32,370 --> 00:33:34,570
And the eight queens problem
says, find a way to put down
592
00:33:34,570 --> 00:33:37,660
eight queens on a chess board
so that no two are attacking
593
00:33:37,660 --> 00:33:38,000
each other.
594
00:33:38,000 --> 00:33:39,685
And here's a particular
solution to the
595
00:33:39,685 --> 00:33:41,430
eight queens problem.
596
00:33:41,430 --> 00:33:44,450
So I have to make sure to put
down queens so that no two are
597
00:33:44,450 --> 00:33:48,570
in the same row or the
same column or sit
598
00:33:48,570 --> 00:33:51,410
along the same diagonal.
599
00:33:51,410 --> 00:33:56,400
Now, there's sort of a standard
way of doing that.
600
00:33:56,400 --> 00:33:59,740
601
00:33:59,740 --> 00:34:03,200
Well, first we need
to do is below the
602
00:34:03,200 --> 00:34:04,940
surface, at George's level.
603
00:34:04,940 --> 00:34:07,340
We have to find some way to
represent a board, and
604
00:34:07,340 --> 00:34:08,095
represent positions.
605
00:34:08,095 --> 00:34:09,800
And we'll not worry
about that.
606
00:34:09,800 --> 00:34:12,540
But let's assume that there's
a predicate called safe.
607
00:34:12,540 --> 00:34:16,040
608
00:34:16,040 --> 00:34:19,090
And what safe is going to do is
going to say given that I
609
00:34:19,090 --> 00:34:22,520
have a bunch of queens down on
the chess board, is it OK to
610
00:34:22,520 --> 00:34:25,400
put a queen in this
particular spot?
611
00:34:25,400 --> 00:34:32,889
So safe is going to take
a row and a column.
612
00:34:32,889 --> 00:34:34,510
That's going to be a place where
I'm going to try and put
613
00:34:34,510 --> 00:34:42,370
down the next queen, and
the rest of positions.
614
00:34:42,370 --> 00:34:45,420
615
00:34:45,420 --> 00:34:48,679
And what safe will say is given
that I already have
616
00:34:48,679 --> 00:34:53,920
queens down in these positions,
is it safe to put
617
00:34:53,920 --> 00:34:58,300
another queen down in that
row and that column?
618
00:34:58,300 --> 00:34:59,360
And let's not worry
about that.
619
00:34:59,360 --> 00:35:01,380
That's George's problem. and
it's not hard to write.
620
00:35:01,380 --> 00:35:06,350
You just have to check whether
this thing contains any things
621
00:35:06,350 --> 00:35:10,530
on that row or that column
or in that diagonal.
622
00:35:10,530 --> 00:35:13,590
Now, how would you organize
the program given that?
623
00:35:13,590 --> 00:35:18,010
And there's sort of a
traditional way to organize it
624
00:35:18,010 --> 00:35:20,116
called backtracking.
625
00:35:20,116 --> 00:35:27,570
And it says, well, let's think
about all the ways of putting
626
00:35:27,570 --> 00:35:31,290
the first queen down in
the first column.
627
00:35:31,290 --> 00:35:32,580
There are eight ways.
628
00:35:32,580 --> 00:35:35,880
Well, let's say try
the first column.
629
00:35:35,880 --> 00:35:37,300
Try column 1, row 1.
630
00:35:37,300 --> 00:35:41,300
These branches are going to
represent the possibilities at
631
00:35:41,300 --> 00:35:43,360
each level.
632
00:35:43,360 --> 00:35:45,875
So I'll try and put a queen
down in the first column.
633
00:35:45,875 --> 00:35:48,360
And now given that it's in the
first column, I'll try and put
634
00:35:48,360 --> 00:35:49,980
the next queen down in
the first column.
635
00:35:49,980 --> 00:35:53,035
636
00:35:53,035 --> 00:35:55,470
I'll try and put the first
queen, the one in the first
637
00:35:55,470 --> 00:35:56,920
column, down in the first row.
638
00:35:56,920 --> 00:35:59,050
I'm sorry.
639
00:35:59,050 --> 00:36:00,780
And then given that, we'll
put the next queen down
640
00:36:00,780 --> 00:36:01,390
in the first row.
641
00:36:01,390 --> 00:36:02,090
And that's no good.
642
00:36:02,090 --> 00:36:04,200
So I'll back up to here.
643
00:36:04,200 --> 00:36:06,280
And I'll say, oh, can I put the
first queen down in the
644
00:36:06,280 --> 00:36:07,510
second row?
645
00:36:07,510 --> 00:36:08,550
Well, that's no good.
646
00:36:08,550 --> 00:36:09,760
Oh, can I put it down
in the third row?
647
00:36:09,760 --> 00:36:12,790
Well, that's good.
648
00:36:12,790 --> 00:36:14,290
Well, now can I put the
next queen down
649
00:36:14,290 --> 00:36:15,380
in the first column?
650
00:36:15,380 --> 00:36:18,030
Well, I can't visualize this
chess board anymore, but I
651
00:36:18,030 --> 00:36:19,195
think that's right.
652
00:36:19,195 --> 00:36:20,450
And I try the next one.
653
00:36:20,450 --> 00:36:24,170
And at each place, I go as far
down this tree as I can.
654
00:36:24,170 --> 00:36:25,640
And I back up.
655
00:36:25,640 --> 00:36:28,970
If I get down to here and find
no possibilities below there,
656
00:36:28,970 --> 00:36:31,740
I back all the way up to here,
and now start again generating
657
00:36:31,740 --> 00:36:33,260
this sub-tree.
658
00:36:33,260 --> 00:36:35,050
And I sort of walk around.
659
00:36:35,050 --> 00:36:37,870
And finally, if I ever manage to
get all the way down, I've
660
00:36:37,870 --> 00:36:40,090
found a solution.
661
00:36:40,090 --> 00:36:45,020
So that's a typical sort of
paradigm that's used a lot in
662
00:36:45,020 --> 00:36:45,930
AI programming.
663
00:36:45,930 --> 00:36:47,300
It's called backtracking
search.
664
00:36:47,300 --> 00:36:57,470
665
00:36:57,470 --> 00:37:03,860
And it's really unnecessary.
666
00:37:03,860 --> 00:37:06,550
You saw me get confused when I
was visualizing this thing.
667
00:37:06,550 --> 00:37:08,550
And you see the complication.
668
00:37:08,550 --> 00:37:10,760
This is a complicated
thing to say.
669
00:37:10,760 --> 00:37:12,390
Why is it complicated?
670
00:37:12,390 --> 00:37:16,190
Its because somehow this program
is too inordinately
671
00:37:16,190 --> 00:37:18,580
concerned with time.
672
00:37:18,580 --> 00:37:19,200
It's too much--
673
00:37:19,200 --> 00:37:21,670
I try this one, and I try this
one, and I go back to the last
674
00:37:21,670 --> 00:37:22,320
possibility.
675
00:37:22,320 --> 00:37:24,340
And that's a complicated
thing.
676
00:37:24,340 --> 00:37:28,590
If I stop worrying about time
so much, then there's a much
677
00:37:28,590 --> 00:37:31,200
simpler way to describe this.
678
00:37:31,200 --> 00:37:40,320
It says, let's imagine that I
have in my hands the tree down
679
00:37:40,320 --> 00:37:43,400
to k minus 1 levels.
680
00:37:43,400 --> 00:37:50,670
See, suppose I had in my hands
all possible ways to put down
681
00:37:50,670 --> 00:37:53,560
queens in the first k columns.
682
00:37:53,560 --> 00:37:54,610
Suppose I just had that.
683
00:37:54,610 --> 00:37:57,070
Let's not worry about
how we get it.
684
00:37:57,070 --> 00:37:59,200
Well, then, how do
I extend that?
685
00:37:59,200 --> 00:38:01,420
How do I find all possible ways
to put down queens in the
686
00:38:01,420 --> 00:38:02,480
next column?
687
00:38:02,480 --> 00:38:03,620
It's really easy.
688
00:38:03,620 --> 00:38:12,210
For each of these positions I
have, I think about putting
689
00:38:12,210 --> 00:38:16,160
down a queen in each row
to make the next thing.
690
00:38:16,160 --> 00:38:18,930
And then for each one I put
down, I filter those by the
691
00:38:18,930 --> 00:38:22,080
ones that are safe.
692
00:38:22,080 --> 00:38:24,190
So instead of thinking about
this tree as generated step by
693
00:38:24,190 --> 00:38:26,860
step, suppose I had
it all there.
694
00:38:26,860 --> 00:38:29,680
695
00:38:29,680 --> 00:38:32,990
And to extend it from level k
minus 1 to level k, I just
696
00:38:32,990 --> 00:38:36,840
need to extend each thing in
all possible ways and only
697
00:38:36,840 --> 00:38:37,800
keep the ones that are safe.
698
00:38:37,800 --> 00:38:39,300
And that will give me
the tree to level k.
699
00:38:39,300 --> 00:38:41,675
And that's a recursive strategy
for solving the eight
700
00:38:41,675 --> 00:38:44,530
queens problem.
701
00:38:44,530 --> 00:38:45,780
All right, well, let's
look at it.
702
00:38:45,780 --> 00:38:50,280
703
00:38:50,280 --> 00:38:54,360
To solve the eight queens
problem on a board of some
704
00:38:54,360 --> 00:39:00,390
specified size, we write
a sub-procedure called
705
00:39:00,390 --> 00:39:01,030
fill-columns.
706
00:39:01,030 --> 00:39:04,050
Fill-columns is going to
put down queens up
707
00:39:04,050 --> 00:39:06,086
through column k.
708
00:39:06,086 --> 00:39:07,700
And here's the pattern
of the recursion.
709
00:39:07,700 --> 00:39:12,990
I'm going to call fill-columns
with the size eventually.
710
00:39:12,990 --> 00:39:15,630
So fill-columns says how to put
down queens safely in the
711
00:39:15,630 --> 00:39:19,255
first k columns of this chess
board with a size number of
712
00:39:19,255 --> 00:39:20,360
rows in it.
713
00:39:20,360 --> 00:39:22,946
If k is equal to 0, well,
then I don't have to
714
00:39:22,946 --> 00:39:23,940
put anything down.
715
00:39:23,940 --> 00:39:26,710
So my solution is just
an empty chess board.
716
00:39:26,710 --> 00:39:28,070
Otherwise, I'm going
to do some stuff.
717
00:39:28,070 --> 00:39:30,522
And I'm going to use collect.
718
00:39:30,522 --> 00:39:31,772
And here's the collect.
719
00:39:31,772 --> 00:39:34,530
720
00:39:34,530 --> 00:39:40,590
I find all ways to put
down queens in the
721
00:39:40,590 --> 00:39:41,910
first k minus 1 columns.
722
00:39:41,910 --> 00:39:43,320
And this was just
what I set for.
723
00:39:43,320 --> 00:39:48,880
Imagine I have this tree down
to k minus 1 levels.
724
00:39:48,880 --> 00:39:53,230
And then I find all ways of
trying a row, that's just each
725
00:39:53,230 --> 00:39:54,130
of the possible rows.
726
00:39:54,130 --> 00:39:58,040
They're size rows, so that's
enumerate interval.
727
00:39:58,040 --> 00:40:03,950
And now what I do is I collect
together the new row I'm going
728
00:40:03,950 --> 00:40:08,950
to try and column k with
the rest of the queens.
729
00:40:08,950 --> 00:40:10,200
I adjoin a position.
730
00:40:10,200 --> 00:40:11,290
This is George's problem.
731
00:40:11,290 --> 00:40:13,640
An adjoined position
is like safe.
732
00:40:13,640 --> 00:40:16,530
It's a thing that takes a row
and a column and the rest of
733
00:40:16,530 --> 00:40:19,660
the positions and makes a
new position collection.
734
00:40:19,660 --> 00:40:26,230
So I adjoin a position of a new
row and a new column to
735
00:40:26,230 --> 00:40:30,310
the rest of the queens, where
the rest of the queens runs
736
00:40:30,310 --> 00:40:32,870
through all possible ways
of solving the problem
737
00:40:32,870 --> 00:40:34,620
in k minus 1 columns.
738
00:40:34,620 --> 00:40:39,730
And the new row runs through all
possible rows such that it
739
00:40:39,730 --> 00:40:43,240
was safe to put one there.
740
00:40:43,240 --> 00:40:46,500
And that's the whole program.
741
00:40:46,500 --> 00:40:49,840
There's the whole procedure.
742
00:40:49,840 --> 00:40:51,990
Not only that, that doesn't just
solve the eight queens
743
00:40:51,990 --> 00:40:56,010
problem, it gives you
all solutions to the
744
00:40:56,010 --> 00:40:56,680
eight queens problem.
745
00:40:56,680 --> 00:40:58,480
When you're done, you
have a stream.
746
00:40:58,480 --> 00:41:00,650
And the elements of that stream
are all possible ways
747
00:41:00,650 --> 00:41:01,900
of solving that problem.
748
00:41:01,900 --> 00:41:05,310
749
00:41:05,310 --> 00:41:06,260
Why is that simpler?
750
00:41:06,260 --> 00:41:10,170
Well, we threw away the whole
idea that this is some process
751
00:41:10,170 --> 00:41:12,720
that happens in time
with state.
752
00:41:12,720 --> 00:41:14,420
And we just said it's a whole
collection of stuff.
753
00:41:14,420 --> 00:41:18,260
And that's why it's simpler.
754
00:41:18,260 --> 00:41:20,110
We've changed our view.
755
00:41:20,110 --> 00:41:22,820
Remember, that's where
we started today.
756
00:41:22,820 --> 00:41:26,230
We've changed our view of what
it is we're trying to model.
757
00:41:26,230 --> 00:41:30,570
we stop modeling things that
evolve in time and have steps
758
00:41:30,570 --> 00:41:31,750
and have state.
759
00:41:31,750 --> 00:41:33,990
And instead, we're trying to
model this global thing like
760
00:41:33,990 --> 00:41:37,950
the whole flight of the
chalk, rather than its
761
00:41:37,950 --> 00:41:40,750
state at each instant.
762
00:41:40,750 --> 00:41:42,000
Any questions?
763
00:41:42,000 --> 00:41:43,810
764
00:41:43,810 --> 00:41:46,190
AUDIENCE: It looks to me like
backtracking would be
765
00:41:46,190 --> 00:41:49,970
searching for the first solution
it can find, whereas
766
00:41:49,970 --> 00:41:54,030
this recursive search would be
looking for all solutions.
767
00:41:54,030 --> 00:41:58,090
And it seems that if you have a
large enough area to search,
768
00:41:58,090 --> 00:42:01,360
that the second is going
to become impossible.
769
00:42:01,360 --> 00:42:07,610
PROFESSOR: OK, the answer to
that question is the whole
770
00:42:07,610 --> 00:42:08,570
rest of this lecture.
771
00:42:08,570 --> 00:42:10,540
It's exactly the
right question.
772
00:42:10,540 --> 00:42:13,522
773
00:42:13,522 --> 00:42:15,540
And without trying to anticipate
the lecture too
774
00:42:15,540 --> 00:42:19,910
much, you should start being
suspicious at this point, and
775
00:42:19,910 --> 00:42:22,220
exactly those kinds
of suspicions.
776
00:42:22,220 --> 00:42:24,830
It's wonderful, but isn't it
so terribly inefficient?
777
00:42:24,830 --> 00:42:28,100
That's where we're going.
778
00:42:28,100 --> 00:42:30,020
So I won't answer now, but
I'll answer later.
779
00:42:30,020 --> 00:42:33,350
780
00:42:33,350 --> 00:42:34,600
OK, let's take a break.
781
00:42:34,600 --> 00:43:29,650
782
00:43:29,650 --> 00:43:35,600
Well, by now you should be
starting to get suspicious.
783
00:43:35,600 --> 00:43:41,450
See, I've showed your this
simple, elegant way of putting
784
00:43:41,450 --> 00:43:46,440
programs together, very unlike
these other traditional
785
00:43:46,440 --> 00:43:50,490
programs that sum the odd
squares or compute the odd
786
00:43:50,490 --> 00:43:53,740
Fibonacci numbers.
787
00:43:53,740 --> 00:43:57,080
Very unlike these programs that
mix up the enumerator and
788
00:43:57,080 --> 00:44:00,440
the filter and the
accumulator.
789
00:44:00,440 --> 00:44:04,770
And by mixing it up, we don't
have all of these wonderful
790
00:44:04,770 --> 00:44:07,990
conceptual advantages of these
streams pieces, these
791
00:44:07,990 --> 00:44:09,840
wonderful mix and match
components for putting
792
00:44:09,840 --> 00:44:13,800
together lots and lots
of programs.
793
00:44:13,800 --> 00:44:15,810
On the other hand, most of the
programs you've seen look like
794
00:44:15,810 --> 00:44:18,340
these ugly ones.
795
00:44:18,340 --> 00:44:19,460
Why's that?
796
00:44:19,460 --> 00:44:23,705
Can it possibly be that computer
scientists are so
797
00:44:23,705 --> 00:44:28,370
obtuse that they don't notice
that if you'd merely did this
798
00:44:28,370 --> 00:44:33,620
thing, then you can get this
great programming elegance?
799
00:44:33,620 --> 00:44:36,760
There's got to be a catch.
800
00:44:36,760 --> 00:44:39,510
And it's actually pretty easy
to see what the catch is.
801
00:44:39,510 --> 00:44:42,030
Let's think about the
following problem.
802
00:44:42,030 --> 00:44:47,510
Suppose I tell you to find the
second prime between 10,000
803
00:44:47,510 --> 00:44:51,020
and 1 million, or if your
computer's larger, say between
804
00:44:51,020 --> 00:44:54,105
10,000 and 100 billion,
or something.
805
00:44:54,105 --> 00:44:55,550
And you say, oh, that's easy.
806
00:44:55,550 --> 00:44:57,080
I can do that with a stream.
807
00:44:57,080 --> 00:45:01,530
All I do is I enumerate
the interval
808
00:45:01,530 --> 00:45:04,160
from 10,000 to 1 million.
809
00:45:04,160 --> 00:45:06,800
So I get all those integers
from 10,000 to 1 million.
810
00:45:06,800 --> 00:45:10,520
I filter them for prime-ness, so
test all of them and see if
811
00:45:10,520 --> 00:45:11,762
they're prime.
812
00:45:11,762 --> 00:45:13,170
And I take the second element.
813
00:45:13,170 --> 00:45:16,130
That's the head of the tail.
814
00:45:16,130 --> 00:45:17,380
Well, that's clearly
pretty ridiculous.
815
00:45:17,380 --> 00:45:21,660
816
00:45:21,660 --> 00:45:24,620
We'd not even have room in the
machine to store the integers
817
00:45:24,620 --> 00:45:27,040
in the first place, much
less to test them.
818
00:45:27,040 --> 00:45:29,810
And then I only want
the second one.
819
00:45:29,810 --> 00:45:36,500
See, the power of this
traditional programming style
820
00:45:36,500 --> 00:45:39,860
is exactly its weakness, that
we're mixing up the
821
00:45:39,860 --> 00:45:45,090
enumerating and the testing
and the accumulating.
822
00:45:45,090 --> 00:45:46,670
So we don't do it all.
823
00:45:46,670 --> 00:45:52,580
So the very thing that makes
it conceptually ugly is the
824
00:45:52,580 --> 00:45:55,210
very thing that makes
it efficient.
825
00:45:55,210 --> 00:45:57,800
It's this mixing up.
826
00:45:57,800 --> 00:45:59,840
So it seems that all I've done
this morning so far is just
827
00:45:59,840 --> 00:46:00,420
confuse you.
828
00:46:00,420 --> 00:46:02,930
I showed you this wonderful
way that programming might
829
00:46:02,930 --> 00:46:05,840
work, except that it doesn't.
830
00:46:05,840 --> 00:46:09,040
Well, here's where the wonderful
thing happens.
831
00:46:09,040 --> 00:46:13,210
It turns out in this game that
we really can have our cake
832
00:46:13,210 --> 00:46:14,870
and eat it too.
833
00:46:14,870 --> 00:46:20,280
And what I mean by that is
that we really can write
834
00:46:20,280 --> 00:46:24,210
stream programs exactly like the
ones I wrote and arrange
835
00:46:24,210 --> 00:46:28,830
things so that when the machine
actually runs, it's as
836
00:46:28,830 --> 00:46:31,690
efficient as running this
traditional programming style
837
00:46:31,690 --> 00:46:36,310
that mixes up the generation
and the test.
838
00:46:36,310 --> 00:46:40,770
Well, that sounds
pretty magic.
839
00:46:40,770 --> 00:46:43,690
The key to this is that
streams are not lists.
840
00:46:43,690 --> 00:46:48,090
841
00:46:48,090 --> 00:46:50,070
We'll see this carefully in a
second, but for now, let's
842
00:46:50,070 --> 00:46:52,115
take a look at that
slide again.
843
00:46:52,115 --> 00:46:55,060
The image you should have here
of this signal processing
844
00:46:55,060 --> 00:47:00,940
system is that what's going to
happen is there's this box
845
00:47:00,940 --> 00:47:05,360
that has the integers
sitting in it.
846
00:47:05,360 --> 00:47:08,680
And there's this filter that's
connected to it and it's
847
00:47:08,680 --> 00:47:10,940
tugging on them.
848
00:47:10,940 --> 00:47:13,680
And then there's someone who's
tugging on this stuff saying
849
00:47:13,680 --> 00:47:16,790
what comes out of the filter.
850
00:47:16,790 --> 00:47:19,630
And the image you should have
is that someone says, well,
851
00:47:19,630 --> 00:47:24,590
what's the first prime, and
tugs on this filter.
852
00:47:24,590 --> 00:47:28,020
And the filter tugs
on the integers.
853
00:47:28,020 --> 00:47:29,830
And you look only at that much,
and then say, oh, I
854
00:47:29,830 --> 00:47:30,930
really wanted the second one.
855
00:47:30,930 --> 00:47:33,710
What's the second prime?
856
00:47:33,710 --> 00:47:37,730
And that no computation gets
done except when you tug on
857
00:47:37,730 --> 00:47:40,500
these things.
858
00:47:40,500 --> 00:47:41,410
Let me try that again.
859
00:47:41,410 --> 00:47:43,815
This is a little device.
860
00:47:43,815 --> 00:47:46,400
This is a little stream machine
invented by Eric
861
00:47:46,400 --> 00:47:49,830
Grimson who's been teaching
this course at MIT.
862
00:47:49,830 --> 00:47:52,940
And the image is here's a stream
of stuff, like a whole
863
00:47:52,940 --> 00:47:54,780
bunch of the integers.
864
00:47:54,780 --> 00:47:58,700
And here's some processing
elements.
865
00:47:58,700 --> 00:48:02,600
And if, say, it's filter of
filter of map, or something.
866
00:48:02,600 --> 00:48:05,570
867
00:48:05,570 --> 00:48:08,760
And if I really tried to
implement that with streams as
868
00:48:08,760 --> 00:48:11,520
lists, what I'd say is, well,
I've got this list of things,
869
00:48:11,520 --> 00:48:12,670
and now I do the first filter.
870
00:48:12,670 --> 00:48:14,070
So do all this processing.
871
00:48:14,070 --> 00:48:18,570
And I take this and I process
and I process and I process
872
00:48:18,570 --> 00:48:19,610
and I process.
873
00:48:19,610 --> 00:48:21,910
And now I'm got this
new stream.
874
00:48:21,910 --> 00:48:24,070
Now I take that result
in my hand someplace.
875
00:48:24,070 --> 00:48:25,260
And I put that through
the second one.
876
00:48:25,260 --> 00:48:28,110
And I process the whole thing.
877
00:48:28,110 --> 00:48:29,510
And there's this new stream.
878
00:48:29,510 --> 00:48:32,130
879
00:48:32,130 --> 00:48:35,230
And then I take the result and
I put it all the way through
880
00:48:35,230 --> 00:48:36,360
this one the same way.
881
00:48:36,360 --> 00:48:41,760
That's what would happen to
these stream programs if
882
00:48:41,760 --> 00:48:43,860
streams were just lists.
883
00:48:43,860 --> 00:48:46,065
But in fact, streams aren't
lists, they're streams. And
884
00:48:46,065 --> 00:48:47,240
the image you should have
is something a little
885
00:48:47,240 --> 00:48:50,230
bit more like this.
886
00:48:50,230 --> 00:48:55,880
I've got these gadgets connected
up by this data
887
00:48:55,880 --> 00:48:57,130
that's flowing out of them.
888
00:48:57,130 --> 00:48:59,960
889
00:48:59,960 --> 00:49:04,190
And here's my original source
of the streams. It might be
890
00:49:04,190 --> 00:49:05,980
starting to generate
the integers.
891
00:49:05,980 --> 00:49:07,580
And now, what happens
if I want a result?
892
00:49:07,580 --> 00:49:10,200
I tug on the end here.
893
00:49:10,200 --> 00:49:13,090
And this element says, gee,
I need some more data.
894
00:49:13,090 --> 00:49:15,830
So this one comes here
and tugs on that one.
895
00:49:15,830 --> 00:49:17,890
And it says, gee, I need
some more data.
896
00:49:17,890 --> 00:49:19,960
And this one tugs on this
thing, which might be a
897
00:49:19,960 --> 00:49:21,640
filter, and says, gee, I
need some more data.
898
00:49:21,640 --> 00:49:24,755
And only as much of this thing
at the end here gets generated
899
00:49:24,755 --> 00:49:25,780
as I tugged.
900
00:49:25,780 --> 00:49:28,030
And only as much of this stuff
goes through the processing
901
00:49:28,030 --> 00:49:30,760
units as I'm pulling
on the end I need.
902
00:49:30,760 --> 00:49:33,720
That's the image you should have
of the difference between
903
00:49:33,720 --> 00:49:36,580
implementing what we're actually
going to do and if
904
00:49:36,580 --> 00:49:37,830
streams were lists.
905
00:49:37,830 --> 00:49:40,600
906
00:49:40,600 --> 00:49:42,430
Well, how do we make
this thing?
907
00:49:42,430 --> 00:49:43,400
I hope you have the image.
908
00:49:43,400 --> 00:49:44,947
The trick is how to make it.
909
00:49:44,947 --> 00:49:47,930
910
00:49:47,930 --> 00:49:52,080
We want to arrange for a stream
to be a data structure
911
00:49:52,080 --> 00:49:55,670
that computes itself
incrementally, an on-demand
912
00:49:55,670 --> 00:49:56,920
data structure.
913
00:49:56,920 --> 00:49:59,220
914
00:49:59,220 --> 00:50:02,700
And the basic idea is, again,
one of the very basic ideas
915
00:50:02,700 --> 00:50:04,490
that we're seeing throughout
the whole course.
916
00:50:04,490 --> 00:50:07,440
And that is that there's not
a firm distinction between
917
00:50:07,440 --> 00:50:09,240
programs and data.
918
00:50:09,240 --> 00:50:12,260
So what a stream is going to be
is simultaneously this data
919
00:50:12,260 --> 00:50:15,270
structure that you think of,
like the stream of the leaves
920
00:50:15,270 --> 00:50:16,810
of this tree.
921
00:50:16,810 --> 00:50:18,880
But at the same time, it's
going to be a very clever
922
00:50:18,880 --> 00:50:23,550
procedure that has the method
of computing in it.
923
00:50:23,550 --> 00:50:25,930
Well, let me try this.
924
00:50:25,930 --> 00:50:28,460
It's going to turn out that we
don't need any more mechanism.
925
00:50:28,460 --> 00:50:31,150
We already have everything we
need simply from the fact that
926
00:50:31,150 --> 00:50:32,770
we know how to handle
procedures
927
00:50:32,770 --> 00:50:35,460
as first-class objects.
928
00:50:35,460 --> 00:50:36,880
Well, let's go back
to the key.
929
00:50:36,880 --> 00:50:39,030
The key is, remember, we
had these operations.
930
00:50:39,030 --> 00:50:48,080
CONS-stream and head and tail.
931
00:50:48,080 --> 00:50:51,580
When I started, I said you can
think about this as CONS and
932
00:50:51,580 --> 00:50:53,340
think about this as CAR and
think about that as
933
00:50:53,340 --> 00:50:55,080
CDR, but it's not.
934
00:50:55,080 --> 00:50:57,550
Now, let's look at what
they really are.
935
00:50:57,550 --> 00:51:09,360
Well, CONS-stream of x and y is
going to be an abbreviation
936
00:51:09,360 --> 00:51:19,540
for the following thing.
937
00:51:19,540 --> 00:51:24,470
CONS form a pair, ordinary CONS,
of x to a thing called
938
00:51:24,470 --> 00:51:28,000
delay of y.
939
00:51:28,000 --> 00:51:31,188
940
00:51:31,188 --> 00:51:34,670
And before I explain that, let
me go and write the rest. The
941
00:51:34,670 --> 00:51:39,790
head of a stream is going
to be just the CAR.
942
00:51:39,790 --> 00:51:42,380
943
00:51:42,380 --> 00:51:47,610
And the tail of a stream is
going to be a thing called
944
00:51:47,610 --> 00:51:56,120
force the CDR of the stream.
945
00:51:56,120 --> 00:51:58,060
Now let me explain this.
946
00:51:58,060 --> 00:52:01,420
Delay is going to be a
special magic thing.
947
00:52:01,420 --> 00:52:06,240
What delay does is take an
expression and produce a
948
00:52:06,240 --> 00:52:08,380
promise to compute
that expression
949
00:52:08,380 --> 00:52:10,600
when you ask for it.
950
00:52:10,600 --> 00:52:11,980
It doesn't do any computation
here.
951
00:52:11,980 --> 00:52:14,820
It just gives you
a rain check.
952
00:52:14,820 --> 00:52:17,110
It produces a promise.
953
00:52:17,110 --> 00:52:23,280
And CONS-stream says I'm going
to put together in a pair x
954
00:52:23,280 --> 00:52:25,360
and a promise to compute y.
955
00:52:25,360 --> 00:52:28,230
956
00:52:28,230 --> 00:52:30,200
Now, if I want the head, that's
just the CAR that I put
957
00:52:30,200 --> 00:52:31,840
in the pair.
958
00:52:31,840 --> 00:52:34,350
And the key is that the
tail is going to be--
959
00:52:34,350 --> 00:52:39,110
force calls in that promise.
960
00:52:39,110 --> 00:52:43,690
Tail says, well, take
that promise and now
961
00:52:43,690 --> 00:52:44,610
call in that promise.
962
00:52:44,610 --> 00:52:47,430
And then we compute
that thing.
963
00:52:47,430 --> 00:52:48,740
That's how this is
going to work.
964
00:52:48,740 --> 00:52:51,550
That's what CONS-stream, head,
and tail really are.
965
00:52:51,550 --> 00:52:54,196
966
00:52:54,196 --> 00:52:55,570
Now, let's see how this works.
967
00:52:55,570 --> 00:52:58,410
And we'll go through this
fairly carefully.
968
00:52:58,410 --> 00:53:01,990
We're going to see how this
works in this example of
969
00:53:01,990 --> 00:53:08,650
computing the second prime
between 10,000 and a million.
970
00:53:08,650 --> 00:53:11,610
OK, so we start off and we
have this expression.
971
00:53:11,610 --> 00:53:15,820
972
00:53:15,820 --> 00:53:20,380
The second prime-- the head of
the tail of the result of
973
00:53:20,380 --> 00:53:24,060
filtering for primality
the integers between
974
00:53:24,060 --> 00:53:26,710
10,000 and 1 million.
975
00:53:26,710 --> 00:53:28,400
Now, what is that?
976
00:53:28,400 --> 00:53:35,790
What that is, that interval
between 10,000 and 1 million,
977
00:53:35,790 --> 00:53:37,480
well, if you trace through
enumerate interval, there
978
00:53:37,480 --> 00:53:40,250
builds a CONS-stream.
979
00:53:40,250 --> 00:53:45,880
And the CONS-stream is the CONS
of 10,000 to a promise to
980
00:53:45,880 --> 00:53:54,480
compute the integers between
10,001 and 1 million.
981
00:53:54,480 --> 00:53:55,750
So that's what this
expression is.
982
00:53:55,750 --> 00:53:57,640
Here I'm using the substitution
model.
983
00:53:57,640 --> 00:53:59,690
And we can use the substitution
model because we
984
00:53:59,690 --> 00:54:01,010
don't have side effects
and state.
985
00:54:01,010 --> 00:54:04,270
986
00:54:04,270 --> 00:54:07,860
So I have CONS of 10,000 to a
promise to compute the rest of
987
00:54:07,860 --> 00:54:08,380
the integers.
988
00:54:08,380 --> 00:54:09,850
So only one integer, so
far, got enumerated.
989
00:54:09,850 --> 00:54:14,380
990
00:54:14,380 --> 00:54:16,580
Well, I'm going to filter that
thing for primality.
991
00:54:16,580 --> 00:54:19,900
992
00:54:19,900 --> 00:54:22,360
Again, you go back and look
at the filter code.
993
00:54:22,360 --> 00:54:25,460
What the filter will first
do is test the head.
994
00:54:25,460 --> 00:54:31,580
So in this case, the filter will
test 10,000 and say, oh,
995
00:54:31,580 --> 00:54:33,500
10,000's not prime.
996
00:54:33,500 --> 00:54:36,260
Therefore, what I have
to do recursively
997
00:54:36,260 --> 00:54:39,220
is filter the tail.
998
00:54:39,220 --> 00:54:42,550
And what's the tail of it, well,
that's the tail of this
999
00:54:42,550 --> 00:54:46,340
pair with a promise in it.
1000
00:54:46,340 --> 00:54:49,680
Tail now comes in and says,
well, I'm going to force that.
1001
00:54:49,680 --> 00:54:53,790
I'm going to force that promise,
which means now I'm
1002
00:54:53,790 --> 00:55:00,880
going to compute the integers
between 10,001 and 1 million.
1003
00:55:00,880 --> 00:55:02,970
OK, so this filter now
is looking at that.
1004
00:55:02,970 --> 00:55:07,810
1005
00:55:07,810 --> 00:55:10,100
That enumerate itself, well, now
we're back in the original
1006
00:55:10,100 --> 00:55:11,960
enumerate situation.
1007
00:55:11,960 --> 00:55:16,920
The enumerate is the CONS of the
first thing, 10,001, onto
1008
00:55:16,920 --> 00:55:19,740
a promise to compute the rest.
1009
00:55:19,740 --> 00:55:23,060
So now the primality filter is
going to go look at 10,001.
1010
00:55:23,060 --> 00:55:25,120
It's going to decide if
it likes that or not.
1011
00:55:25,120 --> 00:55:27,550
It turns out 10,001
isn't prime.
1012
00:55:27,550 --> 00:55:29,610
So it'll force it again
and again and again.
1013
00:55:29,610 --> 00:55:32,920
1014
00:55:32,920 --> 00:55:37,100
And finally, I think the first
prime it hits is 10,009.
1015
00:55:37,100 --> 00:55:40,465
And at that point, it'll stop.
1016
00:55:40,465 --> 00:55:42,500
And that will be the first
prime, and then eventually,
1017
00:55:42,500 --> 00:55:45,240
it'll need the second prime.
1018
00:55:45,240 --> 00:55:47,030
So at that point, it
will go again.
1019
00:55:47,030 --> 00:55:51,880
So you see what happens is that
no more gets generated
1020
00:55:51,880 --> 00:55:53,130
than you actually need.
1021
00:55:53,130 --> 00:55:56,690
1022
00:55:56,690 --> 00:56:00,060
That enumerator is not going to
generate any more integers
1023
00:56:00,060 --> 00:56:02,410
than the filter asks it for as
it's pulling in things to
1024
00:56:02,410 --> 00:56:04,930
check for primality.
1025
00:56:04,930 --> 00:56:07,290
And the filter is not going to
generate any more stuff than
1026
00:56:07,290 --> 00:56:11,255
you ask it for, which is
the head of the tail.
1027
00:56:11,255 --> 00:56:17,180
You see, what's happened is
we've put that mixing of
1028
00:56:17,180 --> 00:56:20,130
generation and test into what
actually happens in the
1029
00:56:20,130 --> 00:56:24,250
computer, even though that's
not apparently what's
1030
00:56:24,250 --> 00:56:28,160
happening from looking
at our programs.
1031
00:56:28,160 --> 00:56:30,230
OK, well, that seemed easy.
1032
00:56:30,230 --> 00:56:33,326
All of this mechanism got put
into this magic delay.
1033
00:56:33,326 --> 00:56:36,900
So you're saying, gee, that must
be where the magic is.
1034
00:56:36,900 --> 00:56:39,070
But see there's no magic
there either.
1035
00:56:39,070 --> 00:56:40,610
You know what delay is.
1036
00:56:40,610 --> 00:56:50,040
Delay on some expression is
just an abbreviation for--
1037
00:56:50,040 --> 00:56:53,400
1038
00:56:53,400 --> 00:56:56,490
well, what's a promise to
compute an expression?
1039
00:56:56,490 --> 00:57:00,700
Lambda of nil, procedure of no
arguments, which is that
1040
00:57:00,700 --> 00:57:03,000
expression.
1041
00:57:03,000 --> 00:57:03,930
That's what a procedure is.
1042
00:57:03,930 --> 00:57:06,050
It says I'm going to compute
an expression.
1043
00:57:06,050 --> 00:57:07,460
What's force?
1044
00:57:07,460 --> 00:57:10,800
How do I take up a promise?
1045
00:57:10,800 --> 00:57:15,890
Well, force of some procedure,
a promise, is just run it.
1046
00:57:15,890 --> 00:57:18,710
1047
00:57:18,710 --> 00:57:20,120
Done.
1048
00:57:20,120 --> 00:57:23,580
So there's no magic
there at all.
1049
00:57:23,580 --> 00:57:26,440
Well, what have we done?
1050
00:57:26,440 --> 00:57:29,510
We said the old style,
traditional style of
1051
00:57:29,510 --> 00:57:30,960
programming is more efficient.
1052
00:57:30,960 --> 00:57:35,260
And the stream thing is
more perspicuous.
1053
00:57:35,260 --> 00:57:40,070
And we managed to make the
stream procedures run like the
1054
00:57:40,070 --> 00:57:43,350
other procedures
by using delay.
1055
00:57:43,350 --> 00:57:46,880
And the thing that delay did
for us was to de-couple the
1056
00:57:46,880 --> 00:57:52,150
apparent order of events in our
programs from the actual
1057
00:57:52,150 --> 00:57:54,440
order of events that happened
in the machine.
1058
00:57:54,440 --> 00:57:56,540
That's really what
delay is doing.
1059
00:57:56,540 --> 00:57:58,290
That's exactly the
whole point.
1060
00:57:58,290 --> 00:58:04,720
We've given up the idea that our
procedures, as they run,
1061
00:58:04,720 --> 00:58:09,182
or as we look at them, mirror
some clear notion of time.
1062
00:58:09,182 --> 00:58:12,960
And by giving that up, we give
delay the freedom to arrange
1063
00:58:12,960 --> 00:58:16,690
the order of events in the
computation the way it likes.
1064
00:58:16,690 --> 00:58:17,610
That's the whole idea.
1065
00:58:17,610 --> 00:58:20,640
We de-couple the apparent
order of events in our
1066
00:58:20,640 --> 00:58:24,200
programs from the actual order
of events in the computer.
1067
00:58:24,200 --> 00:58:25,770
OK, well there's one
more detail.
1068
00:58:25,770 --> 00:58:27,750
It's just a technical detail,
but it's actually
1069
00:58:27,750 --> 00:58:29,730
an important one.
1070
00:58:29,730 --> 00:58:32,190
As you run through these
recursive programs unwinding,
1071
00:58:32,190 --> 00:58:35,360
you'll see a lot of things that
look like tail of the
1072
00:58:35,360 --> 00:58:39,320
tail of the tail.
1073
00:58:39,320 --> 00:58:41,840
That's the kind of thing that
would happen as I go CONSing
1074
00:58:41,840 --> 00:58:43,860
down a stream all the way.
1075
00:58:43,860 --> 00:58:47,170
And if each time I'm doing that,
each time to compute a
1076
00:58:47,170 --> 00:58:51,830
tail, I evaluate a procedure
which then has to go
1077
00:58:51,830 --> 00:58:54,270
re-compute its tail, and
re-compute its tail and
1078
00:58:54,270 --> 00:58:56,380
recompute its tail each time,
you can see that's very
1079
00:58:56,380 --> 00:58:59,610
inefficient compared to just
having a list where the
1080
00:58:59,610 --> 00:59:02,510
elements are all there, and I
don't have to re-compute each
1081
00:59:02,510 --> 00:59:05,290
tail every time I get
the next tail.
1082
00:59:05,290 --> 00:59:15,030
So there's one little hack to
slightly change what delay is,
1083
00:59:15,030 --> 00:59:17,380
and make it a thing which is--
1084
00:59:17,380 --> 00:59:20,390
I'll write it this way.
1085
00:59:20,390 --> 00:59:27,360
The actual implementation, delay
is an abbreviation for
1086
00:59:27,360 --> 00:59:31,000
this thing, memo-proc
of a procedure.
1087
00:59:31,000 --> 00:59:35,150
Memo-proc is a special thing
that transforms a procedure.
1088
00:59:35,150 --> 00:59:39,250
What it does is it takes a
procedure of no arguments and
1089
00:59:39,250 --> 00:59:42,190
it transforms it into a
procedure that'll only have to
1090
00:59:42,190 --> 00:59:44,806
do its computation once.
1091
00:59:44,806 --> 00:59:48,700
And what I mean by that is,
you give it a procedure.
1092
00:59:48,700 --> 00:59:51,950
The result of memo-proc will be
a new procedure, which the
1093
00:59:51,950 --> 00:59:55,370
first time you call it, will
run the original procedure,
1094
00:59:55,370 --> 01:00:00,040
remember what result it got, and
then from ever on after,
1095
01:00:00,040 --> 01:00:01,610
when you call it, it just
won't have to do the
1096
01:00:01,610 --> 01:00:02,360
computation.
1097
01:00:02,360 --> 01:00:05,200
It will have cached that
result someplace.
1098
01:00:05,200 --> 01:00:06,550
And here's an implementation
of memo-proc.
1099
01:00:06,550 --> 01:00:11,210
1100
01:00:11,210 --> 01:00:12,710
Once you have the idea, it's
easy to implement.
1101
01:00:12,710 --> 01:00:15,830
Memo-proc is this little
thing that has two
1102
01:00:15,830 --> 01:00:17,390
little flags in there.
1103
01:00:17,390 --> 01:00:20,320
It says, have I already
been run?
1104
01:00:20,320 --> 01:00:23,620
And initially it says, no, I
haven't already been run.
1105
01:00:23,620 --> 01:00:29,070
And what was the result I got
the last time I was run?
1106
01:00:29,070 --> 01:00:32,200
So memo-proc takes a procedure
called proc, and it returns a
1107
01:00:32,200 --> 01:00:34,360
new procedure of no arguments.
1108
01:00:34,360 --> 01:00:38,610
Proc is supposed to be a
procedure of no arguments.
1109
01:00:38,610 --> 01:00:42,970
And it says, oh, if I'm not
already run, then I'm going to
1110
01:00:42,970 --> 01:00:44,430
do a sequence of things.
1111
01:00:44,430 --> 01:00:48,450
I'm going to compute proc,
I'm going to save that.
1112
01:00:48,450 --> 01:00:51,140
I'm going to stash that in
the variable result.
1113
01:00:51,140 --> 01:00:53,510
I'm going to make a note to
myself that I've already been
1114
01:00:53,510 --> 01:00:56,610
run, and then I'll return
the result.
1115
01:00:56,610 --> 01:00:59,010
So that's if you compute it
if it's not already run.
1116
01:00:59,010 --> 01:01:01,040
If you call it and it's already
been run, it just
1117
01:01:01,040 --> 01:01:03,420
returns the result.
1118
01:01:03,420 --> 01:01:08,400
So that's a little clever
hack called memoization.
1119
01:01:08,400 --> 01:01:12,100
And in this case, it short
circuits having to re-compute
1120
01:01:12,100 --> 01:01:15,270
the tail of the tail of the tail
of the tail of the tail.
1121
01:01:15,270 --> 01:01:17,810
So there isn't even that
kind of inefficiency.
1122
01:01:17,810 --> 01:01:20,590
And in fact, the streams will
run with pretty much the same
1123
01:01:20,590 --> 01:01:24,210
efficiency as the other
programs precisely.
1124
01:01:24,210 --> 01:01:28,110
And remember, again, the whole
idea of this is that we've
1125
01:01:28,110 --> 01:01:32,390
used the fact that there's no
really good dividing line
1126
01:01:32,390 --> 01:01:33,610
between procedures and data.
1127
01:01:33,610 --> 01:01:36,510
We've written data structures
that, in fact, are sort of
1128
01:01:36,510 --> 01:01:38,760
like procedures.
1129
01:01:38,760 --> 01:01:45,280
And what that's allowed us to
do is take an example of a
1130
01:01:45,280 --> 01:01:49,620
common control structure,
in this place iteration.
1131
01:01:49,620 --> 01:01:52,460
And we've built a data structure
which, since itself
1132
01:01:52,460 --> 01:01:54,530
is a procedure, kind of has
this iteration control
1133
01:01:54,530 --> 01:01:55,496
structure in it.
1134
01:01:55,496 --> 01:01:58,650
And that's really what
streams are.
1135
01:01:58,650 --> 01:01:59,900
OK, questions?
1136
01:01:59,900 --> 01:02:03,950
1137
01:02:03,950 --> 01:02:06,110
AUDIENCE: Your description
of tail-tail-tail, if I
1138
01:02:06,110 --> 01:02:10,050
understand it correctly, force
is actually execution of a
1139
01:02:10,050 --> 01:02:13,052
procedure, if it's done without
this memo-proc thing.
1140
01:02:13,052 --> 01:02:16,380
And you implied that memo-proc
gets around that problem.
1141
01:02:16,380 --> 01:02:20,580
Doesn't it only get around it
if tail-tail-tail is always
1142
01:02:20,580 --> 01:02:22,550
executing exactly the same--
1143
01:02:22,550 --> 01:02:23,500
PROFESSOR: Oh, that's--
1144
01:02:23,500 --> 01:02:23,910
sure.
1145
01:02:23,910 --> 01:02:26,050
AUDIENCE: I guess I
missed that point.
1146
01:02:26,050 --> 01:02:26,540
PROFESSOR: Oh, sure.
1147
01:02:26,540 --> 01:02:27,790
I mean the point is--
1148
01:02:27,790 --> 01:02:31,160
1149
01:02:31,160 --> 01:02:31,290
yeah.
1150
01:02:31,290 --> 01:02:34,160
I mean I have to do a
computation to get the answer.
1151
01:02:34,160 --> 01:02:37,590
But the point is, once I've
found the tail of the stream,
1152
01:02:37,590 --> 01:02:39,530
to get the tail of the tail,
I shouldn't have had to
1153
01:02:39,530 --> 01:02:42,980
re-compute the first tail.
1154
01:02:42,980 --> 01:02:45,370
See, and if I didn't use
memo-proc, that re-computation
1155
01:02:45,370 --> 01:02:46,460
would have been done.
1156
01:02:46,460 --> 01:02:47,710
AUDIENCE: I understand now.
1157
01:02:47,710 --> 01:02:50,830
1158
01:02:50,830 --> 01:02:52,550
AUDIENCE: In one of your
examples, you mentioned that
1159
01:02:52,550 --> 01:02:55,010
we were able to use the
substitution model because
1160
01:02:55,010 --> 01:02:56,830
there are no side effects.
1161
01:02:56,830 --> 01:03:01,040
What if we had a single
processing unit--
1162
01:03:01,040 --> 01:03:03,620
if we had a side effect,
if we had a state?
1163
01:03:03,620 --> 01:03:09,120
Could we still practically
build the stream model?
1164
01:03:09,120 --> 01:03:09,530
PROFESSOR: Maybe.
1165
01:03:09,530 --> 01:03:10,540
That's a hard question.
1166
01:03:10,540 --> 01:03:15,540
I'm going to talk a little bit
later about the places where
1167
01:03:15,540 --> 01:03:18,960
substitution and side effects
don't really mix very well.
1168
01:03:18,960 --> 01:03:21,170
But in general, I think the
answer is unless you're very
1169
01:03:21,170 --> 01:03:23,920
careful, any amount of side
effect is going to mess up
1170
01:03:23,920 --> 01:03:25,170
everything.
1171
01:03:25,170 --> 01:03:35,490
1172
01:03:35,490 --> 01:03:36,150
AUDIENCE: Sorry, I didn't
quite understand
1173
01:03:36,150 --> 01:03:39,410
the memo-proc operation.
1174
01:03:39,410 --> 01:03:41,990
When do you execute
the lambda?
1175
01:03:41,990 --> 01:03:46,270
In other words, when memo-proc
is executed, just this lambda
1176
01:03:46,270 --> 01:03:47,600
expression is being generated.
1177
01:03:47,600 --> 01:03:50,390
But it's not clear to me
when it's executed.
1178
01:03:50,390 --> 01:03:51,350
PROFESSOR: Right.
1179
01:03:51,350 --> 01:03:53,890
What memo-proc does-- remember,
the thing that's
1180
01:03:53,890 --> 01:03:57,290
going into memo-proc, the thing
proc, is a procedure of
1181
01:03:57,290 --> 01:03:57,930
no arguments.
1182
01:03:57,930 --> 01:04:00,390
And someday, you're
going to call it.
1183
01:04:00,390 --> 01:04:03,350
Memo-proc translates that
procedure into another
1184
01:04:03,350 --> 01:04:05,110
procedure of no arguments,
which someday
1185
01:04:05,110 --> 01:04:06,620
you're going to call.
1186
01:04:06,620 --> 01:04:09,890
That's that lambda.
1187
01:04:09,890 --> 01:04:17,370
So here, where I initially
built as my tail of the
1188
01:04:17,370 --> 01:04:20,680
stream, say, this procedure
of no arguments, which
1189
01:04:20,680 --> 01:04:24,100
someday I'll call.
1190
01:04:24,100 --> 01:04:27,130
Instead, I'm going to have
the tail of the stream be
1191
01:04:27,130 --> 01:04:30,650
memo-proc of it, which
someday I'll call.
1192
01:04:30,650 --> 01:04:35,340
So that lambda of nil, that gets
called when you call the
1193
01:04:35,340 --> 01:04:40,990
memo-proc, when you call the
result of that memo-proc,
1194
01:04:40,990 --> 01:04:44,400
which would be ordinarily when
you would have called the
1195
01:04:44,400 --> 01:04:47,642
original thing that
you set it.
1196
01:04:47,642 --> 01:04:49,690
AUDIENCE: OK, the reason I ask
is I had a feeling that when
1197
01:04:49,690 --> 01:04:52,610
you call memo-proc, you just
return this lambda.
1198
01:04:52,610 --> 01:04:53,770
PROFESSOR: That's right.
1199
01:04:53,770 --> 01:04:58,100
When you call memo-proc,
you return the lambda.
1200
01:04:58,100 --> 01:05:00,090
You never evaluate the
expression at all, until the
1201
01:05:00,090 --> 01:05:02,270
first time that you would
have evaluated it.
1202
01:05:02,270 --> 01:05:07,590
1203
01:05:07,590 --> 01:05:10,000
AUDIENCE: Do I understand it
right that you actually have
1204
01:05:10,000 --> 01:05:12,980
to build the list up, but
the elements of the
1205
01:05:12,980 --> 01:05:14,240
list don't get evaluated?
1206
01:05:14,240 --> 01:05:15,630
The expressions don't
get evaluated?
1207
01:05:15,630 --> 01:05:18,540
But at each stage, you actually
are building a list.
1208
01:05:18,540 --> 01:05:19,750
PROFESSOR: That's--
1209
01:05:19,750 --> 01:05:20,700
I really should have
said this.
1210
01:05:20,700 --> 01:05:22,270
That's a really good point.
1211
01:05:22,270 --> 01:05:23,660
No, it's not quite right.
1212
01:05:23,660 --> 01:05:25,080
Because what happens is this.
1213
01:05:25,080 --> 01:05:26,890
Let me draw this as pairs.
1214
01:05:26,890 --> 01:05:29,710
Suppose I'm going to make a
big stream, like enumerate
1215
01:05:29,710 --> 01:05:32,740
interval, 1 through 1 billion.
1216
01:05:32,740 --> 01:05:43,045
What that is, is a pair with
a 1 and a promise.
1217
01:05:43,045 --> 01:05:46,520
1218
01:05:46,520 --> 01:05:47,890
That's exactly what it is.
1219
01:05:47,890 --> 01:05:49,140
Nothing got built up.
1220
01:05:49,140 --> 01:05:51,600
1221
01:05:51,600 --> 01:05:56,370
When I go and force this,
and say, what happens?
1222
01:05:56,370 --> 01:06:00,530
Well, this thing is now also
recursively a CONS.
1223
01:06:00,530 --> 01:06:07,770
So that this promise now is the
next thing, which is a 2
1224
01:06:07,770 --> 01:06:11,350
and a promise to do more.
1225
01:06:11,350 --> 01:06:14,470
And so on and so on and so on.
1226
01:06:14,470 --> 01:06:18,200
So nothing gets built up until
you walk down the stream.
1227
01:06:18,200 --> 01:06:20,790
Because what's sitting here is
not the list, but a promise to
1228
01:06:20,790 --> 01:06:24,250
generate the list.
And by promise,
1229
01:06:24,250 --> 01:06:25,500
technically I mean procedure.
1230
01:06:25,500 --> 01:06:28,050
1231
01:06:28,050 --> 01:06:30,485
So it doesn't get built up.
1232
01:06:30,485 --> 01:06:34,280
Yeah, I should have said
that before this point.
1233
01:06:34,280 --> 01:06:34,490
OK.
1234
01:06:34,490 --> 01:06:34,790
Thank you.
1235
01:06:34,790 --> 01:06:36,340
Let's take a break.
1236
01:06:36,340 --> 01:06:55,828
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Ruby
1
https://gitee.com/jacklisp/Learning-SICP.git
git@gitee.com:jacklisp/Learning-SICP.git
jacklisp
Learning-SICP
Learning-SICP
master

搜索帮助