Fork me on GitHub
#beginners
<
2020-04-06
>
Steiner02:04:13

here i have a nums (cons 0 (repeat 19 1)), and i create a new-nums by def

(def new-nums
    (lazy-seq
        (cons 1  (map + new-nums (rest nums))))
but i found that in let ,it doesn't work at all
(let [new-nums (lazy-seq 
                                    (cons 1 (map + new-nums (rest nums))))]
    (take 20 new-nums))
:: Error
Syntax error compiling at (json:localhost:36979(clj)*:346:33).
Unable to resolve symbol: nums in this context

seancorfield02:04:06

@steiner3044 That means that wherever you defined nums is not in scope when you type that let

_rj_r_03:04:17

also, the error message says numss but the symbol you show here is nums.. there a typo somewhere that didn't make it into the code you pasted here?

seancorfield03:04:53

So the code posted in here isn't actually the code being run.

Frederik13:04:32

Hi! I'm looking for fastest way to do some simple plotting while coding in the repl, the clojure equivalent of matplotlib in python basically. Gorilla repl's plotting functionality is exactly what I'm looking for, but I'd like to stay in my vs code calva repl. Any options here?

Frederik13:04:01

great, thanks! Will have a look 🙂

Stas Makarov14:04:18

Hi! I'm reading "Joy of Clojure" at the moment. There's this example in section on clojures:

(defn times-n [n]
  (let [x n]
     (fn [y] (* y x))))
Are there any benefits in using let here? Why not just (defn times-n [n] (fn [y] (* y n))) ?

✔️ 4
Stas Makarov14:04:13

Ah, the answer was on the next page 🙂

adi14:04:15

I don't know what the book says, but these are referentially transparent. My guess is it was meant for illustrative purposes?

Stas Makarov14:04:57

Yeah, your guess is absolutely correct.

👍 4
Akshay C. Gollapalli15:04:58

Is there a way to filter a map by the namespace of its keys? For instance: taking {:user/a 1 :verb/b 2} and getting {:user/a 1} by filtering for keys that begin with :user?

Darin Douglass15:04:32

(filter (comp #{"user"} namespace first) my-map)

noisesmith15:04:17

as a question of style, I think it's better to use key instead of first in this context - it gives the same result but it's more specific about the operation being performed

Darin Douglass15:04:47

i honestly didn't even know key was a thing given how easy it is to destructure everything. TIL

Darin Douglass15:04:39

something like that should work for ya

Akshay C. Gollapalli15:04:15

Ah, yeah that does it

Darin Douglass15:04:39

would need an (into {} ...) to keep it as a map

Akshay C. Gollapalli15:04:07

Yeah, now that I know that the namespace function works on keywords, I kinda get it. Thanks!

Steiner16:04:47

anyone know how this exception happend?

(def nums [
           [75]
           [95 64]
           [17 47 82]
           [18 35 87 10]
           [20 04 82 47 65]
           [19 01 23 75 03 34]
           [88 02 77 73 07 63 67]
           [99 65 04 28 06 16 70 92]
           [41 41 26 56 83 40 80 70 33]
           [41 48 72 33 47 32 37 16 94 29]
           [53 71 44 65 25 43 91 52 97 51 14]
           [70 11 33 28 77 73 17 78 39 68 17 57]
           [91 71 52 38 17 14 91 43 58 50 27 29 48]
           [63 66 04 68 89 53 67 30 73 16 69 87 40 31]
           [04 62 98 27 23 09 70 98 73 93 38 53 60 04 23]])
RuntimeException Unmatched delimiter: ]  clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:221)

noisesmith16:04:17

09 is an invalid number

noisesmith16:04:29

any digit starting with 0 is parsed as octal

noisesmith16:04:13

the reader exception thus interrupts reading of the parent structure, but then it gets closing delimiters meant for structures that had been aborted as invalid

noisesmith16:04:20

so you get the unmatched delimiter errors

Steiner16:04:45

oh my god ,i forget it

noisesmith16:04:10

my editor even highlights 09 differently from other literals since it doesn't match the regex for valid numeric input

Stas Makarov17:04:26

heh, almost default spacemacs doesn't highlight 09, but gives nice error when trying to load it in repl

Syntax error reading source at (joy-ch7.clj:43:30).
Invalid number: 09

noisesmith17:04:53

yeah, - the regular repl gives that too, but when mixed with the closing delimiters errors its easier to miss

eval-on-point17:04:07

might be a good linter to add to kondo

MatthewLisp18:04:46

Hello guys, i'm in doubt about replicating an operation from Java to Clojure:

byte[] byteArray2 = new byte[byteArray1.length];
for (int i = 0; i < byteArray1.length; i++) {
    byteArray2[i] = (byte) (byteArray1[i] ^ -1);
}
it seems that this operation invert the bits from byteArray1 and copy them into byteArray2, i want to do the same in Clojure, but i don't know what is the operator ^ in java, and what is the counterpart of it in Clojure, anyone knows?

MatthewLisp18:04:22

ok, i'll try it, thanks

noisesmith18:04:40

user=> (bit-xor 7 -1) 
-8

noisesmith18:04:23

also, NB clojure's for is not a replacement for java's for - it's a list comprehension and the directly comparable thing is doseq

MatthewLisp18:04:24

fine, i guess i'll just pass a seq to bit-xor using apply

noisesmith18:04:48

bit-xor doesn't actually work that way, but you could use map

noisesmith18:04:19

there are very few (if any) functions that automatically work on both individual values and collections in clojure

noisesmith18:04:38

this kind of overloading is intentionally avoided

MatthewLisp18:04:56

oh, now i'm understanding, the -1 value is a crucial part of the operation

MatthewLisp18:04:02

(byte-array (map #(bit-xor % -1) byteArray1))

MatthewLisp18:04:08

i'll try this

noisesmith18:04:38

that looks right, if performance is a concern you could also use amap or loop

MatthewLisp18:04:18

for a lightweight operation (less than 100 items on the collection) the benefits would be unnoticeable right?

noisesmith18:04:32

most likely yes

MatthewLisp18:04:39

wow, object oriented such as java is so verbose, i have to type twice and think twice to get things done

MatthewLisp18:04:19

getting my hands dirty with some java lately, and i'm glad i primarily work with clojure

noisesmith18:04:34

(let [a (byte-array (range 8))]
  (amap a i res
        (aset res i (byte (bit-xor (get a i) -1)))))
cmd)user=> (load-file "amap.clj")
#object["[B" 0x6e57b5e9 "[B@6e57b5e9"]
(ins)user=> (seq *1)
(-1 -2 -3 -4 -5 -6 -7 -8)

noisesmith18:04:43

above is an example of doing that with amap

noisesmith18:04:07

maybe I should have used aget instead of get, but either works

OrdoFlammae19:04:16

Why is the startup time for Clojure so large? I'm pretty sure even Java doesn't have that large of a startup time.

jumar19:04:31

Because it has to load way more classes usually; also depends on what kind of startup time you’re talking about- plain clojure (no Leiningen, etc) is usually way faster

bfabry19:04:35

it's not much larger than java if you're using straight clojure with no libraries

OrdoFlammae19:04:51

I'm using Lein, maybe that's the issue?

jumar19:04:58

Definitely

OrdoFlammae19:04:14

OK. How do I use "straight clojure"?

jumar19:04:29

What’s the use case?

OrdoFlammae19:04:38

Or do I have to decide between easy-to-setup Lein and something really complicated.

bfabry19:04:57

what are you using leiningen for? dependencies?

OrdoFlammae19:04:31

Just general project setup. I don't know how to do it without Lein.

bfabry19:04:01

what startup do you want to be faster? application startup? repl startup?

OrdoFlammae19:04:29

Both; but I'm assuming that application startup inhibits repl startup.

jumar19:04:53

If it’s the repl I’d say just live with it - you shouldn’t need to restart it very often

bfabry19:04:31

not really. lein repl and lein run are slow, but if you compile your application to a jar using leiningen and then run the jar using java -jar or whatever leiningen is no longer involved

jumar19:04:01

If you have to restart it frequently you are doing something wrong

OrdoFlammae19:04:34

OK, I'll work on it.

noisesmith19:04:59

another consideration - yes a lot of classes are loaded, but also clojure bootstraps the compiler for every run, and most libraries will need to be recompiled each time you start a clojure process (app or repl)

seancorfield19:04:10

lein runs two JVM instances in general. If you switch to the newer CLI/`deps.edn` stuff, documented on http://clojure.org, you'll find startup times are much better.

johnj19:04:14

are there any gotchas if you compiled all the clojure libs one is using?

bfabry19:04:30

there's a lot, it's generally not recommended

seancorfield19:04:38

You really only want to compile whole applications, as the very last step before building an uberjar. You should never publish compiled libraries (to Maven or Clojars).

seancorfield19:04:56

There is some (currently research) work being done around the CLI/`deps.edn` tooling to see if caching compilation of dependencies is worthwhile for dev/test but it's complicated and, as bfabry says, lots of gotchas.

OrdoFlammae20:04:13

I cut it down to a startup time of about 1-3 secs for a basic hello-world project.

Kevin21:04:32

is it possible to catch an error with try and then throw that same error, preserving the original stacktrace? I tried this, but it adds a new stacktrace based on the new throw.

(catch #?(:clj Throwable :cljs :default) t
      (throw t))
The reason I'd like to do this, is that I want to catch all errors, check them to see if I want to throw a custom message. If I don't want to do that, then I want act as if I never caught the exception at all.

deep-symmetry01:04:44

I don’t know about in the JavaScript world, but in Java, the stack trace is associated with the exception, not with throw , so your example already does what you want, the thrown exception will contain the stack trace of the original problem, since you are throwing the same exception that you caught.

Kevin07:04:35

I see. I'm testing this in Clojurescript so maybe that's the problem then.

Michael J Dorian21:04:21

Would you folks recommend "Getting Clojure" for someone who had already read through "Clojure for the Brave and True"?

hindol21:04:35

Don't know about Getting Clojure. No opinion either way. I just wanted to add that The Joy of Clojure is highly regarded as a more advanced Clojure book.

Michael J Dorian21:04:53

Nice, maybe that one. Gotta have something to read while not going outside simple_smile

jtth23:04:14

I read them both. Getting Clojure gives a nice high-level overview of the language, including a tour of the uses and contexts of some things. It assumes you’re already a programmer, which is a nice separation between concepts and implementations. I liked it and found it useful, but it’s not something I go back to.

jumar03:04:33

For me Getting Clojure was still a fun read although I'd already read a few other Clojure books; not that much new stuff but e.g. section about read & eval was refreshing.

jumar03:04:48

Living Clojure is another good beginner's book although it might show its age in couple of places.

jumar03:04:13

Web Development with Clojure (3rd edition?) would be a good one for making something practical with Luminus stack

jumar03:04:36

Clojure Applied is specifically aimed at the intermediate level

jumar03:04:20

Finally, Elements of Clojure is pretty good but it's also a book about programming in general; sometimes it's not immediately obvious how to apply concepts from the book

PB23:04:09

What is a good way to deploy a jar to my local .m2?

Darin Douglass23:04:53

if you're using lein: lein install will work

noisesmith23:04:59

what do you do to manage dependencies? lein, deps.edn?