#+TITLE: Structure and Interpretation of Computer Programs #+AUTHOR: Lio Novelli * Foreword and Preface #+begin_quote Lisp je preživeli, v uporabi je že "polovico stoletja". #+end_quote #+begin_quote The discretionary exportable functionality entrusted to the individual Lisp programmer is more than an order of magniture greater than that to be found within Pascal enterprises. #+end_quote #+begin_quote Želimo vzpostaviti idejo, da programski jezik ni samo način, da računalnik izvaja operacije, ampak da je predvsem nov formalni medij za izražanje idej o metodologiji. Zato morajo biti programi napisani predvsem zato, da jih ljudje berejo, in slučajno, da jih izvajajo računalniki. Bistvena tema ni sintaksa določenih struktur v programskem jeziku, niti ..., temveč tehnike nadzora intelektualne kompleksnosti veliki programskih sistemov. #+end_quote #+begin_quote Naš pristop k temi izvira iz prepričanja, da "computer science" ni znanost in da ima njen pomen bolj malo opraviti z računalniki. Računalniška revolucija je revolucija v načinu mišljenja in izražanju idej. Bistvo teh sprememb najbolše opiše pojem _proceduralne epistemologije_, ki se ukvarja s strukturo vednosti z imperativnega stališča za razliko od klasične matematike, ki je bolj deklerativna. Matematika postavi okvir za natančno spoprijemanje s pojmovanjem "kaj je". Računanje pa ponudi okvir za natančno ukvarjanje s pojmovanjem "kako". #+end_quote * 1. Grajenje abstrakcij s procedurami ** Elementi programiranja - Primitivni izrazi :: predstavtljajo najpreprostejše gradnike (entitete) programskega jezika - Načini kombinacije, :: s katerimi so sestavljeni elementi zgrajeni iz preprostejših - Načini abstrakcije, :: s katerimi so lahko sestavljeni elementi poimenovani in omogočajo upravljanje z njimii kot enotami ** Izvajanje kombinacij(e) Postopek za izvajanje kombinacij: 1. Izvedi podizraz kombinacije. 2. Uporabi/uveljavi proceduro, ki je najbolje levi podizraz (operator) z argumenti, ki so vrednosti drugih podizrazov (operandi). Postopek evalvacije je rekurziven, saj drugi korak v sebi vključuje prvega, oziroma vključuje svojo definicijo. Tako se zgradi akumulacijsko drevo. Na koncu vedno prideš do točke, ko izvajaš primitivne izraze, ki so: - vrednosti numeričnih števk, ki jo označujejo. - vrednosti vgrajenih operatorjev so strojni ukazi sekvenc, ki izvedejo te operacije. - vrednosti drugih imen so objekti asociirani s temi imeni v okolju. Drugo pravilo je poseben primer tretjega pravila. Simboli + in * so tudi vključeni v globalno okolje in so asociirani s strojnimi ukazi, ki so njihove vrednosti. *Pomembno je prepoznati vlogo okolja pri določanju pomena simbolov v izrazih.* To pravilo se ne nanaša na _posebne oblike (special forms)_. ~define~ je posebna oblika. ** 1.1.4 Sestavljene procedure - Številke in aritmetične operacije so primitivni podatki in procedure. - Gnezdenje kombinacij omogoča način za združevanje operacij. - Definicije, ki asociirajo imena z vrednostmi omogočajo omejene načine abstrakcije. ~(define (square x) (* x x))~ ~(define square (lambda (x) (* x x)))~ ** 1.1.5 Substitucijski model za izvajanje procedur Za izvajanje sestavljenih procedur z argumenti, izvedeš telo procedure z vsakim formalnim parametrom, ki ga nadomestiš s pripadajočim argumentom. _ergh, tukaj se zapletam s slovenskimi prevodi_ _kaj je application in kaj evaluation?_ Načini, na katere deluje interpreter (prevajalnik): - Aplikativni vrstni red :: Najprej evalviraj operator in operande, potem pa izvedi proizvedeno proceduro s pridobljenimi argumenti. - Normalni vrstni red :: Ne izvajaj operandov dokler njihove vrednost niso potrebne. Najprej zamenjaj izraze operandov s parametri, dokler ne pride do izraza, ki vsebuje zgolj primitivne izraze in potem izvedi (vso) evalvacijo. ** meta Linki: https://develop.spacemacs.org/layers/+lang/scheme/README.html https://www.nongnu.org/geiser/ https://www.gnu.org/software/guile/learn/ https://spritely.institute/static/papers/scheme-primer.html#introduction Kako nastavit spacemacs, in malo o guile-u. *** video lekcije https://yewtu.be/channel/UCEBb1b_L6zDS3xTUrIALZOw (6.001 SICP: Structure and Interpretation of Computer Programs (2004)) https://yewtu.be/playlist?list=PL7BcsI5ueSNFPCEisbaoQ0kXIDX9rR5FF (MIT 6.001 Structure and Interpretation, 1986) ** vaje *** 1.3 **** najprej narobe Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers. #+begin_src scheme (define (sum-of-large x y z) (+ (if (> x y) (* x x) (* y y)) (if (> y z) (* y y) (* z z)) ) ) (sum-of-large 3 8 5) #+end_src #+RESULTS: : 128 #+begin_src scheme (define (sum-of-larger x y z) (let* ((s (lambda (a) (* a a))) (sl (lambda (b c) (if (> b c) (s b) (s c)))) ) (+ (sl x y) (sl y z)) )) (sum-of-larger 3 8 5) #+end_src #+RESULTS: : 128 **** pravilno #+begin_src scheme (define (sum-squares-of-larger x y z) (if (> x y) (if (> y z) (+ (* x x) (* y y)) (+ (* x x) (* z z)) ) (if (> x z) (+ (* y y) (* x x)) (+ (* y y) (* z z)) ) ) ) (sum-squares-of-larger 9 10 8) #+end_src #+RESULTS: : 181 *** 1.5 Aplikativni vrstni red: pade takoj v neskoncno zanko. Normalni vrstni red: izvrsi test in pride v if, ki ne izvrsi drugega dela. *** 1.6 [[file:sqrt-newton.scm][sqrt-newton.scm]] *** 1.7 - ~good-enough?~ ni vredu za iskanje korenov majhnih stevil. - pravtako za zelo velika stevila - napisi alternativno ~good-enough?~ proceduro, ki bo gledala, kdaj so spremembe dovolj majhne in takrat prekini funkcijo. // Poglej v sqrt-newton.scm *** 1.8 // Glej v sqrt-newton.sqm ** 1.1.8 Procedure kot crne skatle abstrakcij - block structure - lexical scoping