;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname lect29) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) #| = How many syntaxes to write a function, in Java? = advantages and disadvantages of functional (immutable) -- memory usage; = fields vs methods (?) = pondering our own syntax What is the syntax for *calling* a function ... - in racket: -> ( ... ) Examples: (+ 2 3) (add1 pi) (sqrt 16) (expt 2 (+ pi 7)) ( ... pi) assigning: (set! x (+ 2 3)) (set-alien-x! obj (+ 2 3)) - in Java: . ( ) OP new ( ) () e.g. (int) 3.4 [ ] e.g. data[4] . e.g. someObj.someField Things that aren't function-calls (but kinda look like it in racket): (if expressions ... `.. ? .. : ..`) assigning to a variable x = 2+3; assigning to a field obj.x = 2+3; (loops) Separately: In BlueJ code-pad: 2+3 (no semicolon allowed) "hi"+"bye" System.out.println(2+3); } AncTree.main(null); } (semicolon required) int n = 2; } BUT: Math.sqrt(3) } n = 3 } (either way!) "hi".concat("bye") } |# #| What are advantages and dis-advantages of functional programming? (immutable data, no globals) - Rather than mutating a field, we copy the entire struct (old objects are garbage collected). This requires extra cpu time, and memory. (How much extra memory? Up to 2x (but not more). Often much less than 2x more, due to sharing.) + Since every function's result depends ONLY on its inputs (no globals, and no other function can mutate our fields) programs are MUCH easier to reason about (debug). ...A.K.A.: any bug can be discovered by unit-tests. - Since every function's result depends ONLY on its inputs, you can't have one section of code set a global variable/state used by another function far away. [Advocates of func.programming feel that the previous point strongly outweighs this one. Also, note that it's not always all-or-nothing: the less data is mutable, the more simplicity accrues, but you don't have to be functional everywhere. ...Except if using Haskell, or in this course.] + When a compilers knows certain values won't mutate, it can make better optimizations. + Safe to use multiple cores (no worrying about cache coherency) + FP happens to, somehow, encourage writing smaller more focused functions. |# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (my-add1 n) (+ n 1)) ; => is syntactic sugar for => #;(define my-add1 (lambda (n) (+ n 1)) ) (my-add1 16) ( (lambda (n) (+ n 1)) 16) ; make-adder : number -> (number -> number) (define (make-adder k) (lambda (n) (+ n k))) (define my-add2 (make-adder 2)) (map (make-adder 7) (list 100 101 102 103)) (((((( if (((2))) is0 then 4 else 7; plus if 3 is0 then if 0 is0 then 0 else 0; else 7 ))))))