beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Rowan Barnard 2020-12-11T03:59:18.398200Z

Hi everyone I was reading about final in a Java book and how java.lang.String is a final class so it can't be extended and the book was explaining about how it would be dangerous and chaotic to have alternative implementations of String be accepted polymorphically by methods but Clojure's polymorphism allows you to extend even final classes, if so then wouldn't that be dangerous also or is there something I'm not understanding that makes this OK to do?

seancorfield 2020-12-11T04:27:02.399200Z

@flyingpython In Java, polymorphism is intrinsically tied to inheritance. In Clojure, that is not the case.

seancorfield 2020-12-11T04:31:08.401200Z

Clojure's polymorphism is, essentially, a la carte. Protocols allow you to associate type-based dispatch with additional functionality.

2020-12-11T04:35:14.402900Z

Would it be fair to say that Clojure's protocols would allow you to create dangerous and chaotic protocol implementations, if you wished, perhaps in a similar way that the Java book claims that extending java.lang.String might be? At least, it doesn't seem like Clojure somehow prevent that from happening.

2020-12-11T04:35:43.403200Z

I agree that some kinds of danger and chaos are avoided by not having implementation inheritance -- just not all of them. There are so many kinds of danger and chaos, after all 🙂

seancorfield 2020-12-11T04:36:06.403400Z

One person's chaos is another person's ordered functionality... 🙂

seancorfield 2020-12-11T04:36:45.403900Z

For example, in next.jdbc, it has the concepts of "sourceable" -- something you can make a datasource from -- and "connectable" -- something you can make a connection from. That allows you to treat a number of things in a consistent, polymorphic, manner and work in a natural way with things that perhaps weren't designed with the affordances you need.

seancorfield 2020-12-11T04:39:47.404Z

This is why you should only extend protocols you own or types you own. But, sure, you can write dangerous, chaotic code with Clojure (just like any language, even Java, despite final 🙂 )

Rowan Barnard 2020-12-11T05:06:21.404200Z

Ah OK thanks for the explanation guys, so I guess it is mostly avoided by convention of not doing unwise things, it seems super cool that you can do that in Clojure though 🙂

Rowan Barnard 2020-12-11T05:08:16.406Z

Thanks for the explanations, yes the book I am working through on Clojure said working with databases is a common use case for Clojure's polymorphism

seancorfield 2020-12-11T05:14:58.406100Z

And it's probably worth noting that next.jdbc extends Sourcable to String so that you can polymorphically call get-datasource on a JDBC URL as a string, just like you can call it on an associative data structure.

Rowan Barnard 2020-12-11T05:22:42.406300Z

Wow that's super cool!

roelof 2020-12-11T06:57:42.407Z

I know I ask this yesterday but the solution then do not seem to solve it

roelof 2020-12-11T06:57:47.407300Z

clj::ground_up.chapter5=> (ns ground-up.chapter5)
nil
clj::ground-up.chapter5=> 
; Syntax error compiling at (chapter5.clj:38:1).
; Unable to resolve symbol: defn in this context

roelof 2020-12-11T06:58:58.407600Z

code :

(defn palindrome?
  "Checks if a word is a palingdrome"
  [word]
  (= (seq word) (reverse word)))

Daniel Östling 2020-12-11T07:14:58.409100Z

In a cider repl, how do I print a “complex” map in a def-friendly way? I would like to be able to cut & paste from repl into a def in testing code, but I run into issues like lists being (1 2 3) in the output instead of ’(1 2 3) or (list 1 2 3), for example.

Daniel Östling 2020-12-11T07:15:23.409500Z

Do I have to do prn and use reader?

jumar 2020-12-11T07:17:42.409600Z

Every now and then I just quote such "lists" manually. If this is for debugging/inspection you can use cider inspector or debugger and press d when you're focused on the right object - it will prompt you for a var name.

dpsutton 2020-12-11T07:25:50.410Z

(walk/postwalk (fn [x] (if (and (seq? x) (not (vector? x)))
                         `(~'list ~@x)
                         x))
               {:a (range 3)
                :b {:c (range 3)}
                :d (map inc (range 3))
                :e [(map inc (range 3))]})
bit hacky but can work for ya

dpsutton 2020-12-11T07:26:05.410200Z

you'll need to tweak the predicate a bit i'm sure but seems promising

Daniel Östling 2020-12-11T07:32:05.410400Z

Hm, thanks 🙂

Daniel Östling 2020-12-11T07:32:47.410600Z

@jumar, I’ve been playing around in the repl to build a test, and wanted to transfer an expected result to a test case.

Ben Sless 2020-12-11T07:33:11.410800Z

(def foo (quote ,,,,))?

roelof 2020-12-11T07:42:59.412400Z

Can someone explain this :

(defn palindrome?
  "Checks if a word is a palingdrome"
  [word]
  (= (seq word) (reverse word)))

(defn countPalingdromes
  "count the number of palingdromes between 0 and 9999"
  []
  (->> (range 0 9999) (filter palindrome?) (count)))
error message :
; Execution error (IllegalArgumentException) at ground-up.chapter5/palindrome? (form-init12029216532296771069.clj:41).
; Don't know how to create ISeq from: java.lang.Long

phronmophobic 2020-12-11T07:47:18.412500Z

palindrome expects a sequence and it's being given a number. try: (->> (range 0 9999) (map str) (filter palindrome?) (count))

roelof 2020-12-11T07:50:11.412700Z

thanks

roelof 2020-12-11T07:52:08.412900Z

still a lot to learn

scythx 2020-12-11T08:08:40.414800Z

Anyone know how to request with content-type image/png in reitit? I need to create upload image API. Multipart also won't works, i keep getting ClassNotFoundException javax.servlet.http.HttpServletRequest

roelof 2020-12-11T08:24:09.416700Z

how do I make it work that the message is printed

roelof 2020-12-11T08:24:14.417Z

(def logging-enabled :true)

(defmacro log [message]
  (if (= logging-enabled :true)
    '(prn message)
    nil))

(macroexpand `(log :hi))

Young-il Choo 2020-12-19T20:57:34.026900Z

To define macros, you need to understand the difference between • quote (’ apostrophe) • syntax-quote (` back-tick) • unquote (~ tilde) The syntax quote needs to be used, when you need to create an expression using a variable’s value, not the variable itself, done by unquoting the variable. In your example you need to syntax quote the (prn …) and unquote message. Also, you need to quote nil, since that is a return expression.

roelof 2020-12-11T08:24:58.417500Z

right now I see (prn message) as output

roelof 2020-12-11T08:30:23.418200Z

before I forget this is the challenge I try to solve:

; Write a macro log which uses a var, logging-enabled, to determine whether or 
; not to print an expression to the console at compile time. If logging-enabled 
; is false, (log :hi) should macroexpand to nil. If logging-enabled is true, 
; (log :hi) should macroexpand to (prn :hi) .

roelof 2020-12-11T08:35:36.418400Z

not funny

roelof 2020-12-11T08:35:59.419Z

if I restart vs code I see this as soon as I do crtl - enter

roelof 2020-12-11T08:36:05.419300Z

Syntax error compiling at (chapter5.clj:62:1).
; Unable to resolve symbol: defmacro in this context

roelof 2020-12-11T08:51:42.419900Z

even if I do (ns ground_up.chapter5)

roelof 2020-12-11T09:14:34.421100Z

wierd, if i do crtl-enter first on a defn and then on the defmacro it works, If I do tit direct on a defmacro I see the above error

mzuppichin 2020-12-11T09:47:17.423400Z

Hello Clojurians, I am trying to build subsequences from an original seq according to specific criteria (4Clojure p53, https://www.4clojure.com/problem/53#prob-title). I am trying to implement it via a recursive function, any suggestions for a higher level approach? Thanks in advance.

practicalli-john 2020-12-11T10:50:20.429600Z

@mzuppichin a code walk through of how I put together first a very low abstraction loop recur and then used partition for a higher level of abstraction https://github.com/practicalli/four-clojure/blob/master/src/four_clojure/053_longest_increasing_sub_seq.clj

practicalli-john 2020-12-11T10:51:55.430100Z

There is also a video of this walk through here https://www.youtube.com/watch?v=pyIbP4BOGpQ&list=PLpr9V-R8ZxiDjyU7cQYWOEFBDR1t7t0wv&index=36

mzuppichin 2020-12-11T10:53:54.430900Z

@jr0cket Thanks sincerely, I have tons of material to study now!

mzuppichin 2020-12-11T10:54:23.431300Z

Thanks for the quick and exhaustive response!

practicalli-john 2020-12-11T10:55:17.431900Z

If you can find any other solutions, do let me know 🙂

roelof 2020-12-11T10:55:18.432100Z

any expert who can give feedback on my code : https://github.com/RoelofWobben/Learning_in_public/blob/main/ground_up/src/ground_up/chapter5.clj

practicalli-john 2020-12-11T10:58:05.432300Z

The namespace in the file should use a dash instead of an underscore

(ns ground-up.chapter5
  (:import [java.time LocalTime]))
However, the file name should remain as an underscore, as the Java virtual machine that this Clojure code runs on does not support dashes in file names. I appreciate this is awkward at first.

2020-12-11T11:00:15.432500Z

I might model the schedule as a sequence of activity name with time entries

roelof 2020-12-11T11:01:05.432700Z

chancing the name into (ns- ground-up.chapter5) does not solve the problem

roelof 2020-12-11T11:01:47.433Z

I still get this error message :

; Unable to resolve symbol: defmacro in this context

practicalli-john 2020-12-11T11:02:11.433200Z

I am unaware of the problem, I havent looked into the history. However the ns definition I suggest is the preferred syntax.

roelof 2020-12-11T11:02:12.433400Z

@henryw374 how do you mean that ?

roelof 2020-12-11T11:03:16.433600Z

oke, if I do crtl + enter on the new name it works

roelof 2020-12-11T11:03:51.433800Z

@jr0cket

practicalli-john 2020-12-11T11:04:08.434Z

I am unclear why macros are used. They are a small part of writing clojure applications and require more of a learning curve if you are just beginning. Not something I can help with, sorry.

roelof 2020-12-11T11:04:52.434300Z

NP. it seems your suggestion worked on chancing the name

👍 1
2020-12-11T11:16:11.434600Z

(def my-schedule 
[{:activity "brush teeth" :time "7"}
{:activity "gel hair" :time "7.15"}])

2020-12-11T11:17:06.434800Z

for example. then you can have the same fn work on different schedules. and you can validate them to see if they make any sense

dharrigan 2020-12-11T11:18:05.435Z

There is also the #code-reviews channel that may elicit more feedback 🙂

Marcus 2020-12-11T11:22:23.435800Z

Do any of you know if the spit function reads entire file content when using the append true parameter?

roelof 2020-12-11T11:44:13.435900Z

Thanks, I ask there

roelof 2020-12-11T11:45:09.436100Z

@henryw374 I think that I understood what you mean but I also think that is more then I can chew now. Writing clojure now for 3 - 4 days

roelof 2020-12-11T12:12:26.436600Z

Confusing this :

user=> (def x (future (prn "hi") (+ 1 2)))
"hi"
#'user/x
user=> (deref x)
3

roelof 2020-12-11T12:12:48.437100Z

why does hi printed direct and the adding later

roelof 2020-12-11T12:12:59.437400Z

why not both later ?

Jim Newton 2020-12-11T12:15:01.438200Z

is there a function build-in which reverses the args of a binary function. i.e. which maps f to (fn [a b] (f b a)) ?

Jim Newton 2020-12-11T12:15:44.439Z

of course I can write this but it is one of those functions like comp which is useful when doing functional manipulation

Jim Newton 2020-12-11T12:16:50.439500Z

I need this most often when using condp to reverse the args of the predicate

Jim Newton 2020-12-11T14:23:35.441700Z

I need to find the most frequent element of a sequence, and how many times it occurs. The way I'm doing it seems awkward.

(defn most-frequent [items]
  (reduce (fn [[td c] [td' c']]
            (if (< c' c)
              [td c] 
              [td' c']))
          [:empty-set 0]
          (frequencies items)))
So (most-frequent '(a b a b c a b a b a a a d)) returns [a 7]

2020-12-11T14:27:28.442Z

(->> (frequencies '(a b a b c a b a b a a a d))
     (sort-by val >)
     (first))
?

borkdude 2020-12-11T14:28:27.442300Z

(->> (frequencies [1 2 3 1 3]) (sort-by val >))
([1 2] [3 2] [2 1])

Jim Newton 2020-12-11T14:30:17.442500Z

ok, sorting a map using sort-by val is something i wouldn't have guessed. The code is concise, but I don't really need to sort, I just need to find the maximum element

2020-12-11T14:30:46.442700Z

do you need the key or the val?

2020-12-11T14:30:48.442900Z

or both?

Jim Newton 2020-12-11T14:31:16.443100Z

perhaps something like max-key would be cleverer?

Jim Newton 2020-12-11T14:31:34.443300Z

once I have the key, I can get the value, right?

2020-12-11T14:32:08.443500Z

if you just want the value

(apply max (vals (frequencies '(a b a b c a b a b a a a d))))

2020-12-11T14:32:43.443900Z

oh nice! I wasn't aware of max-key 🙂

Jim Newton 2020-12-11T14:32:49.444100Z

the doc for max-key suggests this recipe:

; find the key that has the highest value in a map
user=> (key (apply max-key val {:a 3 :b 7 :c 9}))
:c

Jim Newton 2020-12-11T14:33:49.444400Z

so perhaps something like the following will give me the pair

(apply max-key val {:a 3 :b 7 :c 9})

Jim Newton 2020-12-11T14:34:24.444600Z

max-key is basically what my call to reduce is doing, more or less.

2020-12-11T14:34:38.444800Z

yeah, seems like it.

Jim Newton 2020-12-11T14:36:52.445Z

cool. I'm glad I asked. thanks for the leads.

Jim Newton 2020-12-11T14:37:38.445300Z

when using something like max, one must consider the cases of empty input.

dgb23 2020-12-11T14:38:31.446100Z

When I first checked out the frequencies source, I learned like 3 new things at once. And the function is only a couple of lines long

Jim Newton 2020-12-11T14:38:33.446200Z

for example my function dies when given an empty list.

dgb23 2020-12-11T14:39:41.446900Z

It’s very motivating to read the clojure.core sources for these utility functions.

1
nate 2020-12-11T14:53:10.448Z

(some->> (frequencies [])
         seq
         (apply max-key val))

👍 2
nate 2020-12-11T14:54:17.448900Z

Some threader can help...

Jim Newton 2020-12-11T16:05:12.451200Z

I think the documentation for condp is wrong. can someone help me read it and figure out if I'm confused. The documentation says that the expression (pred test-expr expr) is evaluated repeatedly, however it appears to me that expr is only evaluated once, into a tmp-var and the expression that is evaluated repeatedly is (pred-test-expr tmp-var)

Jim Newton 2020-12-11T16:05:28.451500Z

This is of course the desired behavior, but not the documented behavior.

alexmiller 2020-12-11T16:10:33.451900Z

I think that's what that doc is trying to convey

Jim Newton 2020-12-11T16:11:36.453200Z

I agree that that is what's intended, and it is what the user would assume from NOT reading the doc. But when I read it carefully, I had to perform an experiment to verify.

alexmiller 2020-12-11T16:12:29.454Z

if you're using a side effecting expr where you would see a different result between those two interpretations, then I would suggest maybe that's a bad idea

Jim Newton 2020-12-11T16:13:40.455Z

I'm writing a macro which expands to several invocations of condp. I needed to know whether my macro needs to capture the value of the expression in a let or whether condp already does that for me.

Jim Newton 2020-12-11T16:14:30.455200Z

as to whether it is a good idea to have side effects in the given expression, I understand your concern. But if I'm writing a macro where the user passes the expression to me, I don't have the privilege of requiring that there be no side effects.

alexmiller 2020-12-11T16:14:46.455400Z

sure you do - just say that's not allowed in the docs :)

Jim Newton 2020-12-11T16:15:46.455600Z

Well I prefer that if the user gives me an expression with side effects, then those side effects are only effectuated a maximum of once. That is much friendlier for debugging.

Jim Newton 2020-12-11T16:16:30.455800Z

And is in fact what condp does, despite a biblical fundamentalist reading of the holy documentation text 🙂 grins

pez 2020-12-11T16:36:02.457200Z

With Calva you should always start with loading the file. Otherwise, things are in flux.

Andrew Doolittle 2020-12-11T16:51:46.465500Z

Hello all, I'm trying to create a CSV using (https://clojure.github.io/data.csv/) , however I don't want to write to disk and would like the output to be a byte array. Because I'm unfamiliar with writer, I'm not sure how to do this. (with-open [writer (io/writer file-path)] (clojure.data.csv/write-csv data file-path)) How can I change this to return a byte array and not write to disk? Thanks

Jim Newton 2020-12-11T16:52:10.465600Z

Here is an example of the macro, https://gitlab.lrde.epita.fr/jnewton/clojure-rte/-/blob/master/doc/genus.md#typecase if you're interested

lread 2020-12-11T16:56:07.466600Z

I am working on rewrite-cljc docs and want to check my terminology usage. When I first came to Clojure I really had no concept “form” or “sexpr”. Maybe I still need help. Can these terms be used interchangeably? Is the difference https://clojure.org/guides/learn/syntax#_structure_vs_semantics?

dpsutton 2020-12-11T16:57:06.466700Z

(let [bytes (java.io.ByteArrayOutputStream.)]
  (with-open [writer (io/writer bytes)]
    (csv/write-csv writer [["a" "b" "c"] [1 2 3] [4 5 6]]))
  (str bytes))

🙏 1
Jim Newton 2020-12-11T17:15:34.467600Z

I know that a string in quotes is an expression, but I'm not sure whether a non-parenthesized piece of text is a form????

Jim Newton 2020-12-11T17:16:02.468Z

strings and numbers and symbols are s-expressions.

Jim Newton 2020-12-11T17:16:05.468200Z

are they forms?

Andrew Doolittle 2020-12-11T17:17:44.468300Z

Thanks. I changed the last part and got what I needed.

(defn data->byte-array [data]
  (let [bytes (java.io.ByteArrayOutputStream.)]
    (with-open [writer (io/writer data)]
      (csv/write-csv writer data))
    (.toByteArray bytes)))

(data->byte-array data) ;;  [34, 91, 34, 34, 48 ...]
(type (data->byte-array data)) ;; [B
Thanks again!

1
roelof 2020-12-11T17:22:31.470Z

Confusing this :

user=> (def x (future (prn "hi") (+ 1 2)))
"hi"
#'user/x
user=> (deref x)
3
why does hi printed direct and  the adding later why not both later ?

alexmiller 2020-12-11T17:23:05.470800Z

future runs the expression in a different thread

alexmiller 2020-12-11T17:23:17.471Z

concurrent to the main repl thread

alexmiller 2020-12-11T17:23:31.471500Z

(although they both share the same stdout which can be confusing)

dpsutton 2020-12-11T17:23:48.472100Z

from (doc future) > 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/@.

alexmiller 2020-12-11T17:23:58.472400Z

so "hi" is being printed in thread 2, then the deref returns the result of the expression and prints it in the main thread

2020-12-11T17:24:11.472500Z

s-expression is either an atom (including strings and symbols) or an expression (x y …) where x and y are s-expressions so literals like [1 2 3] or {:x 1} (vectors and maps) are not s-expressions.

2020-12-11T17:25:00.473600Z

s-expression is a subset of form in clojure terminology imho

roelof 2020-12-11T17:25:01.473800Z

oke, so printed cannot be deferred. If I would do there another calculation then both were deffered ?

2020-12-11T17:30:18.474500Z

it sounds like you are expecting the behavior of delay

2020-12-11T17:31:18.476500Z

a delayed expression is only run once you deref or force the delay (and happens on the same thread)

roelof 2020-12-11T17:32:04.477700Z

I expect nothing but try to understand what happens. It thought both are deffered but I see the output of `(prn "hi") direct and I try to understand why that one is direct executed and the calculation is deffered

2020-12-11T17:32:48.478300Z

there is no real ordering of output from another thread (the future) and the output from the repl process (prompting you for input)

2020-12-11T17:33:16.478700Z

they both just print whenever they want, they are independent threads

2020-12-11T17:33:52.479900Z

so basically it is a race condition, how the output of the repl is interleaved with the output of the future

2020-12-11T17:34:00.480100Z

future will evaluate everything in its body as soon as possible, in a separate thread, subject to operating system, thread scheduling, etc. constraints.

2020-12-11T17:34:45.481Z

so "hi" may print out first, or after #'user/x, or after you deref

alexmiller 2020-12-11T17:34:48.481100Z

^^ future is not about future evaluation, it's about getting the result in the future

alexmiller 2020-12-11T17:35:34.481900Z

evaluation is immediate and concurrent

lread 2020-12-11T17:35:53.482700Z

interesting

alexmiller 2020-12-11T17:36:22.483600Z

Clojure Applied has a great chapter on all this btw, also the author is quite strong and handsome

👏 1
😂 2
2020-12-11T17:36:27.483700Z

@roelof perhaps one source of your confusion is that some output in the repl is the implicit print of values as you ask for them to be calcuated, and other output is arbitrary printing behavior?

roelof 2020-12-11T17:40:51.485100Z

oke, so using a future is not a good thing because you never know when the result is returned. And there im confused

2020-12-11T17:41:21.485500Z

the result is returned when you ask for it

2020-12-11T17:41:28.485800Z

any random prints are done as they are executed

2020-12-11T17:42:22.486800Z

this is why I was pointing out the distinction between things implicitly printed (because your REPL form returned them), and things explicitly printed (because you wrote code that prints)

2020-12-11T17:45:08.488200Z

the result of an expression, and output printed by an expression are not the same thing

dpsutton 2020-12-11T17:45:27.488800Z

> oke, so using a future  is not a good thing a future is a thing that could be exactly what you need or very inappropriate. Can you explain what you want to accomplish and the advice can be more tailored to that?

roelof 2020-12-11T17:45:48.489100Z

oke, lets say we have this : (def x (future (* 3 4 ) (+ 1 2))) I see a message #'ground-up.chapter5/x which is the 3

roelof 2020-12-11T17:46:13.489800Z

but where is the outcome of ( *3 4) ?

dpsutton 2020-12-11T17:47:28.490600Z

(do (+ 1 2) (+ 10 20)) will return 30. the (+ 1 2) is computed and ignored as its unused anywhere and not returned

roelof 2020-12-11T17:48:58.490800Z

oke

2020-12-11T17:50:10.491500Z

this isn't just a property of future (which contains an implicit do), it also applies to other places that contain a do block, like let, fn, defmacro, doseq, loop...

2020-12-11T17:50:36.491900Z

all forms in the do block but the one you return are only useful as side effects

roelof 2020-12-11T17:51:38.492900Z

oke, I think I understand it but still I think a wierd example in the book to explain futures

2020-12-11T17:52:06.493400Z

it's showing that the execution happens immediately (via the print side effect), and you can get the value whenever you are ready for it

roelof 2020-12-11T17:52:32.493500Z

thanks

dpsutton 2020-12-11T17:53:34.494400Z

it seems like it really demonstrated what's going on. the println happened immediately and the value comes when derefed. Pretty good probing of how future runs immediately and caches its value for dereferencing

roelof 2020-12-11T17:57:13.495100Z

anyone more who want ot give feedback on my code.See question on the code-review chapter

2020-12-11T18:29:43.496400Z

Hi, I have this deps.edn

{:paths ["src" "resources"]
 :deps {org.clojure/clojure {:mvn/version "1.10.1"}
        aysylu/loom {:mvn/version "1.0.2"}
        org.clojure/math.combinatorics {:mvn/version "0.1.6"}}
 :aliases
 {:remote-repl {:extra-deps {vlaaad/remote-repl {:mvn/version "1.1"}}}
  :reveal {:extra-deps {vlaaad/reveal {:mvn/version "1.0.130"}}}
  :test {:extra-paths ["test"]
         :extra-deps {org.clojure/test.check {:mvn/version "1.0.0"}}}
  :runner
  {:extra-deps {com.cognitect/test-runner
                {:git/url "<https://github.com/cognitect-labs/test-runner>"
                 :sha "b6b3193fcc42659d7e46ecd1884a228993441182"}}
   :main-opts ["-m" "cognitect.test-runner"
               "-d" "test"]}
  :uberjar {:extra-deps {seancorfield/depstar {:mvn/version "1.1.128"}}
            :main-opts ["-m" "hf.depstar.uberjar" "aoc.jar"
                        "-C" "-m" "stuartstein777.aoc"]}}}
And this .clj file:
(ns stuartstein777.2020.day10
  (:require [clojure.string :as str]
            [clojure.math.combinatorics :as combo]))
WHen I try to run anything in the repl in this namespace I just get the error:
Execution error (FileNotFoundException) at stuartstein777.2020.day10/eval1477$loading (day10.clj:1).
Could not locate clojure/math/combinatorics__init.class, clojure/math/combinatorics.clj or clojure/math/combinatorics.cljc on classpath.
I'm using INtelliJ, after recent update I get warnings about old project types and it asks to convert them. Now stuff that worked pre-update is broken. Any ideas?

2020-12-11T18:30:51.496900Z

Cant run REVL either, and this also worked until yesterday. Now it says cant run REVL, no project file found.

2020-12-11T18:31:26.497200Z

Maybe I just need to recreate the project from scratch with clj-new ?

2020-12-11T18:34:06.497500Z

it sounds like something in IntelliJ that needs fixing, not clj

2020-12-11T18:34:23.497900Z

yeah, i just tried another project that 100% worked, and woudl run REVL too. Now it doesn't work either.

2020-12-11T18:35:35.498300Z

Man, I have no other editor setup to do clojure

2020-12-11T18:36:08.498700Z

Guess I can use my other machine that doesn't have latest IntelliJ

2020-12-11T18:36:48.499500Z

running clj in a terminal, then using require to load your namespace should still work (or at least get further than not seeing a dep that's in your config)

lread 2020-12-11T18:38:02.499600Z

Thanks @jimka.issy and @delaguardo, I guess I’ve tested the waters for strong opinions on this. I think I’ll just go ahead and describe the terms rewrite-clj already uses with the caveat they might not be absolutely technically correct.

2020-12-11T18:45:00.000400Z

You might want to post something in the #cursive channel

💯 1
2020-12-11T19:13:59.000800Z

I just posted this solution with max-key a few days ago on Twitter https://twitter.com/PrestanceDesign/status/1336726602777038849 max-key is great!

lread 2020-12-11T20:08:04.001100Z

Found this definition which seems to match rewrite-clj usage: https://www.braveclojure.com/do-things/#Forms

fsd 2020-12-11T21:11:03.002300Z

Hi Everyone, I am a Javascript developer, I recently gotten introduced to Clojure world by a React ClojureScript application. Are there any good resources you would recommend that would will help me with this transition?

borkdude 2020-12-11T21:12:02.002800Z

@singhamritpal49 If you're using Reagent, this might be a nice one: https://www.learnreagent.com/

borkdude 2020-12-11T21:12:23.003300Z

@singhamritpal49 There's also lots of resources listed here: https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f

william 2020-12-11T21:24:01.003900Z

Hmm.. the free version of that course never loads for me.. I just get loads of errors in the js console

william 2020-12-11T21:27:17.004400Z

In chromium it works fine, the errors were just for firefox

borkdude 2020-12-11T21:36:11.004900Z

Maybe pass that as feedback to the author. It's kind of ironic that a webdev course doesn't work in all browsers.

william 2020-12-11T21:37:07.005600Z

yes, that's the same thing I thought 😂 I already wrote about this problem in the chat that popped up

2020-12-11T22:50:44.007Z

Hi! This is a good challenge for Clojure: https://twitter.com/wesbos/status/1337453660482187268 I'm sure there are a clean and simple way to solved this. What functions do you think are appropriate in order to achieve the results?

2020-12-11T22:52:07.008200Z

A library was used, but I like the R version 👍 https://twitter.com/matthewpaulking/status/1337461670243799040

2020-12-11T22:53:10.009300Z

I have looked into the question and I am thinking of using merge-with, reduce, etc.

dpsutton 2020-12-11T22:53:54.010200Z

(let [col [["name" "id" "height"] ["Bob" "2" "50"] ["John" "1" "45"]]]
  (map #(zipmap (map keyword (first col)) %) (rest col)))
({:name "Bob", :id "2", :height "50"}
 {:name "John", :id "1", :height "45"})

👍 1
2020-12-13T08:00:27.115500Z

@admin055 Shouldn’t it be group-by :id instead of group-by :name ?

2020-12-13T08:09:49.115700Z

I suggest to avoid the shortcut for the anonymous function, so that you can name the entry param. It helps the code staying readable.

2020-12-13T08:10:40.116Z

Another suggestion is to use -&gt;&gt;, it helps reading the transformations as they occur chronologically.

2020-12-13T08:11:06.116200Z

parse-array is fine

2020-12-13T08:11:23.116400Z

If you use my extended version of group-by , you can have something even shorter and easier to read:

(def result
  (-&gt;&gt; [arr1 arr2 arr3]
       (map parse-array)
       (apply concat)
       (group-by :id identity merge)
       vals))

2020-12-13T08:12:35.116700Z

The source code of my group-by is:

(defn group-by
  "Same as clojure.core/group-by, but with some handy new arities which apply
   custom map &amp; reduce operations to the elements grouped together under the same key."
  ([kf coll]
   ;(group-by kf identity conj [] coll)
   (cc/group-by kf coll))
  ([kf vf coll]
   (group-by kf vf conj [] coll))
  ([kf vf rf coll]
   (group-by kf vf rf (rf) coll))
  ([kf vf rf init coll]
   (-&gt;&gt; coll
        (reduce (fn [ret x]
                  (let [k (kf x)
                        v (vf x)]
                    (assoc! ret k (rf (get ret k init) v))))
                (transient {}))
        persistent!)))

2020-12-13T08:18:55.117400Z

For more info on this group-by: https://twitter.com/VincentCantin/status/1337815470469042176

2020-12-13T13:33:54.120200Z

Thx a lot @vincent.cantin!

st3fan 2020-12-11T22:53:57.010300Z

I’m doing well with “simple” recursion, like with loop/recur or without. But what I am struggling with is the case when I have to recur into a list of things … like when generating a tree or explore multiple paths

2020-12-11T22:56:55.011800Z

I have gotten into the habit of starting with something like an secd or cek machine whenever I need to process a tree, because those are abstract machines for evaluating programs, and programs are trees

2020-12-11T22:57:48.012700Z

the idea of storing continuations in a stack, processing a list of results and then doing something in the middle of a tree, etc are common features of tree processing and program evaluation

2020-12-11T22:58:20.013500Z

I can't claim it is good, I don't think the programs that come out of it are particularly readable

st3fan 2020-12-11T22:58:32.014Z

interesting i should look into that ..

2020-12-11T22:58:49.014400Z

but it seems to be a universal technique

2020-12-11T23:00:44.015800Z

the last thing I did that with is a pretty printer for graphql schemas and it is very ugly

st3fan 2020-12-11T23:01:34.016200Z

i need to read about some basic algorithms about path exploring i think

2020-12-11T23:02:12.016800Z

another thing you might look at is zippers

st3fan 2020-12-11T23:02:13.017Z

advent of code related 🙂

2020-12-11T23:02:43.017300Z

clojure ships with clojure.zip, which doesn't get a lot of love

2020-12-11T23:02:50.017500Z

there is also clojure.walk

st3fan 2020-12-11T23:03:23.017800Z

oh zipper may actually be what i want

2020-12-11T23:04:32.018500Z

related to zippers are lenses, which there are a few clojure libraries for, or something like spectre

st3fan 2020-12-11T23:05:41.019300Z

i think i basically need something higher level that allows me to give it a function to answer ‘what are the children for this node’ repeatedly until i have no more data for that branch

st3fan 2020-12-11T23:05:50.019500Z

looks like a zipper may be able to do this

phronmophobic 2020-12-11T23:06:42.020600Z

if you need to edit nodes in a nested immutable data structure, zippers are awesome. for simply walking a nested data structure, tree-seq can be an easier alternative

st3fan 2020-12-11T23:07:32.021Z

i need to generate it first 🙂

st3fan 2020-12-11T23:07:46.021200Z

and then count stuff in it