Lalish-Menagh, Trevor on 18 Nov 2011 10:06:36 -0800


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: functional fall -- notes on Mccarthy/Lisp


Dustin, your notes are awesome.

Yours,
Trevor

On Fri, Nov 18, 2011 at 10:14 AM, Dustin Getz <dustin.getz@gmail.com> wrote:
> Mashion-Mike also had notes which I haven't seen yet, I do intend to merge
> them with these and clean them up into a blog post or something, when I find
> time. Wanted to get these out asap.
>
>
> ff notes -- 11/16/11 -- Recursive Functions of Symbolic Expressions and
> Their Computation by Machine, Part I
> http://www-formal.stanford.edu/jmc/recursive.pdf
> moderator: mike b
> introduction
> punch line to the paper - top p2 -- "next we describe s-expr and
> s-finctions, describe universal fn apply"
> s-expressions, is the entirety of the syntax for lisp, and m-expressions,
> which are syntax for function application, and we discuss how to transform
> between s- and m-. we discuss the apply function, which turns out to be a
> lisp interpreter. apply can be implemented in a few thousand lines of
> assembly, and that was the original lisp. note that he didn't write this
> then do lisp, he wrote lisp, then he reduced that to this paper. of course,
> he probably made a grad student actually implement lisp ;)
> narrative of this paper -- starting with the math, taking just far enough to
> get the math into something executable. McCarthy's goal is to say, hey we
> actually implemented this. we can do stuff with this language.
> notice that we take for granted all the things that exist now. p7. note,
> this is describing like the second high level language ever invented.
> mccarthy takes us just far enough -- which is why lisp purists may be
> uncomfortble with clojure, because clojure is adding impure things, native
> types. [ed: pretend we were a lisp purist, why would we believe that?]
> section 2: strictly define a function
> these are mathemeticians -- to us, fn is something in a program, but this is
> a formal definition of functions. the point of this section is to be strict
> aboutwhat a function is, and the notation for a function. a function is
> defined over part of a domain (talked about in lambda calculus -- in fact,
> lisp is almost the same -- basically an impl of lambda calc, with minor
> extensions, such as named labels for recursion). order of operations IS
> defined (just like in math), but its the order at which the parameters are
> bound, which lambda notation lets us define, to be explicit/consistent with
> our substutitions (thanks dan mead). lambda notation expresses explicitly
> how the args are substituted. matters when you have bound variables vs free
> variables. "unambiguous treatment of functions of functions" p7 this is just
> a statement meaning, how to keep your bound variables straight. ad-hoc form
> notation ( f = x^2+y ) doesn't achieve this explicit parameter binding. this
> is one difference between an algebraic expression, and a lambda calculus
> expression.
> `predicate` is a fn whose range is T/F. means always returns either true or
> false. a boolean fn. you see these a lot in higher order fns in lisp. Q:
> what is a higher order fn? A: a function that takes a fn as an argument, or
> returns a fn. FIlter is the quintessential example of a predicate.
> List filter(List collection, Fn predicate)
> conditional expression -- we provide an interesting notation for
> conditionals, mike compares to lisp's `cond` -- looks like P implies E (P ->
> E) means go from left to right, evaluate them in order. if P1 then E1, else
> if P2 then E2, else if P3, then E3, ... else: undefined. its exactly the
> same as in math, and evaluated like if/elseif/else in imperative languages.
> evaluation of Propositions (the conditional) in order, and when we find a
> true proposition, evaluate his Expression (and only his expression, no other
> expressions).
> in math:
> |x| = (x<0 -> -x, True-> x)
> True-> as the last element, means "else if TRUE then return x". note, T
> means True.
> in python:
> def abs(x):
> Â Âif x<0: return -x
> Â Âelif True: return x
> is else being undefined important? in a procedural language, else doesn't
> necessarily have a value. confsion about else -- have to say "else if TRUE
> then blah" -- its an else if -- the else, is not defined. you have to define
> it as else if true. [ed: so else is not even really a necessarily concept.
> just say 'else if T' to define it, and else is always undefined]. undefined
> means, in the math sense e.g. div-by-zero, not in the undefined behavior
> sense in C which means the program may or may not crash or have
> unpredictable side effects.
> see recursive factorial definition in the paper. Divergence about
> y-combinators, which are a very tricky function in lambda calculus that
> allows a function to self-recurse without naming the function. It works
> because effectively, the y-combinator makes a copy of the function to
> evaluate later. mike: y combinator is cool, but it is of no practical use as
> a programming construct. labeling things buys you so much in simplicity of
> understanding. Turns out that Curry discovered/defined y-combinator, Church
> didn't realize it was necessary (cite?). y-combinator was added to
> lambda-calc after the fact.
> p8 -- lambad contexts, always clear the context a variable is bound in --
> mcc. never goes into this with labels. maybe this is just relevant to the
> implementation of this stuff, not relevant to the formalism. dan says "but
> label is a real function in lisp"
> remember, lambda-calculus is important because it gives us vigour in
> reasoning and proving the behavior of a program. as discussed in prior
> weeks, you can't prove a program with iteration, because there's no formal
> calculus dscription of iteration. We can formalize recursion, so we
> implement iteration in terms of recursion. NB: asm has only goto, no
> recursion, no iteration. [ed: but asm doesn't have a theoretical math
> foundation, its based on machine implementation details]
> We extend lambda calculus with "label notation" such we can easily define
> recursion. McCarthy (and we) feel lambda notation is "inadequate" or
> "unweildy" to define recursion without naming the functions. too impractical
> to reason about. y combinatro needs a macro for practical usage. so mccarthy
> invents this label construct.
> seciton 3: s-expressions
> class of symbolic expressions, ordered pairs and lists. define 5 elementary
> functions, which can compose into anything? to build anything.
> note, the label stuff, was pure math, it wasn't an s-expression.
> definition of an s-expression, p9 middle.
> s-expr is a rigorous application of logic (thanks Hunter(Texas)). lisp is an
> impl of lambda calc (almost), lambda calc is an application of math.
> function, is an algebraic function.
> mccarthy introduces shorthand, so we don't have to do this dotted notation
> of nested tree of pairs. note, its synonymous. syntactic sugar. its a series
> of dotted pairs. note, its a recursive definition. mcc. is showing us how to
> represent a list, as an s-expression. (A,B,C,D) is sugar for
> (A*(B*(C*(D*NIL))))
> funny how mcc says "notation is writable and somehwat readable" -- they
> never thought to indent! ha!
> mike: side note for non-lisp programmers: everyone knows it looks funny, all
> the parens (length 1(1 2 3)) which is "prefix notation" for a fn call --
> pass this list to this function. rules for evaluation order. evaluate inner
> things first. quote operator prevents the list from being evaluated.
> Âotherwise it would apply (2,3) to the thing called 1 and say 1 is not a
> function.
> p 10b: functions of s-expr
> we introduce a second notation. M-expr is a function of s-expr. mike: this
> was never implemented in the original lisp, it was never necessary, it got
> in the way of macros. is this a formal crutch along the way, for translating
> the math into pure s expr? mike: no, they thought it would be a more
> conveiniient representation for programmers to use. Mccarthy expected
> M-expressions to be the dominant practical way to express a program, because
> it is familiar to mathemeticians, but turns out the keyboards in use those
> days had parens but not brackets, so s-expressions won. at time paper was
> written: m-expr is the term/syntax for making a fn call (thanks mike).
> this is the first time in this paper we have not had function application in
> s-expressions. [ed: is it acruate to say, that we've defined functions with
> s-expr, but haven't applied them?] s-expr as a func call possible, due to
> special forms? (hunter)
> some things aren't functions. special forms. "things built into the
> language" (small set of stuff) -- car, cdr, cons, apply (?), all teh c/d
> stuff. you can stack a/d e.g. caaaddr to get the n'th thing in the list.
> "special form" basically means, native functions, you can't implement these
> functions in lisp. special froms can do different things to the evaluation
> order of their arguments. ' (read as: quote-operator), just turns off
> evaluation of its functions. special forms "muck with" the evaluation order
> of their arguments.
> dustin: so, m-expr can be translated into an s-expr fairly simply. so m is
> just sugar on top of s expr. mcc doesn't actually say this in the paper, but
> we think this is the case.
> right now, we don't have a notation for applying fns to s-expressions, we
> have m-expr, but we will get there to where we can translate them.
> define equality (NB: always hairy in OO languages). T if same symble, else
> false. "is this the same symbol or not".
> car is the first thing in a dotted pair, cdr is the second (last) thing in a
> dotted pair. which of course can be an s-expression (a tree).
> recursive s-expressions -- so far, no recursion (thus no iteration). how do
> we form new functions ? add conditionals and recursion. ff[x] -- stands for
> "first flattened"? -- takes first atom that it comes to, no matter how
> deeply nested recurses down the first until it gets to an atom, then takes
> it. so its a recursive car that finds an atom. ff[x] = [ atom[x] -> x, T ->
> ff[car[x]] ] recursively finds first element until we get an atom.
> [ed: we skip the other interesting fn definitions, using these 5 forms.
> subst, etc.]
> p15: equivalence of m-expr and s-expr. rules for translation.
> "if youre in an m-expr, and see an s-xpr, quote the s-expr, to prevent it
> from being evaulated." (ed: ahhhh, so quote is critical for fn evaluation)
> prefix notation (with brackets) just translated to infix notation with round
> braces. note, he just introduced quote out of nowhere. just defined it. but
> michael defined it earlier. it means, "dont evaluate this s-expr".
> apparently this is common, to define syntax before defining meaning, in
> papers like this.
> p15.e.4: mathy equivalent of COND. COND is of course a special form, you
> can't implement a conditional with other atoms. e.g. in other lisps, 'if' is
> a macro around cond, which is a native fn. "normal form" vs "special form"
> p16.f: apply, universal fn mike: apply taks two args: a fn, and the list of
> arguments to that fn. (apply fn '(1 2 3)) is like invoking fn(1,2,3).
> p18: apply vs eval... this defines step by step how apply works? this is
> explaining step by step the implementation of apply. notes on how apply
> works. the list of rules of what apply does. how to implement this in
> assembly. of course, once you have apply in asm, you have a lisp
> interpreter, and we can implement apply in lisp.
> note any time you pass something to a fn, you short circuit eval, but what
> if a && b, but b is undefined or never terminates?
> when you're passing arguments into a function, you must eval the args first.
> discussion of what happens if you get undefined. apply, itmust be defined.
> this is for this impl of apply, but not fundamental to lisp (?)
> still in p18.4: cond can short circuit what is the significance of this?
> soon as we find true P, eval E, return that as the value. cond -- doesn't
> eval all its args, and in this impl is literally the only thing that allows
> short circuiting.
> ed: i had confusion here about undefined and short cirtuiting. i think it is
> due to thinking imperatively e.g. in python, instead of in s-expr and lisp.
> p18.6: we don't understand this, is it the same dificulties as the lambda
> calculus?
> skip 2 pages of lol.
> p21: higher order functions maplist, is "map" which inspired mapreduce.
> fundamental functional construct. mike: is this the first definition of map?
> takes an s-expr, returns an s-expr.
> dustn: confused about NLIL -- nil is list terminator, an atom. all lists end
> in nil. null is predicate that returns T if nil.
> ed: im missing something big with and/or and prepositions. begining of the
> paper we defined algebra of expressions. but how do you write an
> s-expression taht says "if a>b and b>c then 0, else 1"? is it part of the
> cond operator? is it a prefix native operator which is impl with a truth
> table? how can you impl AND prefix function with lisp atoms?
> ed: am confused. i think its imprptant to distinguish expresson vs function
> vs equation just like in math. not sure how to implement propositions as
> s-expr, only as algebra. how does this stuff relate? how does proposition
> relate to s-expression?
>
> note: "cdr" pronounced "kuh-dur"
> ed: the derivative s-expr was worth looking at, todo
> section 4: impl on an ibm 704. this stuff is specific to 704. so old, lol,
> that all memory is register! registers are the main memory. this is how the
> physical stuff is put together.
> this is where "car" "cdr" came from -- address, decrement. they come from
> the, like, bouncing around of different instructions -- the computer may not
> execute instructions sequentially? from the audience
> p24: goes over ways to represent s-expr in memory. memory sharing (structure
> sharing), etc. later there became eq and eql (from dan) which this is the
> difference? like in jave, are the objects equal, or are the references
> equal?
> p25: he describes using a linked list in memory to store s-expressions. this
> co[uld have ben represented as an arrya, more in line with the times, but
> they didn't -- they used linked lists, he explains why. size/number of
> expressions cannot be predicted in advance, cann't arrange fixed blocks to
> store them (array). registers put back on free storage list when no longer
> needed. he talks sort of about a heap here.
> talks about garbage collection. 15k registers, ha. 15k words (36 bits). 6
> bits to get a character (47 characters). paragraph somehwere is the first
> desc of a gc algorithm, ever. 26.c free storage list.
> "kidn of like finding out cave men knew how to make cars"
> 27.d elementary s-functions in the computers atom, eq, car, cdr, cons, what
> about cond? atom -- each atom has a special constant address part of a
> register (ed: reread...) eq -- check the address equality (impl detail based
> on atoms being structure shared) car -- ibm 704 impl details
> each register has an address part and a decrement part. decrement i guess is
> a pointer to the next pair.
> discusses how recursive fns are implemnted, and discusses the stack. "public
> push-down list"
> p30.6: "hipster quote" (haha, thanks mike) -- "program feature allows use of
> goto statements" lol
> section 5: "lol someone was drinking" -- mike L-expressions, aother way to
> define functions of symbolic expressions which are similar to lisp.
> basically with strings, and with fns that build new strings, and predicates
> on strings, you can build lisp.
> p31: "yeah, its called writing a parser"
> seciton7 : ycombinator reference about recursion - extension to lambda
> notation (someone else made it) is label.
> michael (mashion) -- formal reference to open vs closed subroutine. open:
> everything inlined. closed: refer to fn once in the code, all references are
> a goto. ed: where was this?



-- 
Trevor Lalish-Menagh
trev@trevmex.com
484.868.6150 (mobile)
trevmex (AIM)