Fork me on GitHub
#clojure
<
2017-01-19
>
alexbaranosky00:01:37

"Other languages will be faster, but Odin attempts to be a "drop in and use" solution where the total run time of a query is not the top priority." Now I wonder what those faster languages/libs, since my main goal here is performance

qqq00:01:44

alexbaranosky: I think it's "slow" vs "highly optimized sql query engines", but probably faster core.logic; because core.oogic is a full relational programming langauges, where was odin is meant ot be a querying language

qqq00:01:03

actually, I don't know if it's slow at all, but "if it is slow, it's 'slow' vs optimized sql engine'

alexbaranosky00:01:25

Looks like I'm going to need to do some benchmarking...

Alex Miller (Clojure team)00:01:40

@qqq there is a dyn var that controls recursion limits. Also, I'd recommend setting :gen-max on any colls in the recursion

qqq00:01:04

@alexmiller what's killing me is not the recursion depth, but the breadth

qqq00:01:22

like if a coll-of generates N items, and I have depth 4, I sudeenly have N^4, and if N is something like 100, then code dies

hiredman00:01:26

depending on what your logic program does it might easy to encode for a SAT or SMT

hiredman00:01:04

and there are really fast SAT solvers

hiredman00:01:25

ah, yeah, for some kind of query engine a sat solver won't likely work well

Alex Miller (Clojure team)00:01:13

qqq so gen-max will help

Alex Miller (Clojure team)00:01:40

The default is 20 I think but I usually set it to 3

alexbaranosky00:01:42

we're doing things like putting large number of tuples (facts) into the logicdb, then running things like:

alexbaranosky00:01:48

(run section-limit [v] (fresh [addr type vs sz n t] (artifact-data-section sha256 addr type vs sz) (artifact-data-section-entropy sha256 addr n t) (== v {:addr addr :type type :vs vs :sz sz :entropy n :entropy-types t})))

alexbaranosky00:01:16

basically a: SELECT a b c d e f FROM artifact-data-section JON artifacat-data-section-entropy ON foo....

alexbaranosky00:01:37

I need to dig deper into our use cases, but I think that's essentially what we're using it for...

alexbaranosky00:01:08

looks like odin would get us the ability to do that --- I should benchmark core.logic vs odin for some typical things we do

hiredman00:01:55

tabling might help, it is memoziation or caching for relations, the other thing often done for performance is abandoning relational purity and use condu or conda

qqq01:01:46

@alexmiller : :gen-max solved my issue; thanks!

qqq01:01:18

If Clojure was minikanren , would clojure.spec generator be far more powerful? The main limitation to Clojure Spec seems to be "sometimes, you ahve to write your own generators to pass the 'such that' test" -- and in all examples, it seems like "if you could run the code backwards in a relational manner" -- then you would be able to automatically synthesize conforming examples. Thus, if all Spec code was limited to "minikanren like funcitons" insted of "arbitrary clojure code", it seems like spec / generators would be even more powerful.

gfredericks01:01:15

And sooooper slow

qqq01:01:57

only during the "automatically brute force test this function for me " phase right? it should not hurt runtime performance

Alex Miller (Clojure team)01:01:23

Did you see the barliman talk at the conj?

alexbaranosky01:01:58

@hiredman thanks, I'll read up on tabling

tbaldridge02:01:20

@alexbaranosky: datalog and spectr will be faste, but with a different set of tradeoffs

tbaldridge02:01:02

I think it's possible to JIT Odin via something like Truffle, but I'm still meditating on that one

tbaldridge02:01:33

Odin should be faster than core.logic done it used transducers instead of the list monad, but I haven't benchmarked it yet.

bbloom02:01:14

yeah, i think we need to let/help will byrd et al do another decade or two of research first 🙂

tbaldridge02:01:54

That being said, I have a query engine in production that uses a minikanren-esque engine, and the engine is rarely the bottleneck, it's network data loads, and out of order joins that are the biggest source of perf problems

bbloom02:01:07

what are you querying?

tbaldridge02:01:29

Diatomic data, but we want lazy query results and our datasets are too large for the heap, so Datalog wasn't working

tbaldridge02:01:02

And I'm on my phone so sorry for the type-os

bbloom02:01:17

interesting

josh_tackett02:01:50

Anyone else having trouble moving tickets in Jira from Column to column on active sprint?

seancorfield03:01:56

@josh_tackett Wrong channel? Wrong Slack maybe? 🙂

josh_tackett03:01:09

haha no I actually was asking here @seancorfield Wondering if the problem is all of Jira or just our companies board?

seancorfield03:01:25

josh_tackett: Just tried dragging a card across columns on our board at work and it just springs back to the original column, even tho' the target column went green to indicate a valid destination.

seancorfield03:01:16

So you'll have to manipulate the workflow state directly on the ticket until they fix it.

seancorfield20:01:32

BTW, looks like JIRA fixed that problem — I can drag cards between columns today.

seancorfield03:01:44

Well, it's #off-topic at best for this channel.

josh_tackett03:01:08

@seancorfield Thank you for testing this for me!

seancorfield03:01:04

josh_tackett: Why didn't you reply in the thread?

qqq03:01:10

How can I get lein to pass arguments to the underlying code? (I.e. I want to define a varaible inside my lein project.clj -- and then have mya ctual code be able to read that varaible and get its value).

seancorfield04:01:39

qqq: If you don't mind using a Java property, you can set JVM options in project.clj and then use System/getProperty in your code to read them.

josh_tackett04:01:43

@seancorfield not sure what you mean?

josh_tackett04:01:42

Oh nice, I didn’t have the update but just downloaded it and this is awesome

josh_tackett04:01:21

How do you start a thread?

zane04:01:27

There's a little icon when you mouseover a message.

zane04:01:49

On desktop, anyway. I think you have to long-press on mobile.

zentrope04:01:33

Comes through as regular messages via the IRC bridge. Phew!

fellshard07:01:32

zentrope: Yeah, they made sure that if you're using older versions of Slack it just shows all messages in-line instead. Very well-executed.

qqq09:01:14

I'm trying to create a project using [org.clojars.nicolaus/cljgae-template "0.2.5-SNAPSHOT"] as a template -- however, where do I put this depednency as I don't ahve a proejct.clj until I create the project ?

dominicm09:01:31

qqq: I think you're trying to use lein new, like lein new cljgae-template

nooga12:01:06

@geoffs @joshjones It puzzles me why my version is reasonably fast. I couldn’t come up with anything that would be significantly better in terms of performance.

cgrand13:01:16

@nooga: laziness (filter and remove resulting seqs are not realized) and, once you get past this, range seqs are specialized (depends on clojure version).

nooga13:01:23

@cgrand but then, when the resulting vector of 2 lists gets realized, filter and remove still execute one after another I think?

cgrand13:01:20

=> (map realized? ((juxt (partial filter odd?) (partial remove odd?)) (range 5)))
(false false)

cgrand13:01:13

=> (let [[a b] ((juxt (partial filter odd?) (partial remove odd?)) (range 5))]
     (doall b)
     [(realized? a) (realized? b)])
[false true]

nooga13:01:49

so this would be an eager implementation then: (reduce (fn [[t f] x] (if (odd? x) [(conj t x) f] [t (conj f x)])) [] (range 10))

cgrand13:01:12

yes which is more or less group-by

nooga13:01:31

I actually ended up rewriting my algorithm so that it just uses group-by instead of filter/`remove`. Thanks @cgrand !

cgrand13:01:50

For the record, using xforms: (x/transjuxt [(comp (filter odd?) (x/into [])) (comp (remove odd?) (x/into []))] (range 10)) more like your initial attempt or (x/into {} (x/by-key odd? (x/into [])) (range 10)) (like group-by but usually faster)

nooga13:01:02

thanks, I stumbled upon xforms but haven’t tried yet 🙂

borkdude15:01:15

What’s the reason I have to call seq here: (shuffle (seq {:a 1 :b 2}))

gfredericks15:01:41

I suspect shuffle is skeptical about the fact that you gave it an unordered collection

gfredericks15:01:17

I assume nth has similar hang-ups, for example

bronsa15:01:31

shuffle works with java Collections, not clojure IPersistentCollections, and for some reason clojure maps don't implement the Collection interface

gfredericks15:01:52

same with sets?

bronsa15:01:59

sets do implement Collection

tbaldridge15:01:49

yeah that is kindof odd. Although on my box: (shuffle #{1 2 3}) = [1 2 3]

tbaldridge15:01:58

So yeah...garbage in, garbage out.

bronsa15:01:55

I don't think that's GIGO

bronsa15:01:00

user=> (shuffle #{1 2 3})
[3 1 2]
user=> (shuffle #{1 2 3})
[2 3 1]

tbaldridge15:01:13

yeah, I ran it again

tbaldridge15:01:38

and it changed, but still I'm not sure what shuffle is supposed to do if something is unordered to begin with. Perhaps just return the argument? lol

gfredericks15:01:03

an unordered collection is not necessarily something that will give you its elements in a random order

gfredericks15:01:18

presumably it almost never is

gfredericks15:01:33

it just gives them to you in a weird order

gfredericks15:01:59

so if what you want is random, then shuffle would be a reasonable function to use

tbaldridge15:01:56

yeah, and considering shuffle is based off of random, I suppose it's fine.

Matt Butler15:01:19

(seq #{1 2 3})
=> (1 3 2)
Consistently, in which case I assume you are just shuffling the sequence (1 3 2) each time

lxsameer15:01:45

hey folks, What is the right way to catch the control-c event ( or handling POSIX signals ) ?

borkdude15:01:54

yes, I wanted random, not weird 😉

arkh15:01:35

I can't seem to figure out why a multiline regex isn't working:

arkh15:01:38

^ shouldn't return nil, right?

rauh15:01:05

I think you also need the ?s flag

rauh15:01:13

So the . matches the newlines.

arkh15:01:38

yes! that did it, thank you

arkh15:01:15

and there the documentation is, clearly stating I needed the 's' : /

lxsameer15:01:38

@rauh un fortunately that code didn't help me

jdkealy15:01:37

Hi, perhaps this is more of a programming question and less a clojure question, but I'm trying to copy a Ruby implementation to generate a signed URL for some API that doesn't have a clojure SDK. I see in their code they're calling SHA1.digest("xyz") and that returns something that looks like this "\x1F\xBE\xB7wtV<\xC6\xB6\xE7\xEC}\x19\xABA\xD2\x16\xDE\x94\x85". .Ruby also has a mehtod hexdigest that returns a regular string with no backslashes. I can't seem to find an sha1 library that returns a digest that looks like above, and furthermore i have the slightest knowledge of what any of this means. What is the above with backslashes?

lxsameer15:01:20

@jdkealy that's the representation string of you digest

jdkealy15:01:40

then what's hexdigest ?

lxsameer15:01:01

hexdigest is the hexadecimal representation of you digest

lxsameer15:01:08

for example

jdkealy15:01:37

is there a clojure lib that will give me the string representation ?

lxsameer15:01:54

you don't need that

lxsameer16:01:10

if you have the digest already you can use it

jdkealy16:01:28

in ruby they do Base64.urlsafe_encode64(Digest::SHA1.digest(to_sign + secret))[0,8]

jdkealy16:01:35

i'm trying to achieve the same thing with pandect's sha1 algo

joshjones16:01:46

a google search for “clojure sha library” turned this up, not sure if it will be useful to you: https://github.com/tebeka/clj-digest and this: http://stackoverflow.com/questions/31729163/clojure-or-java-equivalent-to-rubys-hmac-hexdigest

lxsameer16:01:22

@jdkealy you don't have to do the same thing

lxsameer16:01:47

AFAIK Base64.urlsafe_encode64 method works with both digest and hexdigest

Alex Miller (Clojure team)16:01:57

I’m doing some sha stuff right now and using org.apache.commons.codec.digest.DigestUtils/shaHex

Alex Miller (Clojure team)16:01:03

which is from dep [commons-codec "1.7"]

octahedrion16:01:28

with Spec, is there a way to specify a generator for a part of a spec when it depends on another part (e.g. when numbers need to sum to 1)

gfredericks16:01:59

you probably need to specify a generator for the larger structure

gfredericks16:01:48

it'd be useful in this case for spec to have a helper for modifying the default generator for a spec, but I don't think it does

gfredericks16:01:10

(in that case you could just pass it to gen/fmap and tweak the generated value however you like)

jdkealy16:01:51

@lxsameer i copied the implementation and something's not quite right. i'm using clj-digest library

jdkealy16:01:49

using this lib for b64 [clojure.data.codec.base64 :as b64]

jdkealy16:01:05

the resulting "signed" variable looking like "s--N2E5M2Uy-" whereas in ruby it comes out looking as "s--epPiduos--"

octahedrion16:01:45

@gfredericks ah yes fmap and such-that - cheers!

lxsameer16:01:45

@jdkealy I'm not an expert on this matter but your function makes sense

gfredericks18:01:00

@tbaldridge How do you get the default generator though?

tbaldridge18:01:19

(s/gen :foo)

tbaldridge18:01:35

or maybe I don't understand the question

tbaldridge18:01:25

seems like a global override for the generator of a spec would be a bad idea

tbaldridge18:01:32

instead alias and give it a new generator

hiredman18:01:18

@jdkealy you are base64 encoding the hex encoding of the sha1 (or whatever string representation sha-1 returns) not the actual bytes of the sha1

gfredericks18:01:52

@tbaldridge the problem is when using s/with-gen to define a new spec -- calling s/gen requires repeating the spec expression, which much be larger than :foo

gfredericks18:01:16

A simple helper function would suffice.

gfredericks18:01:25

It's not a huge deal

tbaldridge18:01:48

@gfredericks well you can create an alias (s/def ::foo ...) (s/def ::bar (s/spec ::foo ...newgen..)

gfredericks18:01:37

Yeah. You might not want two names though

borkdude19:01:57

I’m parsing XML and encounter some invalid characters (while using clojure.data.xml). Is there a recommended way to strip these characters in clojure/Java? Maybe some commons library has a function for this?

geoffs19:01:23

@borkdude, like improperly escaped ampersands and such? I've had similar issues with html content inside of xml, and I've just "sanitized" via a potentially too-clever regex...

borkdude19:01:39

@geoffs there is an invalid unicode character in the input. I’ve discovered something like this in one of our dependencies though: (com.ximpleware.parser.XMLChar/isInvalidChar (int \a)), could use that

geoffs19:01:05

oh interesting. :thumbsup:

beppu19:01:52

@borkdude Maybe you could do something like http://stackoverflow.com/a/14323524 (ported to clojure of course). Regexp it out.

borkdude19:01:35

@beppu I might use that if this function I found isn’t performant enough, thanks

beppu19:01:08

Who is giving you invalid XML to start with? Maybe you could solve this problem earlier in the pipeline.

borkdude19:01:35

it’s coming from the internets

nooga19:01:02

ha, the dreaded wire

borkdude19:01:32

regex is much faster

borkdude19:01:41

What does it mean when people react with a camel? 🙂

beppu19:01:54

It was an allusion to Perl, (in)famous for its regexps.

zane19:01:03

Was just about to say.

rcanepa22:01:40

Hi everyone! I'm stuck trying to understand why the instance? isn't working as I expect. I have a function (error handler), which receives and error, and according to the type/class of the error, it do some work. I made a function which prints the type of the error, and also the result of applying instance? to that error object. This is the function:

rcanepa22:01:53

And this is the result:

Alex Miller (Clojure team)22:01:02

you don’t need (class e) - just use e

Alex Miller (Clojure team)22:01:00

(instance? WebServiceException e)

rcanepa22:01:08

Ufff... right. Thank you Alex.

dotemacs22:01:15

I’ve been waiting for this for a while and finally it’s out: http://github.com/aphyr/dom-top specifically this: https://github.com/aphyr/dom-top/blob/master/src/dom_top/core.clj#L126 Figured that it needs a bigger audience

dotemacs23:01:34

@beppu yea, good point. But all excited about letr 🙂 nifty

beppu23:01:58

letr is cool.