This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-16
Channels
- # announcements (18)
- # architecture (11)
- # babashka (20)
- # beginners (32)
- # biff (21)
- # calva (70)
- # clerk (6)
- # clj-kondo (16)
- # clj-otel (5)
- # cljsrn (8)
- # clojure (94)
- # clojure-austin (1)
- # clojure-australia (1)
- # clojure-europe (68)
- # clojure-nl (2)
- # clojure-norway (6)
- # clojure-uk (2)
- # clojurescript (13)
- # conjure (1)
- # core-logic (1)
- # cursive (7)
- # data-science (2)
- # datahike (3)
- # datomic (12)
- # emacs (33)
- # etaoin (1)
- # fulcro (8)
- # graalvm (2)
- # graphql (1)
- # honeysql (1)
- # hyperfiddle (97)
- # improve-getting-started (40)
- # jobs (2)
- # jobs-discuss (12)
- # lsp (9)
- # membrane (6)
- # nbb (2)
- # off-topic (16)
- # portal (6)
- # re-frame (2)
- # reagent (3)
- # releases (2)
- # remote-jobs (1)
- # tools-deps (7)
- # xtdb (38)
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)
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)
my-allergies
(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)
my-curr-allergy-score))
(defn find-my-allergies [my-curr-allergy-score allergenic-scores]
(->> allergenic-scores
(insp)
(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)
(insp)
(maybe-add-allergy my-allergies)
(insp))
(next-allergy-score my-curr-allergy-score allergenic-score)])
['() my-curr-allergy-score])
(first)))
(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)
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 happeningyou already have a function named allergic-to? which is called when you call allergies
oh god, how on earth i missed that
thx i thought i was going crazy here
((set '(:eggs)) :eggs)
yeah, it was not into before
i was changing everything trying to find out what was wrong
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
but, for style stuff, i would recommend using names for function calls (let [my-fn #{}] (my-fn args))
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.
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: https://clojure.org/guides/reader_conditionals
Make a function called e.g. char->int
and define separate implementations for the different runtimes.
@U4P4NREBY @U04V70XH6 thanks a lot you both!
@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 )


