Fork me on GitHub
#clojure
<
2017-10-18
>
qqq00:10:04

@noisesmith , @bronsa: thanks for clarifying this, I misunderstood my compiler error

qqq00:10:42

so I'm calling scala from clojure, and I have a functino clj-seq->scala-seq ... and this scala function expects a scala-seq-of-ints and I'm passing it a scala-seq-of-longs (since clojure integers default to longs)

flyboarder00:10:33

I have a hashmap {:a 1 :b 2 :c 3} and a vector with a new key order [:b :a :c] how do I reorder the hashmap?

dpsutton00:10:56

hashmaps are unordered in general

dpsutton00:10:28

although in general they are based on insertion order for 7 elements or fewer

dpsutton00:10:12

but if you have a vector of keys then you have an ordering so you could (map #(get collection %) [:b :a :c]) to get a lazy seq of them in the order you gave

flyboarder00:10:08

hmmm maybe i’ll have to rethink this a bit

dpsutton00:10:51

yeah this is probably a situation where you can change the data structure a stack frame or two higher

flyboarder01:10:06

well the hashmap comes from the db

flyboarder01:10:20

and generates a form, but the elements are in a different order each time

flyboarder01:10:29

i’d like to force the order

dpsutton01:10:46

not sure what your db is but rows and columns are not considered ordered in theory despite what may happen in practice

flyboarder01:10:47

right, thats why I thought there would be an easy way to reorder the hashmap

dpsutton01:10:46

that puts you right back at my earlier suggestion. you don't care about the order of the hashmap but the order you access the values in the hashmap

flyboarder01:10:20

right, ok makes sense

qqq01:10:37

I realize this is terrible and never should be done, but I have good reason to do this. Is there a way, from Clojure, to call a private static function of a scala class ? I realize calling private functions is bad -- but in this case, I'm wrapping an API in a clojure-ic manner, and I really need to call this particular private function.

qqq01:10:02

There is only one particular private function I need. so I'm willing to do an expensive reflection of sorts upfront to grab this function.

rwilson01:10:41

@qqq I've never tried that with a scala class... but, long as a SecurityManager isn't present, you may be able to use reflection to get ahold of the Method, and modify it's accessibility (via java.lang.reflect.AccessibleObject#setAccessible)

rwilson01:10:13

I've used that trick in the past for auto-marshalling in Java

rwilson01:10:02

Probably something like (-> (.getMethod TheClass "theFnName" ...) (.setAccessible true) (.invoke nil args)) but specifying the parameter types to getMethod. You could also use getMethods and then filter to the one you want, if there's some problem specifying the parameter types.

qqq02:10:50

@rwilson: interesting, I didn't know that one could change accessibility at runtime (I thought maybe private functions were hidden, and there was a way to reference them, but not that one could actually toggle the accessibility bit)

eriktjacobsen02:10:29

When using clojure.core.server/repl, is there an easy way to get a client that has backspace support, up-arrow for history, ctrl-c basic functionality?

noisesmith02:10:31

where this really would break down is for stuff scala doesn't reify into the running code (it just uses the type system to establish what's what and puts an undocumented / non-self-describing structure into the class file)

noisesmith02:10:46

I'm not certain it does that, but I heard a rumor some things were like this

noisesmith02:10:30

@eriktjacobsen there's a CLI program called rlwrap that you can wrap around your telnet process talking to the socket repl

noisesmith02:10:49

other than that, you just want an nrepl client, and to use nrepl in your code

pesterhazy09:10:06

but even rlwrap nc will be a-ok

hlolli09:10:41

what's the best lib for exporting clojure test output, there is to say, I'm testing someting that has many failed assertions, instead of getting number of fails, I'd like to get some sort of checklist, name of the test, maybe the text from the "testing" macro, in nicely formatted text document.

daedelus198210:10:20

Hi guys, Ive got a general question about Clojure... Ive got a bit of experience with Clojure, and love it, and Ive touched on Haskell. I was thinking of learning Haskell properly, but what do you Clojureists think of Haskell?

andre.stylianos12:10:52

I also have the same doubts constantly 😛 Clojure is awesome and probably the best experience I've had developing, but I often miss types. But I don't agree with people who minimize what benefits types bring... The mistakes caught by type systems aren't always trivial to prevent/find; maybe if you have a lot of experience with the language, a very nicely crafted code with the correct abstractions. But that's not always the case. And preventing those kind of errors is only one part of what type systems bring.

manutter5113:10:41

I see Clojure and Haskell as both valid but very different approaches to similar problems. My recommendation would be to learn both and then use the one that best fits the problem you’re working on and the “style” you’re most comfortable with.

hlolli10:10:28

what I described is exacly here, I should be more thorough with my friend google before asking here. https://github.com/pjstadig/humane-test-output

lsenjov10:10:09

@daedelus1982 don't need a huge type system when your code is simple and readable

lsenjov10:10:15

That, and type errors are easy to find. Errors in logic usually bypass type errors

daedelus198210:10:55

@lsenjov Very good point. Some on the web dislike the dynamic typing of Clojure but this is a excellent counter argument.

mccraigmccraig10:10:18

i would like static checking @daedelus1982 - i currently have a lang-crush on https://github.com/LuxLang/lux

daedelus198211:10:24

@mccraigmccraig Actually looks nice, ahhh, so many languages to learn, so little time.

octahedrion13:10:28

I'm reading some code which seems to be using when where cond would do - I thought when was for side-effects, am I missing something ?

mseddon13:10:14

@octo221 (when 1 2 3) => (if 1 (do 2 3))

mseddon13:10:33

so 2 would be side-effectful. if you don't have 2, might as well use (if 1 3)

octahedrion13:10:10

hmm I don't like using if with only 1 branch

octahedrion13:10:25

cond is for that

mseddon13:10:38

Coming from common lisp, i'd use if, but there is another level of parenthesis in common lisp's cond - (cond (1 2)), so perhaps I'm biased towards using if

sundarj13:10:42

cond is for multiple branches

sundarj13:10:09

it's the equivalent of other languages' if ... else if .... else

octahedrion13:10:26

including one branch right ?

sundarj13:10:35

sure, but you can just use an if for that too

octahedrion13:10:08

say you had 2 branches - if or cond ?

sundarj13:10:47

if just an if and an else then if, otherwise cond

octahedrion14:10:09

but what are the trade-offs besides style ?

mseddon14:10:50

(cond (< x 5) 6 :else 7) vs (if (< x 5) 6 7) - less repetition in this case?

bronsa14:10:50

(cond (< x 5) 6 :else 7)

mseddon14:10:20

🙂 whoops, nice catch, thanks

octahedrion14:10:46

and what about when vs cond or if ? when is only for side-effects right ?

mseddon14:10:03

when is only useful for side effects, since it has an implicit do

sundarj14:10:54

when is often more clear if there's only a single condition

octahedrion14:10:28

eh maybe if with one branch isn't so bad...but whenever I read if I expect 2 branches

octahedrion14:10:18

using cond seems to signal "this is not a standard 2-branch if"

octahedrion14:10:45

which helps me scan for single-branches

sundarj14:10:54

when is often used to signal that there's only a single branch

bronsa14:10:58

people sometimes use when even when side-effects are not used, to avoid single-branched ifs

bronsa14:10:08

it's a matter of preference

bronsa14:10:24

cond is just a generalization of nested ifs

bronsa14:10:11

so (if a b (if c d e)) becomes (cond a b c d :else e)

bronsa14:10:38

no need for repeating the first test with negation as in the snippet above

bronsa14:10:52

:else is just by convention, any truthy value will do

octahedrion14:10:21

i'd prefer not to use when in non-side-effecty cases, because it signals "side-effect here"

bronsa14:10:24

not really, some people use it for that but (when foo bar) is a perfectably acceptable alternative to (if foo bar) or (if foo bar nil)

octahedrion14:10:39

only insofaras it works

bronsa14:10:00

the docstring never argues that when should be used in side-effecty behaviour, some people have randomly decided that that's what its only use-case should be

octahedrion14:10:12

well they're wrong.

mseddon14:10:18

Yeah, by 'useful for side effects', really I was saying it doesn't give you any more semantic power

bronsa14:10:18

it's a matter of taste

bronsa14:10:41

it reads better

bronsa14:10:01

it's more explicit in the fact that the else branch will and should be nil

mseddon14:10:13

rather than parinfer ate your code 🙂

bronsa14:10:35

arguing about personal preferences as if they were fact is not very useful IMO

octahedrion14:10:20

wouldn't there be a small cost in speed ? (because of the implict do) ?

mseddon14:10:41

the compiler shouldn't add any overhead

bronsa14:10:52

do have absolutely no bytecode overhead

bronsa14:10:00

it's just a synctactic operator

mseddon14:10:14

overhead is 2 bytes on your source file 🙂

octahedrion14:10:00

ok the results are in:

(use 'criterium.core)
=> nil
(quick-bench (cond (== 1 2) 3))
Evaluation count : 194420304 in 6 samples of 32403384 calls.
             Execution time mean : 1.151155 ns
    Execution time std-deviation : 0.094268 ns
   Execution time lower quantile : 1.026327 ns ( 2.5%)
   Execution time upper quantile : 1.260197 ns (97.5%)
                   Overhead used : 2.091214 ns
=> nil
(quick-bench (when (== 1 2) 3))
Evaluation count : 93839238 in 6 samples of 15639873 calls.
             Execution time mean : 4.354806 ns
    Execution time std-deviation : 0.199131 ns
   Execution time lower quantile : 4.087070 ns ( 2.5%)
   Execution time upper quantile : 4.584328 ns (97.5%)
                   Overhead used : 2.091214 ns
=> nil
(quick-bench (if (== 1 2) 3))
Evaluation count : 94100316 in 6 samples of 15683386 calls.
             Execution time mean : 4.421143 ns
    Execution time std-deviation : 0.387452 ns
   Execution time lower quantile : 4.082193 ns ( 2.5%)
   Execution time upper quantile : 5.040878 ns (97.5%)
                   Overhead used : 2.091214 ns

bronsa14:10:32

that's just random variations

bronsa14:10:57

the emitted bytecode is exactly the same in all 3 cases

octahedrion14:10:04

probably...trying bench...

bronsa14:10:16

just macroexpand

bronsa14:10:26

it makes no sense to benchmark this

octahedrion14:10:22

ok yep same code

qqq14:10:46

it's a function which sets a "dynamic context" and then executes a body

bronsa14:10:18

find how to invoke that from java

bronsa14:10:38

if it's just a regular new Context(..).withScope(..) then just do that in clojure (.withScope body myContext)

qqq14:10:44

so when I try:

(let [ctx (Context/gpu 0)]
  (. ctx withScope
     (fn []
       20)))
I get this error:

qqq14:10:54

1. Unhandled java.lang.ClassCastException server.snip.mxnet$eval7691$fn__7692 cannot be cast to scala.Function0

qqq14:10:03

It seems like I need a wa to "convert a clojure function to a scala function"

bronsa14:10:10

¯\(ツ)

mseddon14:10:25

looks like you can do it with a let

bronsa14:10:27

again, find how to do that in java and then convert it to clojure

mseddon14:10:35

without calling withScope directly

mseddon14:10:49

bash on Context with set!

bronsa14:10:01

clojure IFns implement Runnable and Callable

bronsa14:10:32

or you can try using https://github.com/t6/from-scala, first google result for scala clojure interop ;)

bronsa14:10:57

often asking google or the repl first is way faster than asking people here

qqq14:10:12

@bronsa: I'm aware of that project, but have been trying to bind this library 'from scratch' to understand what's going on.

bronsa14:10:45

just study that library then

bronsa14:10:34

there's no magic solution, clojure and scala use different interfaces to represent their functions, you need to convert one to the other if you want to interop

qqq14:10:14

@bronsa: thanks for the tip

(let [ctx (Context/gpu 0)]
  (. ctx withScope
     (reify scala.Function0
       (apply [this]
         20))))
appears to have worked

ccann15:10:41

I’m trying to use tools.analyzer.jvm to analyze+eval each form in a seq of forms that I read with tools.reader/read and I get a FileNotFoundException because, I think, the ns macro is one of those forms and it’s requiring another namespace. If I switch to analyze instead of +eval then I get a no such namespace error I think because the ns aliases don’t exist since there was no eval. All I want is to parse the analyzed forms and pull out some :binding keys. Anyone know what I’m missing?

bronsa15:10:04

@ccann hi, your analysis of the problem is correct, why aren't your ns dependencies on the classpath?

ccann15:10:20

so I’m writing a lein plugin

ccann15:10:07

and testing it in my repl, so I’m wondering, if I run this lein <my plugin> on the project then the classpath with have the deps loaded right?

bronsa15:10:28

I have no idea how lein plug-ins work, sorry

ccann15:10:45

no problem @bronsa but I will update here if I get it working. Thanks!

hiredman15:10:53

plugins run in the lein jvm, not the project jvm(they will sometimes inject things in to the project jvm)

ccann15:10:53

thanks — I have to dive into that documentation

h.elmougy16:10:05

how to execute procedure with out parameters with jdbc

acron16:10:20

I received this comment today [code is not idiomatic because] it's using when for the return value instead of side-effects.

acron16:10:52

Is it a faux-pas to use when for the return value? I used it to replace a single-branch if

dpsutton16:10:02

i think people were talking about that above

dpsutton16:10:07

i think it's totally fine

acron16:10:15

@dpsutton what a coincidence, I wonder if my feedback was inspired by that conversation 🙂

dpsutton16:10:33

hahah that would be a great circle.

dpsutton16:10:08

is this the person code reviewing?

acron16:10:35

I just wondered that myself!

acron16:10:48

Don't think so though

sundarj16:10:13

@acron one thing to note is that there are plenty of places in clojure.core that use when that way, e.g.:

(defn not-empty
  "If coll is empty, returns nil, else coll"
  {:added "1.0"
   :static true}
  [coll] (when (seq coll) coll))
though, naturally, it's simply a matter of preference

dominicm16:10:45

but the one true way (dictated by me) is to use when for side effects or not

ddellacosta16:10:05

there is apparently history to when usage coming from the lisp world too, which is at least worth considering: https://lobste.rs/s/aqzj0f/robust_clojure_best_way_handle_nil#c_qejrpi

ddellacosta16:10:36

I always find it hard to navigate this stuff in Clojure, as many users are not coming from the lisp world, and Clojure itself is a mix of lisp and other languages in terms of influences

dpsutton16:10:59

yeah. when project maintainer has a style that wins over any other argument

dpsutton16:10:15

and consistent codebase > arguments about local style

dominicm16:10:32

there's a few lisp idioms that aren't applied conventionally in clojure.

dpsutton17:10:24

i was thinking i would argue with boss / coworker. not with open source maintainer

seancorfield17:10:14

I've never heard of decisions around when being tied to side-effects. @dominicm can you elaborate?

dominicm17:10:48

@seancorfield I hadn't until just now in the above github pull request

souenzzo12:10:43

(merge (when x {:x x}) (when x {:y y})) isnt idiomaic?

dominicm12:10:39

I do it. But some people advocate that it isn't. I think they're wrong, clojure.core uses this style.

hiredman17:10:13

this common-lisp guy one time said on mailing list that when is for side-effects, and some clojure people thought it made sense (because of the implicit do in a when) and have been pushing it ever since

ddellacosta17:10:23

yeah to be clear, I wasn’t trying to suggest any one thing is correct--I just thought it was a relevant bit of historical data. Personally I don’t think of when in this way, generally speaking.

hiredman17:10:45

phil happens to be one of the pushers

ddellacosta17:10:07

yeah, in fact he was the one that brought it up in that thread--I just found the second explanation more clear

hiredman17:10:16

(and it is silly and that should clearly be a when-let)

seancorfield17:10:30

I'm fairly sure at least one of the linting tools complains about single branch if and suggests when.

seancorfield17:10:42

(I thought it was Eastwood but I don't see it documented)

noisesmith17:10:56

I think it’s kibit or bikeshed that does that

hiredman17:10:06

I had a pr on bbatsov's style guide several years ago to delete the whole thing and replace it with a bruce lee quote

potetm18:10:38

This has come up at the office before. This was how it was settled 🙂

seancorfield18:10:36

The perfect appeal-to-authority 🙂

tbaldridge18:10:19

perhaps proof that even logical fallacies aren't always to be avoided?

octahedrion18:10:08

ok I'm convinced!

octahedrion18:10:28

well not really

octahedrion18:10:52

i still don't see the point of using an implicit do if it's not needed

potetm18:10:02

Literal same thing happened w/ my coworker. He let it go, but maintains single branch if is better.

octahedrion18:10:15

even if it costs nothing and compiles to the same as if or cond

tbaldridge18:10:16

personally I dislike the dogmatic nature of "X should only be used for Y"

potetm18:10:06

My argument: it's a nicety that can be provided with basically no cost

tbaldridge18:10:09

For me, it's about readability it's hard to hunt down the other expr in a single-legged if

potetm18:10:17

Now you can use it for side effects.

tbaldridge18:10:06

Code reading for me is a pattern matching thing. It's easier for me to match on when and know it returns a nil or a value. Vs a if which involves hunting down both legs of the branch to figure out what each one does. If I can't find the second leg, am I missing it? or does it not exist?

seancorfield18:10:49

It's all a bit of a ridiculous argument since you can have (if some-expr (run-process a) (run-process b)) where run-process both has side effects and returns a value 🙂

seancorfield18:10:29

(consider clojure.java.jdbc/insert! which is very side-effect-y and returns useful information)

octahedrion18:10:50

when I see if i expect to see 2 branches too

potetm18:10:10

Naw yeah. The whole thing is a colossal waste of time.

octahedrion18:10:22

if there's one i get worried the other one was left out by mistake

potetm18:10:30

Doesn't change the fact that I'm right, and someone else is wrong.

seancorfield18:10:32

So, for me, because "side effects" is a red herring, I expect two branches for if, one branch for when (and it signals clearly that I can get nil back) and for cond I expect more than two branches.

dpsutton18:10:20

i love bbatsov's reaction to the PR to replace the whole style guide

seancorfield18:10:27

Besides, in real-world code you're also going to see stuff like (if some-expr (do (side-effect-y a) (compute b)) (compute c)) -- again, the presence or absence of side-effects is a red herring here.

octahedrion18:10:40

I propose a new conditional (name to be suggested) that's like when but without the implicit do

potetm18:10:15

It's like watching a movie all over again. The exact. same. conversation.

tbaldridge18:10:56

but why? @octo221 it's exactly the same thing

hiredman18:10:46

fn's have an implicit do, you should only use them for side-effects yo

octahedrion18:10:03

@tbaldridge (joke!) - I'm persuaded

octahedrion18:10:43

3 ways to say the same thing

octahedrion18:10:16

and no shades of meaning at all ?

markbastian19:10:01

With all the talk of AI/ML/TensorFlow/DeepLearning going on at Clojure/conj and the general observation that Python is ahead of the pack in terms of existing efforts, I was wondering if one approach that might leverage those efforts would be a Clojure hosted on Python. I see that @tbaldridge has done some efforts with https://github.com/halgari/clojure-py-redux and https://github.com/halgari/clj-pypy. What kind of effort would it take to get either of those (or a newer, better solution) rolling again or anew? I'd potentially be interested in taking it on depending on some of the factors (is there an interest, what woluld it take to get there, etc.).

markbastian19:10:29

Just exploring the idea for now, but wanting to get some thoughts from the experts.

bpiel19:10:51

@markbastian I heard a lot of talk about clj/python interop via different mechanisms, but this one is new to me. Mind blown.

noisesmith19:10:09

@markbastian for what it’s worth both of those were superseded by pixie, which is no longer in active development - the second, like pixie, can’t use python directly, it only bootstraps via python’s vm generator

noisesmith19:10:38

for using python in a clojure like language, the most mature and featureful thing is likely hy https://github.com/hylang/hy

noisesmith19:10:53

it’s also the only active one I know of

markbastian19:10:36

I'll have to check those out.

markbastian19:10:08

It seemed like there were some bring "Python Libraries to Clojure" thoughts in the conj talks (just from what I saw on the videos - Sadly, I wasn't able to attend) and I was just speculating to myself whether it'd be easier to do that or bring Clojure to Python.

tbaldridge19:10:49

Hy is the way to go for now, but it's mostly sexprs for Python.

tbaldridge19:10:32

I'm currently working on reviving Clojure-py, but it's quite a few months out, and will be only from Python(and PyPy) 3. Supporting Python2 these days is just too much work.

tbaldridge19:10:03

Hy even has mutable closures like Python, which is a bit icky, but it may work for awhile.

seancorfield19:10:25

There was mention of Grawl(?) at Conj as a possible way to run Clojure and Python in the same VM -- any experience reports on that?

tbaldridge19:10:09

That's a bit different, they're compiling the C VM to Java and then running that via Graal, it would work about as well as someone would expect (which is mostly, kindof, not really)

tbaldridge19:10:57

Would have the same problems as PyPy: a lot of python libs depend on both reference counting and memory layouts of Python objects. PyPy breaks both of those, and Graal would probably break at least one.

markbastian19:10:31

Yeah, that was what I was referring to when I was thinking "bringing Python to us," just couldn't remember the name.

cgore19:10:43

I would love to be able to somehow magically get to CPython stuff from Clojure, geospatial stuff that wouldn’t work in PyPy. But that seems quite difficult.

seancorfield19:10:16

Searching for graal python is not very helpful 😆

cgore19:10:41

It’s a general problem well beyond just TensorFlow. I’m sure there’s other cool Python stuff that would be awesome to somehow squish into Clojure.

cgore19:10:21

I’m not sure where the Python stuff is 😐

tbaldridge19:10:28

@gigasquid has had some discussions with them, it seems the python interop stuff is yet to be fully designed

tbaldridge19:10:45

and sadly that's what kills most alternative python VMs

seancorfield19:10:07

Oracle's page say they have Python running on Graal but I couldn't find any links to it publicly -- so maybe "running" is subjective at this point. On the subject of Tensorflow, I haven't yet watched the Conj video (which I assume will link to Guildsman) but a quick search did not find Guildsman so if someone has a link, that would save me a bit of time 🙂

bpiel19:10:25

I have it handy

seancorfield19:10:07

Thanks Bill... I have absolutely no idea why I couldn't find it! I swear I even looked at your GitHub account. Must have needed more coffee!

bpiel19:10:15

@seancorfield It definitely isn't showing up on google (yet?)

tbaldridge19:10:40

So the better view, IMO, is to bring Clojure to Python which is rather easier considering clojure is designed to be hosted from the start.

bpiel19:10:37

@tbaldridge would that just mean reviving your previous work linked above?

tbaldridge19:10:49

more like rewriting, but yes 🙂

bpiel19:10:07

@seancorfield Let me know if you have any questions. We've (not many of us) have been hanging out in #tensorflow

tbaldridge19:10:50

and making that work well involves working with Cython. that' part has recently gotten much nicer due to Cython adding support for Python type hinting.

tbaldridge19:10:42

There are some performance critical bits in Clojure. Collections, protocols to name a few. What are the other options besides Cython or mandating PyPy?

bpiel19:10:14

@tbaldridge I don't know much about that aspect of python (implementations and differences). I was just wondering.

ghadi19:10:24

@seancorfield the python stuff is included with the Graal OTN download, if I remember correctly. That's how the TruffleJS is/was

ghadi20:10:55

it doesn't work like that... moving to #other-languages

markbastian20:10:49

@tbaldridge - Is there an existing JIRA/task list/etc. you have for the clojure-py-redux-redux effort? Or are you thinking of diving in yourself before soliciting help from the community at large?

tbaldridge20:10:01

I'll move this to #other-languages after this, but it's mostly the latter. There's a lot of foundational interop stuff I want to get done first before looking for porting help

danielcompton23:10:23

Bit late to the if/when debate, but there is also https://github.com/jonase/kibit/issues/2