Why here a arity errror and how to solve it

I try to implement my own update-in as challenge from the brave book

so far I have this :


(def m {:1 {:value 0, :active false}, :2 {:value 0, :active false}})


(defn my-update-in [m keyword number function]
  (function (get-in m  [(number keyword) keyword]) ))

(update-in m [:1] assoc :value 1 :active true)

(defn add-ten [number]
    (+ number 10))

(my-update-in p :age add-ten)

but now I see a arity error on the last one.
So how I can I make the code work in both cases

How many parameters does my-up-date-in require? How many parameters did the invocation provide? That’s the arity error.

Also, keep in mind an interesting subtlety of the real update-in, which is, that its return value is not the return value of the function that the caller provides!

I thought that already
so I cannot make one function which takes both cases

Have a look at the variadic functions section here: https://clojure.org/guides/learn/functions
Also, as @Phill pointed out, you should return the updated map, not the updated value itself

Get some help and I think I solved it

(defn my-update-in [m ks f ]
  (let [up (fn up [m ks f ]
             (let [k (first ks)
                   r (rest ks)]
               (if (empty? r)
                 (assoc m k (f (get m k )))
                 (assoc m k (up (get m k) r f )))))]
    (up m ks f)))

satisfied ??

It’s almost there:

(my-update-in {:a {:b 1}} [:a :b] inc)
;; => {:a {:b 2}}

(my-update-in {:a {:b 1}} [:a :b] + 3)
;; => throws arity exception

(update-in {:a {:b 1}} [:a :b] + 3)
;; => {:a {:b 4}}

This better

  (let [up (fn up [m ks f args]
             (let [k (first ks)
                   r (rest ks)]
               (if (empty? r)
                 (assoc m k (apply f (get m k) args))
                 (assoc m k (up (get m k) r f args)))))]
    (up m ks f args)))

Have you had a look at the varargs section in the link I sent you? update-in should take the map, path to update, a function, and any number of arguments to that function.
What you have there is almost verbatim the clojure.core/update-in body, but missing the varargs part.

yes, I have

(defn infix2 [[first-number operator second-number & r]]
  (if (empty? r)
    (list operator
          (if (list? first-number)
            (infix2 first-number)
            first-number)
          (if (list? second-number)
            (infix2 second-number)
            second-number))
    (if (< (get priorities operator) (get priorities (first r)))
      (list operator first-number (infix2 (conj r second-number)))
      (infix2 (conj r (list operator first-number second-number))))))

this one works also on nested ones like ( ((4 - 2) +2) * 3)

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.