Its definitely a concern to consider, especially in lazy context, since it might surprise the consumer that reading the next element blocks for X amount of time. But it doesn't fall in the classical definition of a side effect
The thing to know is that Clojure's lazy seq are not meant as a way to implement lazy behavior, but as an internal optimization for chaining operations.
That's why they are chunking most of the time, as that is an attempt at further optimizing them for that purpose
In theory, you can construct non chunking lazy seq, but even those, you're probably relying on implementation details of various functions. Its possible that anything taking one would return a chunked version of it.
And even non chunking lazy seq are not guaranteed lazy in all circumstances, some operations might still realize one or more elements
So when using them, you need to ask yourself: Am I okay with anything I do with it possibly realizing 1 or more elements up to probably about two full chunks, so about 64 elements
Now, in general, if realizing an element causes a side effect, most likely you won't be okay with it. Which is why in general people say avoid side effects with lazy-seq. The other thing is generally when the side effect happens matter a lot with dealing with side effect, and with lazyness you lose control on that, so that can be a source of bugs.
But, in your case, it might be if say realizing an element takes 1 minute of pure computation, you might also not be okay with not being able to reliably predict if getting the next element will take 1 minute or 32
Interesting - Thanks for sharing.
In my case I will use delays with regular seqs to get rid of the smell :)
I’m asking an emacs question here out of desperation. I’ve used paredit-slurp
for years, and it always added an extra space between the 2 items. Not anymore. Now, after slurping, I have to add the space between the items on either side of the point. Any ideas how that can be change? This is a feature obviously used all the time in Clojure mode, and it has become a huge annoyance.
if Clojure has gen-interface
& gen-class
and Java source files are merely an intermediate step to bytecode, which Clojure can generate anyway, why do some Clojure projects include Java source files ? Why not generate that bytecode from Clojure ?
Because it would be harder.
Not that much harder if you just read a Java source file and compile it from Clojure. But I guess that's not what you meant.
Also because gen-class only works with AOT compilation for some weird reason, and not at the REPL
which is obtuse enough that "just" writing java feels preferable
since otherwise you need to keep track of the load order of your namespaces - its alot less mentally taxing to say "compile java" all in one step
If you want your interface to preserve generic typing then use a Java interface.
@markbastian yes the only reasons I could think of were generics and declaring exceptions thrown, both of which could be added to Clojure's ASM bytecode-generation functions
By design Clojure’s gen-class and gen-interface do not have the ability create classes/interfaces with all of the options that the Java compiler can. Java is Clojure’s in-line assembler
As in, I believe when this question has arisen before, the Clojure core developers have expressed 0 interest in extending the Clojure compiler to include all possible options there
At least partly because the Java compiler is right there
but say someone else wrote a library providing those features, I think that would be a good thing
because I don't like writing Java
There might be such a library already, even. I haven’t used one, but there are a lot of libraries out there
For interfaces, the Java code is pretty short
do you mean this https://github.com/jgpc42/insn
That library might do it - I have not looked into its capabilities in any detail
hi, I have a data structure like this:
[{:title "thing" :content "test" :tags [:tag1 :tag2]}, {:title "thing 2" :content "foo" :tags [:tag1]
(this isn't the real data, but it is the real structure) and I'd like one like this {:tag1 [{:title "thing" :content "test"},{:title "thing 2" :content "foo"}] :tag2 [{:title "thing" :content "test"}]}
. how would I do this in clojure? (context: I have a list of pages for a website and I want a list for each tag of which pages have that tag)
@nihilazo Depending on how fussed you are about extra tags in the rearranged data:
user=> (def pages [{:title "thing" :content "test" :tags [:tag1 :tag2]}, {:title "thing 2" :content "foo" :tags [:tag1]}])
#'user/pages
user=> (group-by :tag (for [page pages tag (:tags page)] (assoc page :tag tag)))
{:tag1 [{:title "thing", :content "test", :tags [:tag1 :tag2], :tag :tag1} {:title "thing 2", :content "foo", :tags [:tag1], :tag :tag1}], :tag2 [{:title "thing", :content "test", :tags [:tag1 :tag2], :tag :tag2}]}
user=>
If you really don't want :tags
or :tag
in the results, you'll need to do a bit of cleanup.
Using (-> page (assoc :tag tag) (dissoc :tags))
instead of (assoc page :tag tag)
gets you part of the way. Removing the :tag
from each page after you've grouped them is a bit more work.
ah, thanks! I did not know group-by exists, that is a very useful function!
Is nrepl still the way to go if I want to embed a socket REPL in my application, or does Clojure 1.10 have this ability built-in now?
Looks like there is: https://clojure.org/reference/repl_and_main#_launching_a_socket_server
In most usage I have seen "socket REPL" is a distinct thing from "nrepl". socket REPL functionality is built into Clojure itself, as you have found a link for. Such a socket REPL does not use the nrepl 'wire format' for messages. (Perhaps it might be possible to make it do so -- I am not sure, but if so, the code for doing so is not built into Clojure core itself, which contains no nrepl-specific code)
Many people prefer to avoid nrepl. nrepl is used very often for connecting a REPL from Emacs to a running Clojure program, and I am sure there are other editors besides Emacs for which people have implemented the nrepl protocol between that editor and a running Clojure program. Emacs and most (all?) editors also support socket REPL connections.
> Many people prefer to avoid nrepl. People avoiding nREPL might be louder about it than those just using it (probably a far huger number)
@cpmcdaniel The Socket Server was added in Clojure 1.8. It's a bare REPL so you cannot connect an nREPL client to it.
Indeed, even as one of those people, I very much doubt that we are "many" 🙂
There is also prepl - anyone using that?
Sorry, not trying to give the wrong impression here. I do not know of any survey results on fraction of Clojure devs who use/avoid nrepl.
I've got a file that requires all other files and calls the function run-all-tests
. Currently, in Calva, I can execute that file by pressing CTRL
+`ENTER` and in Intellij/Cursive I usually open the file and hit SHIFT
+`CMD`+`L` to load the file in the REPL to execute the tests. What bothers me is that in either way I leave the current file and it involves multiple steps. Do you know a better way of doing this or how to set a shortcut in either Calva or Intellij/Cursive that executes all tests?
I think Conjure uses that (prepl).
@simon.zachau No idea how to do it in Calva or Cursive, but I'm pretty sure CIDER supports that in Emacs and I know Chlorine supports it in Atom (since I use that).
Given the distribution of editors in last year's survey, that could give some hint
Agreed that the vast majority of Emacs Cider users are humming along using nrepl, whether they know it or not.
@seancorfield thanks! I think there must be a way in Intellij/Cursive because I used it a few years ago, but I don't remember it 🙈
At least some of the 43% Emacs crowd use inferior mode I guess, and the 5% Atom users are nearly all Socket REPL users (although Chlorine does support nREPL now and maybe a few of them are still struggling along with ProtoREPL?).
The #cursive channel is a good place to ask, if no one responds in this channel
If you can bind hot keys to arbitrary code execution, you can do it -- that's how I customize stuff in Atom (so I have a hot key that runs tests in the test ns associated with the src file that I'm currently in, for example: so when I'm editing foo.bar
, I can hit ctl-; X
and it requires foo.bar-test
or foo.bar-expectations
and then runs the tests in whichever require was successful).
I think Conjure is moving away from prepl
Maybe a nice question for next year's survey? #clojure-survey
@mauricio.szabo in favor of?
It has. It's now uses nrepl
@borkdude I believe nrepl, as @dharrigan said :)
Eh, I suspect whether someone uses nrepl is often and "under the hood" detail for them, and probably not of much interest to any but a very few tool developers.