Object The functional core still stays:
Records Named fields with values:
“each element of the tuple has a name, and order is unimportant” If the fields are fixed, they are basically just ADTs. Record Type All functions are types, and so are the methods; so we can just add more types for the methods as well. So here’s two properties and a method:
“self” We will have something that’s a recursive data type:
All methods will always take the self parameter first, and then take anything else after as needed. Objects Objects is a collection of fields and methods on those methods Object Calculus \begin{equation} o = [\dots, l_{i} = \zeta (x) b_{i}, \dots] \end{equation} object calculus is a map between field names and object producers. selection: o. l_{i} \to bi [ x := o] (i.e. invoke with self) override: o.l_{i} \Leftarrow \zeta (y) b \to o with l_{i} = \zeta (y) b (i.e. set new method value) wait what about fields! Well, we just have a method that returns a contsant, such as:
Look, when we ask for o.l we will just get 3 because 3[x := o] = 3. recursion \begin{equation} o = [l = \zeta(x) x . l] \end{equation} or
invoking o.l will either get you back o.l or o in these things, enabling recursion. programing with overrides For instance, we can get a thing to rewrite itself!
Meaning:
numbers zero = [ iszero = s(x) true, pred = s(x) x, succ = s(x) (x.iszero <= s(y) false).pred <= s(y) x] that is, in successor, we can keep rolling the number back transforming lambda calculus into object calculus T(x) = x T(e_1 e_2) = \left(T(e_1) . arg \Leftarrow \zeta(y) T (e_2)\right).val T(\lambda x . e) = [arg = \zeta(x) x. arg, val = \zeta(x) T (e) [x := x.arg]] Key idea: a function is an object of two fields, an argument and a body. note that the default argument field for a non-invoked lambda is just an infinite loop, its only a dummy value transforming object calculus into lambda calculus We will represent objects as lists of pairs: the first component is a label (an integer); the second component is the value of the methods/field—if there are more than one object with a particular value, we pick the first one (…which is how we do overrides). Select a field:
And override (we just tack things up front):
LIMITATION: this can’t work for types, because general overrides can’t really work since the target of the override could be literally any types. subtyping A < B if an object with type A can be used in any context where something of type B is required.
that is, we can forget some fields and we can get a good type still. key tension… If you want a typed object language, object method definition mainstream OO Java, C++ properties happens before type checking: inheritance, static overrides, restrictions on superclass modification,, dynamic updates… meaning, typing is independent of program evaluation type checking after method assembly; each class is fully resolved type checking inherentance is a static property method override is resolved at compile time—before type checking functional -> OO OCaml, Haskell We want to add some object orientation to a functional language—OO is a thin wrapper; to work around rough edges, we use higher order functions. OCaml example let counter = object var mutable x = 0 method get = 0 method inc = x <- x + 1 end; This will give you a record type val counter: <get: int, inc: unit >—which is computed dynamically. Unlike intermediate objects like the above, classes defined as a global scope can be inherited. class counter = object var mutable x = 0 method get = 0 method inc = x <- x + 1 end; OO -> functional Java, C++ We want to add some functionalish components (higher order functions, parametric polymorphism) to our OO language:~:W (arg) -> { body } like Lambda Calculus—- functions are anonymous take one argument parametric polymorphism = C++ templates: template <class T> class Test { private: T val; public: MyNum(T n) (val T) {}; } Dynamically Typed “Give up” Python, Javascript, LISP noticeably more popular in the OO world (because static typing in OO is really hard) prototypes Prototype-based systems are the analogies to type systems. New objects are created by copying the prototypes around.