This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-02
Channels
- # 100-days-of-code (1)
- # announcements (2)
- # beginners (122)
- # boot (5)
- # calva (5)
- # cider (54)
- # cljdoc (1)
- # clojure (132)
- # clojure-brasil (1)
- # clojure-italy (4)
- # clojure-nl (6)
- # clojure-uk (105)
- # clojurescript (43)
- # core-async (17)
- # cursive (14)
- # datomic (60)
- # emacs (35)
- # figwheel-main (44)
- # fulcro (70)
- # graphql (1)
- # jobs (19)
- # jobs-discuss (5)
- # leiningen (5)
- # luminus (2)
- # off-topic (40)
- # onyx (2)
- # overtone (5)
- # re-frame (36)
- # reagent (29)
- # ring-swagger (20)
- # rum (13)
- # shadow-cljs (19)
- # testing (5)
- # tools-deps (25)
- # vim (5)
Given Clojure's focus on abstractions, I suspect the second approach would be less surprising -- but I also suspect the first approach would be "easier" for beginners.
since you are comfortable with the "high level" data structures, you can start learn JAVA doing class
in all structs and exploring the clojure source
(I learned java with this path)
i've learned FP by manipulating Data on lists in a language based on Lisp too. So i think the way that books and guides present the data structures from clojure is weird... but that's just because there's a ton of abstraction on top of them, but seeing how lSeq works, i can see more less how those abstractions works. My mind demands that i know how some of those abstractions were made, in order to comprehend the language, but that's just me and the path i took
since you are comfortable with the "high level" data structures, you can start learn JAVA doing class
in all structs and exploring the clojure source
(I learned java with this path)
There are performance guarantees associated with some of the abstractions (e.g., Counted) and then there's the whole thing about (coll ix)
where several collections know how to look things up in themselves -- collections can behave like functions -- and also (kw coll)
where the keyword can look itself up in certain collections -- and those are based on abstractions too (Associative, etc). So the abstractions are important.
e.g., ([1 2 3] 2)
=> 3
because a vector is associative:
user=> (-> [1 2 3] type ancestors)
#{... clojure.lang.Associative ... clojure.lang.Counted ...}
i see how important they are, and i've found a great joy in clojure abstractions, because when i was learning, some of them, i was doing by my own, and learning how to build abstractions by replacing signatures and producing high order functions... then i see a lot of websites and some books that focus primarily on the abstractions mechanisms and (off course) not how they are implemented or how they work... and i'm avoiding that way of programming by thinking that's some kind of magic happening and that i shouldn't bother about how
so i tend to keep digging into those data structures to find how they work, and turns out that i could build most of them by my own, just constructing a lSeq with (cons)
by seeing this way i can learn more being more confident when coding
Hi guys, I'm studying Clojure and I feel that I need to build a project to better understand this language. I want to build an API for a web app, just for fun and learning experience. Which "framework" do you recommend for a beginner? I heard about Pedestal. Any other interesting library for a begineer? ๐
@leandrotk100 i'm planning on learn by using Luminus, which is not a framework, but most like a collection of libraries to dev back end for web
@leandrotk100 Clojure doesn't really have "frameworks" -- it has a few project templates which use collections of libraries but the mindset is composable libraries instead.
Pretty much every Clojure web app has Ring at its core (or a Ring-compatible alternative) and then there are various routing libraries -- I think Compojure is the most popular/easiest to learn when you're getting started.
Whilst you can just start with a template like Luminus, there are a lot of moving parts in such templates so if things start to go wrong, there's a huge amount of stuff to try to understand and debug -- which can be overwhelming. I highly recommend just starting with Ring and Compojure and seeing how you get on.
You will probably want to render HTML if you're not doing just a REST-style API app, so you'll either want to look at Hiccup (data as HTML) or Selmer (Django-style HTML templates).
For now I just want to build a REST-style API. Interesting to know that it's a collection of libraries. It's a different "concept" for me
@seancorfield what about the book Web Development with Clojure by Dmitri Sotnikov? i was planning on reading it on the future
@cybersapiens97 @leandrotk100 Per my comment above: Luminus encompasses a lot of stuff -- I think you're better off learning basic Ring and Compojure first before diving into something as big and complex as Luminus, when you're getting started.
If you look at https://pragprog.com/book/dswdcloj2/web-development-with-clojure-second-edition it shows it is aimed at more Expert level Clojure (see the skills meter on the left -- "About this title").
got it
thats why i'm planning on trying it later, but i'll remember this, if things starts to get a little too complicated, i'll give a try by using one lib after another
why does Numbers are listed as Data Structure on https://clojure.org/reference/data_structures#Numbers i don't get it, wasn't Numbers supposed to be a atomic data type/java primitive, not a data structure ?
Maybe a better name for that page would be data_types rather than data_structures
The skills meters on some of the Pragmatic Bookshelf books are incorrect. For example, Getting Clojure is shown as Intermediate -> Advanced when it is really a beginner book. Web Development with Clojure is actually Intermediate -> Advanced, but maybe not if you consider that it includes a Clojure primer in one of it's appendixes.
Are there any modules/functions/macros to help with error tracing (in Clojure 1.9.0)? I have a small workaround but using it (introducing it to the code) is too manual:
(defn trace [name f & args]
(print "Calling" name "with ")
(clojure.pprint/pprint args)
(try
(let [res (apply f args)]
(print name "returning ")
(clojure.pprint/pprint res)
res)
(catch Throwable e
(print "Threw" e)
(throw e))))
Then I insert trace "description"
before function calls, like
(trace "+ on numbers" + 1 2)
Any tips, please?Unfortunately, that disables compile time validation of number of parameters, so if functions/calls change, I remove to trace "message"
to check the signature, then I re-add trace "message"
back if need be.
Something like this?
dev> (defmacro debug [msg body]
`(let [val# ~body]
(println "DEBUG (MSG): " ~msg)
(println "DEBUG (RET): " val#)
val#))
#'dev/debug
dev> (debug "adding" (+ 1 1))
DEBUG (MSG): adding
DEBUG (RET): 2
2
dev>
@peter.kehl I think you're better of using https://github.com/clojure/tools.trace. Cider has direct support for it (you can trace both individual functions and whole namespaces)
Thank you @dadair and @jumar. I'll use both your macro and Cider.
Hi Team, I am new to this forum, I have 8+yrs of experience in java, spring, I am very interested in learning Clojure. I believe it's latest version is 1.9. I wish to get a Kickstart on Clojure. How to begin it, which book should I prefer? I want make fundamentals strong. Request you to guide me on the same. Regards, -Pankaj.
I think the book "Programming Clojure" is a good choice.
โLiving Clojureโ by Carin Meier is a good one too.
โGetting Clojureโ has also a very gentle ramp-up and also targets 1.9. I advise both.
Yes, and โClojure Appliedโ very much so โ I wish there would be an updated version soon. Such good value of how to structure your code, but some of the libraries there might have been superseded by other things now.
Mainly what I like about Programming Clojure is that it explains why things happen, sometimes in terms of the JVM and in comparison with java
hi all, any recommendations for a good way to learn cljs and clojure simultaneously (preferably with boot, which I gather is superceding leiningen)? I tried to follow the modern-cljs tutorial but it's just out of date enough that none of the examples quite works so I've spent most of my time debugging version / dependency errors instead of just learning the language. I'm a fairly experienced front-end js dev, and I'm comfortable in emacs, fwiw.
@samface boot does not supersede lein, and clj does not supersede lein or boot, theyโre just different tools for similar problems. for beginners lein might be easier.
@borkdude good to know, thanks!
for learning cljs, just learn clojure the language and then start with e.g. Reagent to build some toy app
there is now figwheel.main which combines with clj and thereโs also shadow-cljs. both are targetting easy getting started with cljs, but I donโt use either, so canโt advice on that
i did look at figwheel but left it to pursue the boot-based tutorial I was doing -- I'll circle back and check it out. thanks for the advice!
I do have a project in mind and I definitely agree that trying to build something is the best way to learn anything
once you get the project going, it doesnโt really matter which build tool youโre running, but boot is sometimes hard on beginners
yeah that makes sense
to see the differences between lein and boot: https://blog.michielborkent.nl/2015/06/06/from-leiningen-to-boot/ (may be a bit outdated)
that blog post also references a simple working clj + cljs project which may serve as an example for beginners
๐๐๐
i think I'll be totally fine once I get the basic project / workspace going; so probably going with lein is the move until i'm more comfortable
I stumbled over a function that potentially calls itself a lot recursively, similar to this:
(defn fun
[x]
(let [foo ["lots" "of" "strings" "but" "always" "the" "same" "ones"]]
(if (some-checks-with-x-and-foo)
(fun some-values)
(fun other-values))))
Is having foo
inside the let
there for every call of fun
bad?Regarding performance you mean? I think the JVM Clojure compiler is smart enough to perform constant extraction, meaning that foo
will only be computed once when fun
is compiled. But you'd be relying on an implementation detail here. You can also wrap the (let [foo ...])
around the defn
, or if that disturbs you do something like (def fun (let [foo ...] (fn fun [x] ...))))
Thanks, I think I like the last syntax more, even if looks new to me. I'll check it out!
@U63JKCFC3 Like this I think:
(let [foo ["some" "values"]]
(defn fun
[x]
; function body, use foo here
))
In Slack, I'm not sure you can in this format, but you could post a Snippet with Clojure syntax.
I have a question. How can I turn (< [1 2 3]) into (< 1 2 3) ?
@coinedtalk do you mean (apply < [1 2 3])
?
both actually
many thanks
clojure is really fascinating
Hello, Here is this repo. https://github.com/Otann/shadow-cljs-fullstack That is shadow-cljs mixed clj part. I run successfully and setup as in the readme part. How could I create from this a real solution? compile with lein uberjar for backend and different way to frontend? with lein uberjar I get
Can't find 'shadow.cljs.devtools.clj' as .class or .clj for lein run: please check the spelling.
Exception in thread "main" java.io.FileNotFoundException: Could not locate shadow/cljs/devtools/clj__init.class or shadow/cljs/devtools/clj.clj on classpath.
@sb there are some typos shadow.cljs.devtools.clj
should be shadow.cljs.devtools.cli
, i
not j
.
Hello macro experts.
How do I get the macro's call code as a string from &form
, please?
I worked out how to access the code of one parameter: (defmacro print-code [param] (list 'print (str param)))
which called as (print-code (+ 1 2))
prints: (+ 1 2).
How can I do the same with &form
in either unquoted macro source (list ...)
or in a back tick-quoted one, please?
I tried various combinations, like
(defmacro print-code2 [& param]
(print ~&form))`
(defmacro print-code2 [& param]
(print ~@&form)`
(defmacro print-code2 [& param]
(print @&form)) ;most likely incorrect`
user=> (defmacro hello [s] (let [f (str &form)] `(let [s# ~s] (str s# ~f s#))))
#'user/hello
user=> (hello (do (println "Hi!") "World!"))
Hi!
"World!(hello (do (println \"Hi!\") \"World!\"))World!"
You just use &form
on its own at the macro level -- if you need it in the expansion, you'll need to bind it at the macro level and unquote that binding in the code level.
Hello Clojurians, I'm new to Clojure, can you please suggest or give ideas to work on a beginner project to enhance my knowlegdge.
if you have nothing particular that you want to do, I would suggest http://www.4clojure.com/
Thank you @azzurite
Thank you @seancorfield.
while searching here in Slack I just noticed that the "workspace is over the storage limit".
there's a separate channel for this sort of discussion, for context IRC is still around with hundreds of users and other channels are welcome but there's no real centralized leadership that's going to tell everyone to stop using a particular channel and go somewhere else AFAIC
iirc #community-development was where this discussion happened, ironically the entire contents are gone thanks to slack storage limits
@U0TSNMT53 There are several Clojure rooms on Gitter. Let me go get the link for the main one(s)...
There are also rooms for core.cache, core.memoize, java.jdbc, and tools.cli (since I maintain those four).
I don't do Emacs either -- but CIDER's Orchard library and nREPL (which is part of that same team now) are core to most editors' Clojure integration ๐
Im setting up a newer osx laptop and installed jdk 11 and tried to run a new luminus web app created from leiningen. I am getting some strange errors when running the repl.
Exception in thread "main" java.lang.ExceptionInInitializerError
at clojure.main.<clinit>(main.java:20)
Caused by: java.lang.IllegalArgumentException: Must hint overloaded method: toArray, compiling:(flatland/ordered/set.clj:19:1)...
Caused by: java.lang.IllegalArgumentException: Must hint overloaded method: toArray
at clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:8375)
at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:7937)
at clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:7813)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
... 328 more
I did a little research and found that you may get errors like this if building clojure from source but I am not, so im not sure what's happening.Might come from core.rrb-vector, not Clojure @dfcarpenter - try specifying version 0.0.12 for that
If I need the โssh taskโ before compile with lein uberjar
, how can I add to :prep-tasks
in project.clj?
@ghadi I added it to my lein deps but I am still getting the error. How can I find which dependency is using an older version?
lein deps :tree
Thanks. Well how frustrating. I can't find out what is using rrb-vector. Guess i'll downgrade java
@dfcarpenter the answer is in your stacktrace earlier
Yeah, a similar problem with OpenJDK 11 and Clojure has bitten a handful of Clojure libraries, as well as those who build Clojure from source code themselves. Looks like flatland/ordered/set is one of those.
There is a PR open for that project here: https://github.com/amalloy/ordered/pull/37/files
Ahh I see its a dependency of the lacinia project
Well thank you for the help
Is there a way to exclude a dependency of a dependency so that I can just include rrb-vector 0.0.12 in my deps and it should use that?
You could try pinging amalloy on that PR, perhaps, to see if he is interested in merging and releasing an updated version.
rrb-vector is unrelated to your problem -- unless you know otherwise @dfcarpenter
Oh of course, sorry I need coffee
If you need "work real quick now -- will later update to use official release versions when/if available", you could apply that path to flatland/ordered/set yourself and create a JAR for it, either local or on Clojars.
Then your question above would be the same, except how to override a different dependency.
Does the argument passed in a Macro, can be described as an S-Expression ?
Iโve learned to deal with meta-programming by manipulating S-Expressions, so I think I can mimic the structural design for s-expr data when working with macros