Fork me on GitHub
#clojure
<
2023-08-09
>
igrishaev10:08:35

When running nREPL in a deps-driven project, is it possible to specify a port with an env var? something like:

NREPL_PORT=9911 clj -M:local/nrepl:foo:bar
I've done that many times with lein, but got stuck with deps

p-himik10:08:32

What is :local/nrepl?

igrishaev10:08:24

:local/nrep is my global ~/.config/deps.edn profile:

:local/nrepl
  {:extra-deps
   {nrepl/nrepl {:mvn/version "0.9.0"}
    cider/cider-nrepl {:mvn/version "0.32.0-alpha1"}}
   :main-opts ["-m" "nrepl.cmdline"
               "-i"
               "--middleware" "[cider.nrepl/cider-middleware]"]}}

igrishaev10:08:10

I had a typo in the origin message, now it's fixed. The question is, how to pass a port with an env var?

p-himik10:08:50

Just in case - it's possible to do so via a CLI arg. But there doesn't seem to be a buit-in way to use an env var. However, it's just a few lines to replace nrepl.cmdline with your own namespace that wraps the original and extracts the port from the env.

2
practicalli-johnny11:08:09

clj -M:local/nrepl:foo:bar --port 7777 will start the REPL on the given port, so clj -M:local/nrepl:foo:bar --port $REPL_PORT` will pick up the value from the associated environment variable and pass it in to the main-opts Same can be done for -X using :port $REPL_PORT for clojure.exec

vemv11:08:21

You may have luck with a .nrepl.edn file as well https://nrepl.org/nrepl/usage/server.html

igrishaev11:08:54

Ah, right: --port ... !

practicalli-johnny11:08:09

Arguments on the command line are added (or replace) options defined in the alias. If always using the same port (or using it quite often), then the --port can be added to the alias and overridden on the command line when required.

:local/nrepl
  {:extra-deps
   {nrepl/nrepl {:mvn/version "0.9.0"}
    cider/cider-nrepl {:mvn/version "0.32.0-alpha1"}}
   :main-opts ["--main" "nrepl.cmdline"
               "--interactive"
               "--port" 7777
               "--middleware" "[cider.nrepl/cider-middleware]"]}}
Then call clj -M:local/nrepl:foo:bar --port $REPL_PORT if a port other than the default is required

igrishaev11:08:13

related question: I'm trying to specify --host but it looks like it makes no effect. the host is always localhost. What do I do wrong?

igrishaev11:08:19

I want nREPL be available for other machines, so I specify "--host" "0.0.0.0" but the console renders :port

p-himik11:08:21

Even though it prints localhost, have you tried checking what open ports you have? Or just accessing that nREPL server via your external host. Speculating here, but I suspect that some underlying code might simply be reverse-resolving 0.0.0.0 as localhost and printing that.

igrishaev11:08:28

hm no I don't see it

igrishaev12:08:32

again, it worked great with lein, but doesn't with deps

practicalli-johnny12:08:35

To share the nrepl port with other machines on the local network I assume the IP address of the machine running the repl should be used, e.g 192.168.0.10 What doe ipconfig or if config or look in /etc/hosts if on Linux/unix

p-himik12:08:14

0.0.0.0 should also be working for listening since it means "every available interface". If it doesn't work, there's probably a bug.

igrishaev12:08:15

no I've tried 169.254.117.51 but it didn't work, and I still see localhost:9911 in the console

igrishaev12:08:29

neither all-balls work

igrishaev12:08:30

alright, it must have been --bind

p-himik12:08:04

Just tried, made sure it's not firewall. Sever/client using 0.0.0.0 - worked (but due to a bug - the server is actually listening on 127.0.0.1). Server on 0.0.0.0 with client on a particular non-localhost interface - connection refused (a bug, the server is also listening on 127.0.0.1). Server/client on non-localhost - connection refused (also a bug). Yeah, after a brief look at the code, seems like --host is ignored and replaced with --bind at some point.

practicalli-johnny12:08:17

Specifying host in a .nrepl.edn file in root of project seems to work, reports the ip address anyway

{:bind         "192.168.0.212"
 :port         7234}
The console prints out it is using the specific host address
❯ clojure -M:repl/rebel
nREPL server started on port 7234 on host 192.168.0.212 - 
[Rebel readline] Type :repl/help for online help info
user=> 
Cider-connect also finds the specific IP address and can connect to the repl using that IP address..

practicalli-johnny12:08:28

Ah, so --bind is to set the IP address of the server. --host is to specify the IP address of another nrepl process to connect too (nrepl can also act as a client) Naming of these options are easily confused 🙂

practicalli-johnny12:08:52

❯ clojure -M:repl/rebel --bind "192.168.0.212"
nREPL server started on port 33237 on host 192.168.0.212 - 
[Rebel readline] Type :repl/help for online help info
user=> 

igrishaev12:08:34

yeah right. I've mixed host/bind params. Thank you everyone!

practicalli-johnny12:08:17

I've leaned some new things, thanks for asking the question

pyr13:08:02

(run! f coll) is (reduce #(f %2) nil coll) under the hood. Wouldn't it also make sense to also have (run! xf f coll) be (transduce xf (completing #(f %w)) nil coll) to avoid intermediate collection generation here as well or would that happen anyway?

oyakushev13:08:02

I didn't quite get what code produces the intermediate collection that you refer to.

pyr13:08:56

@U06PNK4HG today (run! xf f coll) doesn't exist, the only signature is (run! f coll). Assuming you want to filter the input, this means you have to (run! f (filter pred coll)) for instance. My (perhaps wrong?) understanding is that this then creates intermediary seqs

Alex Miller (Clojure team)13:08:04

well you don't have to use a seq op there

Alex Miller (Clojure team)13:08:09

the pieces all exist to combine run! with a transducer collection op, question is whether the shorthand is useful enough. not sure, feel free to put on https://ask.clojure.org

mpenet13:08:06

You can use an eduction as arg to run!

pyr13:08:30

Ah right, I forgot, of course

pyr13:08:51

(how could I! :-))

pyr13:08:53

Still feels like (run! xf f coll) could be shorthand for (run! f (eduction xf coll)) but maybe I'm just too lazy 🙂

👍 2
mpenet13:08:06

Sounds like me

mpenet13:08:29

The extra arg would be nice

oyakushev13:08:32

eduction, at first, seems to be something additional, not so important. Even in Rich's talk about transducers, he mentions it somewhere at the end, almost like an afterthought. But over time I started using it more and more, and now I wonder if it should have been more prominently pronounced in the whole transducer infrastructure.

mpenet13:08:08

Indeed, it’s very often misunderstood as well

pyr13:08:26

Well, there are eduction activists in the wild, I know a few

oyakushev13:08:07

And this is a good example of how giving eduction more stage time and mind share, and maybe a shorter snappier name, could have eliminated the need for such extra arities.

mpenet13:08:52

I like to think of it as sort of partial application of xforms to a value without consumption context

mpenet14:08:25

It’s a bit tricky to describe for newcomers to transducers, it’s already a quite thick subject

👍 2
oyakushev14:08:33

I wonder if turning it around and making eduction the centerpiece could have made the transducers more approachable. Probably not, but I like to imagine.

oyakushev14:08:22

Eduction as a stream of values that gets modified by the functions on top of it. I dunno. At least you get something reified as an intermediate step ("a stream of values") whereas when you are just composing transducers, it is just hot air until you give it both to and fro, and that makes transducers hard to think about.

Joshua Suskalo15:08:46

Is there a way to compose caches with core.cache, e.g. to get an lru cache with a timeout?

🆒 2
Joshua Suskalo15:08:15

Oh, I see I was just missing a page in the docs, they can be composed quite easily.

👀 2