Fork me on GitHub
#beginners
<
2022-05-23
>
Nom Nom Mousse06:05:27

(def e "we are {{hi.there}} boo§ {{hullo.there.again}}")
(re-find #"\{\{(.*)\}\}" e)
["{{hi.there}} boo§ {{hullo.there.again}}" "hi.there}} boo§ {{hullo.there.again"]
I was hoping for something like
["hi.there" "hullo.there.again"]
How do I avoid the {} being used for repetition (or whatever is happening?)

Martin Půda06:05:48

This part .* is greedy and doesn't exclude { and } characters. Try something like this:

(->> "we are {{hi.there}} boo§ {{hullo.there.again}}"
     (re-seq #"(?:\{\{)([^\{\}]*)(?:\}\})")
     (map second))

=> ("hi.there" "hullo.there.again")

🙏 1
maverick10:05:03

I need to get input elementById and set its value. How can I do this in Clojurescript ?

maverick10:05:46

(set! (.. js/document (getElementById "app") -value) "Some text") will this work ?

delaguardo10:05:21

(set! (.-value (js/document.getElementById "app-center")) "Some Text") this will work for sure

👍 1
Ho0man10:05:07

Hi everyone, Is there a way that I could override the equality check for byte-arrays? I have a nested structure where the top entities are being checked using equality = I want to replace bytearray equality check to use this instead (-> byte-array seq)

Alex Miller (Clojure team)11:05:07

No,you can't override that

👍 1
zakkor10:05:43

So far I've only been working on my application using the REPL. At some point though, I'm going to want to deploy it to a VPS somewhere. What would be the best method to deploy production Clojure code? Is there any difference between simply clj -Xing a function, or creating an uberjar using tools.build?

delaguardo11:05:33

1. uberjar will have all your dependencies prepacked in one binary. for clj -X you must ensure that it is possible to download dependencies from external repositories or provide it yourself into correct location. Sometimes it is not possible due to restrictions of VPS 2. uberjar might have faster startup time if you compile your code ahead of time 3. uberjar essentially is a container to be executed by JVM so start up command will be different from clj -X

delaguardo11:05:25

those points are not necessarily problems, just the things worth to know about.

zakkor11:05:25

Awesome, looks like uberjar is the way to go in that case, thanks!

plexus11:05:46

The short answer is: either will work fine. clj -X might be easier to get started, and will continue to work fine. I know quite a few Clojure companies that actually do deploy and run this way. Uberjar has some benefits as @U04V4KLKC points out, but also some more things that can potentially break.

zakkor11:05:03

But there's no performance difference between the two, right?

zakkor11:05:13

(maybe other than startup time)

plexus11:05:32

once your code is loaded and the JVM is warmed up there's no difference.

👍 2
Alex Miller (Clojure team)11:05:13

If you compile your uberjar with direct linking, that can be faster

Alex Miller (Clojure team)11:05:38

Although technically you could do that with -X too

Paulo Bardes16:05:16

Hello there fellow clojurists! I’ve been learning my way around spec and test.check, to do so I’m implementing a marble race simulator, but I’m not sure the solution I’ve found to spec a set of marbles is ideal… A marble looks like: #:bookie.marble{:color :white, :luck 3, :speed 9, :weight 5} , which is easy enough to spec, now I’d like to spec a marble set containing exactly one marble of each color from a given set of colors. The best solution I got was doing something like:

(s/def ::marble-set
  (s/with-gen (s/and (s/coll-of ::marble :into [] :count (count color-set))
                     #(apply distinct? (map ::color %)))
    #(gen/fmap (fn [_] (map random-marble color-set)) (gen/boolean))))
I’m basically improvising a constant generator with an s/fmap and using a function to generate a random marble for a given color. Is this the best way to do thing? Should I be using the same function that I’ll validade later to generate examples? I can’t think of any other way of generating tests efficiently…

hiredman18:05:05

no, writing a generator this way breaks shrinking and makes it non-repeatable (the same seed when testing won't result in the same values tested)

hiredman18:05:35

given you have a fixed set of colors, I would generate a vector of booleans, where each position in the vector represents if a color is present or not, and then use fmap to construct the set from the vector

hiredman18:05:42

or if you want a constant set of colors generated, then use gen/return

Paulo Bardes18:05:56

Huh, that sounds good, but every color should always be present…

hiredman18:05:36

(gen/return my-set-of-colors)

❤️ 1
Paulo Bardes18:05:16

I’m trying to make the marble set into a s/map-of or a s/keys with the color as a key and the properties as values…

Paulo Bardes18:05:09

So there is a generator for a constant value, awesome! I’ll give it a try!

hiredman18:05:44

generators are a turducken of monads (a monad in a monad), names like fmap and return are the result of that. return is the usual name for an operation that lifts some value into a monadic value

Zapperdulchen19:05:10

Hi, I have just solved problem 144 of 4clojure and I am wondering whether there is some TCO going on because even for huge numbers this recursive lazy seq doesn't fill up the stack: (defn p144 [x f & fs] (lazy-seq (cons x (apply p144 (f x) (concat fs [f]))))) (reduce + (take 100000000 (p144 0 inc dec inc dec inc))) What is happening here? Thank you in advance, Zapperdulchen

🙂 1
Alex Miller (Clojure team)19:05:33

reduce does not hold the head of the sequence so it can just walk down the (large) lazy sequence, looking at one element at a time while the already seen elements get gc'ed behind

ghadi19:05:32

"recursive" is a bit misleading as it's not stack recursive

ghadi19:05:10

[thunk] [element] -> [next thunk] [element] -> [element] -> [next thunk]

Zapperdulchen19:05:59

I do not understand. How do I know whether something is stack recursive. Some link which explains this difference would be helpful.

Zapperdulchen19:05:25

@U064X3EF3 This explains why (fact 10000) behaves differently depending on the definition: (defn fact [n] (if (= n 1) 1 (*' n (fact (dec n))))) (defn fact [n] (reduce *' (range 1 (dec n)))) Didn't know that, but very helpful!

ghadi21:05:59

fns that are stack recursive call themselves, like your first fact function

ghadi21:05:43

the lazy seq is not stack recursive because it doesn't call itself: lazy-seq is a macro that makes a function that is called later when the seq is realized

ghadi21:05:56

user=> (macroexpand '(lazy-seq (some-recursive-looking-call)))
(new clojure.lang.LazySeq (fn* [] (some-recursive-looking-call)))

Paulo Bardes20:05:35

Another question, I’m trying to procedurally spec a set of namespaced keywords:

(def color-set #{::black ::red ::green ::blue ::yellow ::cyan ::magenta ::white})
I’ve tried the following at the REPL:
(doall (map #(s/def % ::marble) color-set))
But the keywords don’t appear to be registered as specs when I do so :/

Paulo Bardes20:05:27

I ended up doing this:

(eval (cons 'do (map
                  (fn [color] `(s/def ~color ::marble))
                  color-set)))
Not sure if it’s the most elegant way of doing things but it worked :)