beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
euccastro 2020-12-29T07:25:08.225900Z

the futures are not checking for an empty @work and they are not calling add-dosync, just referencing it. see while for a way to run something until a condition becomes false. to call add-dosync just wrap your references in parentheses: (add-dosync)

roelof 2020-12-29T09:35:34.226600Z

why do I get here a classcastexception on the let part :

(def work (ref (apply list (range 1e5))))


; And the sum will be a ref as well:
(def sum4 (ref 0))

; Write a function which, in a dosync transaction, removes the first number in 
; work and adds it to sum. Then, in two futures, call that function over and 
; over again until there's no work left. Verify that @sum is 4999950000. 
; Experiment with different combinations of alter and commute–if both are 
; correct, is one faster? Does using deref instead of ensure change the result?

(defn add-dosync [work sum4]
  (dosync
  (alter (ensure sum4) + (first @work))
  (ref-set work (next @work))))


(let [worker1 (future (while @work (add-dosync work sum4)))
      worker2 (future (while @work (add-dosync work sum4)))]
@worker1 ;wait for worker1
@worker2 ;wait for worker2
@sum4) ;return the result of their work

(deref sum4)

Ben Sless 2020-12-29T10:30:32.227300Z

@marcus.akre you can always pick up where Tim Baldridge left off here https://github.com/halgari/com.tbaldridge.hermod

euccastro 2020-12-29T10:37:39.228600Z

@roelof (ensure sum4) returns the current value of sum4 , which is a long. alter takes a ref, not a long

roelof 2020-12-29T10:39:38.229Z

oke, then I have to think how to solve that

roelof 2020-12-29T10:39:57.229500Z

as far as I know I have to use ensure somewhere

euccastro 2020-12-29T10:45:19.230500Z

you should use ensure on the ref you're reading the value of in the dosync body, which is not sum4

roelof 2020-12-29T10:45:22.230600Z

sorry, I do not

roelof 2020-12-29T10:45:42.231100Z

but still if I change the code to this :

(defn add-dosync [work-ref sum-ref]
  (dosync
  (alter sum-ref + (first @work-ref))
  (ref-set work-ref (next @work-ref)))

roelof 2020-12-29T10:45:54.231500Z

I get the classCastException

euccastro 2020-12-29T10:46:02.231800Z

also, I recommend using alter too to update work: (alter work next)

roelof 2020-12-29T10:46:56.232300Z

also changed

euccastro 2020-12-29T10:47:01.232400Z

are you sure you have reevaluated add-dosync after the change?

roelof 2020-12-29T10:47:08.232600Z

yep

roelof 2020-12-29T10:47:27.233100Z

I re-evaluted everything after a change

euccastro 2020-12-29T10:50:26.234800Z

one additional problem may be that (first @work-ref) may be null. maybe the easiest way around that would be to check for that condition inside the dosync body

roelof 2020-12-29T10:51:03.235600Z

oke, you mean if the work collection is empty ?

euccastro 2020-12-29T10:51:08.235800Z

that's even though you're checking in the future bodies, but there's a possible race condition there; you shouldn't rely on that

roelof 2020-12-29T10:52:01.237Z

the exact error message is :

; Execution error (ClassCastException) at ground-up.chapter6/add-dosync$fn (form-init16078161836259666359.clj:80).
; class java.lang.Long cannot be cast to class clojure.lang.Ref (java.lang.Long is in module java.base of loader 'bootstrap'; clojure.lang.Ref is in unnamed module of loader 'app')

euccastro 2020-12-29T10:52:02.237100Z

that check is OK to make the future finish when it's done, but you are not guaranteed that work won't be completed between the check and the execution of add-dosync

roelof 2020-12-29T10:53:10.237800Z

oke, so you are thinking I have to check for if work is empty also in the do-sync ?

euccastro 2020-12-29T10:53:40.238400Z

yes, but that doesn't look like it could cause the particular error you're getting; you should get a nullpointerexception instead

euccastro 2020-12-29T10:54:13.238900Z

can you paste the whole program again?

roelof 2020-12-29T10:54:17.239100Z

oke, and sentence 80 is alter sum-ref + (first @work-ref))

roelof 2020-12-29T10:54:42.239600Z

of course

; Write a function which, in a dosync transaction, removes the first number in 
; work and adds it to sum. Then, in two futures, call that function over and 
; over again until there's no work left. Verify that @sum is 4999950000. 
; Experiment with different combinations of alter and commute–if both are 
; correct, is one faster? Does using deref instead of ensure change the result?

(defn add-dosync [work-ref sum-ref]
  (dosync
  (alter sum-ref + (first @work-ref))
  (alter work-ref (next @work-ref))))

(let [worker1 (future (while @work (add-dosync work @sum4)))
      worker2 (future (while @work (add-dosync work @sum4)))]
@worker1 ;wait for worker1
@worker2 ;wait for worker2
@sum4) ;return the result of their work

(deref sum4)

euccastro 2020-12-29T10:55:00.240Z

remove the @ before sum4 in the future bodies

roelof 2020-12-29T10:55:52.240700Z

same error

euccastro 2020-12-29T10:55:53.240800Z

that's causing the same problem you were getting before by calling (alter (ensure sum4) ,,,)

roelof 2020-12-29T10:58:02.241700Z

Deleting that did not solve the eror message

euccastro 2020-12-29T10:58:12.242Z

have you reevaluated the whole program?

roelof 2020-12-29T10:58:27.242300Z

yep, as I said I always do that

euccastro 2020-12-29T10:59:23.243Z

(alter work-ref (next @work-ref)) should be just (alter work-ref next)

roelof 2020-12-29T10:59:34.243500Z

now I see this error :

; Execution error (ClassCastException) at ground-up.chapter6/add-dosync$fn (form-init16078161836259666359.clj:81).
; class clojure.lang.PersistentList cannot be cast to class clojure.lang.IFn (clojure.lang.PersistentList and clojure.lang.IFn are in unnamed module of loader 'app')

euccastro 2020-12-29T11:00:03.243800Z

yes, see my latest comment

roelof 2020-12-29T11:00:23.244300Z

yep

euccastro 2020-12-29T11:00:25.244600Z

alter takes a ref and a function, not a value

roelof 2020-12-29T11:00:41.245Z

now a null pointer exception as you said earlier

euccastro 2020-12-29T11:01:33.245800Z

so you can check for a null (first @work-ref) and just exit in that case

roelof 2020-12-29T11:02:06.246300Z

yep, finally after some many days

🎉 1
roelof 2020-12-29T11:07:34.246600Z

thanks

roelof 2020-12-29T11:07:37.246800Z

need a break

roelof 2020-12-29T11:08:00.247200Z

changed it to :

(defn add-dosync [work-ref sum-ref]
  (when (seq @work-ref)
    (dosync
     (alter sum-ref + (first @work-ref))
     (alter work-ref next))))

roelof 2020-12-29T11:08:10.247500Z

but still the null pointer exception

euccastro 2020-12-29T11:11:02.247900Z

you should definitely check inside the dosync

euccastro 2020-12-29T11:12:06.249Z

probably using ensure instead of deref/`@`(but give both a try to verify that ensure is needed)

roelof 2020-12-29T11:14:50.249200Z

oke

roelof 2020-12-29T11:14:59.249500Z

I tried this :

(defn add-dosync [work-ref sum-ref]
  (dosync
   (while @work-ref (alter sum-ref + (first @work-ref)))
   (while @work-ref (alter work-ref next))))

roelof 2020-12-29T11:15:08.249800Z

but it seems this is running forever

roelof 2020-12-29T11:17:23.250Z

finallly working

roelof 2020-12-29T11:17:26.250300Z

(defn add-dosync [work-ref sum-ref]
  (dosync
   (when @work-ref (alter sum-ref + (first @work-ref)))
   (when @work-ref (alter work-ref next))))

roelof 2020-12-29T11:22:11.250900Z

and alter or commute makes no difference. the same output

roelof 2020-12-29T11:22:52.251800Z

hmm, but both the wrong answer 😞

Timur Latypoff 2020-12-29T11:23:29.252700Z

@roelof Please try the following

(defn add-dosync [work-ref sum-ref]
  (dosync
    (when-let [work (seq (ensure work-ref))]
      (alter sum-ref + (first work))
      (ref-set work-ref (next work)))))
— a a single check for non-empty sequence, — single ensure

roelof 2020-12-29T11:23:48.253200Z

it should be 4999950000 and both gives 4999984077

Timur Latypoff 2020-12-29T11:25:48.255100Z

Not sure if this question was discussed before thought (can't read all those pages above), but this is also not a good case for using refs, maybe only as an exercise. Because this algorithm of summing a list does not benefit from parallelization at all (all entries are processed one by one sequentially anyway).

roelof 2020-12-29T11:26:09.255400Z

I know and this is discuused before

👍 1
roelof 2020-12-29T11:26:21.255900Z

but when I try your code it seems to run forever

Timur Latypoff 2020-12-29T11:26:31.256400Z

Ok, let me fire up the repl 🙂

roelof 2020-12-29T11:26:33.256600Z

I still do not see a answer

Timur Latypoff 2020-12-29T11:29:34.256700Z

Would you please paste the code?

roelof 2020-12-29T11:30:16.256900Z

(def work (ref (apply list (range 1e5))))


; And the sum will be a ref as well:
(def sum4 (ref 0))

; Write a function which, in a dosync transaction, removes the first number in 
; work and adds it to sum. Then, in two futures, call that function over and 
; over again until there's no work left. Verify that @sum is 4999950000. 
; Experiment with different combinations of alter and commute–if both are 
; correct, is one faster? Does using deref instead of ensure change the result?

(defn add-dosync [work-ref sum-ref]
  (dosync
    (when-let [work (seq (ensure work-ref))]
      (alter sum-ref + (first work))
      (ref-set work-ref (next work)))))


(let [worker1 (future (while @work (add-dosync work sum4)))
      worker2 (future (while @work (add-dosync work sum4)))]
@worker1 ;wait for worker1
@worker2 ;wait for worker2
@sum4) ;return the result of their work

Timur Latypoff 2020-12-29T11:38:51.257100Z

@roelof from what I see, it's not running forever, it's just being REALLY slow 🙂

Timur Latypoff 2020-12-29T11:39:36.257300Z

roelof 2020-12-29T11:42:32.257900Z

oke, I will try again and wait for the answer

roelof 2020-12-29T11:42:39.258100Z

and see if it's the right one

Timur Latypoff 2020-12-29T11:42:45.258300Z

👌

roelof 2020-12-29T11:42:52.258500Z

does ensure makes is this slow

Timur Latypoff 2020-12-29T11:43:15.258700Z

No idea, first time using refs myself. I'm not an expert, I was just curious 🙂

roelof 2020-12-29T11:43:57.259100Z

me too first time use it. The "Clojure from the ground up" was telling me to use a ref

gibi 2020-12-29T11:44:38.259800Z

Hi, I’ve been trying the fox-goose-corn kata and worked out this solution - https://paste.ofcode.org/mpzmsutwdEK3GczkzjZ6Tx I guess there are still a few things wrong…

gibi 2020-12-29T11:44:42.259900Z

Given a configuration, calc-path tries to generate the possible options using for and evaluate them recursively. If a child configuration is invalid or already explored, returns [] . If the child configuration has all the items on the right bank, returns the entire path. Because I’m using for, I had to apply a few quick fixes to make it work, for example I use remove empty? at line 80 and 86. Another one is at line 115. The path is inside a series of lists ((((path)))) so I had to find a way to extract it.

Timur Latypoff 2020-12-29T11:45:33.260400Z

We'll crack it, no worries 🙂

roelof 2020-12-29T11:45:56.260600Z

yep , here still no answer 🙂

Timur Latypoff 2020-12-29T11:46:16.260800Z

Overall, ref seems like a very heavy-weight tool, that's why it's rarely used, and people use atoms instead.

roelof 2020-12-29T11:47:25.261400Z

yep

roelof 2020-12-29T11:47:40.261600Z

now long did I take in min

roelof 2020-12-29T11:47:54.261800Z

I think im now at 2 - 3 min

Timur Latypoff 2020-12-29T11:49:42.262Z

I think around that, more or less.

Timur Latypoff 2020-12-29T11:50:06.262200Z

I can time it.

roelof 2020-12-29T11:50:59.262400Z

no needed

roelof 2020-12-29T11:51:13.262600Z

then you have a faster computer then I

roelof 2020-12-29T11:51:23.262800Z

here still no answer

Timur Latypoff 2020-12-29T11:53:11.263Z

Yeah, 2:30 on my macbook, but I ran it as uberjar.

roelof 2020-12-29T11:57:00.263200Z

aha, and I did it on repl

roelof 2020-12-29T11:57:25.263500Z

did it again and it's now at 26.000

roelof 2020-12-29T11:57:54.264500Z

so 26 thousand

Timur Latypoff 2020-12-29T11:58:38.266Z

Anyway, I think it’s not a real evaluation of speed of how refs work. Here the workload is so that two CPU threads are constantly fighting and re-doing each-other’s work. I would expect that on a single-core CPU the result will be calculated much faster :)

roelof 2020-12-29T11:59:28.266200Z

yep I know

roelof 2020-12-29T11:59:50.266400Z

When you do this with reduce it takes almost no time

roelof 2020-12-29T12:00:28.266600Z

and I have a 4 core machine so a lot of fighting

roelof 2020-12-29T12:01:04.266800Z

84 thousand

roelof 2020-12-29T12:02:16.267Z

and one with the right answer

roelof 2020-12-29T12:02:26.267200Z

in repl not on vs code

gibi 2020-12-29T12:03:39.267400Z

I wonder if there’s a better alternative to for to reach the same goal and avoid these those confusing lines

roelof 2020-12-29T12:04:18.267600Z

a lot learned and a lot to learn to really understand closures, ref and so on

roelof 2020-12-29T12:04:29.267900Z

I found this a very hard chapter

roelof 2020-12-29T12:07:44.270200Z

thanks a lot with your patience

👍 1
GGfpc 2020-12-29T12:08:51.271600Z

Hello! Can someone help me debug this error? Here is my code

(defn get-books-with-extra-data
  [url]
  (let [cached (cache/fetch url)]
    (if (not (nil? cached))
      cached
      (do
        (timbre/info "Fetching book: " url)
        (http/get url {} (fn [{:keys [status headers body error]}]
                           (->>
                             (map :body)
                             (map #(hash-map :book-genres (get-book-genres %) :book-cover (get-book-cover %)))
                             ;(cache/store url)
                             )))))))
Which is called here (I invoked this from the REPL)
(defn books-with-extra-data
  [books]
  (->> books
       (map #(merge %1 (book/get-books-with-extra-data (string/trim (get-in %1 [:book :link])))))))
And I get this strange stacktrace

GGfpc 2020-12-29T12:08:51.271700Z

(pst)
clojure.lang.ExceptionInfo: null
                                      main.clj:442 clojure.main/repl[fn]
                                      main.clj:458 clojure.main/repl[fn]
                                      main.clj:458 clojure.main/repl
                                      main.clj:368 clojure.main/repl
                                  RestFn.java:1523 clojure.lang.RestFn.invoke
                         interruptible_eval.clj:79 nrepl.middleware.interruptible-eval/evaluate
                         interruptible_eval.clj:55 nrepl.middleware.interruptible-eval/evaluate
                        interruptible_eval.clj:142 nrepl.middleware.interruptible-eval/interruptible-eval[fn]
                                       AFn.java:22 clojure.lang.AFn.run
                                   session.clj:171 nrepl.middleware.session/session-exec[fn]
                                   session.clj:170 nrepl.middleware.session/session-exec[fn]
                                       AFn.java:22 clojure.lang.AFn.run
                                   Thread.java:748 java.lang.Thread.run
Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: org.httpkit.client$deadlock_guard$reify__17177
                                       RT.java:557 clojure.lang.RT.seqFrom
                                       RT.java:537 clojure.lang.RT.seq
                            APersistentMap.java:40 clojure.lang.APersistentMap.cons
                                       RT.java:677 clojure.lang.RT.conj
                                       core.clj:85 clojure.core/conj
                                     core.clj:3049 clojure.core/merge[fn]
                                      core.clj:944 clojure.core/reduce1
                                      core.clj:934 clojure.core/reduce1
                                     core.clj:3048 clojure.core/merge
                                     core.clj:3041 clojure.core/merge
                                   RestFn.java:421 clojure.lang.RestFn.invoke
                                       stats.clj:2 goodstats.consumer.stats/eval17623[fn]
                                     core.clj:2755 clojure.core/map[fn]
                                   LazySeq.java:42 clojure.lang.LazySeq.sval
                                   LazySeq.java:51 clojure.lang.LazySeq.seq
                                       RT.java:535 clojure.lang.RT.seq
                                      core.clj:137 clojure.core/seq
                                 core_print.clj:53 clojure.core/print-sequential
                                core_print.clj:174 clojure.core/fn
                                core_print.clj:174 clojure.core/fn
                                  MultiFn.java:234 clojure.lang.MultiFn.invoke
                                      print.clj:21 nrepl.middleware.print/pr-on
                                      print.clj:17 nrepl.middleware.print/pr-on
                                     print.clj:148 nrepl.middleware.print/send-nonstreamed[fn]
                                     print.clj:147 nrepl.middleware.print/send-nonstreamed[fn]
                                     core.clj:2742 clojure.core/map[fn]
                                  protocols.clj:49 clojure.core.protocols/iter-reduce
                                  protocols.clj:75 clojure.core.protocols/fn
                                  protocols.clj:75 clojure.core.protocols/fn
                                  protocols.clj:13 clojure.core.protocols/fn[fn]
                                     core.clj:6884 clojure.core/transduce
                                     core.clj:6870 clojure.core/transduce
                                     print.clj:156 nrepl.middleware.print/send-nonstreamed
                                     print.clj:138 nrepl.middleware.print/send-nonstreamed
                                     print.clj:174 nrepl.middleware.print/printing-transport[fn]
                                     caught.clj:58 nrepl.middleware.caught/caught-transport[fn]
                        interruptible_eval.clj:114 nrepl.middleware.interruptible-eval/evaluate[fn]
=> nil

GGfpc 2020-12-29T12:08:51.271800Z

I have no idea how to proceed from here because I'm using a callback function to process the request so I think I'm correct to assume that the response has been received when the function is called (which is the only problem I could think of). Previously I was using clj-http and it was working fine, but I switched to http-kit for better performance and most of the requests work correctly but some fail with this error

euccastro 2020-12-29T12:14:27.272400Z

try commute instead of alter, see how fast/correct it is?

roelof 2020-12-29T12:14:55.273100Z

Can anyne tell me how I can make it work that the repl is next to my code instead of the same part so I do not have to switch tabs

roelof 2020-12-29T12:15:26.273200Z

I will if I have the layout of vs code right

lassemaatta 2020-12-29T12:15:30.273400Z

I believe http/get returns a promise, which you must deref somewhere to get the actual returned value

lassemaatta 2020-12-29T12:18:46.273600Z

the Don't know how to create ISeq from: org.httpkit.client$deadlock_guard$reify__17177 error refers to the reified deadlock-guard promise, which you haven't dereffed

GGfpc 2020-12-29T12:25:18.273800Z

But that's when you don't give it a callback function right? When I try to deref the body parameter of the callback I get

java.lang.ClassCastException: java.lang.String cannot be cast to java.util.concurrent.Future

GGfpc 2020-12-29T12:25:39.274Z

both with @body and deref body

lassemaatta 2020-12-29T12:28:46.274300Z

if I read the httpkit code and docstring correctly, it always returns a promise but depending on whether you gave a callback it will resolve to either the response as-is or pass the response to your callback and resolve the return value

GGfpc 2020-12-29T12:29:48.274500Z

I think I know the problem. Since this is asynchronous, I think it's returning immediately to the caller code, which does some processing with the expected response causing it to fail

roelof 2020-12-29T12:32:52.275100Z

on some wierd way repl is now a tab instead of a seperate window

roelof 2020-12-29T12:38:33.275300Z

hmm

roelof 2020-12-29T12:38:50.275500Z

after lunch I have to figure out how to make this work

roelof 2020-12-29T12:38:54.275700Z

(defn add-dosync [work-ref sum-ref]
  (dosync
    (when-let [work (seq (commute work-ref))]
      (alter sum-ref + (first work))
      (ref-set work-ref (next work)))))

roelof 2020-12-29T12:39:13.275900Z

at some way I have to give commute another argument

Timur Latypoff 2020-12-29T12:47:15.276500Z

You should use commute instead of alter

roelof 2020-12-29T12:51:31.276700Z

yep

roelof 2020-12-29T12:53:02.276900Z

it seems to work faster

roelof 2020-12-29T12:53:23.277100Z

wait for the answer

Timur Latypoff 2020-12-29T12:54:06.278400Z

Cool. Good to know. I am not yet proficient enough to know when commute will do, and when alter is required to get a correct result.

roelof 2020-12-29T12:58:54.278600Z

According to the book alter/ensure if the order is important and commute when the order is not important

roelof 2020-12-29T12:59:38.278800Z

so as a example 1 + 2 + 3 the order is not important because also 1 + 3 + 2 - 6 also 3 + 1 + 2 = 6

👍 1
Timur Latypoff 2020-12-29T13:00:00.279100Z

Ok, makes sense

roelof 2020-12-29T13:00:11.279400Z

but on this the order is important (1/2)/3 in not the same as 1/ (2/3)

roelof 2020-12-29T13:01:19.279700Z

that 0.16 or 0,666 if im not mistaken

Timur Latypoff 2020-12-29T13:04:36.280700Z

I guess if you’re asking about VSCode and Calva, better to ask in #calva

roelof 2020-12-29T13:05:55.280900Z

thanks

roelof 2020-12-29T13:11:52.281100Z

yep

roelof 2020-12-29T13:12:16.281300Z

this :

(defn add-dosync [work-ref sum-ref]
  (dosync
    (when-let [work (seq (ensure work-ref))]
      (alter sum-ref + (first work))
      (ref-set work-ref (next work)))))
and this :
(defn add-dosync [work-ref sum-ref]
  (dosync
    (when-let [work (seq (ensure work-ref))]
      (commute sum-ref + (first work))
      (ref-set work-ref (next work)))))

roelof 2020-12-29T13:12:33.281500Z

give the same right outcome

👍 1
roelof 2020-12-29T13:14:31.281800Z

@euccastro

roelof 2020-12-29T13:35:01.283500Z

Did I do it right now ?

roelof 2020-12-29T14:07:25.285700Z

when I try this :

(parse-string (slurp "2008.json"))
I get a file not found error where im sure the 2008.json file is in the same src directory as the chapter7,clj file

2020-12-29T14:13:04.285900Z

Is the chapter7.clj source file in a directory like src/some-name-space/chapter7.clj in a Leiningen project, or something like that? If so, the current directory of the running JVM process is likely to be the top level directory of that project when you run the code.

2020-12-29T14:14:32.286100Z

If you print out the value of this expression, which should return a string, it should show you the current directory of the running JVM process, or at least what it was when the JVM process began: (System/getProperty "user.dir")

euccastro 2020-12-29T14:32:52.286300Z

you could use (commute work-ref next) too

roelof 2020-12-29T14:42:43.287200Z

yep, it was the root dir of the projecy

"/home/roelof/ground-up/ground-up"

roelof 2020-12-29T14:43:18.287700Z

oke

roelof 2020-12-29T14:43:32.288Z

also you thanks for the patience with me

euccastro 2020-12-29T14:55:36.295Z

np 🙂

yubrshen 2020-12-29T15:02:41.297600Z

Seeking advice on selection of full stack suits web app of ToDo: I'd like to develop an app of todo. It should support web browser as interface, and eventually maybe native mobile app. I hope the user experience should be better than typical web browser experience, For example, I'd like to support extensive auto-completion of user input, allow context menu by clicking the right mouse button, and have timer etc. For data storage, I guess a SQL database would be enough, as the storage would be mostly in table and sequential, Datomic would be an overkill. It should also support user authentication. Would you kindly advise me which full stack suits I should take? I've studied using ring/hiccup/compojure, rum, jdbc.next, datomic for database web app. I have not tried Coast framework, Fulcro, Luminus, Pedestal, etc. With so many seemingly good choices, I feel anxious. This is a hobby/prototype effort, for MVP (Minimal Viable Product). Thanks a lot for your help!

roelof 2020-12-29T15:39:50.298800Z

Wonder why the output is not sorted on the numbers

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              [(fips (fips-code county))
               (:driving_under_influence county)]))
       (into {})))

2020-12-29T15:41:42.299500Z

In the last step, you put the data into a Clojure map (into {}). Clojure maps are not sorted by keys.

2020-12-29T15:42:55.300800Z

There is a sorted map variant of Clojure maps, which are sorted by keys. If that is something you want to try, you could change the last line to (into (sorted-map)) (there is no literal representation of sorted maps that is like {} for the default (unsorted) maps).

clyfe 2020-12-29T15:44:41.301500Z

Nor ordered, see https://github.com/clj-commons/ordered

roelof 2020-12-29T15:45:25.302Z

still not ordered

roelof 2020-12-29T15:45:30.302300Z

{"AZ, Maricopa" 26235,
 "CA, Los Angeles" 45056,
 "CA, Orange" 17572,
 "CA, Riverside" 10814,
 "CA, Sacramento" 8589,
 "CA, San Bernardino" 13983,
 "CA, San Diego" 18562,
 "NV, Clark" 10443,
 "TX, Harris" 10432,
 "WA, King" 11439}

roelof 2020-12-29T15:46:35.302500Z

` (defn most-duis   "Given a JSON filename of UCR crime data for a particular year, finds the   counties with the most DUIs."   [file]   (->> file        load-json        (sort-by :driving_under_influence)        (take-last 10)        (map (fn [county]               [(fips (fips-code county))                (:driving_under_influence county)]))        (into (sorted-map)))) `

2020-12-29T15:51:47.305Z

sorted-map order keys by hash function, not alphabeticaly this is wrong ) my bad

2020-12-29T15:57:01.307Z

@roelof The result you showed last above is sorted alphabetically by the keys. What do you want it sorted by?

2020-12-29T15:59:06.308500Z

Oh, I see now you said earlier "on the numbers". One recommendation: write a little print function to print the data in the order you want to see it in, but let it be stored in a default Clojure map, which is not sorted in any particular order (well, it is sorted on a hash function of the keys, but that is unlikely to be an order you are interested in knowing).

2020-12-29T16:02:28.308700Z

Example:

(def d1 {"AZ, Maricopa" 26235,
         "CA, Los Angeles" 45056,
         "CA, Orange" 17572,
         "CA, Riverside" 10814,
         "CA, Sacramento" 8589,
         "CA, San Bernardino" 13983,
         "CA, San Diego" 18562,
         "NV, Clark" 10443,
         "TX, Harris" 10432,
         "WA, King" 11439})

user=> (pprint (sort-by val d1))
(["CA, Sacramento" 8589]
 ["TX, Harris" 10432]
 ["NV, Clark" 10443]
 ["CA, Riverside" 10814]
 ["WA, King" 11439]
 ["CA, San Bernardino" 13983]
 ["CA, Orange" 17572]
 ["CA, San Diego" 18562]
 ["AZ, Maricopa" 26235]
 ["CA, Los Angeles" 45056])

2020-12-29T16:03:54.310200Z

I know that last print result does not look like a map. That is because it is a sequence of map entries, which is what you get when you take a map and use it as a parameter to a function that expects a sequence, like sort-by does in the expression above. If all you care about is seeing it in the desired order, that shouldn't be a problem.

Andrew Byala 2020-12-29T16:09:00.310400Z

I have a pattern type of question for designing APIs. I come from a Java background where there are a lot of pure and impure functions mixed together, especially when reading and writing from a database. I've read Clojure guidance that says to write as much of the logic in pure functions as possible, and then use some sort of wiring layer to mix together these pure functions. It would seem that once you get past simple CRUD APIs, the coordination functions would become both very large and could potentially have a lot of duplication. Can anyone point me to either examples or tutorials that show how this works as the codebase grows?

Bill St. Clair 2020-12-29T16:31:03.314500Z

Old lisp expert here. New to Clojure. Writing a Swank client in ClojureScript (replacement for Emacs SLIME, for the browser). Once that’s done, I’ll likely add a cider client as well. This is a retirement project for me. I don’t have the mental energy I once did, so the Clojure startup transient is harder than it would have been 10 years ago, but I’ll get there. Clojure is, after all, just another lisp with some added syntax and a new standard library to learn (he said, not really knowing what he’s saying). https://github.com/billstclair/wilfred Not much here yet. If somebody has ideas for improvement of the basic project, I’d love the feedback. I’m just copying what I found on the web at this point. I think it will be good enough to get started, however.

👍 2
pavlosmelissinos 2020-12-29T16:31:50.314800Z

If you don't need constant time lookup, you might want to consider representing your data as a list of maps instead of a map:

[{:county "AZ, Maricopa" :dui 26235}
 {:county "CA, Los Angeles" :dui 45056}
 ...]
That way you don't have to treat maps (associative arrays) as something they're not and as an added bonus you get much prettier output out of the box using print-table! https://clojuredocs.org/clojure.pprint/print-table

roelof 2020-12-29T16:37:16.315500Z

@andy.fingerhut thanks, solved it

roelof 2020-12-29T16:38:25.315600Z

then I need to convert my data to it because its from a external source

roelof 2020-12-29T16:39:11.315800Z

or do you mean I can change something here to make this output :

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              [(fips (fips-code county))
               (:driving_under_influence county)]))
       (into{})
       (sort-by val)))

pavlosmelissinos 2020-12-29T16:40:15.316Z

yup, I'm talking about this:

(fn [county]
              [(fips (fips-code county))
               (:driving_under_influence county)])

roelof 2020-12-29T16:41:31.316300Z

oke, then I have to think how to make those changes

👍 1
2020-12-29T16:45:20.316600Z

that's incorrect - ensure is only needed for values you are not altering but only reading

Klavs Klavsen 2020-12-29T17:03:31.318500Z

I'm trying to grasp clojure here - playing with stumps of code. How do I loop through a list of maps and rewrite the maps (in other languages filter can be used for this):

(def mylist
  ({:a 1 :b 2 :c 3}
   {:a 1 :b 5 :c 6}
   {:a 7 :b 8 :c 12}
   {:a 10 :b 11 :c 12}))
and I want to modify the key 'b' so it contains the contents of key 'c'

2020-12-29T17:06:47.320600Z

(map (fn [m] (assoc m :b (m c)) mylist)

euccastro 2020-12-29T17:07:21.320900Z

with a colon before the c

Klavs Klavsen 2020-12-29T17:14:21.321100Z

Thanks. Trying that out however, Calva repl (visual studio code) just gives me:

println mylist #prints out mylist in repl window
(map (fn [m] (assoc m :b (m :c)) mylist)) #just prints out: #function[clojure.core/map/fn--5847]
😞

Klavs Klavsen 2020-12-29T17:14:53.321300Z

so println mylist works.. map just fails.. I'm doing ctrl+shift+p and evaluate top form

2020-12-29T17:15:15.321500Z

It appears that it evaluated just the sub-expression map, which I would expect to return a result like you showed.

Michael W 2020-12-29T17:15:41.321700Z

Parens are wrong, mylist should be in the last form, not inside the fn definition.

Michael W 2020-12-29T17:16:51.321900Z

(map #(assoc % :b (% :c)) mylist)

Klavs Klavsen 2020-12-29T17:17:26.322100Z

this worked:

println (map (fn [m] (assoc m :b (m :c))) mylist)
Thank you

Michael W 2020-12-29T17:17:40.322300Z

It's like you ran map without a collection, which returns a transducer function.

Klavs Klavsen 2020-12-29T17:17:43.322500Z

Now I have something to play with.. trying to get the hang of this 🙂

2020-12-29T17:26:50.322700Z

FYI the println at the beginning of those lines is probably not even being evaluated at all. You should be able to leave that out.

2020-12-29T17:27:22.323Z

Unless the REPL you are using is quite different than ones I have used before somehow ...

roelof 2020-12-29T17:37:21.323200Z

then I misunderstood the book

roelof 2020-12-29T17:37:32.323400Z

thanks for pointing this to me

roelof 2020-12-29T17:42:06.323600Z

hmm, I take a break this idea does not work

roelof 2020-12-29T17:42:10.323800Z

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              [{:county (fips (fips-code county)), :population (:driving_under_influence county)}]))
       (into {})))

roelof 2020-12-29T17:57:32.324200Z

Got it working

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              [{:county (fips (fips-code county))}, {:population (:driving_under_influence county)} ]))
       (into {})))

roelof 2020-12-29T17:57:42.324400Z

hopefully i did it right

pavlosmelissinos 2020-12-29T17:58:02.324600Z

you can simplify it further

roelof 2020-12-29T17:58:24.324800Z

can I ?

pavlosmelissinos 2020-12-29T17:59:19.325Z

also this still creates a map

pavlosmelissinos 2020-12-29T18:00:39.325200Z

Try this out:

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              {:county     (fips (fips-code county)),
               :population (:driving_under_influence county)}))))

roelof 2020-12-29T18:02:20.325600Z

that gives this :

({:county "CA, Sacramento", :population 8589}
 {:county "TX, Harris", :population 10432}
 {:county "NV, Clark", :population 10443}
 {:county "CA, Riverside", :population 10814}
 {:county "WA, King", :population 11439}
 {:county "CA, San Bernardino", :population 13983}
 {:county "CA, Orange", :population 17572}
 {:county "CA, San Diego", :population 18562}
 {:county "AZ, Maricopa", :population 26235}
 {:county "CA, Los Angeles", :population 45056})

roelof 2020-12-29T18:02:54.325800Z

where my old code gave this :

{{:county "AZ, Maricopa"} {:population 26235},
 {:county "CA, Los Angeles"} {:population 45056},
 {:county "CA, San Diego"} {:population 18562},
 {:county "CA, Sacramento"} {:population 8589},
 {:county "CA, Riverside"} {:population 10814},
 {:county "CA, Orange"} {:population 17572},
 {:county "CA, San Bernardino"} {:population 13983},
 {:county "NV, Clark"} {:population 10443},
 {:county "TX, Harris"} {:population 10432},
 {:county "WA, King"} {:population 11439}}

pavlosmelissinos 2020-12-29T18:04:11.326Z

yup, notice the parens instead of the curly brackets in the beginning/end?

roelof 2020-12-29T18:05:13.326200Z

yep

roelof 2020-12-29T18:06:30.326400Z

then tomorrow look if I can make it work to calculate the prevalance so this number divided by the population

roelof 2020-12-29T18:06:45.326600Z

as I see it now I have to make the calculation two times

roelof 2020-12-29T18:30:03.326800Z

hmm, this eems to do it almost

Klavs Klavsen 2020-12-29T18:30:31.327Z

you're right.. now it outputs it without the prinln @andy.fingerhut - odd it didn't at first

2020-12-29T18:31:46.327200Z

I would be very surprised if it actually required that -- the P in REPL is for Print, so after reading and evaluating your expression, it should always Print the return value (in addition to printing anything that the expression itself causes to print, e.g. a function call with calls to functions print and/or println inside of it).

👍 1
roelof 2020-12-29T18:31:46.327400Z

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :driving_under_influence)
       (take-last 10)
       (map (fn [county]
              {:county     (fips (fips-code county)),
               :total_uid (:driving_under_influence county)
               :prevalance ( / (:driving_under_influence county) (:county_population county))
               }))))
only the prevalence is not calculated:
{:county "CA, Los Angeles",
  :total_uid 45056,
  :prevalance 45056/9872263}

pavlosmelissinos 2020-12-29T18:36:01.327700Z

yes that's expected: https://clojure.org/reference/data_structures#_ratio

pavlosmelissinos 2020-12-29T18:39:08.327900Z

it is the correct form but you don't see the calculated value, you can run float on top of the division to get the actual result

roelof 2020-12-29T18:47:10.328100Z

thanks

roelof 2020-12-29T18:47:42.328300Z

next "problem"

roelof 2020-12-29T18:48:04.328500Z

it now sorts on drunk driving (sort-by :driving_under_influence)

roelof 2020-12-29T18:48:27.328700Z

I think I need to make a new key prevelance to see the 10 most highest ones

pavlosmelissinos 2020-12-29T18:49:05.328900Z

how many data points are there in the file?

roelof 2020-12-29T18:49:43.329100Z

183 thousand

roelof 2020-12-29T18:50:14.329300Z

he, I can do this :

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (sort-by :prevalance)
       (take-last 10)
       (map (fn [county]
              {:county     (fips (fips-code county)),
               :total_uid (:driving_under_influence county)
               :prevalance (float (/ (:driving_under_influence county) (:county_population county)))
               }))))

roelof 2020-12-29T18:50:41.329500Z

but I have to make a check against the fact that population can be zero

👌 1
pavlosmelissinos 2020-12-29T18:50:55.329700Z

that key doesn't exist yet when you sort

pavlosmelissinos 2020-12-29T18:52:20.329900Z

you could either compute it twice or move sort-by and take-last to the end, after the map

roelof 2020-12-29T19:12:41.330300Z

thanks

roelof 2020-12-29T19:12:47.330500Z

last question

roelof 2020-12-29T19:12:58.330700Z

I have now this :

(defn calculate_prevalance
  [county]
  ( if (zero? (:county_population county))
         0
    (float (/ (:driving_under_influence county) (:county_population county)))))
    

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (map (fn [county]
              {:county     (fips (fips-code county)),
               :total_uid (:driving_under_influence county)
               :prevalance (calculate_prevalance county)}))
       (sort-by :prevalance)
       (take 10)))

roelof 2020-12-29T19:13:18.330900Z

but the highest 10 are now all countys with prevelance of 0

roelof 2020-12-29T19:13:37.331100Z

Should I filter these out or is there a better way

pavlosmelissinos 2020-12-29T19:14:43.331900Z

sort-by sorts the data in ascending order

pavlosmelissinos 2020-12-29T19:15:21.332300Z

so take 10 takes the 10 items with the lowest prevalence

roelof 2020-12-29T19:15:22.332500Z

yep, so I get the countys with the lowest prevelance

pavlosmelissinos 2020-12-29T19:15:32.332800Z

exactly

pavlosmelissinos 2020-12-29T19:16:23.333100Z

Also, you might want to turn the fn into an actual function

roelof 2020-12-29T19:17:08.333300Z

??

roelof 2020-12-29T19:17:28.333500Z

this seems not to be sorted on the highest prevelance

roelof 2020-12-29T19:17:34.333700Z

|       :county | :total_uid | :prevalance | |---------------+------------+-------------| |      NC, Hyde |        125 | 0.024447488 | |      CA, Inyo |        424 | 0.024500173 | |      NC, Ashe |        655 | 0.025449742 | |  CO, Costilla |         85 | 0.026001835 | |   CO, Conejos |        210 | 0.026122652 | |  CO, Cheyenne |         45 | 0.026254376 | |    TX, Kenedy |         11 | 0.028132992 | |    VA, Norton |        118 | 0.031969655 | |    MS, Tunica |        432 |  0.04056338 | | WI, Menominee |        189 | 0.040935673 |

roelof 2020-12-29T19:17:59.333900Z

`(defn calculate_prevalance
  [county]
  ( if (zero? (:county_population county))
         0
    (float (/ (:driving_under_influence county) (:county_population county)))))
    

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
  (->> file
       load-json
       (map (fn [county]
              {:county     (fips (fips-code county)),
               :total_uid (:driving_under_influence county)
               :prevalance (calculate_prevalance county)}))
       (sort-by :prevalance)
       (take-last 10)))

pavlosmelissinos 2020-12-29T19:21:20.334100Z

it's sorted, in ascending order

pavlosmelissinos 2020-12-29T19:21:33.334300Z

you're just seeing the last 10 counties in the list

pavlosmelissinos 2020-12-29T19:22:00.334500Z

if you want to see it in descending order you need to reverse the result

roelof 2020-12-29T19:22:06.334700Z

yep, and I assumed that were the 10 county's with the highest prevelance

roelof 2020-12-29T19:22:58.335Z

yep, and then I see the 10 with prevelance zero because there is no population

roelof 2020-12-29T19:23:08.335200Z

so I set the return on zero

roelof 2020-12-29T19:23:25.335400Z

so I think I have to filter those out. Right ?

seancorfield 2020-12-29T19:23:55.335600Z

It can be hard to completely separate out database interaction from pure logic because you typically have a lot of situations where the pure logic at some point may well rely on DB activity from earlier in the request (assuming a complex DB-backed web app). The pragmatic question is: how separate does it really need to be? You definitely want to aim for separation and composability but there are practical limits to what you can realistically achieve in general, in my opinion, without resorting to somewhat artificial code structure and monadic-looking code.

clyfe 2020-12-29T19:25:10.335800Z

https://www.youtube.com/watch?v=yTkzNHF6rMs https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell The 2 vids may help somewhat (functional core, imperative shell). Also, personal anecdote: afaict functional architectures tend to converge into middleware pattern (ring's wrap-*, re-frame interceptors, stuff I seen in enterprises).

pavlosmelissinos 2020-12-29T19:25:36.336200Z

no need to, just add reverse in the end

pavlosmelissinos 2020-12-29T19:25:50.336400Z

the result is correct, it's just in ascending order

pavlosmelissinos 2020-12-29T19:26:40.336600Z

you have the top 10 counties, starting from the 10th

pavlosmelissinos 2020-12-29T19:26:53.336800Z

so if you reverse it you'll get the top county first

roelof 2020-12-29T19:28:35.337Z

yep,, this looks good

|       :county | :total_uid | :prevalance |
|---------------+------------+-------------|
| WI, Menominee |        189 | 0.040935673 |
|    MS, Tunica |        432 |  0.04056338 |
|    VA, Norton |        118 | 0.031969655 |
|    TX, Kenedy |         11 | 0.028132992 |
|  CO, Cheyenne |         45 | 0.026254376 |
|   CO, Conejos |        210 | 0.026122652 |
|  CO, Costilla |         85 | 0.026001835 |
|      NC, Ashe |        655 | 0.025449742 |
|      CA, Inyo |        424 | 0.024500173 |
|      NC, Hyde |        125 | 0.024447488 |

👌 1
seancorfield 2020-12-29T19:30:13.337600Z

Years ago, I built a generic "workflow" engine library for Clojure that separated everything into "sources", pure functions, and "sinks". The idea was that sources could (only) be queried -- the sources were passed into the pure code, so you could write mock sources for testing -- and that the pure functions would return data structures that indicated what actions would need to be taken on the sinks, which could be database writes (inserts and updates) and email systems and anything else you needed to apply changes or effects on. As soon as a later part of your pure workflow needs the generated ID from an earlier DB insert, things get complex, and it also gets a bit artificial when the DB inserts you need "at the end" have to include stuff that you got from side-effecting calls to third-party systems. It's doable, but it gets pretty convoluted. And I finally gave up on the engine after using it for a while in production code because it was just too awkward (and monadic) to be readable once the actual workflow got complex. It's still on GH as an archive https://github.com/seancorfield/engine with an explanation of why I stopped using it.

seancorfield 2020-12-29T19:32:39.337900Z

Having an imperative shell drive everything is a much more straightforward approach but it can still take quite a bit of work to completely separate out pure and impure logic -- and if you have an imperative shell, you are still going to need some amount of tests to verify that the imperative combining of the pure/impure calls really does what you want. Definitely more maintainable than just arbitrarily mixing pure and impure code together tho' -- and more maintainable than going "full-monad" IMO.

roelof 2020-12-29T19:34:03.338100Z

next challenge from the "Clojure from the ground up"

|       :county | :prevalance | :report-count | :population |
|---------------+-------------+---------------+-------------|
| WI, Menominee | 0.040935673 |           189 |        4617 |
|    MS, Tunica |  0.04056338 |           432 |       10650 |
|    VA, Norton | 0.031969655 |           118 |        3691 |
|    TX, Kenedy | 0.028132992 |            11 |         391 |
|  CO, Cheyenne | 0.026254376 |            45 |        1714 |
|   CO, Conejos | 0.026122652 |           210 |        8039 |
|  CO, Costilla | 0.026001835 |            85 |        3269 |
|      NC, Ashe | 0.025449742 |           655 |       25737 |
|      CA, Inyo | 0.024500173 |           424 |       17306 |
|      NC, Hyde | 0.024447488 |           125 |        5113 |

phronmophobic 2020-12-29T19:47:20.338300Z

I think it's interesting that many of these functional ideas can even be applied to games, https://fabiensanglard.net/quake3/index.php

roelof 2020-12-29T19:47:57.338700Z

hmm, I think the last challenge is nonsens

Write a test to verify that most-prevalent is correct.

roelof 2020-12-29T19:48:19.338900Z

how can I make a test if im not knowing the numbers myself

pavlosmelissinos 2020-12-29T19:49:59.339100Z

Make them up. The logic should be correct no matter what the actual values of the numbers are.

pavlosmelissinos 2020-12-29T19:51:14.339300Z

correctness != truth

roelof 2020-12-29T19:51:38.339500Z

oke, I have to think about it

roelof 2020-12-29T19:52:44.339700Z

so I should make a test file with only 1 county with some duis and some population

roelof 2020-12-29T19:52:52.339900Z

and use that for the test

Christian 2020-12-29T21:05:11.348100Z

I want to do some natural language processing (summarizing) and DL (one-shot-learning). I found this: https://dragan.rocks/articles/19/Deep-Learning-in-Clojure-From-Scratch-to-GPU-0-Why-Bother and Dragan recommends to use intel-mkl. He states it's 750 mb, but the only download I can find is a whooping 22gb. Are there other libraries I should use, or is this really the way to go?

caumond 2020-12-29T21:23:10.353600Z

Hi everybody, maybe this is a dumb question, but, I don't feel confortable with my solution up to now. I work with a defmulti, defined in a ns, and some defmethod, provided in their respective namespace. Now, when I want to call the method, I fall in situations where de defmethod are not found, until I explicitly require the namespace containing the defmethod. I would prefer a behavior where the calling function needs not to know its implementation, as a plugin is expected to act.

caumond 2020-12-30T08:34:08.086600Z

Hi, @sova I don't see the breakthrough with protocols, maybe I missed something. @smith.adriane, I guess this is my best option, I'm not sure how to do it. I will provide a simple example just to share my issue an better see the solution

caumond 2020-12-30T09:14:32.093400Z

caumond 2020-12-30T09:15:31.094Z

What I am not happy with are the near useless require of english and french namespace in the core.ns

caumond 2020-12-30T09:22:08.095700Z

And here is a git repo of this example https://gitlab.com/caumond/defmulti-multi-ns

caumond 2020-12-30T09:39:44.096100Z

I finally found this solution:

caumond 2020-12-30T09:40:26.096500Z

Starts to make sense to me. Your opinion?

phronmophobic 2020-12-30T19:43:15.140800Z

looks good to me. I think it's reasonable to expect someone that uses greeting to load the namespaces it needs to fill in which ever languages they expect

phronmophobic 2020-12-30T19:43:33.141Z

you can also override the default implementation of greeting to throw a more helpful exception

phronmophobic 2020-12-30T19:44:02.141200Z

maybe an exception that says something like (str "Did you forget to load the plugin for language " x "?")

phronmophobic 2020-12-30T20:22:23.141800Z

reading through Clojure Applied and it mentions something similar:

(defmethod convert :default [u1 u2 q]
  (if (= u1 u2)
    q
    (assert false (str "Unknownunitconversionfrom "u1" to "u2))))

phronmophobic 2020-12-30T20:22:34.142Z

this chapter is available online, http://media.pragprog.com/titles/vmclojeco/validating.pdf

caumond 2020-12-30T21:36:39.150900Z

Thx @smith.adriane, yes I put already this :default option in my full version.

👍 1
sova-soars-the-sora 2020-12-31T03:46:01.158200Z

Glad you found a solution.

dorab 2020-12-29T21:43:48.354300Z

It is best if you install via your package manager. Failing that, install via the Intel installer. I don't believe either of those are anywhere close to 22GB. The instructions at https://neanderthal.uncomplicate.org/articles/getting_started.html#the-native-library-used-by-neanderthals-native-engine-optional should be helpful. Which OS are you on?

Christian 2020-12-29T22:36:07.354900Z

Windows 10

Christian 2020-12-29T22:36:48.355100Z

Ihor Horobets 2020-12-29T23:55:38.358900Z

Hi everyone! Does anybody use hickory library? https://github.com/davidsantiago/hickory