Fork me on GitHub
#beginners
<
2018-10-06
>
Michael Fiano01:10:21

I'm having trouble adjusting to Clojure coming from CL. "Brave" seemed to go too fast for me. I need to get used to the basics, preferably with writing code instead of a reference textbook. Any recommendations?

Michael Fiano01:10:22

I'm moreso looking for something better suited for someone with many years of Lisp experience, just not Clojure or the JVM

noisesmith01:10:43

Joy of Clojure isn't an easy book, but it does start from a lisp oriented background

noisesmith01:10:13

(also I think it's one of the better programming books)

Michael Fiano01:10:52

I was told that's a good reference book to have next to you, but not a linear read to get the language down.

Michael Fiano01:10:12

I haven't read it yet though

noisesmith01:10:34

I'd say it's got plenty of linear introduction

v3ga01:10:21

joy of clojure and Ï really liked living clojure as well. I’ve purchased just about every book related to clojure to see what worked best.

andy.fingerhut01:10:25

One of the biggest changes from idiomatic CL code is the default immutability of data structures, and the easy access and very common use of maps, vectors, and sets. Lists are there, but the others are probably used more often than lists.

Michael Fiano01:10:28

I just started reading Clojure Applied, and I think it's too big of a step for me so far

Michael Fiano01:10:42

I'll try Joy since it keeps on being recommended. Thanks for the suggestions

noisesmith01:10:49

I wonder what the best intro is for JVM via interop with Clojure. I basically learned Java by learning Clojure (at least the parts of Java you need in order to use the JVM interop...)

mfikes01:10:09

I basically did the opposite with ClojureScript, learning JavaScript via interop. :)

noisesmith01:10:28

I also learned js via cljs interop, mostly

noisesmith01:10:52

but I don't know cljs/js as well as I know clj/jvm at this point

seancorfield01:10:57

@mfiano What other Clojure books have you (tried to) read, and what did you think of them?

Michael Fiano01:10:23

@seancorfield Clojure For The Brave and True only. I thought it was too quirky and moved a little too fast for me to really get. I've never done any parallel programming before, and there was a bit of this IIRC, and also I just couldn't get into the immutable mindset, coming from CL.

seancorfield01:10:23

Can you article where you're struggling with the JVM aspects of Clojure, compared to the Lisp aspects?

seancorfield01:10:49

Hmm, have you looked at Living Clojure by Carin Meier?

seancorfield01:10:29

I agree that Brave is kinda quirky and not to everyone's taste but Carin's book is supposed to be a pretty gentle way in...

Michael Fiano01:10:51

I haven't yet, but it's what I'm going to try next I think.

seancorfield01:10:16

Russ Olsen's Getting Clojure might also be an option (although I get mixed messages about whether it's truly an intro book or not).

Michael Fiano01:10:45

Also hello again sean. I'm back to studying Clojure after a 6 month hiatus, and I remember you helped me a bit, which I found really nice. Thanks

seancorfield01:10:53

I'm happy to try to help 1:1 with the JVM aspects if you think I can assist...?

Michael Fiano01:10:57

I don't really know anything about the JVM, or when I would come across it in Clojure

Michael Fiano01:10:03

So I haven't yet 🙂

seancorfield01:10:33

Well, I'm on West Coast US time so feel free to DM me with questions when I'm around 🙂

Michael Fiano01:10:22

Thank you, I'll keep that in mind. 🙂

Michael Fiano01:10:31

For now I'll read Carin's book

seancorfield01:10:52

I have a copy of that so I can try to help with questions about that too 🙂

seancorfield01:10:09

(I think I've got a copy of almost every Clojure book 🙂 )

Michael Fiano01:10:28

I discovered the incident with zcaudate. Looks like I'll have to modify my global lein profile to remove his stuff.

Michael Fiano02:10:37

Hmm I get a bunch of warnings when starting a lein REPL

Michael Fiano02:10:54

A lot has changed since I tried Clojure it seems

andy.fingerhut02:10:49

Clojure hasn't changed much in the last 6 months. If you have updated to a later JVM version, you may be hitting some teething pains due to updates in the JVM since then.

Michael Fiano02:10:04

Yeah I downgraded from 10 to 8, and most warnings went away...only have this now: WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: fipp.visit, being replaced by: #'fipp.visit/boolean?

seancorfield02:10:23

Feel free to share the warnings/errors and we'll offer direction if we can...

seancorfield02:10:31

Ah, going from Clojure 1.8 to 1.9? That introduces a lot of new predicates to support clojure.spec -- you may well need to update all the various library dependencies as well.

Michael Fiano02:10:03

cider doesn't support jdk10. that was all the warnings

Michael Fiano02:10:27

except that last one left

seancorfield02:10:19

You should be able to ignore that -- I expect fipp.visit/boolean? is effectively the same functionality as Clojure 1.9's cloure.core/boolean?

seancorfield02:10:46

Looks like that warning has been addressed in a more recent version of fipp

seancorfield02:10:04

It was fixed almost a year ago.

seancorfield02:10:58

Like I say, if you're going from Clojure 1.8 to 1.9, you'll probably have to update a lot of library versions as well to avoid warnings (and potentially "syntax" errors detected by clojure.spec that used to be silently allowed by the compiler).

Michael Fiano02:10:30

How doI tell what fipp is a transitive dependency of?

seancorfield02:10:42

lein deps :tree should show you

Michael Fiano02:10:25

Oh I missed it

seancorfield02:10:39

It may be a dependency of one of your plugins... oh, ok.

Michael Fiano03:10:51

It's from spyscope, which I don't even remember what that does, so I can probably remove it

seancorfield03:10:16

You can exclude the old version of fipp (`bigml/fipp`) from spyscope and specify a newer version [fipp "0.6.13"]

seancorfield03:10:11

[spyscope "0.1.6" :exclusions [bigml/fipp]] [fipp "0.6.13"]] should fix that I think...

seancorfield03:10:36

(looks like Brandon changed the name of the artifact...?)

seancorfield03:10:55

Or maybe spyscope was using an old fork?

Michael Fiano03:10:37

It looks like spyscope 0.1.7 is a fork that is 1 commit ahead and 10 commits behind the original 0.1.6 repository

seancorfield03:10:02

(it does seem that people run into problems with old dependencies that they add to ~/.lein/profiles.clj -- back when I used Leiningen, I found it was safer to avoid putting things in that file!)

seancorfield03:10:12

(and that fork has a very out of date readme -- still refers to 0.1.5 release 😞 )

Michael Fiano03:10:10

I just removed it from my deps

4
defenestrated04:10:45

v basic question that i’m having trouble googling successfully: what does Integer. mean? and/or what’s the difference between (Integer. "42") and (Integer/parseInt "42")?

Alex Miller (Clojure team)04:10:09

both create an instance of an Integer object

Alex Miller (Clojure team)04:10:26

the first uses the constructor (the trailing dot on the class is interop form to invoke the constructor)

Alex Miller (Clojure team)04:10:12

the second invokes a static method Integer/parseInt, which is now the preferred way to do this - Integer has a static cache for values around 0 and has been intrinsified for performance in later jdks

Alex Miller (Clojure team)04:10:21

the primary perceivable difference is the val cache:

Alex Miller (Clojure team)04:10:23

user=> (identical? (Integer. "42") (Integer. "42"))
false
user=> (identical? (Integer/parseInt "42") (Integer/parseInt "42"))
true

Alex Miller (Clojure team)04:10:51

the latter is definitely preferred

defenestrated04:10:43

okay cool thanks

defenestrated04:10:22

and is the reason neither works as a function is that both are technically objects?

defenestrated04:10:42

in the context of (def formatters {:name clojure.string/lower-case :number Integer/parseInt}) for example

defenestrated04:10:18

(which throws an error unless it’s wrapped like #(Integer/parseInt %)

andy.fingerhut05:10:22

(Integer. "42") is a call to a Java constructor. (Integer/parseInt "42") is a call to a Java method. Neither of those by themselves are Clojure functions, but they can be made into Clojure functions in several ways, one of which is the #(Integer/parseInt %) syntax you mentioned.

andy.fingerhut05:10:04

Or more precisely worded, you can create a Clojure function that way, that does nothing but call a Java method. Doing so does not change the Java method in any way -- it is still a Java method.

defenestrated07:10:35

that’s really clear, thanks for the clarification!

defenestrated07:10:33

just for my own edumucation, is there a “better” way of wrapping a Java method into a clojure function than my attempt?

Alex Miller (Clojure team)12:10:01

There’s also https://clojuredocs.org/clojure.core/memfn although that often leads to reflective calls

andy.fingerhut08:10:06

The way you showed is quite common and readable, and no less efficient than any of the other ways that I know of. One other is just a slightly more verbose way that does exactly the same thing under the covers: (fn [x] (Integer/parseInt x)). Another is to use Clojure's memfn.

defenestrated10:10:50

awesome. thanks!

peter-kehl12:10:45

https://clojure.org/reference/reader#_symbols sounds out of date. It reads: > Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, ', and ? (other characters may be allowed eventually). However, lower than < and greater than > work, too. Can you see any other characters that are not listed?

Alex Miller (Clojure team)12:10:15

This section is intentionally ambiguous. It provides guidance on what is definitely allowed.

Alex Miller (Clojure team)12:10:45

And in some cases what is definitely not allowed

Alex Miller (Clojure team)12:10:18

While attempting to leave the door open on other characters to future mods

sambaran15:10:07

Is there any function in clojure which returns the first n natural numbers? Similar to F# way of using let a = [1..100];;

zakora15:10:03

@sambaran2010

user=> (range 10)
(0 1 2 3 4 5 6 7 8 9)

👍 8
Azzurite17:10:38

why not (circle 42)?

Andrea Imparato19:10:34

hello everyone, I’m about to buy the Getting Clojure book because I’ve read that is highly recommended for beginners like me

Andrea Imparato19:10:48

can anybody confirm me this? 🙂

orestis19:10:48

I read it as a non-beginner and it indeed has a very gradual ramp up to the syntax and important concepts.

orestis19:10:08

But I was already familiar with the material so can’t comment further.

Andrea Imparato19:10:48

ok, what about Clojure Applied? I already read Clojure for the brave and trueactually

Andrea Imparato19:10:12

so I’m already aware of the language syntax and structures

Andrea Imparato19:10:35

what I’m missing is more how to build real world applications and how to think in the “functional way”

rpkarlsson20:10:23

@andrea.imparato I really enjoyed Clojure Applied. Seems like it could be what you are looking for. The back of the book says "[...]Discover how to use Clojure in the real world[..]". For me the chapters "Model Your Domain", "State, Identity and Change", "Use Your Cores" and "Thinking in Clojure" was some of the topics that I found extra interesting having already read some other Clojure books ("Clojure for the brave and true" one of them). I haven't read Getting Clojure so I cant compare the two.

orestis21:10:38

If you already know Clojure’s syntax definitely get Clojure Applied.

orestis21:10:52

Actually, I’m not which book out there gives you “the functional way”. It might be one of those things that you have to practice than read out of a book.

orestis21:10:33

I highly recommend doing some toy problems like Advent of Code that will force you to write some algorithms with immutable data structures.

Andrea Imparato21:10:45

thanks for your answers guys :)

orestis21:10:50

The moment you realize you can’t use a mutable variable followed by a for loop, forcing you to think in terms of filter/map/reduce, that was a huge first step for me. Not in Clojure, in my case, but in Elixir, but same principles.

rpkarlsson21:10:09

@andrea.imparato thinking about it perhaps "Functional programming patterns in Scala and Clojure" could be of interest? https://pragprog.com/book/mbfpp/functional-programming-patterns-in-scala-and-clojure.

Andrea Imparato21:10:16

@rpkn yeah that could be good too by looking at the summary 👍

seancorfield21:10:53

@orestis Would you say Joy of Clojure might be a good one for "the functional way"? (I had an FP background before I read it so I'm not sure I'm a good judge -- but that would be the book I'd consider recommending) /cc @andrea.imparato

orestis22:10:29

I can’t remember whether I’ve read that or not...

pablore22:10:37

So I have a macro that throws an exception when some of its arguments are invalid and I am failing to test for that with clojure.test/thrown?, it doesn’t catch the exception. Is it possible to catch exceptions from macros?

noisesmith23:10:53

only if the try/catch surrounds the initial compilation of the form

noisesmith23:10:43

remember that macros run when creating the bytecode for your form, not when that bytecode gets executed

noisesmith23:10:14

so (is (thrown? ...) (eval '(my-macro ...)))