This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-16
Channels
- # aws (6)
- # beginners (129)
- # calva (9)
- # cider (4)
- # cljs-dev (2)
- # clojure (41)
- # clojure-beijing (2)
- # clojure-dev (3)
- # clojure-spec (23)
- # clojure-uk (46)
- # clojurescript (38)
- # community-development (20)
- # core-async (4)
- # cursive (12)
- # data-science (7)
- # datascript (13)
- # datomic (15)
- # duct (11)
- # emacs (18)
- # figwheel-main (5)
- # fulcro (26)
- # off-topic (4)
- # pathom (28)
- # pedestal (3)
- # reagent (8)
- # reitit (6)
- # shadow-cljs (32)
- # specter (3)
Hello guys. I am very new in Clojure yet and am now reading Clojure for The Brave and True. I am thinking to read the entirely book first and them start coding for real. Do you think this is a good aproach? How was your process of learning Clojure? I would appreciate some help to speed up my study. I came from Java and have already some contact with functional programming in Javascript.
I would work as you go. I find that typing and thinking at the repl helps cement the concepts
Hello, can anyone recommend me some good books for learning clojure? As well as an additional book for learning web development with clojure?
I am currently reading the Joy of Clojure and it's good!
@db0349It's a bit dated but most everything is still true, and the second edition was made in 2016 I believe
But it goes fast, so maybe not a book for total beginner
Okay thank you! Does anyone have any recommendations for a clojure book for web development as well?
I have been updating my workshop for server-side web apps, still some work in progress http://practicalli.github.io/clojure-webapps/
And that's fine I've done clojure in the past, and I just need to be refreshed
I believe http://www.allitebooks.in/web-development-clojure-2nd-edition/ was recommended to me, but I never read it
maybe someone else can comment on it
Okay thank you
The second edition of Joy Of Clojure is from 2014, but from my understanding clojure hasnt changed a whole lot since then, right?
pretty much any book ever written about Clojure is still valid. I'm not aware of any glaring deprecations
@db0349 The main thing to watch out for in older books is library versions. In particular, the older "monolithic Contrib" (1.2) isn't compatible with newer versions of Clojure, and several of the library names changed. But as long as your book is Clojure 1.3 or later, you're mostly alright /cc @john
@seancorfield thanks sean, nice to know!
Hi everyone! Quick question about using a library created in clojure in a Java project.
What I did
- I created a library in Clojure and I exported it using lein uberjar
.
- I took the (non-standalone) .jar
and added it to my class path in my Java Project.
How can I access the functions from that library in my Java project? What would be the import? Something like import project-name.core
? Thanks a bunch!
-'s in clojure namespaces become _'s
but whether there is a class to import depends on whether you did aot, gen-class, etc
I used aot and gen-class. The gen-class :name
is com.myname
. So, I can import com.myname
but the only function I can access is main
.
all of the functions that use the prefix (by default -
in the gen-class'ed namespace) should be available
so -main
becomes main
hmm, ok. So if I created another function in my .core
which was -somethingElse
then that will also be accessible? And since it’s a function, can I do a static import of it?
yes, it will be accessible and yes I think you should be able to do a static import on it
it's just a normal java static method on the class
Awesome! Gonna give it a shot. Thank you!
you can also use the java API for invoking Clojure (http://clojure.github.io/clojure/javadoc/)
http://clojure.github.io/clojure/javadoc/clojure/java/api/Clojure.html
Can clojure immutable data structure be used in java like java native data structure? I mean not by the java API for invoking clojure?
Yes, but they only implement the read APIs
@tjh.xbow Technically yes, they implement the appropriate java interfaces (vector implements List etc.), but they might not be the most convenient option. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java
Howdy Y'all! I'm building a simple compojure + reagent app and I want to use the same compojure service but have it talk to multiple databases. Where should i store the configuration?
So the service will need to know of the databases before hand? How i reload the config when I add a new db? Is this good practice?
How do people usually abstract out effects in Clojure? Similar to how Haskell would use type classes or object oriented code would use interfaces
- Partly just the discipline of trying to keep most functions pure and segregate side effects into a few places. - Protocols are like OO interfaces. - Or there are a handful of libs (eg re-frame in cljs) that go further, using data to describe desired effects and having a single centralized resource to actually act on them.
I've created application with leiningen, and I was wondering why this code thorws exception, but prints value before it.
(ns clojure101.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
((def greting "Hello there")
(println greting)))
Hello there
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn, compiling:(/tmp/form-init7051855349601256406.clj:1:73)
at clojure.lang.Compiler.load(Compiler.java:7526)
at clojure.lang.Compiler.loadFile(Compiler.java:7452)
at clojure.main$load_script.invokeStatic(main.clj:278)
at clojure.main$init_opt.invokeStatic(main.clj:280)
at clojure.main$init_opt.invoke(main.clj:280)
at clojure.main$initialize.invokeStatic(main.clj:311)
at clojure.main$null_opt.invokeStatic(main.clj:345)
at clojure.main$null_opt.invoke(main.clj:342)
at clojure.main$main.invokeStatic(main.clj:424)
at clojure.main$main.doInvoke(main.clj:387)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
at clojure.lang.Var.fn(Var.java:365)
at clojure.lang.Var.invoke(Var.java:381)
at clojure101.core$_main.invokeStatic(core.clj:7)
at clojure101.core$_main.doInvoke(core.clj:4)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:377)
at user$eval149.invokeStatic(form-init7051855349601256406.clj:1)
at user$eval149.invoke(form-init7051855349601256406.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:7062)
at clojure.lang.Compiler.eval(Compiler.java:7052)
at clojure.lang.Compiler.load(Compiler.java:7514)
... 12 more
def should only be used at the top level (like where you have ns and defn)
functions have an implicit body and can take multiple expressions - you have them grouped in a set of parentheses
parentheses mean function invocation
so how would I save value that needs to be printed but takes value based on some logic?
so the def expression is getting evaluated, then the println, then you are trying to invoke the result of the def (a var) with the result of the println (nil). vars are invokable actually
use let
here, not def
(defn -main
[& args]
(let [greting "Hello there"]
(println greting)))
let
creates locally scoped bindings
(defn -main
[& args]
(let [a 1
b (+ a 1)]
(println a b)))
let bindings can build on each other
the most popular are Emacs with CIDER (https://github.com/clojure-emacs/cider) or Intellij with Cursive (https://cursive-ide.com/)
Some others to consider are VS Code with Calva, or Atom with a variety of plugins (I'm not up on the latest there)
I use emacs but I think every editor is going to have some kind of basic setup to integrate with the clojure repl. That's the key, you want to start using the repl. So google sublime text clojure repl setup
or something similar. Or if you want something more like Sublime Text but a little more popular for Clojure development look into Atom w/ Chlorine or Proto repl (I think it's called) or VS Code and Calva.
(ns clojure101.core
(:gen-class))
(def random-number (rand-int 11))
(defn -main
"I don't do a whole lot ... yet."
[& args]
((if (< random-number 5)
(println (str random-number "Number is smaller than 5!"))
(println (str random-number "Number is bigger than 5!")))))
It's because you have two open parentheses before the If
(defn -main
"I don't do a whole lot ... yet."
[& args]
(if (< random-number 5)
(println (str random-number "Number is smaller than 5!"))
(println (str random-number "Number is bigger than 5!"))))
oops formating 😕
howd do you format code here?
I would like to have the snippet of code I wrote to be formatted as code, the same as in your message
thanks
Thanks 👍
@cvetan.simsic To get back to your problem, when you define a function like,
(defn example-fn
[arg1]
(println arg1))
You only need one set of parenthese around what's inside the function definition
If you write
((some-fn arg1 arg2))
it means that some-fn
is a function returning a functionlike
(defn closure
[n]
(fn []
(+ n 1)))
I'm setting up codox, for generating documentation.
In my project.clj I've configured it with
:codox {:metadata {:doc/format :markdown}}
and ive tried writing by docstrings both as just regular docstrings and as the doc meta ` (defn foo [x] " Returns x" {x}) (defn foo [x] {:doc "Returns x"} {x}) ` But the docstrings and arguments arent added in my documentation. My namespaces are enumerated just fine.
Check the form for defn. I believe the docstring goes before the arg vector to disambigate the docstring from a value in the body of the function
Hi! setting up Leiningen with shadow-cljs and having a bit of a headache
I can call shadow-cljs nicely with npm but it seems that invoking calls via lein fail, etc: lein run -m shadow.cljs.devtools.cli help
produces just "Unknown action."
@theamazingekko did you try anything else but help
? that action only happens to be implemented on the JS side 😉
ooooooohhhh!
gotcha!
yeah it works xD
you may not want to use lein
to run things as that does not work with the server mode
you can just configure :lein
in shadow-cljs.edn and it will use lein
to run things internally https://shadow-cljs.github.io/docs/UsersGuide.html#Leiningen
ah yes already changed that, if you mean adding that true -value? 🙂
hmm.. I know the user manual is still work in progress but I think the help -command should be omitted from the examples. I know it was stupid of me not to try other commands but it kinda tripped me as it was the first step in testing calling commands from lein 😄
no problem! thanks a bunch for the help though! Really looking forward to getting to know this tool 🙂
if you have questions come on by #shadow-cljs. I don't always notice questions here.
noted! thanks 🙂
how idiomatic is doing something like this
(def ^:dynamic add-acc)
(defn pipeline []
(into []
(map (fn [x]
(add-acc x)
(inc x)) (range 10))))
(let [state (volatile! [])]
(binding [add-acc (fn [x] (vswap! state conj (* 2 x)))]
(pipeline)
@state))
is there a better way to accumulate a value inside a transducers pipeline?using an atom/volatile seems fine: https://clojure.org/reference/transducers#_transducers_with_reduction_state
your example doesn’t seem to be really using transducers, though, just a regular map
over a sequence.
one thing to note is that a transducer might be lazy, in which case using binding
probably is a bad idea
I think the idiom is to use a higher-order function to create the stateful transducer
Hello! Trying to get Emacs+Cider going. I can open the repl buffer, and go into 'insert mode' and type stuff, but how do I get it to evaluate? 😛
All parens have to be closed for it to evaluate on return
— otherwise it assumes you want to continue onto another line. My guess is that’s what you were tripping over.
You can evaluate code in the Clojure buffer too, in Vim normal state using SPC e f
and other commands under SPC e
(def ^:dynamic add-acc)
(defn pipeline []
(into []
(comp
(map (fn [x] (add-acc x)(inc x)))
(map (fn [x] (add-acc 10) (dec x))))
(range 10)))
(let [state (volatile! [])]
(binding [add-acc (fn [x] (vswap! state conj (* 2 x)))]
(pipeline)
@state))
i need to be able to accumulate the value in any transducer inside the "pipeline"