Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created January 13, 2017 23:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tenderlove/04e1a4d5f9f0bf44e222e4104bc14cdf to your computer and use it in GitHub Desktop.
Save tenderlove/04e1a4d5f9f0bf44e222e4104bc14cdf to your computer and use it in GitHub Desktop.
/*
I am trying to implement cons / car / cdr in terms of lambdas, then
implement `each` to walk the cons cells, but I can't seem to get the `each`
function to work :(
*/
@discardableResult func cons(_ x: Any, _ y: Any) -> (((Any, Any) -> Any) -> Any) {
return { m in m(x, y) }
}
@discardableResult func car(_ z: (((Any, Any) -> Any) -> Any)) -> Any {
return z { p, q in p }
}
@discardableResult func cdr(_ z: (((Any, Any) -> Any) -> Any)) -> Any {
return z { p, q in q }
}
/*
func each(_ x: Any, _ thing: (Any) -> Any) -> Any {
thing(car(x))
each(cdr(x), thing)
}
*/
car(cons(1, 2))
print(cdr(cons(1, cons(2, 3))))
print(car(cons(1, cons(2, 3)))) // => 1
@robrix
Copy link

robrix commented Jan 14, 2017

Here’s what I came up with using casting. Note that the types differ—I wasn’t clear on what should be returned, so I opted to return () (nothing).

typealias List = ((Any, Any) -> Any) -> Any
func each(_ x: Any, _ thing: (Any) -> ()) -> () {
  if let x = x as? List {
    thing(car(x))
    return each(cdr(x), thing)
  } else {
    thing(x)
  }
}

print(car(cons(1, 2)))
print(cdr(cons(1, 2)))
print(cdr(cons(1, cons(2, 3))))
print(car(cons(1, cons(2, 3)))) // => 1

each(cons(1, cons(2, 3)), { x in print(x) })

@tenderlove
Copy link
Author

@robrix OMG thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment