This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-15
Channels
- # adventofcode (6)
- # beginners (63)
- # boot (39)
- # cider (25)
- # clara (9)
- # cljs-dev (27)
- # clojure (100)
- # clojure-dev (39)
- # clojure-dusseldorf (7)
- # clojure-italy (32)
- # clojure-russia (23)
- # clojure-spec (28)
- # clojure-uk (51)
- # clojurescript (197)
- # core-async (44)
- # cursive (3)
- # datomic (14)
- # emacs (4)
- # fulcro (27)
- # graphql (23)
- # hoplon (4)
- # jobs (9)
- # juxt (1)
- # leiningen (3)
- # nyc (1)
- # off-topic (6)
- # om (7)
- # onyx (6)
- # parinfer (11)
- # re-frame (23)
- # reagent (15)
- # ring-swagger (1)
- # rum (15)
- # shadow-cljs (37)
- # sql (24)
- # uncomplicate (4)
- # unrepl (17)
I'm pretty sure it is not a documented feature, but all versions of Clojure I am aware of read %1.1 %1.2 etc without any errors, and truncate the floating point values to the next lowest integer. That is, #(f %1.1 %1.2 %1.3) is syntactically legal and completely equivalent in behavior to #(f %1 %1 %1)
rely on that at your peril
The closest thing to what you want that I can think of is to use destructuring, e.g.
(map (fn [[a b]] (f a b)) ...)
fasicnating, problem is, to use destructuring, I need to use (fn
of (let
.. which makes it verbose
It is less verbose than using first, second, third, etc.
Clojure does work the way it was intended, just not by anyone's intentions except Rich Hickey 🙂
More nice stuff about destructuring approach -- you can nest it arbitrarily deeply, if you want. https://clojure.org/guides/destructuring is a nice set of examples and explanatory docs for those who haven't used the feature before.
Have you used expressions like (-> 1 (nth 2) :foo :bar) before?
(get-in % [1 :foo :bar])
edit: (-> %1 (nth 2) :foo :bar)
Anyone is free to create modified versions of Clojure that work however they want, but you cannot legally distribute them as something called Clojure (at least not under US law), and you are not likely to get a lot of users of your modified version.
it seems like it'd be much easier to just dfeine a new macro, i.e. (defmacro ff ... ) and changing #(.... ) to (ff .... ) where the ff looks at symbols starting with % and rewrites them
I'm not suggesting it. You said you are looking for something. I am telling you where you can find it (or in this case, create it, since I don't think it currently exists)
The syntax you give as an example: %1.2.:foo.:bar is unreadable by the existing Clojure reader, so not possible to do exactly that via a macro definition.
Things starting with % in Clojure are not symbols. I'm not sure if they have been given a name, but they are restricted to contain things that can be read as a number after the %
I thought % was just another symbol constituant
user=> (let [%a 1] (+ %a %a %a))
3
I am pretty sure reading of % is special within a #( ) expression
Yeah, looks like it can be used as part of a normal symbol outside of #( )
oh, yeah, there we go
+user=> (#(let [%a %] (+ %a %a %a)) 2)
IllegalStateException arg literal must be %, %& or %integer clojure.lang.LispReader$ArgReader.invoke (LispReader.java:928)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: % in this context, compiling:(NO_SOURCE_PATH:0:0)
RuntimeException Unmatched delimiter: ] clojure.lang.Util.runtimeException (Util.java:221)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: %a in this context, compiling:(NO_SOURCE_PATH:4:15)
RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221)
2
RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221)
@qqq If you want to stick with straight Clojure, then you have to have at least a single-character name for your macro, and enclose invocation of that macro inside parens, so that is 3 chars plus a space. Only 1 less than (fn )
Yes, fn requires the arg vector, too, which #( ... ) does not.
Hmm. I guess maybe possible to write a macro invoked like (f ...) instead of #( ... ) that did something like you want. It would not be a straightforward macro to write, depending on how general you wanted it to be, e.g. whether one could use macro invocations inside of (f ...)
@andy.fingerhut: when I want to destructure an entire structure, I like destructuring notation; when I am just 'selecting' a portion of the structure, I like get-in .... alot more, and this saves quite a bit over get-in, especially considering 80-char lines
I understand. If what you are asking for already exists, I haven't heard of it, but I don't claim anywhere near 100% knowledge of Clojure libraries. I am 99.9% sure it isn't in the core Clojure library.
Shouldn't concat
be lazier in this case? It prints the "X"
even though it's never needed:
(take 3 (apply concat [1] [2] [3] (lazy-seq (prn "X") [[4]])))
@schmee Yeah I'm aware, but not in this case there is no chunking. I just noticed the use of next
instead of rest
for concat so I came up with arguments that show the potential problem (since next is less lazy than rest).
Hi, I have an xml that needs parsing and I'm down a rabbit hole trying to work out the easiest way to go about go this. I need to extract the values log-start-date
player-name
player-uuid
log-end-date
and get back a list of the entries.
everything I've tried to date either a, doesn't give me what I'd like b, way too complicated and doesn't feel very clojure like.
I worked it work... too many late nights 🙂
Hmmm may be not...
I just need a list (of some sort) of the entires back now... currently I appear to be getting a concat'd string back.
hey, anyone managed to use lein-protobuf with proto3? trying not to use a custom protoc executable. or maybe there's a better option for proto3? thanks
Hi. I'm building one test case and I need to verify if one function that runs in background is invoked. Currently I'm using something like:
(defn do-something-1 [a b c]
;; dosemthing)
(defn do-something-2 [a]
(let [b 1 c 2]
(send-off (agent a) b c)))
And my test case is:
(deftest test-do-something-2
(let [invoked? (promise)]
(with-redefs [do-something-1 (fn [a b c]
(is (= a 3))
(is (= b 1))
(is (= c 2))
(deliver invoked? true))]
(do-something-2 3)
(is (true? (deref invoked? 5 false)))))
It works as long as do-something-1
function is invoked in less 5 millisecond.
Thanks for some suggestion.
PDT. Sorry for my english 🙂@rauh @schmee it’s not chunking doing this - it’s because apply needs to access the last arg, so the implicit do of the lazy-seq body is realized
=> (take 3 (apply concat '([1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30] [31] [32]) (lazy-seq (prn 'x) [[4]])))
x
([1] [2] [3])
or… it might not be that simple, but I don’t see a reason to think concat is doing it
@noisesmith Oh I see, good catch.
@rauh - this is the same behavior I think
=> (do (apply map inc (lazy-seq [[(do (prn 'x) 1) 2 3]])) nil)
x
nil
it's the apply of concat that is doing it. See https://dev.clojure.org/jira/browse/CLJ-1218
(IIRC, because concat has an arity-4 defined, applying it will realize at least 4 elements of its input)
@ghadi I believe even in the original example concat
has nothing to do with this in this case — the last sequence gets forced before it reaches concat
user=> (def x (list* 1 2 3 (lazy-seq (prn "foo") [1])))
#'user/x
user=> (def x (list* 1 2 3 4 (lazy-seq (prn "foo") [1])))
"foo"
#'user/x
user=> (.applyTo (fn [& _] 1) (list* [1] [2] [3] (lazy-seq (prn "foo") [[1]])))
1
user=> (.applyTo (fn [& _] 1) (list* [1] [2] [3] [4] (lazy-seq (prn "foo") [[1]])))
"foo"
1
user=> (.applyTo concat (list* [1] [2] [3] (lazy-seq (prn "foo") [[1]])))
"foo"
(1 2 3 1)
I have the following bootstrap for my webapp:
(defn -main
[& args]
(try
(let [c (create-config-spec env)]
(component/start (system/new-system c)))
(catch Exception e
(println e))))
When running the app via lein
or uberjar
, the exception is printed with the classpath,
though in the repl it doesn't.
How can I configure it to exclude the classpath as it just redundant and too verbose?regarding the lack of laziness and concat vs. apply as a culprit - backing up for a second to the big picture, I’d say the lesson here is to never write code that would break if an extra 32 items of your lazy seq were unexpectedly realized early; if you are doing side effects over a lazy input use a separate imperative step after all the lazy operations (eg. run!
or doseq
) - if the take call were inside run! or doseq the extra realized elements would not be a problem
is there a way to cancel execution in the new default clj repl ?
also, why is that with lein repl and clj I have to use rlwrap to get basic things like history with arrow keys, whereas that comes for free with python's repl ?
- i mean, i don't care but for beginners it's an extra step you have to tell them
no ctrl+c quits the repl
in the clj repl
@octo221 regarding the history stuff, that should be handled by jline, which both lein repl and clj support, though they probably won’t use your custom local readline config it’s pretty comprehensive feature wise, including control-r
backward history completion
I would consider the clj
REPL to be a very bare bones experience, just good enough to get up and running. If rlwrap
isn't available, use clojure
instead (I believe that's the only difference between those scripts?). If you want a "better REPL", use boot repl
or lein repl
. clj
is not intended to be a replacement for those.
Yeah, it's kinda subjective...
Why would one ever use repl in the terminal instead of editor sending last-sexp or sending entire buffer to repl ?
How do I set field of an abstract class which I am extending using gen-class
in the init
method ?
ok i updated to the latest clj and that does have history - so that's nice, but still no ctrl+c to stop execution
@qqq - well, I agree, but when you're demonstrating something quickly to someone you want to start a repl quickly
- clj starts fast and has no dependencies apart from needing brew installed first
(and to install brew all you have to do is paste some dodgy ruby code from your browser into your terminal)
I don't think there's anything conceptually wrong with having a "simple" way to get up and running and then recommending Boot or Leiningen as the next step to graduate to -- after all, you'll need one of those tools to build/deploy any project.
No one is going to be able to manage "forever" using just clj
...
when i was starting if i had to manage my own classpath and figure out how to load a file and remember that dashes become underscores on the file system i'd probably not be doing clojure
To me, going from: 1. editing entire file in editor 2. switching to REPL terminal and typing in (load-file "...") to relolad to 1. editing in editor, hitting C-x C-e to send last sexp was transformational and I think newcomers should be shown this workflow asap
I tutored for clojurebridge a while ago, and one of the biggest problems was that we wasted too much time with weird tooling that prioritized capabilities over stability or usability, so in addition to the natural beginners problems for people new to both programming and clojure, we also dealt with problems in the tools themselves
I would rather have let the students write code in microsoft word (or whatever program they want) and just use a simple predictable tool with copy/paste
to me something like clj is perfect if your goal is to see what this clojure thing is right now with as little hassle or nonsense as possible
i think i would take the opposite side of that. i can't see anyone sticking with clojure on their own after an intro if they can't navigate and load code
@qqq of course I would recommend notepad (or even sublime) - I’m just saying spending 30 minutes because nobody in the room understands why a tool is misbehaving is a terrible use of class time
there’s 30, take your pick, they all mostly almost work
Hi guys, I am having issues using the clojure.java.jdbc library to connect to a database. I have a gradle java project with some clojure code up and running. I have the library in my build.gradle and its pulling the dependency, but when I put the library in the require statement in my clojure namespace like this: (:require [clojure.java.jdbc :as jdbc])
I get this error: Caused by: java.lang.RuntimeException: Unable to resolve symbol: volatile! in this context
Just FYI folks, this got answered in #beginners
@dpsutton all you need for an intro class is “this is what the code looks like, this is how to call it, here’s how to copy and paste” - if they run into trickier things that is better served by the clojure knowledge of the instructors, rather than editor specific domain knowledge (of the 8 instructors in our room, none used the editor provided with the lesson as a primary editor, and most had never used it for a substantial task - and honestly you’d have that problem no matter which editor you pick)
i was gonna help with an intro class down in new orleans but i had a wedding that weekend. I'd like to help out to see what their experiences are
@noisesmith: the diff between dr razcket vs "the 30 clojure variants" is taht dr racket comes prepackaged with racket
anyway that got kind of tangential. even if I am trying a new language, I’d vastly prefer something where I can hand it valid code and get my result, rather than having to spend a bunch of time learning weird UI that has nothing to do with the language itself
Just FYI folks, this got answered in #beginners