Fork me on GitHub
Lucas Paszinski00:02:28

I’m doing the exercism for clojure, and im doing a exercise, and ran into something that i think it’s a wierd bug (or some behaviour i don’t get why it’s happening) The code is the one below i left some comments, but if you eval function by functions you probably see for yourself

(ns allergies)

;; On mac os, but exercism pipeline also fails like this
(clojure-version) ;; => "1.11.1"

(def score->allergy {1  :eggs      2 :peanuts
                     4  :shellfish 8 :strawberries
                     16 :tomatoes  32 :chocolate
                     64 :pollen    128 :cats})

(defn insp [n]
  (clojure.pprint/pprint n)

(defn possible-allergenic-scores [s]
  (->> (range)
       (map #(Math/pow 2 %))
       (map int)
       (take-while #(>= s %))))

(defn maybe-add-allergy [new-allergy my-allergies]
  (if (nil? new-allergy)
    (conj my-allergies new-allergy)))

(defn allergic-to? [my-curr-allergy-score allergenic-score]
  (>= my-curr-allergy-score allergenic-score))

(allergic-to? 1 1) ;; => true

(defn find-allergy [my-curr-allergy-score allergenic-score]
  (when (insp (allergic-to? my-curr-allergy-score allergenic-score))
    (score->allergy allergenic-score)))

(find-allergy 1 1) ;; => :eggs

(defn next-allergy-score [my-curr-allergy-score allergenic-score]
  (if (insp (allergic-to? my-curr-allergy-score allergenic-score))
    (- my-curr-allergy-score allergenic-score)

(defn find-my-allergies [my-curr-allergy-score allergenic-scores]
  (->> allergenic-scores
       (reduce (fn [[my-allergies my-curr-allergy-score] allergenic-score]
                 (insp [[my-allergies my-curr-allergy-score] allergenic-score])
                 [(-> (find-allergy my-curr-allergy-score allergenic-score)
                      (maybe-add-allergy my-allergies)
                  (next-allergy-score my-curr-allergy-score allergenic-score)])
               ['() my-curr-allergy-score])

(defn allergies [score]
  (find-my-allergies score (possible-allergenic-scores score)))

;; If i push everything above to the REPL and run 

(allergies 1) ;; => (:eggs)
(find-my-allergies 1 [1]) ;; => (:eggs)

;; after i define this everything starts go crazy
(defn allergic-to? [score allergenic]
  ((into #{} (allergies score)) allergenic))

(allergic-to? 1 1) ;; => Stackoverflow
(find-my-allergies 1 [1]) ;; => Stackoverflow 
(find-allergy 1 1) ;; => Stackoverflow

;; If i redefine after allergic-to?
(defn allergies [score]
  (find-my-allergies score (possible-allergenic-scores score)))

(allergies 1) ;; => (:eggs)

Lucas Paszinski00:02:22

but after i define

(defn allergic-to? [score allergenic]
  ((into #{} (allergies score)) allergenic))
i see stackoverflow in all functions until i redefine them. i don’t get why this is happening


you already have a function named allergic-to? which is called when you call allergies


then you redefine allergic-to? to call allergies

Lucas Paszinski00:02:28

oh god, how on earth i missed that

Lucas Paszinski00:02:43

thx i thought i was going crazy here


you are executing the result of your (into....) seems very wrong


sorta like calling ({})


oh, i see, you are giving it an arg, it's hard to see that at first

Lucas Paszinski00:02:24

((set '(:eggs)) :eggs)

Lucas Paszinski00:02:35

yeah, it was not into before

Lucas Paszinski00:02:48

i was changing everything trying to find out what was wrong


it's just a style issue for me, not a functional issue

Lucas Paszinski00:02:10

yeah, if you have suggestions i would love to hear, but i think mostly it was it for me thx!


your problem is actually a tricky one to debug. i'm not sure there is a good heuristic to follow for this type of issue


i've been bitten by the same thing recently


but, for style stuff, i would recommend using names for function calls (let [my-fn #{}] (my-fn args))


anonymous function calls can be very confusing, at least for me


Not your original question, but notes if you want them: • I would avoid s as a fn arg for score, typically that indicates a generic string • [hint] because the scores are powers of 2, there are some simplifications you can make • it’s very powerful to build up your code in a REPL inside your editor, evaluating as you go. might decrease your reliance on insp . YMMV, etc.

🙌 2
Danilo Oliveira19:02:27

Why does (int \8) gives 56 in Clojure and 8 in Clojurescript? 😞 I'm sad, I wanted my cljc code to behave the same in both runtimes...


Different runtimes… Clojure data structures behave identical, for most day-to-day purposes.


@U035WLPF552 JS doesn't have character as a type separate from string, I believe, and JS doesn't have integers, only "numbers". I think \8 in cljs is treated as "8", so I suspect int in cljs is a coercion and just happens to work on numeric strings, whereas in clj int is a cast and you can cast Character to int but you can't cast String to int.


(the integer value of a character has pretty much always been non-portable across computers and runtimes -- back in the day it depended on the native encoding of the platform: ascii vs ebcdic vs ...)


> I wanted my cljc code to behave the same in both runtimes... This sounds great on the surface, but there are some pretty big trade-offs with that approach. In the extreme, it would impose a pretty large performance and payload size penalty. It would also make interop with the underlying platform much more cumbersome.


@U035WLPF552 This is how you typically solve any CLJ/CLJS mismatch in a CLJC file: Make a function called e.g. char->int and define separate implementations for the different runtimes.

🙌 2
Danilo Oliveira20:02:26

@UTF99QP7V now I see why you wrote an ANTLR grammar... If you consider clock info, comments, analysis ($1, $2, ...), things get more complicated than regexes can handle lol


Yeah, it’s also worth thinking about performance if you ever want to ingest something like Caissabase etc.


A while ago I asked about installing Clojure by kids in a programming course. We tried installing Java, VSC, Calva, and manual project creation with deps.edn. I have to say it worked really well. Within 1 hour most kids that have had java preinstalled were able to get the REPL up and running. It's gone much better than expected. Now they were able to load the quil library and start drawing creative stuff : ) Great job and kudos to all tooling providers )

gratitude 20
clojure-spin 16
🚀 36
💪 24
calva 12

Thanks for sharing this!

✔️ 2

Thank you for you hard work and tenacity @U0ETXRFEW et all !

🙏 2

et all is a great many! It's almost impossible to picture the eco system of hard working, and tenacious tool smiths working together and independently to bring ever better Clojure and Start with Clojure experiences. I know as much as that the picture is beautiful.

gratitude 2