|->| voidSig := |->| {} |->Int| returnsInt := |->Int| { 42 } Methods are just function wrappers |Int a, Int b ->Int| plus := Int#plus.func |->| mainFunc := #main.func Functions can bind arguments op := |Method m, Int a, Int b| { m.callOn(a, [b]) } mul := opFunc.bind([Int#mult]) //|Int, Int->Int| plus2 := opFunc.bind([Int#plus, 2]) //|Int -> Int| Closures are exprs returning funcs Str prefix := "" print := |Obj o->Str| { prefix + o.toStr }
invoke person?.phones?.first //null if p == null Elvis operator //alias for this == null ? that : this this ?: that No () for methods w/o args cap := "a".capitalize No ‘return’ for single expr Int negate(Int arg) { arg.negate } ‘isnot’ keyword alwaysFalse := "a" isnot Str
Const fields must be set in constructor • Const fields can have only const type or [List, Map, Func].toImmutable • Static fields must be const • List and Maps can be const or mutable class NonConst { const Int constField Int nonConstField Void mutate() { constField = 4 //compile err nonConstField = 4 //ok } } class Const { new make(Int i, Str[] list) { //implicit call of list.toImmutable this.list = list } const Str[] list }