What does clojure 'val' mean?

I am just starting to learn clojure and reading some simple examples and then doing my best for rtfm for concepts.

However, I'm a little confused by what val does in the example below. This was taken from the clojure doc examples for val .

 (first {:one :two}) ;; => [:one :two] 

Here is a hash-map with the key :one and the value :two passed first . Behind the scenes, clojure converts this hash-map into a sequence of vectors . Since there is only one vector in this sequence , it returns [:one :two] .

 (val (first {:one :two})) ;; => :two (val [:one :two]) ;; => ClassCastException clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry (val {:one :two}) ;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry 

If I try to call val on (I think) a hash-map (I understand that this is actually a "persistent array map"), I get an exception, as shown above.

The following also confuses me:

 (first {:one :two}) ;; # => [:one :two] (this is a vector right?) (val [:one :two]) ;; # => ClassCastException (why doesn't this give back the same result as the example above?) 

Why can't I just connect the result (first {:one :two}) to val and get the same result?


In addition, another example shown on the page is as follows:

 (map val {:a 1 :b 2}) ;; => (1 2) 

This is how I read the line. Take array-map {:a 1 :b 2} . For each key-value pair, call val for the pair to return the value. Return a sequence from the received calls to map . Is this the right way to read the problem?

As always, thanks for any help.

+5
source share
3 answers

the sequence displays MapEntry values, as you noted, that look and can be mapped to vectors

 user=> (= (first {:a 1 :b 2}) [:a 1]) true 

but are not the same class

 user=> (= (class (first {:a 1 :b 2})) (class [:a 1])) false 

So, although the output to repl (first {:a 1}) looks like a vector, it’s not a MapEntry , so it can be passed to val , but the vector [:a 1] cannot, therefore, throw an exception to the class.

Your reading of what the map does is right at a high level, a little more specific might be "For each record in the sequence of {: a 1: b 2} (which are MapEntry values) call the function val on each element (MapEntry) and generates a sequence of results. "

This will explain why something like

 user=> (map val '([:a 1] [:b 2])) 

will result in the same ClassCastException , because the sequence throws Vector elements, not MapEntry elements.

+6
source

val returns the value of the map entry, not the map.

(first {:one :two}) returns the first record of the map (although it looks like just vec)

(map val {:one :two}) returns the value of each record and is equivalent to (vals {:one :two})

+5
source
 (first {:one :two}) ;; # => [:one :two] (this is a vector right? No, it not.) 

[:one :two] in this case is MapEntry , not a vector.

+2
source

All Articles