Fork me on GitHub
#beginners
<
2021-07-17
>
sova-soars-the-sora00:07:22

I’m using (doseq [date dates] …) to do some per-day calculations. I’m wondering, what other “looping” constructs might be good? Conceptually I’d like to turn everything into mapping operations but I’m starting with a little bit more explicitness in transfomations

sova-soars-the-sora02:07:19

How do you invoke this function here https://clojuredocs.org/clojure.core/recur#example-542692d0c026201cdc326ea6

(def factorial
  (fn [n]
    (loop [cnt n
           acc 1]
       (if (zero? cnt)
            acc
          (recur (dec cnt) (* acc cnt))
; in loop cnt will take the value (dec cnt)
; and acc will take the value (* acc cnt)
))))

sova-soars-the-sora02:07:54

I was thinking something like (take 5 factorial) but it’s not returning a sequence, it’s just a def with an internal (fn [n] …) so I don’t understand how @ invoke

dpsutton02:07:12

It’s a function. So just call it (factorial 4)

dpsutton02:07:36

It’s a var that points to a function which is exactly what you get with defn

sova-soars-the-sora02:07:58

oh, even as def instead of defn?

sova-soars-the-sora02:07:49

Thanks. I did not know you could do that.

sova-soars-the-sora02:07:08

o.o mini mind blown

dpsutton02:07:52

I think you can do (macroexpand ‘(defn foo [])) and see exactly what it does

sova-soars-the-sora02:07:19

thanks for that. Great tip. I’ll have to macroexpand errthang going forward

sova-soars-the-sora02:07:02

It makes a lot of sense. Everything is a function or… a collection … or primitive

noisesmith18:07:09

everything is a java.lang.Object, some of those Objects happen to implement the right methods to be called (functions) or accessed for contents (collections)

sova-soars-the-sora02:07:54

so here’s some weird looking stuff

(def sum-it-up
  (fn [n] 
    (fn [y] 
      (+ n y))))
And

sova-soars-the-sora02:07:07

((sum-it-up 3) 2) 
=> 5

nivekuil02:07:37

I want to register some code within a macro to be called in a different context. I think I need to close over the refer somehow, or ns qualify it, but not sure how to do it

(register ; macro
 (fn [x]
   ;; bar is from [com.something :refer [bar]]
   (bar x)))

indy03:07:10

You could qualify bar yourself, com.something/bar or if the com.something ns is required in the ns that the macro is being defined, then using a syntax quote will automatically qualify all the symbols inside the macro. It would be easier to comment on an attempt that you’ve already made.

nivekuil03:07:40

no manual work; the macro has to know that bar should be qualified and x should not

indy03:07:13

Is the code snippet a pseudo code for the macro definition of register or is that how you expect to call the macro? (I'm attempting to write one)

nivekuil03:07:11

thats' how I expect to call the macro , which I call here`register`

indy03:07:51

Not sure if the following is your intent,

(defmacro register [[x binding] & body]
  `(do 
     (com.something/bar ~binding)
     (let [~x ~binding]
       ~@body)))

(macroexpand-1 '(register [x 2] (when x "hello")))
It expands to,
(do (com.something/bar 2) (clojure.core/let [x 2] (when x "hello")))

indy04:07:18

You should look at unquote ~ and syntax quote.

indy04:07:16

My macro assumes com.something is required somewhere in your code

nivekuil04:07:19

not quite -- the thing is that bar is actually part of the body, and the macro has to figure out its nature at the time the macro is evaled

nivekuil04:07:40

it's a little hard to explain the practical use case without going into how pathom works

indy04:07:35

Ooh got it. From my pov it's quite difficult to do that if bar is not going to be passed in a definite position. But I'll let others chime in at this point

sova-soars-the-sora04:07:44

I don’t understand the question but I’m a total newb so… what’s the output you want?

nivekuil04:07:48

bit hard to explain, but I actually just figured out the problem I was mulling over here over on #pathom

nivekuil04:07:20

tl;dr didn't need to eval late, so this problem is avoided entirely

didibus04:07:54

You probably wanted (~'bar x)

didibus04:07:39

Otherwise macros do what you ask naturally, so it depends what you want

didibus04:07:28

If you wanted bar to refer to the function bar that exist at the time the macro is defined, then you just need to use backquote bar and it'll expand automatically to whatever bar refers too at that time. But if you want bar to refer to whatever it is bound too when the macro is called, then you want ~'bar`

sova-soars-the-sora07:07:42

(def primes-display (atom [2]))
(defn get-primes [max]
  (loop [n 3]
  (let [mars (map #(not (= 0 (rem n %1))) @primes-display)] ;result bools table for is not divis?
    (if (every? true? mars)
        (swap! primes-display conj n)
      )
    (if (or 
         (not (> n max)) 
         (not (> n (last @primes-display))))
          (recur (inc (inc n)))
    @primes-display))))
Hi, the above is a prime number sieve i made using an atom. It works I reckon, but I don’t know how to make it better so that it can handle numbers significantly larger than 3000. I am under the impression that (map f coll) will be a lazy coll, and every? will short-circuit on a false.

sova-soars-the-sora07:07:35

Maybe #code-reviews would be better for this? Unsure.

sova-soars-the-sora07:07:32

Apparently it can handle numbers as high as 15,000 in the online REPL as long as I don’t print the result…. Just getting the time it takes… maybe the online REPL I’m testing it in is rate limited

roelof09:07:52

Is there no learning group to learn clojure well ?

dgb2313:07:32

what would be the clojure way of writing this function? should I use loop and recur instead of reduce here?

(defn all-symbols
  [form]
  (reduce (fn [syms exp]
            (cond (symbol? exp) (conj syms exp)
                  (list? exp) (cset/union syms (all-symbols exp))
                  :else syms))
          #{}
          form))

indy13:07:25

Just an alternative using postwalk

(defn all-symbols 
   [form]
   (let [syms (atom #{})]
     (clojure.walk/postwalk (fn [x] 
                              (when (symbol? x) 
                                (swap! syms conj x))) 
                            form)
     @syms))

indy13:07:31

One more

(filter symbol? (tree-seq list? identity '(def a (inc 9))))

dgb2313:07:16

there also might be one with zippers, which is something I want to learn to use too

dgb2314:07:42

wow tree-seq is super useful ty for bringing this to my attention @UMPJRJU9E

JohnJ13:07:05

yes if your input can be large and you don't want to blow the stack

dgb2315:07:50

why does this work: (zipmap #{true false} (repeat :value)) but not this: (zipmap (repeat :value) #{true false})

dgb2315:07:44

well the first one actually doesn’t do what I want either. but at least I get a value for each of one in the set

dgb2315:07:59

oops i get it

dgb2315:07:27

this is what I want: (map (fn [v] {:value v}) #{true false})

ghadi15:07:00

remember sets don’t have an order

ghadi15:07:10

Iteration order cannot be relied upon

dgb2316:07:20

I use a set here intentionally, but this is a good reminder!