beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
phoenixjj 2020-12-12T08:04:52.022800Z

To count the number of vowels in string. This is the first version.

(defn count-vowels [input]
  (let [vowels [\a \e \i \o \u]]
    (->>
     (for [x (char-array (clojure.string/lower-case input))]
       (some #{x} vowels))
     (filter some?)
     (count))))
Can it be done better ?

dpsutton 2020-12-12T08:13:39.023Z

(let [vowels (set "aeiou")] (count (filter vowels "mississippi")))

🤘 1
🙏 1
roelof 2020-12-12T11:46:49.024300Z

What do you experts find of this solutions ? https://github.com/RoelofWobben/Learning_in_public/blob/main/ground_up/src/ground_up/chapter5.clj

okwori 2020-12-12T13:25:12.025400Z

How do you check the version of Clojure CLI and also upgrade?

borkdude 2020-12-12T13:27:59.025800Z

@simon clojure -Sdescribe and clojure --help will print the version

kwrooijen 2020-12-12T13:50:38.026100Z

Any built-in function for this?

(defn repeat-reduce [f acc n]
  (reduce (fn [acc _] (f acc)) acc (range n)))

bronsa 2020-12-12T13:52:05.026400Z

check iterate

okwori 2020-12-12T13:55:15.026500Z

Thanks, I guess an upgrade will be a reinstall, right?

kwrooijen 2020-12-12T13:56:37.027100Z

Comes close but not entirely what I'm looking for :thinking_face:

kwrooijen 2020-12-12T13:56:45.027300Z

I'd still have to manually take

kwrooijen 2020-12-12T13:57:23.027900Z

take + last or drop + first

kwrooijen 2020-12-12T13:58:08.028100Z

or nth

kwrooijen 2020-12-12T13:58:20.028300Z

That's actually not bad

kwrooijen 2020-12-12T13:59:48.028500Z

Thanks

borkdude 2020-12-12T14:07:11.028600Z

Depends on your OS. brew upgrade clj-kondo for macOS, linux, might have to reinstall

👍 1
roelof 2020-12-12T16:19:35.029400Z

Is my question forgotten ??

roelof 2020-12-12T16:38:06.030800Z

user=> (defn sum [start end] (reduce + (range start end)))
user=> (time (sum 0 1e7))
"Elapsed time: 1001.295323 msecs"
49999995000000

    Use delay to compute this sum lazily; show that it takes no time to return the delay, but roughly 1 second to deref.
So the answer will be (defn sum [start end] (delay (reduce *(range start end))) ?

Aviv Kotek 2020-12-12T17:14:00.031Z

i'm failing to initial an atom using a validator,

(defn shape [M] .....impl.....)

(defn dim-2? [M]
  (= (count (shape M)) 2))

(def price-matrix (atom [] :validator dim-2?))

(defn set-pricing-rules! [M]
  (swap! price-matrix into M))

=> Syntax error (IllegalStateException) compiling at (kata01.clj:15:19).
Invalid reference state
but when changing to another validator, i.e: vector? it compiles, how could it make sense?

dpsutton 2020-12-12T17:16:21.032Z

What’s the value of (dim-2 [])?

Aviv Kotek 2020-12-12T17:17:01.032300Z

false

dpsutton 2020-12-12T17:18:01.033100Z

So [] is not a valid state but you are starting your atom in that state

dpsutton 2020-12-12T17:18:14.033600Z

And it’s rejecting it

Aviv Kotek 2020-12-12T17:18:23.033800Z

yep

Aviv Kotek 2020-12-12T17:18:28.034Z

right!

dpsutton 2020-12-12T17:18:39.034400Z

Did that resolve the confusion?

Aviv Kotek 2020-12-12T17:19:02.034600Z

yep, guess I'm misusing atom here

dpsutton 2020-12-12T17:21:27.035100Z

What’s your expectation here?

Aviv Kotek 2020-12-12T17:21:51.035400Z

basically i'd like to initial a 2dim matrix, something like that: [[1 2 3] ......]

Aviv Kotek 2020-12-12T17:22:07.035600Z

(def price-matrix
  ; Item Price Special Price
  [["A" 50 #(* (/ % 3) 130)]
   ["B" 30 #(* (/ % 2) 45)]
   ["C" 20 identity]
   ["D" 15 identity]])

dpsutton 2020-12-12T17:22:47.035800Z

do that then. (atom [] :validator dim-2?) is saying start an atom and reject values which don't conform to dim-2?. And the initial value you give it [] does not conform to the validator function

Aviv Kotek 2020-12-12T17:23:11.036Z

yea

Aviv Kotek 2020-12-12T17:24:00.036300Z

basically i'd like to set each row of the "price-matrix" (cons it) to the initial atom

dpsutton 2020-12-12T17:25:23.036500Z

(def price-matrix
  ;; Item Price Special Price
  (atom [["A" 50 #(* (/ % 3) 130)]
         ["B" 30 #(* (/ % 2) 45)]
         ["C" 20 identity]
         ["D" 15 identity]]
        :validator dim-2?))

dpsutton 2020-12-12T17:26:48.036700Z

i'm not following the confusion. maybe update dim-2? to allow for empty vectors as empty 2-dimensional vectors?

Aviv Kotek 2020-12-12T17:27:50.036900Z

changing the initial atom to [[]] would work as expected,

dpsutton 2020-12-12T17:28:03.037100Z

ok. so make your validator accept that as a valid state

Aviv Kotek 2020-12-12T17:28:07.037300Z

so basically i'm good, just need to define the swap! correctly now

dpsutton 2020-12-12T17:28:12.037500Z

cool!

Aviv Kotek 2020-12-12T17:28:16.037700Z

: ) ty

roelof 2020-12-12T18:34:51.038600Z

ser=> (defn sum [start end] (reduce + (range start end)))
user=> (time (sum 0 1e7))
"Elapsed time: 1001.295323 msecs"
49999995000000

    Use delay to compute this sum lazily; show that it takes no time to return the delay, but roughly 1 second to deref.
So the answer will be (defn sum  [start end] (delay (reduce *(range start end)))   ? Wanted to be sure I understand state well on clojure ?

dpsutton 2020-12-12T18:37:45.038800Z

i don't see you using any delay

roelof 2020-12-12T18:38:52.039Z

I did it here : (defn sum [start end] (delay (reduce *(range start end)))

roelof 2020-12-12T18:39:04.039400Z

or do I use it on the wrong place ?

roelof 2020-12-12T18:39:31.039700Z

I use it after the arguments

dpsutton 2020-12-12T18:40:08.039900Z

i don't know. it wasn't in the lsat snippet

roelof 2020-12-12T18:41:08.040500Z

chips, you are right. im sorry

roelof 2020-12-12T18:41:19.040800Z

but did I use it right ?

dpsutton 2020-12-12T18:42:56.041300Z

Now there’s multiplication instead of addition in your sum

dpsutton 2020-12-12T18:43:03.041600Z

But looks fine otherwise

roelof 2020-12-12T18:44:21.042200Z

🙂 the Clojure from the ground up is vrey fast becomimng very diffuclt

roelof 2020-12-12T18:44:36.042600Z

and I want to be sure I understand it well

roelof 2020-12-12T18:45:04.043100Z

IM now at a chapter about atoms, delay, promises and futures

roelof 2020-12-12T18:45:10.043300Z

so bvery confusing

roelof 2020-12-12T18:45:22.043700Z

so sorry to ask so many question

dpsutton 2020-12-12T18:45:41.044200Z

Take your time and run the examples and think them through

roelof 2020-12-12T18:45:55.044400Z

I try

roelof 2020-12-12T18:46:27.044900Z

yesterday I was struggeling with futures

roelof 2020-12-12T18:49:46.045900Z

ClojureFarm says you can learn clojure, reframe and databses in 35 days but I think its'too fast

roelof 2020-12-12T18:49:49.046100Z

so I take my time

roelof 2020-12-12T18:50:32.046900Z

to understand things and try to solve the challenges from this page : https://aphyr.com/posts/306-clojure-from-the-ground-up-state

roelof 2020-12-12T18:50:38.047100Z

they look difficult

roelof 2020-12-12T18:51:34.047300Z

@dpsutton

st3fan 2020-12-12T19:02:49.047700Z

What is Clojure Farm 🐮 🐷

roelof 2020-12-12T19:07:05.047900Z

@st3fan https://github.com/athensresearch/ClojureFam

roelof 2020-12-12T19:17:13.048700Z

what is wrong here :

; Execution error (ClassCastException) at ground-up.chapter6/eval13962 (form-init13914588690575444785.clj:16).
; class ground_up.chapter6$sum cannot be cast to class java.util.concurrent.Future (ground_up.chapter6$sum is in unnamed module of loader clojure.lang.DynamicClassLoader @58b8d871; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
code :
(defn sum [start end] (delay (reduce + (range start end))))

(sum 0 1e7)

(time(deref sum))

borkdude 2020-12-12T19:20:18.049200Z

You are not calling the function sum but you are trying to deref the function itself.

roelof 2020-12-12T19:22:41.049600Z

hmm, was looking at this example

user=> (def later (delay (prn "Adding") (+ 1 2)))
#'user/later
user=> later
#<Delay@2dd31aac: :pending>
user=> (deref later)
"Adding"
3

seancorfield 2020-12-12T19:24:11.050800Z

later is not a function there.

roelof 2020-12-12T19:24:12.050900Z

@borkdude what is then the right way to tell how long the calculating of the sum takes as the challenge ask me to do

; Use delay to compute this sum lazily; show that it takes no time to return the
;  delay, but roughly 1 second to deref.

seancorfield 2020-12-12T19:24:31.051300Z

(time (deref (sum 0 1e7)))

seancorfield 2020-12-12T19:24:55.051800Z

Or something like

(def later (sum 0 1e7))
(time (deref later))

roelof 2020-12-12T19:25:51.052200Z

thanks

roelof 2020-12-12T19:25:55.052500Z

clj::ground_up.chapter6=> 
"Elapsed time: 835.0006 msecs"
49999995000000

seancorfield 2020-12-12T19:25:56.052800Z

Your sum is a function that returns a delayed expression

roelof 2020-12-12T19:26:19.053300Z

it takes less then 1 second on my computer but its allright

roelof 2020-12-12T19:26:54.053600Z

he, a second time costs more time

roelof 2020-12-12T19:28:00.054Z

tomorrow or Monday time for this one :

We can do the computation in a new thread directly, using (.start (Thread. (fn [] (sum 0 1e7)))–but this simply runs the (sum) function and discards the results. Use a promise to hand the result back out of the thread. Use this technique to write your own version of the future macro.

roelof 2020-12-12T19:28:32.054500Z

I think I have to think well how to future macro should look like

seancorfield 2020-12-12T19:28:54.054900Z

user=> (defn sum [start end] (delay (reduce + (range start end))))
#'user/sum
user-> (time (sum 0 1e7))
"Elapsed time: 0.2965 msecs"
#object[clojure.lang.Delay 0x847f3e7 {:status :pending, :val nil}]
user=> (time (deref (sum 0 1e7)))
"Elapsed time: 156.6201 msecs"
49999995000000
user=>

roelof 2020-12-12T19:30:41.055300Z

I see these numbers

clj::ground_up.chapter6=> 
"Elapsed time: 0.0385 msecs"
#<Delay@1c7ac1a6: :not-delivered>
clj::ground_up.chapter6=> 
"Elapsed time: 848.3458 msecs"

roelof 2020-12-12T19:31:15.055700Z

so I think you have a faster pc then me 🙂

roelof 2020-12-12T19:31:21.055900Z

@seancorfield

seancorfield 2020-12-12T19:31:31.056200Z

A Microsoft Surface 3 laptop 🙂

roelof 2020-12-12T19:31:49.056600Z

I have a pc with 8G and a i5 processor

roelof 2020-12-12T19:32:00.056800Z

with Windows 10 Pro

roelof 2020-12-12T19:34:04.057700Z

GN all and tomorrow a nice challenge where I already said I have to think how the future macro should look like

roelof 2020-12-12T20:44:49.061Z

How to solve this one error: ; Wrong number of args (1) passed to: ground-up.chapter6/future code:

; We can do the computation in a new thread directly, using (.start (Thread. 
; (fn [] (sum 0 1e7)))–but this simply runs the (sum) function and discards the
; results. Use a promise to hand the result back out of the thread. Use this
; technique to write your own version of the future macro.


(defn sum2 [start end] promise)

(defmacro future[start end]
  '(reduce + (range start end))
  )

(def answer (future (sum2 0 1e7)))

phronmophobic 2020-12-12T20:52:52.061300Z

one macro writing trick is to put all the logic in a regular function. the regular function makes it easier to test:

(defn sum2 [start end] promise)

(defn future* [start end]
  '(reduce + (range start end)))

(defmacro future[start end]
  (future* start end))

repl> (future* 0 100)
;; (reduce + (range start end))
you can see that start and end are being used literally, instead of as variables

dpsutton 2020-12-12T20:54:16.061600Z

@roelof how would you go about diagnosing this error? What is the error telling you?

roelof 2020-12-12T20:54:57.061800Z

oke, so to get tje answer :

(deref(future* 0 100) 

roelof 2020-12-12T20:54:59.062Z

?

roelof 2020-12-12T20:55:45.062200Z

The error is telling me I have that the future has only 1 argument and I give more @dpsutton

phronmophobic 2020-12-12T20:55:52.062400Z

you can also use macroexpand-1 similarly:

repl> (macroexpand-1 '(future 0 100))
;; (reduce + (range start end))

dpsutton 2020-12-12T20:56:06.062700Z

no its telling you that the wrong number of args (1) was passed to future

dpsutton 2020-12-12T20:56:16.062900Z

how many args does future expect here? how many did you pass it?

roelof 2020-12-12T20:56:37.063100Z

i gave 1 and it needed 2

roelof 2020-12-12T20:57:23.063300Z

so I have to think well how I can pass the function

dpsutton 2020-12-12T20:58:45.063500Z

i'm not sure what that means. you defined future as requiring two arguments and then supplied it with only one. the error said "wrong number of args (1) passed to future

roelof 2020-12-12T20:59:01.063700Z

I mean the same

roelof 2020-12-12T20:59:57.063900Z

and what I mean is how to pass this promise

(defn sum2 [start end] promise)
in the macro

roelof 2020-12-12T21:01:01.064100Z

if I do :

(defn sum2 [start end] promise)

(defmacro future[start end]
  '(reduce + (range start end))
  )

(def answer (future 0 1e7))

dpsutton 2020-12-12T21:01:05.064300Z

that promise there is just the function promise

dpsutton 2020-12-12T21:01:19.064500Z

its not invoked or used, and doesn't use the start and end supplied

roelof 2020-12-12T21:02:06.064700Z

back to the drawing board

roelof 2020-12-12T21:02:28.064900Z

The page were promise is explained did not give a example with arguments

roelof 2020-12-12T21:04:40.065100Z

see this page : https://aphyr.com/posts/306-clojure-from-the-ground-up-state

roelof 2020-12-12T21:05:00.065300Z

stupid to ask for something that is never explained

roelof 2020-12-12T21:06:02.065500Z

or do I have to use this : (deliver box :live-scorpions!)

roelof 2020-12-12T21:08:44.065700Z

nope

roelof 2020-12-12T21:09:12.065900Z

(defn sum2 [start end] promise)

(defmacro future*[start end]
  '(reduce + (range start end))
  )

(def calc (deliver sum2 future*))
errror : `
; Can't take value of a macro: #'ground_up.chapter6/future*

phronmophobic 2020-12-12T21:09:54.066100Z

i kind of agree that their explanation is confusing

phronmophobic 2020-12-12T21:10:29.066300Z

I would split up the task into two parts: 1. write a non macro version 2. write the macro

roelof 2020-12-12T21:10:57.066500Z

(defn sum2 [start end] promise)

(defmacro future*[start end]
  '(reduce + (range start end))
  )

(def calc (deliver sum2 (future 0 1e7)))

error: 

; Unable to resolve symbol: start in this context

roelof 2020-12-12T21:12:45.067300Z

yep

roelof 2020-12-12T21:13:02.067800Z

that is I think easy

(defn sum2 [start end] promise)

(defn future*[start end]
  '(reduce + (range start end))
  )

(def calc (future* 0 1e7)

roelof 2020-12-12T21:13:22.068300Z

but still I do not see how I can use the promise here

phronmophobic 2020-12-12T21:13:49.069Z

here's an example of how to use promise since it doesn't seem to be explained:

;; promise example
;; 

;; create a promise
> (def my-promise (promise))

;; start a new thread
;; the new thread will set the value of my-promise to 42
> (.start (Thread. (fn []
                      (deliver my-promise 42))))
;; nil

;; access the value of my-promise
;; this will block the dereferencing thread until a value is
;; delivered to my-promise
> @my-promise
;; 42

caumond 2020-12-12T21:14:08.069600Z

Hi guys, I want to try hexagonal architecture. I don't find good reference for that. How am I suppose to ?

phronmophobic 2020-12-12T21:14:35.069700Z

you create a promise with (promise) and then you can set its value in any thread using deliver

phronmophobic 2020-12-12T21:15:21.069900Z

in my example, I'm simply setting the value of my-promise to 42 with (deliver my-promise 42)

roelof 2020-12-12T21:17:38.070100Z

hmm

roelof 2020-12-12T21:17:48.070600Z

so this schould working

roelof 2020-12-12T21:17:55.070900Z

(defn sum2 promise)

(defn future*[start end]
  deliver sum2 0 1e7)

caumond 2020-12-12T21:18:09.071400Z

Maybe another way to ask is "how do you implement port / adapter pattern in clojure?"

roelof 2020-12-12T21:18:16.071500Z

but where do I then set the formula for calculating

roelof 2020-12-12T21:18:40.071700Z

so this one

(defn sum [start end] (delay (reduce + (range start end))))

phronmophobic 2020-12-12T21:20:37.071900Z

the goal is to recreate the behavior of future. i'm not sure the provided explanation of what future does is explained clearly. maybe it's worth breaking down what future 's behavior is

phronmophobic 2020-12-12T21:21:16.072200Z

can you outline what future's desired behavior is?

roelof 2020-12-12T21:25:29.073200Z

as far as I understand a future does something and returns direct the result

roelof 2020-12-12T21:26:29.073500Z

so for example

(dotimes [i 5] (future (prn i)))

roelof 2020-12-12T21:27:15.074100Z

prints the numbers 1 till 5 but no garuntees that is will print 1 2 3 4 5

roelof 2020-12-12T21:27:23.074400Z

it can be in any order

phronmophobic 2020-12-12T21:27:30.074700Z

ah ok

roelof 2020-12-12T21:27:31.075Z

@smith.adriane

seancorfield 2020-12-12T21:27:46.075400Z

@caumond It's mostly just about layers and making sure the dependencies only go in one direction. In Clojure you mostly want to have a pure functional core and have your side-effect-y stuff at the edges.

roelof 2020-12-12T21:28:27.076100Z

I hope I said it right,this stuff is still confusing for me

phronmophobic 2020-12-12T21:28:30.076300Z

from future's doc string:

Takes a body of expressions and yields a future object that will
  invoke the body in another thread, and will cache the result and
  return it on all subsequent calls to deref/@

phronmophobic 2020-12-12T21:29:18.077Z

so crucially: 1. it does the work in a separate thread 2. it doesn't directly return the value, it returns an object that can be dereferenced to obtain the value

seancorfield 2020-12-12T21:29:27.077400Z

Some folks will suggest using protocols to mirror interfaces but I don't think that's necessarily a good way to go (if you only have one implementation of a protocol, you might just as well use plain functions).

roelof 2020-12-12T21:29:31.077500Z

yep, so here a future with hopefully all the numbers 1 till 5 in my example

roelof 2020-12-12T21:29:45.077700Z

amd with deref I can see the result

phronmophobic 2020-12-12T21:29:55.077900Z

in clojure @, will deref the result

roelof 2020-12-12T21:30:23.078100Z

oke, I use (deref ...) for it

phronmophobic 2020-12-12T21:30:28.078300Z

yup

phronmophobic 2020-12-12T21:30:34.078500Z

deref also works

phronmophobic 2020-12-12T21:30:51.078700Z

I'm not sure what your current code looks like, but I didn't see where you started a new thread

roelof 2020-12-12T21:31:24.078900Z

I have now this :

(def sum2 promise)

(defn future*[start end]
  deliver sum2 0 1e7)

phronmophobic 2020-12-12T21:31:56.079400Z

ah ok. promise should probably be something like (promise)

roelof 2020-12-12T21:32:09.079800Z

and wonder where this formula must be placed

(reduce + (range start end))

phronmophobic 2020-12-12T21:32:12.080Z

promise is a function that must be called to create a new promise

seancorfield 2020-12-12T21:32:33.080500Z

@caumond you might find this interesting https://polylith.gitbook.io/polylith/ as a way to have some formal structure between components and layers.

roelof 2020-12-12T21:32:58.080700Z

??

roelof 2020-12-12T21:33:02.080900Z

now I miss you

phronmophobic 2020-12-12T21:33:12.081100Z

ie. promise vs (promise)

roelof 2020-12-12T21:33:36.081300Z

oke, I changed it to (promise)

phronmophobic 2020-12-12T21:33:37.081500Z

(def sum2 promise) vs (def sum2 (promise))

roelof 2020-12-12T21:34:02.081700Z

I have now this :

(def sum2 (promise))

(defn future*[start end]
  deliver sum2 0 1e7)

roelof 2020-12-12T21:34:34.081900Z

but still I do not see where the reduce miust be placed

phronmophobic 2020-12-12T21:34:46.082100Z

what does deliver do?

roelof 2020-12-12T21:35:02.082300Z

it placed the two values in the promise

roelof 2020-12-12T21:35:13.082500Z

as far as I undestand it

phronmophobic 2020-12-12T21:35:28.082900Z

clojure.core/deliver
 [promise val]
Added in 1.1
  Delivers the supplied value to the promise,...

seancorfield 2020-12-12T21:35:54.083200Z

@roelof You need to pay more attention to parens. You are not calling deliver because you have no parens around it.

phronmophobic 2020-12-12T21:36:06.083400Z

deliver accepts two arguments, the promise and a single value

roelof 2020-12-12T21:37:00.083600Z

oke, changed the code to this :

(def sum2 (promise))

(defn future*[start end]
  (deliver sum2 0 1e7))

seancorfield 2020-12-12T21:37:15.083800Z

No, deliver takes two arguments.

seancorfield 2020-12-12T21:37:21.084Z

You gave it three.

roelof 2020-12-12T21:37:38.084200Z

yep, I was just wanted to say that the code is wrong

roelof 2020-12-12T21:38:25.084400Z

(defn future*[start end]
  (deliver sum2 0 )
  (deliver sum2 1e7)
  )

seancorfield 2020-12-12T21:38:42.084600Z

No, you can only deliver a single value.

roelof 2020-12-12T21:38:44.084800Z

Think this is also wrong. I think the 0 is overwritten

roelof 2020-12-12T21:39:07.085Z

hmm, but I need 2 the begin and the end of the range

roelof 2020-12-12T21:39:54.085200Z

or I have to give it the (reduce ...) part ?

🎉 1
roelof 2020-12-12T21:40:56.085500Z

(def sum2 (promise))

(defn future* [start end]
  (deliver sum2 (reduce + (range start end))))

phronmophobic 2020-12-12T21:41:43.086600Z

sweet. does *future now implement all of future’s desired behavior?

roelof 2020-12-12T21:42:17.086800Z

I think so

phronmophobic 2020-12-12T21:42:30.087100Z

are you sure?

seancorfield 2020-12-12T21:42:35.087300Z

You can try this stuff out in the REPL piece by piece:

user=> (def p (promise))
#'user/p
user=> (deliver p 0)
#object[clojure.core$promise$reify__8501 0x220c9a63 {:status :ready, :val 0}]
user=> (deliver p 1e7)
nil
user=> @p
0
user=>

roelof 2020-12-12T21:42:44.087500Z

I only have to find out how to make it work with thr 2 numbers

roelof 2020-12-12T21:43:22.088Z

this is not working `(sum2 0 1e7)

phronmophobic 2020-12-12T21:43:30.088400Z

what about the threading requirement?

phronmophobic 2020-12-12T21:45:38.090100Z

also, i’m pretty confident in recommending that you find a different tutorial to work through. unfortunately, i’m not sure what a good getting started tutorial might be

roelof 2020-12-12T21:45:40.090300Z

chips you are right

roelof 2020-12-12T21:47:13.090500Z

yep, the course im now doing is telling met that doing the clojur from the ground up is a good starting point. But I see that on almost every challenge I need help to solve the challenges

seancorfield 2020-12-12T21:47:26.090700Z

@roelof You've been trying to learn Clojure on and off for a long time now. Remind me which books you've tried to work through?

roelof 2020-12-12T21:47:57.090900Z

I tried earlier the brave book but that is also going very deep very soon

roelof 2020-12-12T21:48:39.091100Z

further no books because I do not want to pay for books just for a hobby

seancorfield 2020-12-12T21:49:38.091300Z

Well, then you are very restricted on material: "Brave and True" and "Ground Up" are pretty much the only free ones I know out there.

roelof 2020-12-12T21:51:03.091500Z

bummer

seancorfield 2020-12-12T21:51:32.091700Z

I learned originally from a course I paid $200 for, and I bought books.

phronmophobic 2020-12-12T21:53:49.092500Z

i can’t actually remember how i learned clojure. I didn’t buy any books

roelof 2020-12-12T21:54:33.092700Z

oke,, Thanks both so far for the help. Time to think about how to go on on my clojure way or know that clojure is not for me

seancorfield 2020-12-12T21:54:42.092900Z

My first two were Joy of Clojure and Clojure in Action. Then I bought Clojure Programming. Since then I've bought almost every single Clojure book out there 🙂

😄 1
roelof 2020-12-12T21:54:43.093100Z

which I find pity, I like the language

roelof 2020-12-12T21:55:17.093600Z

Again thanks. Time to lseep and think about this

phronmophobic 2020-12-12T21:55:23.094Z

what kind of things would you like to build?

seancorfield 2020-12-12T21:55:27.094300Z

@roelof Given how you've struggled with the basics of Clojure each time you've tried, it is possible that Clojure may not be your thing...

phronmophobic 2020-12-12T21:55:49.094900Z

sometimes there are good resources for specific use cases

roelof 2020-12-12T21:55:55.095100Z

I like to solve things like Advent of Code or making websites

phronmophobic 2020-12-12T21:56:25.095800Z

there are some really good resources for building web sites

seancorfield 2020-12-12T21:56:27.096Z

I was just talking with someone who was trying to learn Forth and finding that they just couldn't "get it" when they actually tried to build stuff, even though they'd read books and liked the idea of the language...

roelof 2020-12-12T21:56:41.096400Z

Im thinking thenabout a gallery or much later a crm for a volunteer organisation with some member , invoice part

seancorfield 2020-12-12T21:57:08.097200Z

@smith.adriane web sites? What sort of resources? I can't imagine anything being suitable given the conversation thread above...

roelof 2020-12-12T21:57:28.097800Z

@seancorfield that is why I said I have to think bout how and if I want to go on learning clojure

phronmophobic 2020-12-12T21:57:45.098500Z

it’s not clojure, but i’ve heard good things about the “learn X the hard way” series, https://shop.learncodethehardway.org I think their ruby edition is freely available

roelof 2020-12-12T21:58:01.098900Z

but maybe go back to haskell or try a new language like rust

roelof 2020-12-12T21:58:18.099300Z

really going to bed

roelof 2020-12-12T21:58:36.099700Z

again thanks but for now byee

seancorfield 2020-12-12T21:58:47.100100Z

I think Haskell is much, much harder than Clojure...

seancorfield 2020-12-12T21:59:00.100400Z

And Rust is also much, much harder than Clojure.

caumond 2020-12-12T22:01:30.102100Z

ok, pure functional seems more appealing, I didn't know polylith but I'll try to do the simple way, with layers and their dependency well managed

caumond 2020-12-12T22:01:36.102300Z

thx @seancorfield

chepprey 2020-12-12T22:08:26.104300Z

Hi - I'm going through https://clojure.org/guides/deps_and_cli to try out deps.edn, I've gone literally through the steps in the "Writing a program" section. It's just a "hello world" world program that also prints the current timestamp. I'm getting this error instead:

:~/hello-world$ clj -X hello/run
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
-X (No such file or directory)

Full report at:
/tmp/clojure-6673920467411785967.edn
:~/hello-world$ 

seancorfield 2020-12-12T22:20:10.104700Z

@chepprey You have an old version of the CLI installed. Upgrade to the latest.

seancorfield 2020-12-12T22:20:27.105200Z

See clojure -Sdescribe to see what you've got installed.

chepprey 2020-12-12T22:20:55.105500Z

{:version "1.10.1.536"...

seancorfield 2020-12-12T22:21:24.105800Z

1.10.1.536 is old -- it doesn't have -X.

✔️ 1
chepprey 2020-12-12T22:21:40.106100Z

I shall upgrade, thanks!

seancorfield 2020-12-12T22:22:48.106600Z

(I'm on 1.10.1.763 but that's a prerelease -- 1.10.1.754 is the latest, see https://clojure.org/releases/tools )

roelof 2020-12-12T22:23:40.106700Z

sorry I do not agree on haskell

roelof 2020-12-12T22:24:03.106900Z

I find clojure much harder then haskell

chepprey 2020-12-12T22:27:32.107600Z

upgraded to {:version "1.10.1.754" and it works a treat. :thanks:

2020-12-12T22:41:34.109Z

I have a map like this

{:ship [0 0] :waypoint [10 1]}
I pass it to a function and destructure it
(defn move2 [{:keys [ship waypoint] :as acc} [inst distance]]
  (let [[waypoint-x waypoint-y] waypoint]
    ;; do stuff.
    ))
Can I destructure the keys and waypoint-x and waypoint-y in the argument destructuring, rather than destructuring int he arg list AND the let ?

seancorfield 2020-12-12T22:43:43.109900Z

@qmstuart Like this:

user=> (let [{[x y] :waypoint} {:waypoint [10 1]}] (println 'x x 'y y))
x 10 y 1

seancorfield 2020-12-12T22:44:30.110500Z

You can use that destructuring in the function argument instead. let was just easier in the REPL.

2020-12-12T22:44:40.110700Z

thank you!

2020-12-12T22:44:58.111200Z

btw, is your talk on repl driven development going to be available on youtube or elsewhere afterwards?

seancorfield 2020-12-12T22:46:24.111700Z

After the London event, yes, both versions will be posted online.

2020-12-12T22:46:32.112100Z

great! 🙂

seancorfield 2020-12-12T22:46:57.112800Z

I figure with the two very different timezones, more folks can be there "live".