Skip to content

Instantly share code, notes, and snippets.

@tooky
Created September 11, 2012 07:26
Show Gist options
  • Select an option

  • Save tooky/3696665 to your computer and use it in GitHub Desktop.

Select an option

Save tooky/3696665 to your computer and use it in GitHub Desktop.
Working through FP for OO Programers by @marick
;solution presented
(def a
(fn [type & args]
(apply type args)))
;my original solution
(def a
(fn [type & args]
(eval (cons type args))))
;which I realised was the same as this
(def a
(fn [& args]
(eval args)))
;The solution presented in the book is definitely clearer as to what's going on.
;I'm wondering though if there's anything to be aware of about using eval like this?
@marick
Copy link
Copy Markdown

marick commented Sep 11, 2012

In this particular case, it doesn't matter. The big difference between eval and apply is that eval can't "see" symbols bound in a let. Compare this:

user=> (let [args [1]]
         (apply inc args))
2
user=> (let [args [1]]
         (eval '(inc args)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: args in this context, compiling:(NO_SOURCE_PATH:169) 

This doesn't become important until (I think) chapter 10.

@marick
Copy link
Copy Markdown

marick commented Sep 11, 2012

Probably a clearer example of how eval is blind would just be this:

user=> (let [args [1]]
         (eval '(inc args)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: args in this context, compiling:(NO_SOURCE_PATH:169) 

@marick
Copy link
Copy Markdown

marick commented Sep 11, 2012

Urk. Pasted wrong thing:

user=> (let [x 1] (eval 'x))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:171) 

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