#lang plai ;; YESTERDAY ;; - The Web is programming without an automatic stack ;; - A stack is control + data ;; TODAY ;; - Closures are control + data [0:07] ;; -- convert add-two-numbers.com [0:14] ;; - add-many-numbers.exe [0:25] ;; - add-many-numbers.com [0:35] ;; -- remove closures [0:40] ;; - What is Web style? ;; -- order of evalaution & sequential ;; -- global ;; -- no-closures [0:50] ;; CONSOLE (define (prompt text) (displayln text) (read)) (define (add-two-numbers.exe) (displayln (+ (prompt "First number:") (prompt "Second number:")))) ;; WEB (define (web-prompt text whose-next more) (web-displayln text whose-next more)) (define (web-displayln text whose-next more) (printf "\n~a\n" whose-next more text) (whose-next (read) more) (error 'http "I'm stateless")) (define (add-two-numbers.com) (web-prompt "First number:" add-two-numbers.com/first.cgi #f)) (define (add-two-numbers.com/first.cgi first-number junk) (web-prompt "Second number:" add-two-numbers.com/second.cgi first-number)) (define (add-two-numbers.com/second.cgi second-number first-number) (web-displayln (+ first-number second-number) void #f)) ;;(add-two-numbers.com) ;; WEB w/ closures (define (web-prompt/clo text clo) (web-displayln/clo text clo)) (define (web-displayln/clo text clo) (printf "\n~a\n" clo text) (clo (read)) (error 'http "I'm stateless")) (define (add-two-numbers.com/clo) (web-prompt/clo "First number:" (λ (first-number) (web-prompt/clo "Second number:" (λ (second-number) (web-displayln/clo (+ first-number second-number) void)))))) ;; (add-two-numbers.com/clo) ;; (... wants ans ... (f arg ...)) ;; -> ;; (f/clo arg ... (λ (ans) ... wants ans ...)) ;; -> cgi -> ;; "lambda lifting" ;; take a lambda and add arguments as you go out of the program (define (sum l) (foldr + 0 l)) (define (build-list n f) (cond [(zero? n) empty] [else (define the-rest (build-list (sub1 n) f)) (cons (f n) the-rest)])) (define (add-many-numbers.exe) (define how-many (prompt "How many numbers?")) (displayln (format "Your ~a numbers sum to ~a" how-many (sum (build-list how-many (λ (i) (prompt (format "~ath number?" i)))))))) ;; (add-many-numbers.exe) (define (web-build-list/clo n web-f/clo clo) (cond [(zero? n) (clo empty)] [else (web-build-list/clo (sub1 n) web-f/clo (λ (the-rest) ;; (f arg ...) -> (f/clo arg ... (λ (ans) ...)) (web-f/clo n (λ (the-first) (clo (cons the-first the-rest))))))])) (define (add-many-numbers.com/clo) (web-prompt/clo "How many numbers?" (λ (how-many) (web-build-list/clo how-many (λ (i clo) (web-prompt/clo (format "~ath number?" i) clo)) (λ (the-numbers) (web-displayln/clo (format "Your ~a numbers sum to ~a" how-many (sum the-numbers)) void)))))) ;; (add-many-numbers.com/clo) (define (web-build-list n web-f next next-data) (cond [(zero? n) (next empty next-data)] [else (web-build-list (sub1 n) web-f web-build-list.com/got-rest.cgi (list web-f n next next-data))])) (define (web-build-list.com/got-rest.cgi the-rest data) (match-define (list web-f n next next-data) data) (web-f n web-build-list.com/got-one.cgi (list next next-data the-rest))) (define (web-build-list.com/got-one.cgi the-first data) (match-define (list next next-data the-rest) data) (next (cons the-first the-rest) next-data)) (define (add-many-numbers.com) (web-prompt "How many numbers?" add-many-numbers.com/got-how-many.cgi #f)) (define (add-many-numbers.com/got-how-many.cgi how-many junk) (web-build-list how-many add-many-numbers.com/get-one.cgi add-many-numbers.com/caught-em-all.cgi how-many)) (define (add-many-numbers.com/caught-em-all.cgi the-numbers how-many) (web-displayln (format "Your ~a numbers sum to ~a" how-many (sum the-numbers)) void #f)) (define (add-many-numbers.com/get-one.cgi i next next-data) (web-prompt (format "~ath number?" i) next next-data)) (add-many-numbers.com)