This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-07
Channels
- # announcements (4)
- # babashka (20)
- # beginners (167)
- # calva (1)
- # cider (18)
- # circleci (10)
- # clara (45)
- # clojure (85)
- # clojure-argentina (1)
- # clojure-europe (3)
- # clojure-finland (3)
- # clojure-greece (2)
- # clojure-italy (9)
- # clojure-nl (30)
- # clojure-spec (32)
- # clojure-survey (39)
- # clojure-uk (72)
- # clojurescript (12)
- # core-async (4)
- # data-science (3)
- # emacs (10)
- # figwheel-main (9)
- # fulcro (44)
- # graalvm (3)
- # jobs (12)
- # jobs-discuss (6)
- # joker (3)
- # juxt (1)
- # leiningen (4)
- # off-topic (23)
- # planck (5)
- # re-frame (4)
- # reitit (2)
- # remote-jobs (1)
- # shadow-cljs (43)
- # spacemacs (8)
- # test-check (19)
- # tools-deps (21)
For transducer
s, is a single step transducer filter #(and (int? %) (pos? %))
more efficient than a two step transducer (filter int?) (filter pos?)
or are they same because no intermediate sequences are created anyways?
Yes, it is faster as it will perform a single pass with no intermediate sequence objects, rather than two passes. Filter seqs are chunked (in 32-element chunks) so the benefits are smaller than you might expect. In general, transducers will increasingly win as you increase the number of transformations and/or the size of the collection.
yes, many
and many that aren't
and generally, I'd say that if you care which you're using, you shouldn't be using lazy seqs
@hindenbug I wouldn't expect there to be much difference in practice -- I'd expect the single step to be slightly faster -- but I'd go with readability until it was proven I had a performance issue.
I ran some tests with Criterium and, yes, the single step is faster but it's not all that much faster (and the output I'm getting from my benchmarks are sufficiently variable that I can't really get an accurate read on the difference).
(the slowest runs of the single-step are slower than the fastest runs of the two step)
Perfect, thanks. I really need to start looking into criterium for quick perf tests like this.
This (slurp (:body (client/get "
with the actual domain I am requesting. Returns this
Execution error (IOException) at org.apache.http.conn.EofSensorInputStream/isReadAllowed (EofSensorInputStream.java:107).
Attempted read on closed stream.
class .IOException
I can't slurp directly because i run out of memory.
(defn append-to-file
[file-name s]
(spit file-name s :append true))
(defn write-json-file [file-name s]
(with-open [rdr (io/reader (:body s))]
(map #(append-to-file file-name (str % "\n"))
(line-seq rdr))))
(defn fetch-data
[{:keys [url query-params]}]
(client/get url
{:accept :json
:as :stream
:query-params query-params}))
(write-json-file "result.json"
(fetch-data {:url "}))
This is what I have so far. The client is clj-http
I am getting this
Error printing return value (IOException) at .BufferedReader/ensureOpen (BufferedReader.java:122).
Stream closed
class clojure.lang.ExceptionInfo
Though it does write the file to disk. How do I return a value? When I add a println
as a message to say it's finished it doesn't write to disk. Adding a nil
or ìdentity
also stops it from writing to disk.
Ah figured it out. I use doseq
Just realised it closes stream after first read. This is what I get when first running against the stream.
Execution error (OutOfMemoryError) at (REPL:1).
Java heap space
class java.lang.OutOfMemoryError
Hey guys, i'm triyng to create a vector with some maps on it.
(def address-request {:uri "api/address"
:method :post
:format ajax/json-request
:response-format ajax/json-response
:on-success [:customer/addresses-success]
:on-failure [:customer/addresses-failure]})
This is my map. I would like to, for each element that i have in another map do a update-in
for add :param
with the value and then add it on a vector.
This is my attempt to do it:
(defn request-vector [params request-body]
(reduce (conj [] (update-in request-body :params assoc params) params)))
But i'm getting a error:
java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
What you guys think it would be the best approach do achieve this goal?check arguments for update-in
, the path where you want to apply update function must be sequence. (update-in request-body [:params] assoc params)
or use update
instead of update-in
Thank you for the insight!
I got almost there
i did a (reduce-kv
`(fn [r k v]`
`(conj r (update request-body :params v)))`
`[]`
`params)`
But the v is null
params {:main {:street "name" :customer ..uuid..} :facturation {:street "name" :customer ..uuid..}}
Maybe show an example of the map and then the resulting vector you'd want. I'm not sure I fully follow what you're trying to achieve
I println v and it shows a value
It worked
Thanks friend
Hello! Starting to learn clojure and programming in general. Total beginner. I have a question. I have a nested vector: [something [a 1]] What I want from it: a new key + value based on this. so: :someting/a 1 How can I do this?
You can construct qualified keywords by calling keyword
with 2 arguments, does that help?
do you mean like this?
(clojure.string/replace "a\nx" "\n" "\\n")
Hi, I'm just starting with reagent, following this tutorial
https://dhruvp.github.io/2015/02/23/mailchimip-clojure/
doing the input field example, I modified it to a number input, so I can input hours/minutes, and then wanted to pass :min
and :max
values.
Not sure what to do, I've added to the input-element component an argument called &attrs
, then passed a hash-map
{:min 0 :max 24}
and merged it with the rest of the attributes.
Which seems to work, but I still fear I might have sinned and there is a more preferred way to do it. what do you think?
(defn input-element
"An input element which updates its value on change"
[id name type value attrs]
[:input (merge {:id id
:name name
:class "form-control"
:type type
:required ""
:value @value
:on-change #(reset! value (-> % .-target .-value))} attrs)])
;; TODO pass min and max values into input-element.
(defn hours-input [hours-atom]
[input-element "hours" "hours" "number" hours-atom {:min 0 :max "23"}]
)
Some people like to put all the props on a map (not just max and min on your example).
The &attrs
also threw me off a bit, since it resembles a typo on the rest format (`& attrs`)
The "&" was my very silly voodoo/cargo-cult concept of the rest format, now read about it and realized my mistake, so I'll edit it away from the snippet 🙂
Hi, question about embedding Metabase in a clojure app: the metabase docs say “Insert this code snippet in your server code to generate the signed embedding URL” where is server code located in a Clojure/CLJS app?
Hi! I’m just getting started with clojure and one thing I find a bit confusing is which tool I should use for dependencies. Some places recommend Leiningen (which is build on top of Maven?) but others recommend just using deps. Which one is the recommended option? I’m looking for something lightweight that can generate a simple project setup with a test runner, do some builds etc
I echo everything that was said in the channel (good idea to use lein to start). If you'd like more commentary on the subject, we did a podcast episode about it: https://clojuredesign.club/episode/040-should-i-use-lein-boot-or-tools-deps/
If you have not read this https://corfield.org/blog/2018/04/18/all-the-paths/ I would take a look to familiarize yourself with the options available.
As for what your looking for, my recommendation to each one is:
> generate a simple project setup
https://github.com/seancorfield/clj-new
> builds + dep management
clj
+ deps.edn
> test runner
Clojure has a light weight testing library. I recommend to use that. https://clojure.github.io/clojure/clojure.test-api.html
Leiningen is the "easiest", CLI/`deps.edn` is the simplest. Pragmatically, use whichever tool the book or tutorial you are learning from is using.
Thanks for the advice!
Leiningen it is then 😄
For background @dennistel90 I started with Leiningen back in 2010 because it was the only option. At work we switched from Lein to Boot in 2015 and then to CLI / deps.edn in 2018. These days I only use the CLI / deps.edn tooling.
@seancorfield what is the motivation (from your team, but also the community) to move from leiningen -> deps + cli?
I blogged about our switch from Leiningen to Boot https://corfield.org/blog/categories/boot/ but I didn't write up why we changed to CLI/`deps.edn` (I will, eventually).
I also blogged a comparison of Leiningen, Boot, and CLI for aspects of running code and building artifacts etc https://corfield.org/blog/2018/04/18/all-the-paths/
oh yeah thats definitely the plan for learning
asking more to get an idea of what is going on and where to possibly move to after learning clojure
One thing that's good to learn after learning Clojure with lein. Is using Clojure without a dependency manager and build tool at all. Learn how to manually download jar and sources, and build up a classpath, and call clj with it manually, and similarly start a repl with clojure.main directly and learn to use the Clojure load and compile functions
Once you know that, you'll understand what all these tools do under the hood, and it'll be easier for you to pick up and use any of them
Slightly related to tooling, how hard/easy is it to write a clojure library that works on JVM but also in Clojurescript?
Don’t have one yet 😄 is this similar to a global .npmrc/.bashrc or something?
Yes, the CLI/`deps.edn` tooling uses three deps.edn
files: the "system" installed version (from the CLI -- technically it's baked into tools.deps.alpha
now rather than a physical file on disk), the "user" version (in ~/.clojure/deps.edn
-- a default version appears after installing the CLI but you can customize it as you wish), and then the "project" version (in the current directory).
Yeah , it being a hosted language is definitely what draws me to it since I plan to use it on node/JVM and possible the BEAM VM(clojerl?) as well
If you're looking for doing ClojureScript as well, shadow-cljs is a great build tool for it. Probably the easiest
@deleted-user Thank you so much for the info and suggestions! now lets learn some Clojure! 💪
How do people redefine a variable or swap out some kind of reference with a large data structure. Using an atom and reset! Is too slow. I also tried using a volatile! Then vreset! But it’s still way too slow. At the moment I have (def my-def val-1) and (def my-def val-2) inside a comment block so I can use the repl to redefine it. I’m doing this because I have a lot of other functions I am using at the repl to inspect the data structures. I only want to change the reference once.
Setting the atom or the def is fine for the first time. I can reset it to a string or something small. But when I reset it to the alternate data structure the repl simply hangs.
Yea I was trying to avoid binding because all the snippets I have would need to go inside the binding. What I have for the moment works for what I need but I’m curious if there is something I was doing wrong.
can you def the alternate data structure? do something like (def new-stuff big-nasty-thing-that's-slow)
and then (reset! the-atom new-stuff)
and see if that is slow?
also, are you printing the big nasty thing? maybe try (do (reset! the-atom new-stuff) nil)
so that your repl isn't choking on printing a big gnarly structure
@dpsutton aha! That’s it when you reset the atom in the repl it prints out the new result. The (do ... nil) was what I was looking for. Thanks!
It's also a good idea to set *print-length*
and *print-level*
if you're working with large / infinite data structures in the REPL :)
hi i have a short question regarding clojure.spec. how would you spec lets say a person who can have children (which are also persons)?
The datastructure would look something like
{:name "person1" :children [{:name "child1"} {:name "child2"}]}
when trying to register a spec child
like (s/def ::children ::person)
it doesn't work, 'cause person is not defined yet (which makes sense)
(it will work because the spec combinators won't immediately try to resolve ::children)
user=> (s/def ::bar (s/coll-of ::foo))
:user/bar
user=> (s/def ::foo (s/coll-of ::bar))
:user/foo
user=>
Hi Everyone, when we read a future via deference , do it add overhead of passing the data back to the reader thread?
For Clojure/Java, the value passed back is just a pointer, i.e. a Java reference. It will not make a "deep copy" or anything like that. Pretty much nothing in Clojure makes a deep copy of anything, unless you do it yourself.
Safely passing objects between Java threads requires proper synchronization, which should be implemented for you already for all immutable Clojure values, including collections. For other Java objects, it depends on their implementation.
I'm using a Ring request's :body
's .hasContent
(https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/server/HttpInput.html#hasContent() ) in a handler, but ring-mock uses ByteArrayInputStream
s for mock requests' bodies, which causes tests to fail with an error that .hasContent
doesn't exist.
What is the "Right Way" to hack in a .hasContent
to specific ByteArrayInputStream
instances? I've looked at reify
, extend
and related, but haven't found anything that works.
the ring spec says it is an inputstream, which doesn't have that method, you are looking at a particular implementation of the ring spec, that happens to use a subclass of inputstream which has that method
using that method means you are not using the ring spec, which is why it will break when you use things like ring-mock and that stick to the spec
Is it possible to defmacro
that would be available in all namespaces (of the project?)
any macro must be in a namespace, all namespaces are potentially available
yes, but that would mean that I would have to import the namespace (with the macro) into each other namespace. I get that (and I understood that would be the case), but I was wondering that if I define a macro, can it be treated like one of the special forms, like when-let
where it's in core and available everywhere, perhaps by defining my own namespace that would be available everywhere too - rather than importing...
I could mitigate this by importing the namespace and using a small alias, like m
so I could do (m/my-funky-macro ....)
Because in non REPL contexts, you want to make sure that you require or use the dependent namespaces always. Using a fully qualified function from another namespace if it wasn't loaded, thus you want to be sure you do by explicitly declaring a require or use on them.
In REPL contexts, I declare all these fns and macros I want everywhere in the user.clj file. That file is auto-required by the REPL, and so you can start using functions from it directly without requiring it.
But, if you mean to say only within a given namespace that you explicitly required, you can use :refer :all
or use
to be able to call the functions or macros from the required namespace with just their name like when-let
That said, its not good practice when not in a REPL context, since it makes it hard for people to track where the fn or macro originates from.
No, not for the REPL, for the project - but thank you for helping out too! It's all good and based upon the excellent advice here and above, I can move forward with a design decision 🙂
the ns macro just ends up making all of clojure.core available unqualified by default, if you create your ns some other way it won't be
I mean, if you want, you can define new functions and/or macros in clojure.core, but I wouldn't recommend it.
$ clj
Clojure 1.10.1
user=> (doc foo)
nil
user=> (foo 7)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: foo in this context
user=> (in-ns 'clojure.core)
#object[clojure.lang.Namespace 0x2e61d218 "clojure.core"]
clojure.core=> (defn foo "foo in clojure.core" [x] (+ x 5))
#'clojure.core/foo
clojure.core=> (in-ns 'user)
#object[clojure.lang.Namespace 0x235a0c16 "user"]
user=> (ns bar)
nil
bar=> (doc foo)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: doc in this context
bar=> (clojure.repl/doc foo)
-------------------------
clojure.core/foo
([x])
foo in clojure.core
nil
bar=> (foo 7)
12
For most purposes, it is just another namespace.
Note that I created a new namespace bar to test it in. foo
wasn't visible in user
namespace for some reason, perhaps because it did the refer-clojure operation before I defn'd foo. Not sure exactly what is happening there.
Yep, new defmacro created in clojure.core was visible in ns bar also
Ah, I was just moving back to user, and you're right, you need to force refer again, or call ns again to have it refer the new clojure.core vars
there's a library that uses some weird hack to make a .
namespace, so your macro could be ./my-funky-macro
- but this is meant more as a dev time convenience
having namespaces that let a human reader know where something came from is actually a very nice feature
I even get annoyed by the way java code examples always leave out the import clause / full package name, with the assumption you have a tool that inserts the import for you
language conventions that avoid needing tooling > tooling
Oh man, and I hate static imports, I guess similar to how I hate use or refer all, though I understand its value at the repl
Single-letter or otherwise short aliases seem far preferable, if you can stand to type them 🙂
right, and explicit aliases to a namespace with a meaningful name in the ns block
hi, why my repl prints less info when there is an exception? I'm using this library https://github.com/ptaoussanis/truss , calling the sample function
(defn square [n]
(let [n (have integer? n)] ; <- A Truss assertion [1]
(* n n)))
(square nil)
it should print something like
;; Invariant violation in `taoensso.truss.examples:10`.
;; Test form `(integer? n)` with failing input: `<nil>`
;; {:*?data* nil,
;; :elidable? true,
;; :dt #inst "2016-10-14T10:01:28.671-00:00",
;; :val nil,
;; :ns-str "taoensso.truss.examples",
;; :val-type nil,
;; :?err nil,
;; :*assert* true,
;; :?data nil,
;; :?line 10,
;; :form-str "(integer? n)"}
but I only get
Syntax error (ExceptionInfo) compiling at (src/clj/sample/core.clj:200:1).
Invariant violation in `pim.product.core:198`. Test form `(integer? n)` failed against input val `<truss/nil>`.
it happens both at Intellij with cursive and launching lein repl
from terminal. I'm using the latest clojure version@vachichng if you evaluate *e
, that shows the full printed form of the most recent exception
this is described in the repl startup splash, alongside *1
etc. for most repls
@noisesmith oh thanks, it worked! how can I set that as default?
that's set by the repl itself, I don't know if there' s a universal answer
are you using nrepl, clj, socket repl?
if you are using it via lein, this should do the trick https://github.com/technomancy/leiningen/issues/799#issuecomment-45261174
where you might just want pst
(which is in clojure.core) without the clj-stacktrace dep
I wonder if there's a more generic answer that would work with clojure.main / socket repls - maybe starting a new repl with a different error handling function is possible? sadly these days calling pr
on an exception-info object has better info than pst
You can use any accept function with the socket repl - the provided repl is just one convenient answer
@noisesmith tried both ways, as you said, and from the github comment, but still getting the same results, no stacktrace printed
user=> (clojure.main/repl :caught pst)
user=> (/ 1 0)
ArithmeticException Divide by zero
clojure.lang.Numbers.divide (Numbers.java:188)
clojure.lang.Numbers.divide (Numbers.java:3901)
user/eval144 (NO_SOURCE_FILE:1)
user/eval144 (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:7177)
clojure.lang.Compiler.eval (Compiler.java:7132)
clojure.core/eval (core.clj:3214)
clojure.core/eval (core.clj:3210)
clojure.main/repl/read-eval-print--9086/fn--9089 (main.clj:437)
clojure.main/repl/read-eval-print--9086 (main.clj:437)
clojure.main/repl/fn--9095 (main.clj:458)
clojure.main/repl (main.clj:458)
(starting a repl inside a repl)ahh! that's the option I was missing
(cmd)user=> (clojure.main/repl :caught pr)
(cmd)user=> (throw (ex-info "foo" {:a 0}))
#error {
:cause "foo"
:data {:a 0}
:via
[{:type clojure.lang.ExceptionInfo
:message "foo"
:data {:a 0}
:at [user$eval9 invokeStatic "NO_SOURCE_FILE" 1]}]
:trace
[[user$eval9 invokeStatic "NO_SOURCE_FILE" 1]
[user$eval9 invoke "NO_SOURCE_FILE" 1]
[clojure.lang.Compiler eval "Compiler.java" 7177]
[clojure.lang.Compiler eval "Compiler.java" 7132]
[clojure.core$eval invokeStatic "core.clj" 3214]
pr is so much better than pst now
A built-in default that trimmed :trace
would be nice tho'...
@vachichng so if the right :caught
is set you can get better printing behavior, and you can start a new subrepl and supply any one-arg-function you like there
yeah, it worked on the terminal launched repl, but still not working under Intellij cursive nrepl
right - it only takes effect in the repl that clojure.main starts, it doesn't change any behavior of the parent
I wouldn't be surprised if there was an nrepl middleware out there somewhere that improves trace printing as well
I havn't used Cursive in a while, but I think it has a button to show the full exception
There's Throwable->map
if you want to turn exceptions into data and manipulate them.
that's what pr/ prn use under the hood for exceptions now right?