Figuring out memoize from WWDC 2014 - Session 404 - swift

I'm working through understanding the parameters used in the (simple) version of the memoized fibonacci explained in the Advanced Swift session (jump to 00:38:00)
In the session the following memoize function is defined (adapted to Swift 3)
func memoize<T: Hashable, U>(body: #escaping (T) -> U) -> (T) -> U {
var memo = Dictionary<T, U>()
return { x in
if let q = memo[x] { return q }
let r = body(x)
memo[x] = r
return r
}
}
And it will wrap simple functions, for example:
let ntos = memoize {(n: Int) -> String in
print("Must evaluate something")
return "\(n)"
}
print(ntos(3))
print(ntos(3))
print(ntos(30))
output:
Must evaluate something
3
3
Must evaluate something
30
The type of ntos is (Int) -> String so the T in memoize becomes Int and U becomes String.
But for the fibonacci function, the example apple are using is
let fibonacci = memoize {
fibonacci, n in
n < 2 ? Double(n) : fibonacci(n: n - 1) + fibonacci(n: n - 2)
}
Here I'm not sure what types T, and U are adapting? and how the function behaves for the recursive nature? How the closure parameter declaration fibonacci, n translate to the type memoize (T) -> U body parameter?
Why fibonacci is even in the definition of closure passed to memoize? I assume it's something to do with the idea of curried functions (that was replaced by closures in Swift 3) but the implementation syntax just doesn't clicks for me.

I've decided to it a step further and wrote a full fledges walk through of memoize

Related

Is is possible to callAsFunction() variable that is Any?

Recently I have encountered a need of creating an Array of Functions. Unfortunately, Swift language does not provide a top level type for functions, but instead they must be declared by their specific signature (...)->(...). So I tried to write a wrapper that can hold any function and later specialize it to hold only closures having Void return type and any number of arguments.
struct AnyFunction {
let function: Any
init?(_ object: Any){
switch String(describing: object){
case let function where function == "(Function)":
self.function = object
default:
return nil
}
}
func callAsFunction(){
self.function()
}
}
As I was progressing, I have found out that it is not trivial and possibly requires some hacks with introspection, but I failed to find solution, despite of my attempt. The Compiler messaged:
error: cannot call value of non-function type 'Any'
So how would you make this trick that is, to clarify, to define an Object that can hold any functional type?
Clarification:
What I would prefer is defining something like:
typealias SelfSufficientClosure = (...)->Void
var a, b, c = 0
let funcs = FunctionSequence
.init(with: {print("Hi!")}, {a in a + 3}, {b in b + 3}, { a,b in c = a + b})
for f in funcs { f() }
print([a, b, c])
//outputs
//"Hi"
//3, 3, 6
PS This question has relation to this one (Any or a trouble with sequence of functions)
A function is a mapping from inputs to outputs. In your examples, your inputs are void (no inputs), and your outputs are also void (no outputs). So that kind of function is precisely () -> Void.
We can tell that's the right type because of how you call it:
for f in funcs { f() }
You expect f to be a function that takes no inputs and returns no outputs, which is exactly the definition of () -> Void. We can get exactly the input and output you expect by using that type (and cleaning up a few syntax errors):
var a = 0, b = 0, c = 0
let funcs: [() -> Void] = [{print("Hi!")}, {a = a + 3}, { b = b + 3}, { c = a + b}]
for f in funcs { f() }
print(a, b, c, separator: ",")
//outputs
//Hi!
//3, 3, 6
When you write a closure like {a in a + 3}, that doesn't mean "capture a" (which I believe you are expecting). It means "This is a closure that accepts a parameter that will be called a (completely unrelated to the global variable of the same name) and returns that value plus 3." If that's what you meant, then when you called f(), you would need to pass it something and do something with the return value.
You can use an enum to put various functions into the Array and then extract the functions with a switch.
enum MyFuncs {
case Arity0 ( Void -> Void )
case Arity2 ( (Int, String) -> Void)
}
func someFunc(n:Int, S:String) { }
func boringFunc() {}
var funcs = Array<MyFuncs>()
funcs.append(MyFuncs.Arity0(boringFunc))
funcs.append( MyFuncs.Arity2(someFunc))
for f in funcs {
switch f {
case let .Arity0(f):
f() // call the function with no arguments
case let .Arity2(f):
f(2,"fred") // call the function with two args
}
}

Is it possible to call a function as a parameter of another function in Swift?

Is it possible to call a function as a parameter of another function in Swift??
I am making a sound effects app in Swift which uses different effects like AVAudioUnitReverb() and AVAudioUnitDistortion() etc. I wanted to create a single function and just be able to call which effects I wanted to do.
Because in Swift functions are first-class types, you can pass it as an argument to another function.
Example:
func testA() {
print("Test A")
}
func testB(function: () -> Void) {
function()
}
testB(testA)
You can pass in functions as parameter my typing the parameter with the same signature.
As sunshine's example just deals with Void parameters and return types, I want to add another example
func plus(x:Int, y:Int) -> Int {
return x + y
}
func minus(x:Int, y:Int) -> Int {
return x - y
}
func performOperation (x:Int, _ y:Int, op:(x:Int,y: Int) -> Int) -> Int {
return op(x: x, y: y)
}
let resultplus = performOperation(1, 2, op: plus) // -> 3
let resultminus = performOperation(1, 2, op: minus) // -> -1
note: Of course you should consider dynamic typed parameters. For simplicity here just Ints
this is called Higher Order Functions and in many languages this is the way of doing it. But often you don't won't to explicitly create functionss for it. Here Closures are a perfect tool:
The function performOperation stays untouched, but the operations are implemented differently:
let plus = { (x:Int, y:Int) -> Int in
return x + y
}
let minus = { (x:Int, y:Int) -> Int in
return x - y
}
let resultplus = performOperation(1, 2, op: plus)
let resultminus = performOperation(1, 2, op: minus)
Often this would be preferred as it doesn't need methods to be added to a class, pretty much like anonymous functions in other languages.
More on this and how it is used in the swift standard library: https://www.weheartswift.com/higher-order-functions-map-filter-reduce-and-more/
I would recommend book "IOS 9 Programming Fundamentals with Swift" by Matt Neuburg, especially subchapter "Functions".
You should not only find the answer for your question:
func imageOfSize(size:CGSize, _ whatToDraw:() -> ()) -> UIImage {
...
}
But also how to construct function that returns the function:
func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {
...
}
As well as brief introduction to Curried Functions.

Swift higher order function (Church pair aka cons) with generic parameter types not accepting input parameter types

I was messing around with the functional programming in Swift 2.1, trying to implement the Church encoding pair/cons function (cons = λx λy λf f x y in untyped lambda calculus), which I had read couldn't be done in earlier versions of Swift.
With generics it looks like
func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y)}
}
cons(1,2)
//error: cannot invoke 'cons' with an argument list of type '(Int, Int)'
//note: expected an argument list of type '(S, T)'
which doesn't work, and gives an error I cannot understand (surely parameter list of type (Int,Int) can match generic type variables (S,T)?)
If you get rid of the generic types, and declare them all Ints, the function works, but of course we want to be able to cons together lists longer than 2; consing a list of length 3 is consing an Int with an (Int,Int) -> Int, for example.
Another option is to type everything as Any (see Type Casting for Any and AnyObject), but I couldn't make that work either.
Do you have any ideas? Is this possible in Swift yet? I'm sure there are simpler ways to implement cons/car/cdr, but I'm specifically interested in the Church encoding, where the list elements are arguments to anonymous functions (lambdas).
func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y)}
}
let i: ((Int,Int)->Int)->Int = cons(1,2)
let d: ((Int,Int)->Double)->Double = cons(2,3)
let e: ((Double,Int)->String)->String = cons(2.2, 1)
let e: ((Double,Int)->Double)->Double = cons(2.2, 1)
stil one of type is an 'extra' type and could not be inferred by compilator. if you define the types, you can see, that not all combinations are valid. Just define the output type and the compilator should be happy
func cons<S,T, U>(x:S,_ y:T, outptAs: U.Type) -> ((S,T) -> U ) -> U
{
return { (f:((S,T) -> U)) -> U in return f(x,y) }
}
let i = cons(1.2 ,"A", outptAs: Int.self)
let j = cons("alfa","beta", outptAs: Double.self)

Swift: Reduce with closure

Code:
var treasures: [Treasure] = []
treasures = [treasureA, treasureB, treasureC, treasureD, treasureE]
let rectToDisplay = self.treasures.reduce(MKMapRectNull) {
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
// 2
let treasurePointRect = MKMapRect(origin: treasure.location.mapPoint, size: MKMapSize(width: 0, height: 0))
// 3
return MKMapRectUnion(mapRect, treasurePointRect)
}
In the code above, we are running the reduce function on treasures array, two parameters are passed in the closure: (mapRect: MKMapRect, treasure: Treasure). How does the closure know to that the second parameter will be the element from the treasures array and the first parameter will be result of the what this closure returns?
Is this something by default that the second parameter passed in the closure will be the element from the array that's executing the reduce function?
Swift's array class has a definition of reduce that most likely looks something like this:
func reduce<T>(initial: T, fn: (T, T) -> T) -> T {
var val = initial
for e in self {
val = fn(val, e)
}
return e
}
That is to say, the definition of reduce dictates the order in which parameters are passed to the closure you provide.
Note that the actual definition of Swift's reduce is more complicated than the one I provided above, but the example above is the basic gist.
If you look at the definition of reduce:
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: #noescape (U, S.Generator.Element) -> U) -> U
The first parameter of the closure is the result and the second is element of your sequence.

How to understand the currying in Swift?

I'm new to Swift, and when I look the book, I found the currying in Swift is complicated, and I write the code follow the book, such as:
func curry<A, B, C>(f: (A, B) -> C) -> A -> B -> C {
return { x in { y in f(x, y) } }
}
func paraFunc(pa: Int, pb: Int) -> Int {
return pa - pb
}
var cab = curry(paraFunc)
cab(2)(3)
and I don't know how to comprehend the "-> A -> B -> C". And I know the Generics. But I confused about the func curry, how it works? and anybody can help me?
-> operator is right associative. So we can rewrite curry function like this.
func curry<A, B, C>(f: #escaping (A, B) -> C) -> ((A) -> ((B) -> C)) {
return { x in { y in f(x, y) } }
}
Every ( matches with { inside return part.
EDIT: Further explanation
curry function takes a non-curried two argument function and makes it curried. For example we have:
func sum(a: Int, b: Int) -> Int {
return a + b
}
Now we can use this function like this:
let result = sum(3, 6)
But if we make it curried
let curriedSum = curry(sum)
Now we can use it like this:
let result = curriedSum(3)(6)
At first this seems unnecessary and complex. But think about what next expression does.
let sumWith3 = curriedSum(3)
This produces a new function that takes an Int sums it with 3. Now here we created a new function from another function. Now we can use it like any other function.
Currying is common paradigm in functional programming. In fact in Haskell (another functional programming language) every function is curried by default.