Keyword Overloading in Clojure

I have a map like this:

(def a {:a 1, :b 2}) 

: I want to reload the map so that some keywords perform functions so that:

 (c: a) 

It can perform a function. Is it possible?

Update:

I understand that I can do something like:

 (def a {:a (fn[] 1) :b (fn[] 2) :c (fn[] x)}) 

: a:

 ((c: a)) 

: but then I have to convert every existing map entry that I have into a function.

I want the function to be "reevaluated" every time. For example, when I do:

 (def ab{:a 1 :b 2 :c ( #(.nextInt (java.util.Random.) 1000))}) (str (:c ab) " " (:c ab) " " (:c ab)) 

I get:

 61 61 61 

Instead of three different numbers

Update 2

I thought about the answer that gave me, and realized that he was right, I should only use immutable structures. The final solution I came up with was to have an enrichment function that creates dynamic properties on demand.

  (def a {:a 1, :b 2}) 

: I want to reload the map so that some keywords perform functions so that:

 (str (:c (enrich ab)) " " (:c (enrich ab)) " " (:c (enrich ab))) 

will produce different numbers every time like this:

 58 639 710 
+6
source share
3 answers

I believe that you can redefine the behavior of associative searches if you make your data structure a record, not a regular map.

Basically you need to override clojure.lang.ILookup: see this question for more details

Here is an example:

 (deftype TestLookup [] clojure.lang.ILookup (valAt [this k not-found] (str "Generated value for key - " k)) (valAt [this k] (.valAt this k nil))) (def lookupable-object (TestLookup.)) (:somekey lookupable-object) => "Generated value for key - :somekey" 
+4
source

Using the same card to sometimes transmit immutable values, and sometimes to skip unclean functions, it seems to me that this contradicts the spirit of why you need to use immutable cards. Instead, I would recommend using a reference type that points to an immutable map with only data values. Then, when one of these data values ​​should be something else, point your reference type to a new immutable map that reflects any changes.

+2
source

Clojure prefers pure data structures over objects that combine data and behavior. You can get the desired behavior by accessing your data structure using the function:

 (def base-foo {:a 1, :b 2}) (defn foo [key] (if (= :c key) (rand-int 100) (get base-foo key))) (str (foo :c) " " (foo :c) " " (foo :c)) ;;=> "66 52 25" 
+2
source

Source: https://habr.com/ru/post/885429/


All Articles