A workshop for writing macros.
It covers the basic elements of a macro and shows you the difference and similarity between puzzling things like `'~....
Here it goes
https://gist.github.com/anonymous/49053496eb88c7c6a1a1
Alfred on Clojure
Sunday, May 18, 2014
Wednesday, March 19, 2014
var and symbol
A symbol object stands for the symbol itself, not the value.
Example:
'abc
(symbol "abc")
These guys are the same thing. They are a symbol object.
In runtime, you can evaluate a symbol to find out the value associated with them.
;;; suppose you had a variable named "abc"
; (def abc 20)
(eval 'abc)
(eval (symbol "abc")) ;; ==> 20
A var is an object holding the value of a symbol.
(def ^:dynamic a 3)
(binding [a 30]
(var-set (var a) 300)
(println a)
(var-set (resolve (symbol "a")) 3000)
(println a)
(var-set #'a 30000)
(println a)
(set! a 30000) (println a)
)
1. In compile time (var a) is resolved to the var object itself.
2. In runtime, (resolve 'a) or (resolve (symbol "a")) is something stands for the var object itself.
// #'xxx is a macro, expands to (var xxx)
Example:
'abc
(symbol "abc")
These guys are the same thing. They are a symbol object.
In runtime, you can evaluate a symbol to find out the value associated with them.
;;; suppose you had a variable named "abc"
; (def abc 20)
(eval 'abc)
(eval (symbol "abc")) ;; ==> 20
A var is an object holding the value of a symbol.
(def ^:dynamic a 3)
(binding [a 30]
(var-set (var a) 300)
(println a)
(var-set (resolve (symbol "a")) 3000)
(println a)
(var-set #'a 30000)
(println a)
(set! a 30000) (println a)
)
1. In compile time (var a) is resolved to the var object itself.
2. In runtime, (resolve 'a) or (resolve (symbol "a")) is something stands for the var object itself.
// #'xxx is a macro, expands to (var xxx)
Saturday, February 15, 2014
Using expectations
1. Install expectations lib
Goto http://jayfields.com/expectations/installing.html
Or, simple add [expectations "1.4.52"] into your project.clj
2. Install expectations plugin for leiningen
add :plugins [[lein-expectations "0.0.7"]] into your project.clj
3. Write your tests
(expect nil? nil)
(expect (add 2 3) 5)
4. Run your tests
lein expectations
5. Install autoexpect (to Automate it)
Goto https://github.com/jakemcc/lein-autoexpect
or add [lein-autoexpect "1.0"] to plugins section of project.clj
6. Run autoexpect
lein autoexpect
Goto http://jayfields.com/expectations/installing.html
Or, simple add [expectations "1.4.52"] into your project.clj
2. Install expectations plugin for leiningen
add :plugins [[lein-expectations "0.0.7"]] into your project.clj
3. Write your tests
(expect nil? nil)
(expect (add 2 3) 5)
4. Run your tests
lein expectations
5. Install autoexpect (to Automate it)
Goto https://github.com/jakemcc/lein-autoexpect
or add [lein-autoexpect "1.0"] to plugins section of project.clj
6. Run autoexpect
lein autoexpect
Monday, December 16, 2013
difference between rest and next
(def x (next (random-ints 50)))
; realizing random number (evaluating first element)
; realizing random number (evaluating second element, which is the head of the tail)
(def x (rest (random-ints 50)))
; realizing random number
NOTE: ‘next’ tries to evaluate the head of the tail, while ‘rest’ does not, which is lazier than ‘next’
head retention
if you hold a reference to the head of a sequence, you prevent VM from GC any elements in the sequence.
e.g.
(let [[t d] (split-with #(< % 12) (range 1e8))] [(count d) (count t)])
- because, when counting d, t is retained, and none of the elements are GC-able.
However, in
(let [[t d] (split-with #(< % 12) (range 1e8))] [(count t) (count d)])
- because after counting t, when you count d, numbers(elements) are are already counted can be GC collected.
the difference between get and find
‘find’ returns the entry of a map
‘get’ returns the value of a map
NOTE: get can be tricky when working with ‘nil’, as
(get {:ethel nil} :lucy)
;= nil
(get {:ethel nil} :ethel)
;= nil
in this case, ‘find’ is a better choice
(find {:ethel nil} :lucy)
;= nil
(find {:ethel nil} :ethel)
;= [:ethel nil]
be careful of contains?
contains works with keys not values!
(contains? [1 2 3] 0) ⇒ true !!!!(contains? [1 2 9] 3) ⇒ false!!!!
Subscribe to:
Comments (Atom)