Fork me on GitHub
#clojure
<
2015-07-16
>
gtrak00:07:21

is there any way for code to detect that it's in the presence of an nrepl thread? I can probably hack thread-bound vars in tools.nrepl namespaces

malabarba00:07:06

an nrepl eval thread?

malabarba00:07:17

check for *msg*

malabarba00:07:52

tools.middleware.interruptible_eval/*msg*

malabarba00:07:00

I mean, tools.nrepl

malabarba00:07:28

if its value is a map you're in an eval thread

gtrak00:07:29

sweet, yea i see it

gtrak00:07:01

now I can special-case debug logging for my app when running in a repl simple_smile

gtrak00:07:57

theoretically I can grab the out-stream too when this gets multithreaded.

malabarba00:07:46

Yes, I think so

gtrak00:07:04

> (keys @(:session @(resolve 'clojure.tools.nrepl.middleware.interruptible-eval/*msg*)))
(#'clojure.core/*assert* #'clojure.core/*print-level* #'clojure.core/*data-readers* #'clojure.core/*e #'clojure.core/*warn-on-reflection* #'clojure.core/*print-meta* #'clojure.core/*1 #'clojure.core/*out* #'clojure.core/*in* #'clojure.test/*test-out* #'clojure.core/*command-line-args* #'clojure.core/*print-length* #'clojure.core/*err* #'clojure.core/*3 #'clojure.core/*ns* #'clojure.core/*default-data-reader-fn* #'clojure.core/*compile-path* #'clojure.core/*2 #'clojure.core/*unchecked-math* #'clojure.core/*math-context* #'clojure.tools.nrepl.middleware.session/*out-limit*)

gtrak00:07:11

(.write (get @(:session @(resolve 'clojure.tools.nrepl.middleware.interruptible-eval/*msg*)) #'clojure.core/*out*) "WAT") totally works

malabarba00:07:06

that's much better than what I usually do

malabarba00:07:20

which is to send a reply to *msg*

gtrak00:07:34

I've been using (alter-var-root #'out (constantly out)) to work around threading issues

gtrak00:07:37

for years

gtrak00:07:52

so this is basically the same hack but more usable

gtrak00:07:55

in other contexts

malabarba00:07:11

I don't even know what that does :)

gtrak00:07:18

only works at the repl

gtrak00:07:54

at threads that are not repl threads, or threads not created by clojure, out goes to stdout.

gtrak00:07:17

so, this will change the root binding to the current value of *out*, which is exactly (get @(:session @(resolve 'clojure.tools.nrepl.middleware.interruptible-eval/*msg*)) #'clojure.core/*out*)

gtrak00:07:35

people always complain about this when using cider.. .it's really no big deal

malabarba00:07:59

bozhidar: Wouldn't this help us with the lack of middleware printing when developing cider-nrepl?

gtrak00:07:31

hijacking the root binding might not be desirable in general

malabarba00:07:06

We brought this up earlier today (or yesterday) on gitter

malabarba00:07:31

that when we're writing the cider middleware we don't have access to a println

malabarba00:07:29

But certainly not something to enable on the user's sessions

gtrak00:07:43

tying the outputs of sessions together might be nice

gtrak00:07:48

i don't see when i wouldn't want that

malabarba00:07:37

Me neither, but I'm pretty new at this

gtrak00:07:57

i think we talked about different tradeoffs of managing multiple sessions early on in cider-nrepl

gtrak00:07:12

with some ideas of tunneling ids and such.

gtrak00:07:18

not sure where that ended up

malabarba00:07:35

probably nowhere :)

gtrak00:07:35

@malabarba: https://github.com/clojure-emacs/cider/issues/460 @bozhidar said "I'm OK with dispatching the (autocomplete) op in the main session for now."

malabarba00:07:35

Ah, the tooling session is basically gone now

malabarba00:07:45

It's still there, but everything uses the main session

bozhidar05:07:16

yeah, I remember this discussion

bozhidar06:07:28

it seems that the biggest gain of using the tooling session was actually that “tooling evals” (evaling the huge inlined Clojure strings), didn’t clutter the special vars set the by actual evaluations

bozhidar06:07:22

although the problem with blocking evaluation in the main session is real, nobody seems to have complained about it

bozhidar06:07:59

btw, regarding the logging - I was actually thinking of implementing a special logging scheme in the middleware

bozhidar06:07:12

a logger backed by an agent

bozhidar06:07:40

which would push the logs to cider and optionally to a file as well

bozhidar06:07:10

we won’t be doing the logging using println, but this will likely be for the best

bozhidar06:07:54

at any rate - the idea you discussed for dealing with standard output sounds reasonable to me

bozhidar06:07:03

@gtrak: btw, we should probably add something in the troubleshooting and pitfalls sections of our README about the standard output

bozhidar06:07:21

this would save many (readme reading folks) a lot of time

abtv06:07:00

When I run lein repl :headless :port 4000, I'll see 2 java instances in memory. Can anyone explain me why clojure repl needs 2 jvm instances?

Pablo Fernandez09:07:46

I have the name a function in a string and I want to call it, I could use ns-resolve but it requires the name of the namespace. Is there a way to do it with the current namespace, and by that I mean the one in the file I’m located (lexically?)

ordnungswidrig09:07:07

*ns* is bound to the current namespace. May I ask what you want to achieve?

andrewmcveigh09:07:00

@pupeno: clojure.core/resolve will resolve a symbol in the current namespace, with aliases/etc., you can call (symbol “name”) to construct a symbol from a string.

Pablo Fernandez09:07:57

@ordnungswidrig: I’m trying to call a function having the name on a string, I’m getting the name from a database connection uri.

Pablo Fernandez09:07:09

@andrewmcveigh: (ns-resolve ‘korma.db (symbol name)) works but (resolve (symbol protocol)) doesn’t. I believe the reason is that calling resolve is trying to resolve the symbol in the namespace that’s calling the function… that is, ns and it’s not being called from ‘korma.db.

andrewmcveigh09:07:01

The symbol would have to actually resolve in the current namespace for that to work.

Pablo Fernandez09:07:56

Yes, I don’t want to resolve it in the current namespace, I want to write this: (ns-resolve 'korma.db (symbol protocol)) without having to hard-code the name of the namespace that this file represents. Is that possible?

ordnungswidrig09:07:19

I question that the approach makes sense.

andrewmcveigh09:07:48

I’m not really sure what you’re asking to be honest, but unless clojure can resolve the symbol in the current namespace, or you give it a namespace you can’t resolve it.

andrewmcveigh09:07:08

btw, I agree with @ordnungswidrig , this sounds like a bad idea

Pablo Fernandez09:07:11

@ordnungswidrig: do you have any suggestion?

ordnungswidrig09:07:30

In the particular case I would dispatch based on the connection uri and map that fixed set of values to the functions in kormab.db

Pablo Fernandez09:07:26

@ordnungswidrig: do you mean with a case expression?

ordnungswidrig09:07:35

Or simply use defdb with the right values and lookup the driver classname from the database name.

Pablo Fernandez09:07:25

@ordnungswidrig: I am contributing to Korma so that you can more easily connect with a URI, not just using Korma.

ordnungswidrig09:07:30

yes, however the opts argument is very generic. Why not simply call (defdb my-deb opts)?

Pablo Fernandez09:07:46

@ordnungswidrig: because Korma doesn’t accept connection-uri, so I’m building that: https://github.com/korma/Korma/pull/317

Pablo Fernandez09:07:08

2 feels way more repetitive than 1 to me.

ordnungswidrig09:07:39

At least whitelist the symbols, then

Pablo Fernandez09:07:10

@ordnungswidrig: yes, of course, that’s what that if with a set is doing.

ordnungswidrig09:07:08

yes. The second option has the advantage that you could mangle the opts if necessary for individual methods.

ordnungswidrig09:07:57

and runtime resolution is always a little fragile simple_smile Maybe could use a macro generate the second option.

joelkuiper13:07:55

I made a stupid HTTP queue/load balancer https://github.com/joelkuiper/aplomb, probably not something reusable but could be interesting, maybe

Lambda/Sierra14:07:58

@voxdolo: Sounds like what you have is lazy sequences embedded in some larger data structure. pr-str will usually force evaluation of everything, or you could write a recursive function that walks all the data.

voxdolo14:07:52

@stuartsierra: yep, that's the situation. I've wrapped the lazy portions of the datastructure in a doall for now, but would love to be doing something more elegant.

voxdolo14:07:28

fwiw, I created the data structure, so I have full control over it. I just haven't found a way of forcing the evaluation that doesn't feel bolted on.

Lambda/Sierra14:07:32

@voxdolo: there is no completely general way to do it. So many built-in clojure functions return lazy sequences by default.

Lambda/Sierra14:07:01

If it's your code, you can do things like replace map with mapv and sprinkle vec or doall elsewhere.

voxdolo14:07:02

@stuartsierra: okay, thanks for the pointers simple_smile

voxdolo15:07:52

@stuartsierra: replacing my calls to map with mapv throughout the data structure resolved the issue. Also has the pleasant side-effect of making the whole data structure associative. Thanks again!

Lambda/Sierra17:07:07

You're welcome!

logaan18:07:51

can anyone suggest a good resource for getting emacs set up for clojure dev from scratch?

borkdude18:07:40

@logaan my colleague started with this I believe: http://www.braveclojure.com/basic-emacs/

borkdude18:07:19

@logaan: I use emacs prelude myself

bozhidar18:07:56

using Prelude is a good idea, because the same person wrote CIDER and Prelude

bozhidar18:07:15

there’s also an example config for Clojure hacking here

borkdude18:07:31

❤️ prelude

voxdolo18:07:32

@logaan: there's also http://overtone.github.io/emacs-live/ and if you're from vim-land (as I am) then you'd do well to look into https://github.com/syl20bnr/spacemacs

bozhidar18:07:51

it might be a bit too fancy for some people, though

bozhidar18:07:06

as it sets up an ton of packages on the side

borkdude18:07:11

I used emacs-live, but it was difficult to upgrade it to more recent ciders I found

bozhidar18:07:27

generally clojure-mode + CIDER is all you need to hit the ground running

logaan18:07:33

@borkdude: thanks. I noticed braveclojure but was hoping for something that wouldn’t come with a big config repo. I’d prefer to know what’s been changed from raw emacs.

bozhidar18:07:46

and perhaps paredit-mode is you’re extra adventurous

bozhidar18:07:13

you can always do just M-x package-install cider

malabarba18:07:21

logaan: then just boot up Emacs, configure Melpa, run list-packages and install cider

bozhidar18:07:21

this will install everything you need

bozhidar18:07:33

perfect sync simple_smile

malabarba18:07:40

This will give you the cleanest Emacs experience

bozhidar18:07:16

P.S. We have a dedicated #C0617A8PQ channel, btw

logaan18:07:22

@bozhidar, @malabarba: thanks for the tips. I’ll try clojure-mode + CIDER

bozhidar18:07:45

so, if you’re ever in need of assistance, feel free to drop by

logaan18:07:01

emacs comes with a package manager built in now? When I was last using it in about 2009 there were several competing package managers.

bozhidar18:07:11

yep, it does

bozhidar18:07:21

btw, you can’t really do what we said

bozhidar18:07:29

you need to configure the package repositories first

malabarba18:07:39

Since version 24.1, though I don't know what year that is

borkdude18:07:58

@logaan: I found checking in my elpa directory in git useful, for when I upgrade libraries and they don't work 😉

bozhidar18:07:12

just go through CIDER’s readme

bozhidar18:07:18

everything you need for the setup is there

malabarba18:07:36

(add-to-list 'package-archives '("melpa-stable" . "") t)

bozhidar18:07:08

btw, there’s also https://github.com/clojure-emacs/inf-clojure if you need just a basic Clojure REPL, with no bells and whistles

logaan18:07:14

thanks. if I hit any issues is #C0617A8PQ the best place to ask for help? Rather than polluting #C03S1KBA2.

bozhidar18:07:34

we also have a gitter channel

bozhidar18:07:38

whatever you prefer

logaan18:07:57

@bozhidar: I’d like some clojure related bells and wistles. They’re the main thing attracting me away from a pretty mature vim setup.

bozhidar18:07:31

Well, CIDER’s got you covered there

bozhidar18:07:38

we have plenty of those simple_smile

logaan18:07:42

@voxdolo: I’ve had bad experiences with viper, evil and vim emulation in sublime and IDEA. Is spacemacs really that much better than previous attempts?

voxdolo18:07:34

spacemacs is evil-mode

voxdolo18:07:52

I used vim for over a decade before recently coming to emacs

voxdolo18:07:12

and I generally hit some annoyance within the first 10 minutes of using some other emulation of it

voxdolo18:07:40

but evil-mode is super solid and I've yet to do even some obscure chording or phrasing that it hasn't been able to do

voxdolo18:07:12

spacemacs is really just an opinionated set of packages that caters to evil mode and leverages the spacebar for using helm everywhere

voxdolo18:07:20

and making things more discoverable

logaan18:07:34

ok. I’ll give it a look once I’ve got my basics down. thanks for the tip.

robert-stuttaford18:07:09

logaan, it’s so worth it. soldier through the initial tough bits simple_smile

logaan18:07:32

@robert-stuttaford: emacs is worth it or spacemacs is?

robert-stuttaford18:07:54

i never acquired vim fingers, so never needed the latter

logaan18:07:05

I’ve used it before for about 6 months. unfortunately I developed RSI and was left unable to type/work for a couple of weeks. switching back to vim seemed to help.

robert-stuttaford18:07:19

goodness. my condolences

robert-stuttaford18:07:30

have you seen the talk by the guy who uses emacs with his voice?

logaan18:07:22

I believe so. I can’t imagine that’d go down well in an open plan office…. though maybe it’d help people come to the conclusion that open plan offices aren’t so great after all

logaan18:07:55

having to deal with the jankyness of paredit.vim is really what’s got me motivated to try emacs again.

robert-stuttaford18:07:03

emacs’ paredit is solid, and there’s paxedit too, which has some nice additions. there’s smartparens for emacs as well

arrdem18:07:57

My experience with smartparens is a little more positive

arrdem18:07:27

As long as you don't use it in strict mode it's surprisingly easy to get a useful amount of structural nav into your workflow

shaun-mahood19:07:17

@logaan: I found the brave clojure start worked pretty well, I used it to get up and running when brand new to both emacs and clojure.

logaan19:07:11

@shaun-mahood: It looks very well written, but I’m going to try and avoid setups that require adopting a heap of config up front. I’m having decent luck so far just following the cider instructions.

voxdolo19:07:06

@logaan: paredit.vim is bad 😕 https://github.com/guns/vim-sexp with https://github.com/tpope/vim-sexp-mappings-for-regular-people is a much better experience for vimmers, imo.

voxdolo19:07:39

I only left vim for the better cider integration in emacs, personally. Could never quite get a satisfactory clojure setup going there.

logaan19:07:51

@voxdolo: I hadn’t heard of vim-sexp, thanks for the tip.

voxdolo19:07:05

:thumbsup:

logaan19:07:53

thanks to everyone for their help. I’ve managed to get a basic setup going from scratch simple_smile

akiva19:07:33

Spacemacs has converted this vim user to Emacs as well. It’s fantastic and getting better with each release.

cddr21:07:09

Say you want to bundle some clojure code into a non-clojure project that uses maven to package everything up. What options are available for doing that?

Alex Miller (Clojure team)21:07:20

if it's all integrated in the same project, you can use clojure-maven-plugin

Alex Miller (Clojure team)21:07:28

or maven-clojure-plugin

Alex Miller (Clojure team)21:07:33

or whatever it's called :)

Alex Miller (Clojure team)21:07:58

if it's separate, just create an artifact from the clojure parts, then depend on it from the java project

cddr21:07:05

Ah cool. Thanks alex

emil0r21:07:57

is it possible to capture the namespace of where a macro is used which is itself used inside another macro? right now i get back clojure.core as the namespace which is not what i was hoping for

gtrak22:07:25

try metadata on the form?

gtrak22:07:52

hrmm i can't seem to figure it out

gtrak22:07:16

actually, yea

gtrak22:07:25

(defmacro dbg [body]
  (let [{:keys [line column]} (meta &form)
        ns (str *ns*)]
    `(let [x# ~body]
       (println (with-out-str
                  (print (str ~ns ":" ~line "," ~column) (quote ~body) "= ")
                  (pp/pprint x#)))
       (flush)
       x#)))

emil0r22:07:53

right... so it needs to be in the outer part

gtrak22:07:03

because it happens at eval time

gtrak22:07:12

during macro expansion, not runtime

emil0r22:07:16

i had hoped to do it only once 😛

abtv22:07:36

What are good examples of clojure codebases for learning? For a person, who has about a 6 months of clojure experience and wants to do more and also would like to train other people too. clojure.core is an interesting example and I want more good examples simple_smile

emil0r22:07:37

hmmm nah... still got the same problem. appears to me that the outer macro executes the inner macro inside clojure.core namespace. probably over a map

emil0r22:07:25

or rather is executed at a later stage during a http request

emil0r22:07:29

spoke too soon. got it to work

logaan23:07:47

@abtv: I’m not sure how much you’d learn but you should be able to handle https://github.com/logaan/vlad core.cljc is a couple hundred lines