Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In what way are Clojure maps functions?

In his talk "Maybe not" Rich Hickey states:

maps are (mathematical) functions!

in Clojure, we can directly write, and invoke

({:a 1 :b 2} :b) => 2

However I have the feeling that they are not in fact first class Clojure functions, or are they?

I can call the map with a keyword, or the other way around:

user=> (:b {:a 1 :b 2 :c 3})
2
user=> ({:a 1 :b 2 :c 3} :b)
2

But I can't use apply either way it seems:

user=> (apply #(:b %) {:a 1 :b 2 :c 3})
ArityException Wrong number of args (3) passed to: user/eval1762/fn--1763  clojure.lang.AFn.throwArity (AFn.java:429)

user=> (apply #({:a 1 :b 2 :c 3} %) :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:542)

And neither can I apply the keyword directly to the map:

user=> (apply {:a 1 :b 2 :c 3} :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword  clojure.lang.RT.seqFrom (RT.java:542)

So are they functions only in the mathematical sense, or is there more to them in the sense of applying a keyword similar to a "normal" clojure function?

like image 871
Arne Avatar asked Mar 22 '19 13:03

Arne


People also ask

What is map in Clojure?

A map is a collection that holds key-value pairs. The values stored in the map can be accessed using the corresponding key. In Clojure there are two types of maps: Hash maps. Sorted maps.

Are Clojure maps ordered?

Clojure has three built-in map types: array maps, hash maps and sorted maps. Of these, hash maps and sorted maps are unordered, but array maps actually are ordered: this is explained in the data structures section of the official documentation on clojure.org.

Is Clojure map lazy?

Lazy Sequences in Clojure This means that unless there is someone to consume the sequence, nothing really happens. It turns out that the function print-numbers produces a lazy sequence on line 1 (as indicated on the code-block above), i.e., the map produces a lazy sequence.

What is a Clojure function?

Clojure is a functional language. Functions are first-class and can be passed-to or returned-from other functions. Most Clojure code consists primarily of pure functions (no side effects), so invoking with the same inputs yields the same output.


1 Answers

Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.

The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.

(apply #(:b %) {:a 1 :b 2 :c 3})

In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:

user=> (seq {:a 1 :b 2 :c 3})
([:a 1] [:b 2] [:c 3])

This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:

user=> (apply {:a 1 :b 2 :c 3} [:b])
2

Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.

like image 127
Taylor Wood Avatar answered Sep 20 '22 03:09

Taylor Wood