Fork me on GitHub
#clojure
<
2019-03-01
>
ag00:03:26

from the docstring of http://clojuredocs.org/clojure.core/case > Unlike cond and condp, case does a constant-time dispatch, the clauses are not considered sequentially. can someone explain in plain English what that means?

noisesmith00:03:56

it jumps to the condition, rather than linearly checking the conditions one at a time

šŸ‘ 5
noisesmith00:03:24

it compiles to effectively (or maybe literally) a hash-map lookup on the dispatch value

Alex Miller (Clojure team)02:03:08

the jvm has two bytecodes supporting "switch" - one is a linear series of checks, the other is effectively a constant time jump table keyed off of hashcode

Alex Miller (Clojure team)02:03:24

Clojure's case does a ridiculous amount of work to use the latter

šŸ‘ 20
devn05:03:25

That got me scrolling through my phone to find the case source, which stirred up a couple of questions/comments: 1.) some?, if-some, when-someā€” do people use these often? I donā€™t, personally. Anyone have insight as to why they made it into core? I think I saw an added in 1.6, which makes me guess at it being related to transducers? Maybe Iā€™m off 0.2 and that was the time of reducers? Either way, curious on the history. 2.) modā€™s docstring has a line ā€œTruncates toward negative infinity.ā€ Could someone explain that to me, and perhaps provide an example of why itā€™s important to know?

andy.fingerhut07:03:08

I typically avoid calling modulo/remainder or division operations on negative numbers, to avoid having to know, and because applications I have written didn't need such operations on negative numbers. But this page on the divide and modulo behavior in various flavors of C/C++ might answer some of your question: http://www.microhowto.info/howto/round_towards_minus_infinity_when_dividing_integers_in_c_or_c++.html

leonoel07:03:12

I prefer if-some and when-some over if-let and when-let almost every time

leonoel07:03:20

if I remember correctly the reason why they were added was because core.async channels impose nil as the end-of-stream sentinel

vemv07:03:46

> I prefer if-some and when-some over if-let and when-let almost every time yes I've met other clj programmers following that style It might boil down to Java-like vs. Lisp-like boolean semantics (in Java there's no 'truthiness' - just true and false can be used in conditions). Some people prefer Java-like

Nazral12:03:37

Hi! Anybody knows of a clojure nlp library with things like RAKE/LDA?

Nazral12:03:07

Thank you! I actually know about corenlp but it doesn't have LDA nor RAKE. I know Spark has LDA but I'd like to avoid to massive overhead Spark creates... Worst case I'll go an implement it...

borkdude12:03:58

I saw something about LDA mentioned in the JavaDoc of CoreNLP, thatā€™s why I thought it may be relevant, but maybe not.

victorb13:03:58

I'm trying to find any previous implementations (or some library I could steal ideas from) for having a pipeline which basically all functions inside this pipeline depends on the previous step and also have side-effects. Goes something like fetch source -> build -> report status but with a bit more steps in-between. Any previous art or thoughts on the subject are welcome! I've looked at some implementations using async/pipeline but feels like over-engineering for my case, no need for it to be async

Scott McCaughie14:03:21

If I understand your requirement, Iā€™ve done similar before simply using thread-first, passing a context as I go:

(-> initial-context fetch-data parse-data categorise send)

victorb14:03:58

Ah, basically build up some context map that contains all the parts that are needed? Actually not a bad idea

Scott McCaughie14:03:34

Yep exactly. Youā€™re welcome šŸ™‚

amarjeet18:03:57

I couldnā€™t find clojure.java.jdbc channel, so asking here: At the time of table creation, if I provide [:age :int :default 18] then jdbc throws error, but it accepts "18", which is logically incorrect. How to handle this?

noisesmith18:03:48

the channel for jdbc is #sql

amarjeet18:03:07

oh okay, thanks

nkraft19:03:35

I'm making myself crazy with this... I'm using clojure.data.json to create a json string. The string I want to create looks like this: {"query": {"field": {"text": "123",

nkraft19:03:48

Sorry, hit the wrong key. Let me try again.

nkraft19:03:29

{"query": {"field": {"text": "123", "title": "ABC"} } }

nkraft20:03:03

the json/write-str I use looks like this: (json/write-str {:query {:field {:text "123", :title "ABC}}})

nkraft20:03:44

But I keep getting "No value for key" error on the generation.

nkraft20:03:56

I've tried just about every combination I can think of, with no joy.

noisesmith20:03:03

is the " after C missing in your original?

nkraft20:03:03

Does someone see something I'm missing?

nkraft20:03:21

No, it's there. Just a typo.

hiredman20:03:35

user=> ((fn [& {:as m}]) 1)
Execution error (IllegalArgumentException) at user$eval1467$fn__1469/doInvoke (REPL:1).
No value supplied for key: 1
user=> 

noisesmith20:03:10

egret.run=> (j/write-str {:query {:text "123", :title "ABC"}})
"{\"query\":{\"text\":\"123\",\"title\":\"ABC\"}}"
egret.run=> (println *1)
{"query":{"text":"123","title":"ABC"}}
nil
egret.run=> (j/write-str {:query {:text "123", :title "ABC"}} :foo)
IllegalArgumentException No value supplied for key: :foo  clojure.lang.PersistentHashMap.create (PersistentHashMap.java:77)

noisesmith20:03:12

extra arg, yeah

nkraft20:03:36

It seems to me that query is matched by field, field is matched by the object containing text and title. Everything has a key value. The original JSON validates. It just doesn't work with json/write-str. Very odd.

noisesmith20:03:49

you are providing the wrong number of args to write-str

hiredman20:03:04

what does the stacktrace say?

nkraft20:03:15

Where did the :foo come from in your example?

noisesmith20:03:24

it's how you make that error message happen

nkraft20:03:52

Ah. Is there a better way to make sub-objects in a JSON string with json/write-str?

noisesmith20:03:37

what does this mean?

hiredman20:03:59

you have supplied the error message, which says what the error is, but the stacktrace will tell you where the error is actually happening

nkraft20:03:36

IllegalArgumentException no value supplied for key: then: clojure.lang.PersistentArrayMap.createAsIfByAssoc (PersistentArrayMap.java:79)

noisesmith20:03:01

*e will contain the full trace

nkraft20:03:15

That's the whole stack trace (this is in the repl)

noisesmith20:03:25

that's not a stack trace, it's a message

noisesmith20:03:29

*e contains the trace

nkraft20:03:34

Never mind, I see it.

nkraft20:03:28

Here's the whole thing: at [clojure.lang.PersistentArrayMap createAsIfByAssoc "PersistentArrayMap.java" 79]}] :trace [[clojure.lang.PersistentArrayMap createAsIfByAssoc "PersistentArrayMap.java" 79] [clojure.core$array_map invokeStatic "core.clj" 4256] [clojure.core$array_map doInvoke "core.clj" 4249] [clojure.lang.RestFn applyTo "RestFn.java" 137] [clojure.core$apply invokeStatic "core.clj" 646] [clojure.core$apply invoke "core.clj" 641] [clojurewerkz.elastisch.arguments$GT_opts invokeStatic "arguments.clj" 9] [clojurewerkz.elastisch.arguments$GT_opts invoke "arguments.clj" 3] [clojurewerkz.elastisch.rest.percolation$register_query invokeStatic "percolation.clj" 30] [clojurewerkz.elastisch.rest.percolation$register_query doInvoke "percolation.clj" 25] [clojure.lang.RestFn invoke "RestFn.java" 467] [esearch.handler$get_register_search invokeStatic "handler.clj" 124] [esearch.handler$get_register_search invoke "handler.clj" 119] [mysql.core$eval11790 invokeStatic "form-init1224899402989498950.clj" 1] [mysql.core$eval11790 invoke "form-init1224899402989498950.clj" 1] [clojure.lang.Compiler eval "Compiler.java" 6927] [clojure.lang.Compiler eval "Compiler.java" 6890] [clojure.core$eval invokeStatic "core.clj" 3105] [clojure.core$eval invoke "core.clj" 3101] [clojure.main$repl$read_eval_print__7408$fn__7411 invoke "main.clj" 240] [clojure.main$repl$read_eval_print__7408 invoke "main.clj" 240] [clojure.main$repl$fn__7417 invoke "main.clj" 258] [clojure.main$repl invokeStatic "main.clj" 258] [clojure.main$repl doInvoke "main.clj" 174] [clojure.lang.RestFn invoke "RestFn.java" 1523] [nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 79] [nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55] [nrepl.middleware.interruptible_eval$interruptible_eval$fn__764$fn__768 invoke "interruptible_eval.clj" 142] [clojure.lang.AFn run "AFn.java" 22] [nrepl.middleware.session$session_exec$main_loop__865$fn__867 invoke "session.clj" 171] [nrepl.middleware.session$session_exec$main_loop__865 invoke "session.clj" 170] [clojure.lang.AFn run "AFn.java" 22] [java.lang.Thread run "Thread.java" 748]]}

nkraft20:03:53

esearch.handler is my code.

noisesmith20:03:42

so this problem has nothing to do with data.json

nkraft20:03:22

Probably not, but I presume that people have built JSON like this before with data.json..

nkraft20:03:43

I'm just looking for what I'm doing wrong in my write-str.

noisesmith20:03:57

write-str has nothing to do with that error

nkraft20:03:25

write-str triggers it, that's all I know.

noisesmith20:03:40

if that were true, write-str would be in the stack trace

nkraft20:03:07

I'd think so. It could be when it gets passed to ElasticSearch. Maybe something goes wrong there.

noisesmith20:03:44

what does ->opts do and how is it being called?

seancorfield20:03:58

You are most likely realizing a lazy sequence that was created somewhere else.

āž• 10
nkraft20:03:01

I think one problem might be that the values for title and text aren't simple like "123". They are 1024 character strings containing search terms that may or may not have foreign characters in them.

seancorfield20:03:19

And the error is in what you passed to the code that created that lazy sequence.

nkraft20:03:38

That's a reasonable idea.

alexyakushev20:03:27

Is -Dclojure.compile.warn-on-reflection property supposed to work? If so, what effect should it have? I supposed it will set the reflection warning dynvar for all namespaces by default, but it doesn't seem to.

seancorfield20:03:33

-Dclojure.compile.warn-on-reflection=true should work.

noisesmith20:03:02

$ clj -J-Dclojure.compile.warn-on-reflection=true
Clojure 1.10.0
(cmd)user=> *warn-on-reflection*
false

didibus20:03:02

I think it only sets it when compiling

seancorfield20:03:22

Ah, yes, that's it.

didibus20:03:48

So its not controlling the value of *warn-on-reflection*, it is just looked up as well by the compiler when compiling to decide if it should emit or not the warnings.

alexyakushev21:03:30

@U0K064KQV So it seems like I can't use it to check all namespaces for warnings. Sad.

seancorfield21:03:02

clojure -J-Dclojure.compile.warn-on-reflection=true -e "(compile 'entry.point)" should do it @U06PNK4HG?

seancorfield21:03:02

(you'll need a classes folder for it to compile into -- or else add a binding call around the compile for *compile-path*)

alexyakushev10:03:55

I still use Boot, but thanks, I will try to do something similar.

seancorfield20:03:23

@nkraft have you shown us exactly what code is on line 124 of esearch.handler?

nkraft20:03:05

this is Elastisch, submitting a query to the ElasticSearch percolator: (pcl/register-query conn index rowid json) That's on line 124. 'json' is the output of data.json. index and rowid are strings.

seancorfield20:03:38

Which version of Elastisch are you using? The stack trace does not match the latest version.

seancorfield20:03:37

It looks to me like register-query expects kw-args style arguments, i.e., named arguments, not a single JSON map.

nkraft20:03:56

Elastisch is 2.2.1

nkraft20:03:19

Really, I didn't see that in the docs. That is very helpful to know.

seancorfield20:03:21

Yes. Then you're calling it per the 3.x API, instead of the 2.x API.

seancorfield20:03:57

& args is expected to be unrolled keyword args, not a map.

seancorfield20:03:11

In Elastisch 3.x, this call changed to accept a single hash map of opts

seancorfield20:03:54

So you either need to change your call or update to 3.x.

nkraft20:03:09

I'll try both. šŸ™‚

nkraft20:03:34

Well, updating Elastisch to 3.0.0 didn't fix it. Same problem. I'll try keyword args rather than the JSON.

seancorfield20:03:57

It should be a hash map not a JSON string.

seancorfield20:03:26

Here's the commit that changed the kwargs to option hash maps across the whole of Elastisch in May 2016 https://github.com/clojurewerkz/elastisch/commit/f3ea4289b9a9cb37a491f0a3a2df4ec6388d27ae#diff-62e296465e10f4b062c0484560be3e12

seancorfield20:03:21

So (pcl/register-query conn index rowid {:query {:text "123" :title "ABC"}}) for 3.x or (pcl/register-query conn index rowid :query {:text "123" :title "ABC"}) for 2.x.

nkraft20:03:08

Thanks that's very helpful. OF course our ElasticSearch servers just went down so I'll have to test later. My localhost ES doesn't have enough data for what I'm doing.

dchelimsky21:03:20

[ANN] Cognitect Labs' aws-api 0.8.273 is now available: https://groups.google.com/forum/#!topic/clojure/PgnJxiam_qk

bbqbaron21:03:49

this is pure gush but i just got my first full-time clojure gig and am incredibly excited. thanks for being such a thoughtful, curious community lambdalove

šŸš€ 40
šŸŽ‰ 35
the2bears21:03:40

Nice, congratulations!

nkraft21:03:43

@seancorfield I have to thank you. That one post about 3.x vs. 2.x was the key. It's fixed now.

nkraft21:03:01

@bbqbaron Congratulations! That's pretty exciting.

šŸ‘ 5
seancorfield21:03:15

@nkraft This is a good example of why Rich is such a strong advocate of accretion, relaxation, and fixation -- rather than breakage. Admittedly, Elastisch did a major version change to signal "potential breakage" per so-called Semantic Versioning, but it really does show that you never really know whether updating to a new major version is "safe" or not -- and changes like this make it hard to trust the docs, unless they are also fully versioned for every new release.

seancorfield21:03:22

(That said, my "flagship" Clojure project, clojure.java.jdbc also went through two rounds of API breakage -- to move to a more idiomatic API -- and, in fact, it was precisely the same changes that Elastisch made, switching from keyword arguments to an options hash map!)

nkraft21:03:21

That's true. I use your java.jdbc as well. Many times reading code is all that really works. Still, in my job I'm often trying to hack together something needed in a matter of hours, and I rely on docs to get things started probably more often than I should.

nkraft21:03:43

(I write mostly back end data moving stuff)

seancorfield21:03:42

I don't think I've broken the java.jdbc API in about two and a half years now, but 2016 and 2013 were bumpy years for the API šŸ™‚

seancorfield21:03:51

(unfortunately there are still a lot of books and tutorials out there containing 0.2.x examples which haven't worked since 2013 šŸ˜ž )

olfal21:03:49

I saw the following spec in some code and I was wondering what the or was supposed to do.

(s/def ::my-string string?)
(s/def ::my-int integer?)
(s/def ::my-spec (s/keys :req-un [(or ::my-string ::my-int)]))
I generated a few samples using clojure.spec.gen.alpha/generate and saw that it does not yield the same results in Clojure 1.9 and 1.10. In 1.9, it always returns maps with both keys (which looks like a bug :thinking_face:) In 1.10, it returns maps with either ::my-string key, ::my-int or both (which looks like a normal or) What is the expected behavior?

Alex Miller (Clojure team)22:03:00

well first, the or here is not xor, so the generated examples in 1.9 are still "correct". in 1.10, it was updated to include either or potentially both.

Alex Miller (Clojure team)22:03:41

so, expected behavior is its current behavior

olfal22:03:28

Great, thanks for your answer

olfal22:03:19

It seems like the valid? function behaves the same way on this spec, though

olfal22:03:54

So in 1.9, it generates only one case (both keys) of the 3 valid ones (first key, second key, both keys)

Alex Miller (Clojure team)22:03:43

yes, we improved it

šŸ‘ 5
borkdude21:03:19

@seancorfield I recently learned about clojure.jdbc. Are you aware of it and its criticisms of java.jdbc? https://funcool.github.io/clojure.jdbc/latest/#why-another-jdbc-wrapper

seancorfield22:03:37

Are you aware that it started life by copying code from clojure.java.jdbc and ripping out the license and copyright? I had to call the guy out on the main Clojure Google Group for that.

šŸ˜¬ 5
borkdude21:03:13

FWIW I still use java.jdbc but I thought it might be worth sharing

noisesmith21:03:57

I find it odd and annoying that the clojure.jdbc docs call clojure.java.jdbc java.jdbc, and that the project picked a name such that many discussions about using jdbc with clojure now look ambiguous

noisesmith21:03:07

I haven't used it at all though

borkdude22:03:32

yeah, we can refer to it as funcool jdbc šŸ˜‰

seancorfield22:03:37

Are you aware that it started life by copying code from clojure.java.jdbc and ripping out the license and copyright? I had to call the guy out on the main Clojure Google Group for that.

šŸ˜¬ 5
seancorfield22:03:01

Also, it's criticisms are mostly out of date (and will be completely irrelevant when next.jdbc comes out which I've been working on a for a while). And it hasn't had any code updates in three years now (and only minor doc updates that were two years ago) -- so I'd say it's abandoned at this point.

borkdude22:03:23

great, thanks. So yes, you were aware, now I know šŸ˜‰

borkdude22:03:08

didnā€™t know there was this ā€œdramaā€ associated with it. I just saw someone mentioning it on clojureverse

borkdude22:03:04

Somewhere he said: > Currently I have removed all taken code from the clojure.java.jdbc, license problem should be solved. I wonder with what he replaced that code then

seancorfield22:03:04

I won't comment on that... for legal reasons...

borkdude22:03:48

fine, we can close this topic

seancorfield22:03:01

Where it was mentioned on ClojureVerse, I also pointed out that the original code was ripped off, BTW. https://clojureverse.org/t/next-jdbc-early-notes/3480/5 Or is there another thread that mentions it?

borkdude22:03:43

Iā€™ll see if I can find this

seancorfield22:03:04

(that's the only thread that search finds where it seems to be mentioned)

Lennart Buit22:03:32

thats so uncool, not attributing code. Even disregarding the legal implications

Lennart Buit22:03:07

derivation is at the heart of open source, but not by copying others work and posing it as your own

borkdude22:03:49

or maybe it was on Redditā€¦ or Zulipā€¦ or Slackā€¦ I forgot, sorry šŸ˜•

seancorfield22:03:37

I think I saw a mention on Reddit (and also linked to the Google Group thread there about the code being ripped off in the early versions).

borkdude22:03:05

This was the comment: https://www.reddit.com/r/Clojure/comments/ao8hlb/using_databases_in_clojure_a_lot_of_options/efzpxxj/ and I see 3 days later you reacted on it. I think I missed that.

seancorfield22:03:33

I try to catch every mention of it I can. As someone who's been doing OSS development for over twenty five years, I'm very sensitive to the issues of licensing and plagiarization šŸ˜ 

Ā©ļø 25
borkdude22:03:46

Rightly so. Sorry man, didnā€™t want to trigger you into a bad mood.

seancorfield22:03:46

We're good. I'm just listening to Amanda Palmer's new album so not much is going to dampen my enthusiasm today šŸ™‚

noisesmith22:03:48

legal issues aside, it's a disrespectful way to engage with a project whose work is leveraged that heavily

borkdude22:03:38

thatā€™s totally (f)uncool

šŸ˜ 5
borkdude22:03:25

(sorry, bad joke šŸ˜‰ )

johnj22:03:37

this went from technical to legal issues ( but the technical part was never talked about )

Lennart Buit22:03:15

or ethical šŸ˜›

seancorfield23:03:31

As technical people, we'd do well to remember there are ethical and legal aspects to our work a lot of the time... for example http://2018.clojure-conj.org/keynote-speaker-rebecca-parsons/

Lennart Buit23:03:19

I often cite ā€˜computer ethicsā€™ as the most influential course in my masters

āœ”ļø 5
borkdude23:03:46

which uni? my uni also paid quite some attention to it

Lennart Buit23:03:34

University of Twente (Enschede, The Netherlands)

borkdude23:03:32

Yep, thatā€™s where I was too šŸ™‚

Lennart Buit23:03:31

Also had lectures from Johnny SĆøraker? Its such a shame that heā€™s no longer at the uniā€¦

borkdude23:03:00

I graduated in 2005

borkdude23:03:07

Donā€™t know the name.

Lennart Buit23:03:20

yeah probably not, I think he started teaching around 2006. Anyhow, cool to hear that this has been a trait of the UT for so long. I still believe that having a good ethics course is great for a computer scientist.

seancorfield23:03:37

Small world šŸ™‚

Lennart Buit23:03:40

Quite, moreso because the university we went to is one of the smaller of The Netherlands