clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2020-10-17T01:30:56.229500Z

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

2020-10-17T01:33:50.229800Z

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.

2020-10-17T01:34:18.230Z

That's why they are chunking most of the time, as that is an attempt at further optimizing them for that purpose

2020-10-17T01:35:43.230200Z

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.

2020-10-17T01:36:15.230400Z

And even non chunking lazy seq are not guaranteed lazy in all circumstances, some operations might still realize one or more elements

2020-10-17T01:37:34.230600Z

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

2020-10-17T01:39:00.231Z

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.

2020-10-17T01:40:55.231300Z

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

2020-10-17T02:21:50.231500Z

Interesting - Thanks for sharing.

2020-10-17T02:23:38.231700Z

In my case I will use delays with regular seqs to get rid of the smell :)

jmckitrick 2020-10-17T11:39:41.240200Z

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.

octahedrion 2020-10-17T11:42:48.242Z

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 ?

p-himik 2020-10-17T11:47:31.242200Z

Because it would be harder.

p-himik 2020-10-17T11:49:03.242400Z

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.

emccue 2020-10-17T12:14:05.242600Z

Also because gen-class only works with AOT compilation for some weird reason, and not at the REPL

emccue 2020-10-17T12:16:14.242800Z

which is obtuse enough that "just" writing java feels preferable

emccue 2020-10-17T12:20:12.243100Z

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

2020-10-17T14:28:27.244800Z

If you want your interface to preserve generic typing then use a Java interface.

octahedrion 2020-10-17T14:42:48.247700Z

@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

2020-10-17T14:43:50.250100Z

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

2020-10-17T14:46:10.252500Z

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

2020-10-17T14:46:43.253700Z

At least partly because the Java compiler is right there

octahedrion 2020-10-17T14:47:50.254100Z

but say someone else wrote a library providing those features, I think that would be a good thing

octahedrion 2020-10-17T14:48:04.254400Z

because I don't like writing Java

2020-10-17T14:48:40.255500Z

There might be such a library already, even. I haven’t used one, but there are a lot of libraries out there

2020-10-17T14:49:54.256500Z

For interfaces, the Java code is pretty short

octahedrion 2020-10-17T14:50:20.256700Z

do you mean this https://github.com/jgpc42/insn

2020-10-17T14:50:59.257700Z

That library might do it - I have not looked into its capabilities in any detail

Nico 2020-10-17T14:55:12.259Z

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)

seancorfield 2020-10-17T15:17:15.262300Z

@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=> 

seancorfield 2020-10-17T15:18:02.263Z

If you really don't want :tags or :tag in the results, you'll need to do a bit of cleanup.

seancorfield 2020-10-17T15:19:03.264100Z

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.

Nico 2020-10-17T15:19:35.264500Z

ah, thanks! I did not know group-by exists, that is a very useful function!

cpmcdaniel 2020-10-17T17:36:20.267500Z

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?

cpmcdaniel 2020-10-17T17:38:51.267700Z

Looks like there is: https://clojure.org/reference/repl_and_main#_launching_a_socket_server

2020-10-17T17:46:07.267800Z

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)

2020-10-17T17:48:36.268Z

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.

borkdude 2020-10-17T18:02:12.268200Z

> Many people prefer to avoid nrepl. People avoiding nREPL might be louder about it than those just using it (probably a far huger number)

seancorfield 2020-10-17T18:07:12.269100Z

@cpmcdaniel The Socket Server was added in Clojure 1.8. It's a bare REPL so you cannot connect an nREPL client to it.

seancorfield 2020-10-17T18:08:05.269200Z

Indeed, even as one of those people, I very much doubt that we are "many" 🙂

borkdude 2020-10-17T18:26:36.271400Z

There is also prepl - anyone using that?

2020-10-17T18:34:24.274900Z

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.

simon 2020-10-17T18:36:29.275500Z

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?

seancorfield 2020-10-17T18:36:36.275700Z

I think Conjure uses that (prepl).

seancorfield 2020-10-17T18:37:59.276800Z

@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).

borkdude 2020-10-17T18:39:36.277500Z

Given the distribution of editors in last year's survey, that could give some hint

2020-10-17T18:41:01.278400Z

Agreed that the vast majority of Emacs Cider users are humming along using nrepl, whether they know it or not.

simon 2020-10-17T18:42:10.278800Z

@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 🙈

seancorfield 2020-10-17T18:42:39.278900Z

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?).

2020-10-17T18:44:32.279800Z

The #cursive channel is a good place to ask, if no one responds in this channel

👍 1
seancorfield 2020-10-17T18:46:24.282Z

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).

👍 1
mauricio.szabo 2020-10-17T18:48:49.282700Z

I think Conjure is moving away from prepl

borkdude 2020-10-17T18:51:07.283100Z

Maybe a nice question for next year's survey? #clojure-survey

borkdude 2020-10-17T18:58:09.283600Z

@mauricio.szabo in favor of?

dharrigan 2020-10-17T18:58:16.283800Z

It has. It's now uses nrepl

mauricio.szabo 2020-10-17T19:24:42.285Z

@borkdude I believe nrepl, as @dharrigan said :)

2020-10-17T20:28:39.285100Z

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.