#clojure log - May 17 2015

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:26 tmtwd: is there a way to load files in the repl

0:26 ?

0:26 like :l hello.clj?

0:56 crocket: (:hell worlds)

1:07 heurist: tmtwd: (doc load-file)

1:08 tmtwd: thanks

1:51 ffwacom: brap cunts

1:53 crocket: cunt

2:36 chomwitt: can i ask a question about the ring library ?

2:37 andyf: ~ask

2:37 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

2:39 chomwitt: :-). i want to start experimenting with a webapp (i mean using websockets or ajax?) . does 'ring' support that or is just for post-get traditional websites?

3:29 TimMc: chomwitt: Well, AJAX is just regular ol' HTTP calls from the server's point of view.

3:29 I think there's a websocket adapter for ring but I haven't looked specifically.

3:33 chomwitt: You will probably want a routing library on top of ring, such as compojure. And I haven't played with it myself.

3:33 ...but clojure-liberator is apparently a great way to handle a lot of the complexities of HTTP.

3:40 chomwitt: TimMc: so ring is necessary even for a websocket baset webapp

3:41 so i guess i'll start with ring+compojurte and http-kit

3:57 TimMc: By the way, careful about web searches for liberator -- that's also a brand of sex furniture. Add the keyword "clojure" to be sure. :-P

3:59 wasamasa: wat

3:59 well, indeed

4:00 guess I've always combined it with a CS-related term

4:00 mind you, not *that* kind of CS

4:04 TimMc: Counterstrike?

4:55 dysfun: chomwitt: if you're using websockets, you may want to look into sente. or one of aleph and core.async

4:56 https://github.com/ptaoussanis/sente

6:28 wei: re-frame question: why does a subscription function get an atom, when it’s supposed to be read-only? why not just receive value?

7:43 TimMc: wei: "subscription function"? What's the context?

7:45 wei: I’m talking about subscriptions in Day8/re-frame. https://github.com/Day8/re-frame. He has an example of a subscription function toward the middle of the page, (defn greet …)

7:45 TimMc: ^

7:53 TimMc: Hmm! No idea.

7:56 wei: Thanks anyway TimMc

8:09 benhuda: hello

8:09 i'm looking for some opinion about json web tokens and authentication with them (JWT/JWS)

8:29 TimMc: benhuda: Huh, hadn't heard about this before. Looks like it's just an HMAC standard for JSON?

8:30 benhuda: TimMc yes. it didn't come up on my radar, and i just go to manage this new team who sprinkled this all over the place in their microservice arch.

8:30 it takes me back to oauth1/oauth2 times. they used it to replace "regular" token auth with a database

8:30 something here feels broken architecturally but i cant point a finger

8:31 i accept that it's a good way to do 3rd party API calls, but not internally in your own arch.

8:34 TimMc: benhuda: I dunno, the only issue I see is revocation.

8:35 If you make a call back to the auth server you're incurring a network call but you get instant revocation of authn.

8:37 (You can have either one with OAuth.)

8:46 benhuda: TimMc see here http://lucumr.pocoo.org/2013/11/17/my-favorite-database/

8:51 TimMc: benhuda: Our OAuth2 service at work is running into token size limits *because* we're not using a database. "Small" is relative.

8:52 I might like to see us move to a hybrid DB/signed-token model.

8:53 Encoded token too bug to fit in an HTTP header or URL? Shove it in a DB.

8:56 (Revocations can also be managed by sending hashes or IDs of tokens off to a DB asynchronously and then distributing revocation lists to all your consuming servers, but that adds complexity too...)

9:00 benhuda: TimMc i'm seeing it how you see it.

9:00 TimMc for some reason it feels this kind of solutions are escaping reality and just postponing the solution

9:01 I see now reason why you can't incur a 1-5ms DB query at worst (better cases using k/v store or inmemory k/v provisioning)

9:01 and then if other microservices need to identify a user, make a service-to-service call via some kind of fast RPC (pb/thrift/zmq)

9:01 s/now reason/no reason

9:02 TimMc: Well, every dependency on the DB might turn into an ∞ ms latency at any time.

9:02 benhuda: if that stops working and doesn't "scale" - THEN try looking at those kind of solutions

9:03 TimMc yep, but then again that's only one of many dependencies in today's systems

9:03 it's just that i'm facing this team now who is in love with this kind of solution and they want to stick tokens and signing literally everywhere

9:04 it is over engineering, but there's no argument i can take that can shed some light at this for them

9:04 and i really believe in convincing rather than forcing everyone to not use this anymore

9:05 revocation is good - but then, how often do you revoke registered users

9:05 TimMc: On logout.

9:05 (Unless there are async operations still using the token.)

9:05 Or you use short expiries.

9:06 benhuda: the context is this - accounts service is responsible for registration, it will give you a token to use with APIs for other services of the system. you then take this token and for every system, you need to carry it along. every such system needs to make sure you are registered and valid before letting you in

9:07 so every "feature" system, let's say your Dashboard service, will take your token - will need to "ask" the accounts service if you are valid by handing it the token.

9:07 it can be done server-to-server by RPC

9:07 TimMc: And every system has its own trust boundary because they're all accessed via the web?

9:07 benhuda: it can also be done by PKI. if the accounts service signed the token and the Dashboard service validated it.

9:08 yes, they're all accessed from the web. there is no "unifying gateway" through which all clients access features of the system.

9:08 TimMc: or a datacenter where you have lots of trusted calls between servers

9:09 benhuda: TimMc feature services such as the Dashboard expose API to any kind of client. say a mobile phone.

9:09 TimMc: *nod*

9:10 benhuda: so the two models are: a feature service checks with the accounts service "under the counter", or the accounts service signs the token while the feature service verifies it

9:11 TimMc: Or a hybrid, just to make things confusing. :-P

9:11 benhuda: yep :)

9:11 there's nothing bad in adding a signature

9:11 i'm not sure it's all good if signing is the only security mechanism here

9:11 TimMc: (e.g. fall back to signature when only recourse)

9:12 We've gone the signature route and it has mostly worked fine.

9:12 The signing keys last long enough that even when there is network trouble, resource servers can still authorize inbound requests, and that has been very valuable.

9:13 but like I said, it turns out not to be sufficient either

9:14 Sign-only also means you need short token lifetimes (unless you have revoke-on-logout, which is a whole 'nother problem!) so long-running operations get into trouble.

9:20 benhuda: I feel pretty comfortable with signatures. I count three failure modes:

9:21 1) Someone compromises the signing keys. (Irrelevant because someone could compromise the user database or accounts server just as easily.)

9:22 2) Someone cracks the signing keys but not by gaining access. (Unlikely, I think, but different from the network call scenario.)

9:23 3) The cryptography or trust model is wrong, and someone can replay, coin, modify, or otherwise subvert the token system due to a design flaw. (Most likely scenario, but largely avoided by using a popular standard and library.)

9:25 (On point 1... this suggests not using a symmetric key distributed to the consuming servers, because that increases the number of places a compromise could occur. On the other hand, asymmetric crypto is pretty computationally expensive!)

9:28 benhuda: TimMc your logic is sound

9:42 crocket: I'm getting a feeling that the way "Chas Emerick, Brian Carper, Christophe Grand-Clojure Programming-O'Reilly Media (2012)" explains things is close to reference manual.

9:54 I think I'll read "Clojure Programming-O'Reilly Media" after braveclojure.com

9:54 Not really a good introduction to clojure...

10:04 m1dnight_: Is there a way on clojure for a thread to read out the value of another threads threadlocal variables? (readonly)

10:04 or have an abstraction to do so or something?

10:26 crocket: Does #() support a rest-param?

10:27 Oh yes, %&

10:41 surrealanalysis: Is there a way to reload leiningen dependencies while using cider, via cider-jack-in?

10:42 justin_smith: surrealanalysis: you can add new ones, but you can't update to newer versions

10:42 without restarting clojure

10:44 surrealanalysis: Is there a function to run that makes them available? I added clojurewerkz.neocons to my project.clj, but in cider after doing a lein deps from the command line, I still get “FileNotFoundException Could not locate clojurewerkz/neocons/rest__init.class”

10:45 justin_smith: surrealanalysis: you can use pallet/alembic to load any new deps from project.clj

10:45 surrealanalysis: Awesome, thanks

10:45 justin_smith: it's also possible, but a little more complicated to do, with pomegranate

10:45 surrealanalysis: I’ll check that out

10:45 justin_smith: surrealanalysis: for future reference, the function is alembic.still/load-project

10:46 surrealanalysis: I appreciate it. Though I was originally hoping to not reload at all, this definitely helps for future times this comes up

10:53 justin_smith: yeah, alembic is one item that will always be in my profiles.clj (along with criterium and clojure.trace)

10:57 allenj12: is there a common math library where I can get simple functions e^nth

10:57 justin_smith: ,(Math/exp 2.0)

10:58 clojurebot: 7.38905609893065

10:58 justin_smith: http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html

10:58 borkdude: cider says: "Please, install (or update) cider-nrepl 0.8.2 and restart CIDER". but I have cider-nrepl 0.8.2...

10:58 https://www.dropbox.com/s/uqu4bnek6svs2m6/Screenshot%202015-05-17%2016.57.37.png?dl=0

10:58 allenj12: justin_smith: thanks

10:59 borkdude: screenshot here http://postimg.org/image/i2wghig8j/

11:03 TEttinger: allenj12: also numeric-tower is a nice lib that takes math fns and makes them work with clojure ratios and other types

11:03 https://github.com/clojure/math.numeric-tower

11:04 allenj12: TEttinger: thats what i originally go to, but the exp function forced 2 arguments and was wondering if there was anything else because of that

11:04 justin_smith: ,Math/E

11:04 clojurebot: 2.718281828459045

11:05 borkdude: it's probably a lein ring problem

11:09 lein ring still depends on nrepl 0.2.3, that may cause problems? https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/server.clj#L43

11:30 Majenful: Hello there

11:32 I saw a piece of code on ruby lang website, there is 2 arrays (foo = %w[a b c d] and bar %w[b c]), and with foo - bar the output is %w[a d]

11:33 I tested with vector, it works with this code: (clojure.set/difference (set foo) (set bar)), is there a better code ?

11:38 allenj12: hmm i have a style qusestion... I want to write a function (map #(repeatedly % #(rand)) [1 3]) say for example, however clojure does not let you have nested #() is there a way to do this whle keeping this a one liner?

11:39 justin_smith: use fn

11:39 ,(map #(repeatedly % rand) [1 3])

11:39 or just use rand

11:39 clojurebot: ((0.15493350293339403) (0.07908483961278112 0.6330284451347732 0.38239825150370765))

11:40 justin_smith: in the example case rand is already the function you want so there is no need to construct one, but more generally, use fn

11:40 ,(map (fn [i] (repeatedly i rand)) [1 3])

11:40 clojurebot: ((0.6449643600828655) (0.44102695938111813 0.5327623466180637 0.7406192877830506))

11:46 allenj12: justin_smith: alright

13:02 Seylerius: Damnit. Trying to test my work in CIDER, but it's failing. This (http://ix.io/iBB) is getting "Unable to resolve symbol" errors on everything.

13:02 Well, almost everything.

13:02 numbers and sample-2d resolve, but blank-square, doesn't resolve in sample-2d's resolution

13:07 xeqi: Seylerius: clojure evaluates the file in order. In his case sample-2d is trying to use blank-square, but blank-square is not defined yet. I'd move sample-2d below blank-square

13:08 Seylerius: It also didn't resolve (-main), which doesn't use anything.

13:08 xeqi: what do you mean by resolve?

13:08 Seylerius: But, strangely, that fixed (-main) too

13:08 "Unable to resolve symbol"""

13:09 But it's fixed now, thanks.

13:09 xeqi: when you try to ...? load-file, jump-to-symbol, etc?

13:10 justin_smith: Seylerius: like I said last night, the definition of blank-square needs to be before the definition of sample-2d

13:10 Seylerius: I must've missed that bit.

13:10 justin_smith: this has nothing to do with cider. Clojure does not look ahead in files while compiling.

13:10 Seylerius: Yeah, I see that in my logs, totally missed it.

13:10 Majenful: any words for my question about vectors ?

13:10 Seylerius: I was _tired_ last night.

13:11 justin_smith: Majenful: is order in the output important

13:11 ?

13:12 if no, use the two sets approach, if yes use (filterv (set coll2) coll1) or filter rather than filterv if you don't need the output to be a vector

13:12 ,(filterv #{:a :b :c} [:x :y :a :g :b :c])

13:12 clojurebot: [:a :b :c]

13:13 justin_smith: err, sorry, removev

13:13 ,(removev #{:a :b :c} [:x :y :a :g :b :c])

13:13 clojurebot: #error {\n :cause "Unable to resolve symbol: removev in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: removev in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: removev i...

13:13 Majenful: justin_smith: I would like but it's not important

13:13 justin_smith: erm...

13:13 ,(remove #{:a :b :c} [:x :y :a :g :b :c])

13:13 clojurebot: (:x :y :g)

13:31 Majenful: justin_smith: but your solution cannot "compare" 2 vectors ? In fact, I want to get the element not in the other vector

13:36 oddcully: Majenful: look at clojure.set/difference

13:40 Majenful: or just complement the solution from justin_smith from above: ,(filterv (complement (set [:a :b :c])) [:a :x :b :c :y :z])

13:40 clojurebot: you're on vacation or what?

13:40 clojurebot: Gabh mo leithscéal?

13:49 Majenful: oddcully: I already used clojure.set/difference (clojure.set/difference (set foo) (set bar)), but I wonder if there was a shorter code, or without having to transform into seq before testing the difference

13:49 anyway, thanks for the help :)

14:01 justin_smith: Majenful: the remove version gives you the elements in the second arg that are not in the first set

14:01 turn your se3cond arg into a set, make it the first arg to remove

14:07 michaelr`: hi

14:12 xeqi: hello

14:29 michaelr`: trying to run some stuff which starts an embeded jetty, when executing from Clojure the jetty code fails on NPE after getting a null from getClassLoader(), when ran from java works ok

14:29 anyone familiar with this sort of problems?

14:30 Caused by: java.lang.NullPointerException: null

14:30 at org.eclipse.jetty.util.log.Log$1.run (Log.java:94)

14:34 bensu: michaelr`: are you starting it from java with special options?

14:35 it looks like you need to specify a log class

14:35 michaelr`: No

14:35 not starting with special options

14:36 bensu: michaelr`, have you setup custom logging?

14:38 michaelr`: not sure.. I have log4j.xml if that's what you mean

14:39 URL testProps = Log.class.getClassLoader().getResource("jetty-logging.properties");

14:40 This is the line from org.eclipse.jetty.util.log.Log

14:40 getClassLoader() returns null when called from Clojure and the system class loader when called from java

14:40 bensu: michaelr`, that is line 94? So Clojure can't find the class Log

14:40 ?

14:41 michaelr`, sorry, I missread. getClassLoader() returns null

14:42 michaelr`, not sure I can help, I have no knowledge of Class Loaders

14:44 michaelr`: thanks anyway!

15:22 wei: I have a build that works with cljsbuild but not with figwheel. Any tips on troubleshooting? Here’s the project.clj: https://gist.github.com/yayitswei/317dfec919d01e67fb4c

15:46 Seylerius: Is there a good reason why (= sample-2d (resheet-rows (sheet-rows sample-2d))) would be false using this code? http://ix.io/iBV

15:52 amalloy: the & in resheet-rows makes me think you might need (apply resheet-rows ...), but if that's not it you'll need to find someone who knows anything about core.matrix

16:05 Seylerius: amalloy: That's totally it.

16:05 Thanks.

16:08 borkdude: why is rename-keys in clojure.set?

16:14 Seylerius: Grr... Still not working.

16:17 gfredericks: borkdude: clojure.set would get lonely otherwise

16:54 holo: hi

16:55 Seylerius: amalloy: Okay, that's stupid and annoying, and makes testing difficult. I simplified the data a wee bit, and the string representations are identical, even though they don't test as equal.

16:56 holo: defn is forgiving about doc-string and params order. is it considered bad style to use params before doc-string?

16:56 Seylerius: There's something stupid in the optimizations the damn thing's using that keeps identically structured matrices from equating.

17:03 Okay. How do I chop a 9x9 into 9 3x3s, in box form?

17:05 jtmarmon: hey there - i'm trying to do some basic logging on an import job via "prn", but it seems the output doesn't go to the screen until the thread is done executing. is there a way I can send the data to the screen via a background thread so i can watch the logs as the process executes

17:08 Seylerius: Okay, better question: what will let me take [:a :b :c :d :e :f :g :h :i] and return [[:a :b :c] [:d :e :f] [:g :h :i]]?

17:09 amalloy: &(doc partition)

17:09 lazybot: ⇒ "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to comple... https://www.refheap.com/101228

17:11 xeqi: holo: doc-strings go before params. If you put the string after the params then your using the string as part of the function body, not as a doc-string

17:13 jtmarmon: are you running this via a future, a (Thread. ..), or another mechanism ?

17:13 jtmarmon: xeqi: it's simply a bunch of cascading function calls. there's no multi threading currently

17:13 Seylerius: amalloy: Thanks

17:14 holo: xeqi: oh yes :> haha thanks

17:14 (inc xeqi)

17:14 lazybot: ⇒ 16

17:15 jtmarmon: should I just have my printlns be wrapped in a function and dispatched asynchronously (.start (Thread. (fn [] (prn "hi!")))?

17:18 xeqi: I'm surprised its not working if your not currently doing any threading currently

17:20 jtmarmon: xeqi: it's not :P. would that be the right solution to handle logging then?

17:22 xeqi: nope, trying to use Thread. will cause problems due to *out* and its binding. future would be better since it sets the dynamic vars up right, but I still don't think thats the right solution.

17:23 I would have thought flushin to be a problem, but prn is suppose to do that

17:23 Seylerius: How do I take (nthrest row 3) of each row in coll?

17:24 xeqi: so as long as *flush-on-newline* is true, I don't have any idea why your not seeing output until the very end. I definitly wouldn't want to introduce multithreading to try so solve it, I'd expect that would just make things worse

17:25 jtmarmon: yep it's true

17:26 Seylerius: you mean you want [[1 2 3] [4 5 6] ...] -> [3 6]?

17:28 Seylerius: jtmarmon: [[:a :b :c :d :e :f :g :h :i] [:a :b :c :d :e :f :g :h :i]] ==> [[:d :e :f :g :h :i] [:d :e :f :g :h :i]]

17:28 And I'll also need [:a :b :c :a :b :c]

17:29 jtmarmon: &(doc take-last)

17:29 lazybot: ⇒ "([n coll]); Returns a seq of the last n items in coll. Depending on the type of coll may be no better than linear time. For vectors, see also subvec."

17:29 jtmarmon: (map #(take-last n %) data)

17:32 Seylerius: jtmarmon: Yeah, that's it.

17:32 jtmarmon: if you want the first half as well, you can use:

17:32 &(doc split-at)

17:32 lazybot: ⇒ "([n coll]); Returns a vector of [(take n coll) (drop n coll)]"

17:33 Seylerius: Need them in different spots, so I'll probably map a #(drop-last n %) over it for that, and reduce it into a vector.

17:36 Now how does this become non-ugly? http://ix.io/iC5

17:37 Maybe break it into two functions...

17:40 xeqi: Seylerius: is that outer loop equiv to mapcat?

17:43 Seylerius: xeqi: Hmm...

17:44 xeqi: Here it is in two functions. I think maybe. What do you think?

17:44 Maybe I can reduce the whole loop of sheet-boxes into mostly just a mapcat of break-box-row?

17:46 xeqi: Seylerius: think you forgot a new paste

17:47 Seylerius: http://ix.io/iC7

17:48 xeqi: I did forget the new paste, you're right.

17:48 That's it.

17:54 xeqi: Weird. break-box-row is failing on memory overload, demanding something in the neighborhood of 150+G of memory.

17:54 about 190G, give or take

17:54 Wait...

17:55 xeqi: Seylerius: I can't reason about what its doing. why is (map #(take-last 6 %) box-row) the new value thats checked for loop termination

17:55 Seylerius: No, that's 295M

17:55 Raynes: Clojuresque could use a wee tad bit of documenting huh

17:55 Sure wish I knew shit about gradle, it'd make this much easier.

17:56 irctc_: I am calling map over a collection. The function that process the items of the collection has side effects. If I use dorun on the map it does not realizes the map, but if I omit the dorun the map executes. Why is that? Should not be the other way around.

17:56 Raynes: Do you return a collection of values from the map?

17:57 Because if not, use doseq instead.

17:57 Seylerius: What it's supposed to do is take a 9x3, break it into 3x3s, and give back the 3x3s as 9x1s.

17:58 Raynes: So it does return a collection of values, just those values are the result of a function that performs side effects to produce them?

17:58 Seylerius: Raynes: I want to take a sudoku sheet and return the 3x3 boxes as 9x1 vectors

17:59 xeqi: Raynes: 2 different conversations

17:59 Raynes: Oh, this shitty irc client.

17:59 xeqi: Derpthnx

17:59 Probably would have carried on real confused for a while.

17:59 xeqi: I was tempted....

17:59 Raynes: I'll hurt you

18:00 irctc_: Okay sir those previous messages were all directed at you.

18:00 Seylerius: I still love you but I hate sudoku and can't even

18:00 Seylerius: xeqi: That's the total goal. I have a 9x9 sudoku sheet (well, 9 of 'em), and I want to take the 3x3s out of it as 9x1s.

18:01 Raynes: It's okay, sudoku hates you too.

18:01 Raynes: You don't even know

18:01 Seylerius: Raynes: I'm making a solver. For 3d sudoku. So if you ever want to beat it into submission, this thing could probably help.

18:02 Raynes: But only if you get it working first

18:02 Seylerius: Right.

18:02 Raynes: So let's get that sorted out for the betterment of mankind.

18:02 Seylerius: I'm struggling on breaking out the boxes.

18:02 Right.

18:02 And the betterment of my wallet.

18:03 I can break the sheet into 9x3s reliably now.

18:03 irctc_: Raynes With dorun I have tried returning items and not returning them, and none of them works

18:03 It just return nil

18:04 Seylerius: xeqi: So how would you take a 9x3 and chop it into 3 3x3s?

18:05 Raynes: irctc_: The point is, if the map executes but you don't get back a return value, does it matter? Do you need to call foo on (1, 2, 3) and get back (new1, new2, new3) or will foo just do *things* and you don't care about the result?

18:05 Seylerius: xeqi: If I've got [[:a :b :c :d :e :f :g :h :i] [:a :b :c :d :e :f :g :h :i] [:a :b :c :d :e :f :g :h :i]], I need [[:a :b :c :a :b :c :a :b :c] [:d :e :f :d :e :f :d :e :f] [:g :h :i :g :h :i :g :h :i]]

18:06 Raynes: Because if you don't care about the result of the map, you should use doseq. If you do care, you should use doall

18:06 Seylerius: How does one do that?

18:06 Raynes: dorun is supposed to return nil.

18:07 irctc_: Raynes for now I do not care. But I have a use case where I care. And I care that the whole seq is never in the memory since it is too big. So I would like to make dorun work, since in the docs it says that is meant just for this.

18:07 Raynes: You cannot make dorun work.

18:07 It is not designed for this purpose.

18:08 If you want to not hold the entire seq in memory but still have the side effects happen, you're gonna have to iterate through and do things with the results one way or the other.

18:08 Seylerius: amalloy: Any idea what would turn [[:a :b :c :d :e :f :g :h :i] [:a :b :c :d :e :f :g :h :i] [:a :b :c :d :e :f :g :h :i]] into [[:a :b :c :a :b :c :a :b :c] [:d :e :f :d :e :f :d :e :f] [:g :h :i :g :h :i :g :h :i]]?

18:09 The way I'm currently doing it demands 295M and fails hard.

18:10 amalloy: how on earth can you use up 300MB on a 3x9 vector?

18:10 Raynes: Where there's a will there's a way.

18:10 Seylerius: amalloy: With this crap: http://ix.io/iC9

18:10 amalloy: anyway, it starts with (map (partial partition 3) m)

18:11 xeqi: Seylerius: somethign like (apply map concat (map #(partition 3 %) matrix)

18:12 irctc_: Raynes I am composing lazy operation together (->> map filter ...) and one of this has side effects(it writes to db and returns beck what itsaved). Is there a way to execute this chain of functions without never having the entire sequence in memory?

18:13 amalloy: i just finished writing a worse version of xeqi's solution

18:13 Raynes: Yay you're second best

18:13 amalloy: at least mine had balanced parens, though. that's a win

18:13 Raynes: irctc: Yes, you need to either throw away the results or process them and produce a smaller sequence.

18:14 Seylerius: amalloy, xeqi: Thank you both so much.

18:14 (inc amalloy)

18:14 lazybot: ⇒ 270

18:14 Seylerius: (inc xeqi)

18:14 lazybot: ⇒ 17

18:15 Seylerius: Is there a difference between (inc <nick>) and (inc <nick> )?

18:15 In fact, let's find out:

18:15 oddcully: (inc justin_smith )

18:15 lazybot: ⇒ 12

18:15 oddcully: yes

18:15 Seylerius: (inc xeqi )

18:15 lazybot: ⇒ 2

18:15 Raynes: We're not actually reading Clojure forms there.

18:15 Seylerius: Very interesting.

18:15 Raynes: It's a regex that amalloy will never get right.

18:16 oddcully: (dec justin_smith ) ; didn't deserve it

18:16 lazybot: ⇒ 11

18:16 Seylerius: I'll need to remember that when I'm tab-completing nicks for that...

18:16 (dec justin_smith ) ; Did this last night, meant to give it to the real person

18:16 lazybot: ⇒ 10

18:16 Seylerius: (inc justin_smith)

18:16 lazybot: ⇒ 254

18:20 Seylerius: Okay. The two functions do their job. Now how do I reverse them? http://ix.io/iCa

18:20 irctc_: Raynes let´s say i do not return elements from the map˙s function. dorun should still force the sequence right?

18:20 Raynes: Yes.

18:21 I know you said this was not working, but without sample code I'm afraid I can't do much beyond say I'm sorry :P

18:22 irctc_: in my case it does not. I have a fun that as body has a let which does not return anything. Can this be the problem?

18:23 like this (map (fn [x y z] [a side-effect1 b side-effect2...]) coll)

18:24 Seylerius: Damn. It's symmetric.

18:24 xeqi: Your solution, when combined with my mapcat, is completely symetric.

18:24 (inc xeqi)

18:24 lazybot: ⇒ 18

18:26 Seylerius: Take a look at the whole file, and try (matrix/array (sheet-boxes (sheet-boxes sample-2d)))

18:26 irctc_: (map (fn [x y z] (let [a side-effect1 b side-effect2...])) coll) * eh... But I think this has nothing to do with it. I will try to explore further

18:26 Seylerius: There are quirks about the NDArray implementation that prevent it from equating, but if you take the string reps and diff them, they're identical.

18:40 If you're constraining a foo-seq based on a constraint-seq, is it more clojurish to have the args go [foo-seq constraint-seq] or [constraint-seq foo-seq]?

18:40 From a stylistic perspective...

18:41 Actually, nvm

18:52 devn: hello all

19:00 Seylerius: Damn, functional programming is easier to reason about in the long run.

19:01 Is this where y'all would put the line breaks for maximum readability? http://ix.io/iCe

19:21 wei: Is there a library for helping to create REST api bindings? Seems like it would be useful

19:22 devn: wei: you mean like liberator?

19:22 wei: like the other way around- client bindings

19:22 e.g. a facebook, twitter, or youtube api wrapper

19:22 devn: what's an example from another language?

19:23 wei: devn: I’m not sure there is one. but I find myself rewriting the same patterns as I’m building these bindings, and was wondering if anyone else had generalized it

19:24 or even better— parse the docs and generate the code!

19:40 Seylerius: Damnit. I wish NDArray would test equality properly. Maybe I need the operators from core.matrix...

19:47 xeqi: Seylerius: re line breaks, consider using -> in that example

19:48 amalloy: also, (map f\n (x y)) is usually more readable than (map f (x\ny))

19:49 Seylerius: Thank you both

19:49 (inc xeqi)

19:49 lazybot: ⇒ 19

19:49 Seylerius: (inc amalloy)

19:49 lazybot: ⇒ 271

19:49 Seylerius: -> is... awesome.

19:52 xeqi: Seylerius: in this case I meant ->> since you have a bunch of (map fn ...)

19:53 Seylerius: Yeah, I noticed that.

19:53 xeqi, amalloy: How's this look? http://ix.io/iCf

19:57 amalloy: Seylerius: looks okay. have you tried factoring out the repeated calls to map constrain? it might be nicer if you did something like (let [steps [(comp sheet-columns resheet-rows) (comp sheet-boxes resheet-columns) (comp matrix/array sheet-boxes)]] (reduce (fn [sheet f] (f (map constrain sheet))) (sheet-rows sheet) steps))

19:57 that's probably not shorter, but it does separate out the tedious (map constrains) from the specialized steps

20:00 Seylerius: I could also make a constrain-rows, constrain-columns, and constrain-boxes that just does the steps for each, with a map constrain in the middle, and push the sheet through those.

20:01 amalloy: that would also be reasonable

20:03 Seylerius: amalloy: http://ix.io/iCg

20:04 Clojure <3s functions. I should remember to take advantage of that.

20:04 amalloy: Seylerius: why do you not have a funciton somehwere for (map constrain xs)?

20:05 Seylerius: A constrain-these?

20:08 amalloy: Like this? http://ix.io/iCh

20:08 amalloy: sure

20:08 Seylerius: amalloy: The point being to make the meanings fully obvious?

20:09 Rather than having to think about what mapping constrain over shit means?

20:09 amalloy: well, the point being to write things in the language of your domain. since you basically never call constrain alone, mapping constrain seems like the domain-specific thing to do

20:10 Seylerius: …And now I continue hunting for the appropriate way to make equality-testing work with an object-NDArray.

20:11 Right. That makes sense.

20:12 amalloy: Do you know anything about core.matrix? I'm trying to figure out how to check equality of the NDArrays, but it's designed to work with fscking doubles and longs, not objects.

20:13 amalloy: no. why are you using core.matrix anyway instead of just some vectors?

20:13 Seylerius: I suppose I could. Thought it might be better/faster, and I like the slices function a lot.

20:13 And the easy transpose, which makes resheet-columns work more simply.

20:14 amalloy: transpose is not hard

20:14 Seylerius: True. I could just grab a transpose out of rosetta-code.

20:14 amalloy: (apply map list '((1 2 3) (4 5 6) (7 8 9)))

20:14 ,(apply map list '((1 2 3) (4 5 6) (7 8 9)))

20:14 clojurebot: ((1 4 7) (2 5 8) (3 6 9))

20:14 Seylerius: That's not hard.

20:14 What about slicing?

20:15 That's the other main thing I use.

20:15 I basically need to work with progressively smaller-dimensioned slices (in arbitrary axes) of a 9x9x9.

20:15 amalloy: that is too vague a feature fro me to propose an alternative. what kind of slicing do you do, and why?

20:16 Seylerius: Turn a cube into sheets from each of the three axes, and slice those sheets into rows, columns, and boxes.

20:16 I get how with a transpose I can get columns out of a sheet.

20:17 But getting sheets out of the cube, along an arbitrary axis, is a tougher one.

20:18 Basically, I'm going to need (slices cube 0) (slices cube 1) and (slices cube 2) to give me the slices along each axis in turn.

20:18 amalloy: are you still talking about sudoku? this talk of cubes, axes, and sheets is bizarre

20:18 Seylerius: 3d sudoku

20:19 TimMc: amalloy: Makes sense to me -- array slicing.

20:20 Seylerius: In 3d sudoku, you could say that each square is constrained by 3 different sudoku boards: one in the X-axis, one in the Y, and one in the Z.

20:23 Solving 3d sudoku can be thought of as taking passes of "constrain slices along the x-axis", "constrain slices along y", and "constrain slices along z", followed by "fill slices along (x y z)"

20:24 And then you branch on ambiguities.

20:25 amalloy: So, I just need to be able to, from an arbitrary direction, turn a 9x9x9 into a succession of 9x9s.

20:26 And reliably be able to put them back together.

20:26 Maybe a 3d transpose would do it.

20:26 Being able to essentially rotate the whole cube before slicing it.

20:29 TimMc: Any ideas on how to transpose in three dimensions?

20:29 (In a reversible way?)

20:30 Ah, fuck it. I

20:30 I'll just study mikera's damn slices function and re-use it.

20:35 xeqi: (first cube), (apply map first cube), (map #(apply map first %&) cube) ?

20:41 Seylerius: xeqi: testing that with a 3x3x3 with toy values to see if it works

20:43 ,(def toy-cube [[[:a :b :c] [:d :e :f] [:g :h :i] [[:j :k :l] [:m :n :o] [:p :q :r]] [[:s :t :u] [:v :w :x] [:y :z :zz]]]])

20:43 clojurebot: #'sandbox/toy-cube

20:43 Seylerius: ,(first cube)

20:43 clojurebot: #error {\n :cause "Unable to resolve symbol: cube in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: cube in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: cube in this co...

20:43 Seylerius: ,(first toy-cube)

20:43 clojurebot: [[:a :b :c] [:d :e :f] [:g :h :i] [[:j :k :l] [:m :n :o] [:p :q :r]] [[:s :t :u] [:v :w :x] [:y :z :zz]]]

20:45 Seylerius: ,(def toy-cube [[[:a :b :c] [:d :e :f] [:g :h :i]] [[:j :k :l] [:m :n :o] [:p :q :r]] [[:s :t :u] [:v :w :x] [:y :z :zz]]])

20:45 clojurebot: #'sandbox/toy-cube

20:45 Seylerius: ,(first toy-cube)

20:45 clojurebot: [[:a :b :c] [:d :e :f] [:g :h :i]]

20:45 Seylerius: ,(apply map first cube)

20:45 clojurebot: #error {\n :cause "Unable to resolve symbol: cube in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: cube in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: cube in this co...

20:45 Seylerius: ,(first toy-cube)

20:45 clojurebot: [[:a :b :c] [:d :e :f] [:g :h :i]]

20:45 Seylerius: ,(apply map first toy-cube)

20:45 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/first--4107>

20:47 xeqi: ,(map first toy-cube)

20:47 clojurebot: ([:a :b :c] [:j :k :l] [:s :t :u])

20:47 devn: not really sure what you're going for here

20:47 but...

20:48 ,(apply (partial map first) toy-cube)

20:48 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/first--4107>

20:48 devn: err uhhh wait, what

20:48 xeqi: heh

20:48 devn: works in my repl

20:49 ,(apply (partial mapv pop) toy-cube)

20:49 clojurebot: #error {\n :cause "Wrong number of args (3) passed to: core/pop"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: core/pop"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 40]\n [clojure.core$map$fn__4557 invoke "core.clj" 2633]\n [clojure.lang.Lazy...

20:49 xeqi: Seylerius: do you have a 9x9 solver already?

20:49 devn: why is it breaking on this?

20:50 these work in my repl

20:50 ,*clojure-version*

20:50 clojurebot: {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}

20:50 devn: oh, transducers?

20:52 no, that's not it

20:52 Seylerius: xeqi: Very nearly. Got sidetracked by the question of "how do I know when I've blocked at an ambiguity?", which I figured I could answer with "does attempting to constrain and fill do nothing?" which blocked on the fact that core.matrix didn't want to test equality for object matrices. And so I'm tossing core.matrix, but I can only toss core.matrix if I can replace 3d slicing.

20:52 devn: ,(apply (partial mapv peek) #'sandbox/toy-cube)

20:52 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Var"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Var"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.core$seq__4125 invoke "core.clj" 135]\n [clojure.core...

20:52 devn: ,#'sandbox/toy-cube

20:52 clojurebot: #'sandbox/toy-cube

20:52 devn: ,sandbox/toy-cube

20:52 clojurebot: [[[:a :b :c] [:d :e :f] [:g :h :i]] [[:j :k :l] [:m :n :o] [:p :q :r]] [[:s :t :u] [:v :w :x] [:y :z :zz]]]

20:54 Seylerius: I suppose I could simply assume that I /can/ build 3d slicing and recomposing, and leave it for later, and toss core.matrix in the now...

20:54 devn: i don't mean to detract from the discussion, but xeqi or anyone else know why clojurebot cant handle that?

20:55 not the most previous one, that's my bad

20:55 but the arity exceptions

20:55 xeqi: devn: so the (apply (partial mapv pop) toy-cube) one?

20:55 devn: yeah

20:56 Seylerius: xeqi: Figure I ought to table the 3d-slicing for now?

20:56 And simply mark it "assumed solvable later"?

20:57 xeqi: devn: because toy-cube is a list of 3 lists. Then apply passes it to map which takes the first element of each list, and calls pop with them as the 3 arguments

20:57 did you miss the redefinition of toy-cube earlier due to a misplaced ] ?

20:57 devn: xeqi: it works in my REPL. why?

20:57 perhaps

20:57 * devn looks up

20:58 devn: ah yes, that's what happened

20:58 d'oh

20:58 xeqi: i was sitting here wondering if i was taking crazy pills

20:59 xeqi: Seylerius: well, if I was solving it (by brute force) my plan would be split along X axis. Get solutions for each 9x9 board. Then combine them into all possible cubes. Then remove them based on each board in the Y and Z directions. I'd start with the 9x9 solver as its used in both the generate and filter steps

21:08 Seylerius: xeqi: My basic strategy boils down to looping (constrain-x constrain-y constrain-z fill-axis), cycling through the axes for each pass with fill-axis. When I block on an ambiguity, I take the most-constrained unit (choosing one arbitrarily if there are multiple), and recurse the solver with each possibility for the selected unit. A solver returns one of the following [solution (solutions-returned-by-branches)], or throws an exception.

21:10 filling works both on situations where a unit has only one possibility left after being constrained, or when a given row, column, or box can only get a particular value in one location.

21:33 devn: what's the name of the clojure "fork"?

21:33 the one with the rationale

21:34 xeqi: $google dunaj clojure

21:34 lazybot: [Dunaj project · GitHub] https://github.com/dunaj-project

21:34 devn: ty

21:43 Seylerius: Okay... Recurse the solver with each step, or loop with each step?

21:43 What's going to be more efficient?

21:47 devn: ah-ha, i missed this: https://github.com/cgrand/megaref

21:55 Seylerius: Okay. Wrapping up the 2d solver. Going with recursion, rather than loops.

22:04 xeqi: Seylerius: do you have a 3d input file?

22:13 TimMc: Neat, it looks like Rust has full macros! Awkward, but full-powered.

22:14 devn: yeah, pretty cool eh?

22:15 TimMc: I'm s proud of them.

22:15 Welcome to the club, kiddo.

22:17 Seylerius: xeqi: Not at the moment.

22:17 Need to gen one of those.

22:17 Okay... I need (foo x y) for each x and y in seqx and seqy.

22:20 amalloy: (map foo xs ys)

22:20 Seylerius: Wait, map'll do that

22:20 Yep

22:25 Does this look like a sensible way to get the coords of the square with the smallest value (most constrained possibilities)? http://ix.io/iCs

22:26 All three relevant functions: http://ix.io/iCt

22:27 aravind: hi, if I have to wait for a second before doing anything else in a thread.. is there any difference (or advantage) to using (Thread/sleep 1000) vs. (async/alts!! [(async/chan) (async/timeout 1000)]) ? The general advise seems to be don't sleep in a thread, because it prevents the thread from doing anything else.. but if I don't have anything else for the thread to do.. is there any point to using the more

22:27 complicated alts!! ?

22:29 justin_smith: aravind: clojure or clojurescript?

22:30 I mean Thread/sleep is clojure, and so you can easily have more threads than you have CPUs, if you need to wait, you can just wait, right?

22:43 aravind: justin_smith: yeah, in clojure.

22:43 justin_smith: yup.. in a simple wait for x seconds type situation.

22:44 justin_smith: it's better to have an event to wait for, but a simple sleep can work too

22:45 aravind: in this case, how does waiting for an event (a fake one like the simulated alts!! thing) make it better than a sleep ?

22:45 justin_smith: no, I mean a real event

22:45 like, if you can actually be notified of the thing you are waiting for

22:45 not treating a sleep as if it were an event

22:46 aravind: well.. here its more a case of I have a problem now, I want to wait a second and retry again.

22:46 there is no real event to wait for.

22:46 justin_smith: yeah, just use sleep

22:46 aravind: cool.

22:46 thanks.

22:48 kristof: aravind: Why are you using async with multiple threads if you're pretty confident about how many threads you need and what they're going to do?

22:48 binjured: i apologize in advance for the vague question... i'm using Luminus, just running the sample app basically, which should be a super simple ring server... but it takes 30+ seconds to get the server running with `lein ring server`. is that normal?

22:48 kristof: aravind: The point of async is the ability to spawn concurrent green threads.

22:48 aravind: So when one green thread is blocked, the machine worker thread can take another task off the queue and keep doing work.

22:49 justin_smith: kristof: but he doesn't need green threads for a simple pause and retry

22:49 kristof: aravind: So in your case, there is no advantage to using alts!! over sleep. But there is also no advantage to using green threads at all.

22:49 aravind: kristof: yeah, I guess you are right.

22:50 kristof: justin_smith: Right, that's what I'm saying.

22:50 justin_smith: got it

22:50 kristof: justin_smith: I didn't see any of the conversation after "complicated alts!! ?", I disconnected

22:51 justin_smith: ahh, OK

22:51 kristof: apologies if I missed something

22:51 aravind: hrmm.. the reason I am using a go style thing is I want to kick something off in the background, and return an initial value. The background thing does it's business with waits etc.

22:52 I guess this is a case where I should be using a future, and return

22:52 justin_smith: sleep / retry in a future works for that

22:53 aravind: yeah, this whole go block is overkill for what I am doing.

22:53 kristof: Yeah, go is cool because you can spawn all teh procz and you don't race conditions, the semantics are clear, etc.

22:53 Takes and puts block until there's actually a value. Communication points are lock-proctected by default. Etc.

22:54 aravind: yeah.. somehow the whole idea that I didn't need a go block for this was never clear to me.. until I open my mouth in public and ask stupid questions.

22:54 thanks for the pointers.

22:54 kristof: CSP is so cool, actors are actually emergent from CSP. an actor can just be defined as a loop that takes from a mailbox buffered chan and dispatches on the message received

22:57 And you might say "well, can't everyone take from the mailbox? Isn't that bad?" But to that I say that that's just a feature of flexibility, and you can do all sorts of mixing and matching. Have multiple actors take from the same mailbox without needing a man in the middle to distribute messages.

23:00 Seylerius: How do you find the coords of the smallest value in a grid?

23:19 amalloy: Seylerius: create a seq of all the coords, and do something like (apply max-by #(get-in the-grid %) coord-seq)

23:20 Seylerius: amalloy: I think I've figured it out, hold on and I'll have a function for you to check out.

23:23 Ah, crap. It worked in the repl, but I must've made a typo bringing it to the code.

23:24 Nope, it works, I forgot a step when testing it.

23:24 Okay.

23:25 http://ix.io/iCu

23:25 amalloy: That works.

23:25 It's kinda ugly, though.

23:30 amalloy: What do you think of this? http://ix.io/iCv

23:35 xeqi: Seylerius: I'l be interested to see how your looks/runs when your finished

23:36 Seylerius: xeqi: Thanks

23:36 xeqi: the problem intrigued me enough to adapt https://github.com/clojure/core.logic/wiki/Examples#sudoku into a 3d solver

23:36 Seylerius: xeqi: Is there an easy way to replace a given item in a seqence?

23:37 xeqi: &(doc replace)

23:37 lazybot: ⇒ "([s match replacement]); Replaces all instance of match with replacement in s. match/replacement can be: string / string char / char pattern / (string or function of match). See also replace-first. The replacement is literal (i.e. none of its characters are treated... https://www.refheap.com/101234

23:38 xeqi: ,(replace {1 4} [1 2 3 4])

23:38 clojurebot: [4 2 3 4]

23:38 xeqi: Seylerius: ^ like that?

23:38 Seylerius: That's pretty close.

23:38 I just need to swap at an index

23:38 xeqi: ,(replace [0 4] [1 2 3 4])

23:38 clojurebot: [4 2 3 4]

23:39 xeqi: ,(replace [1 4] [1 2 3 4])

23:39 clojurebot: [4 2 3 4]

23:39 xeqi: blah

23:39 Seylerius: If coll is [:a :b :c], (replace-index coll 1 :d) ==> [:a :d :c]

23:39 Basically

23:42 xeqi: (assoc [:a :b :c] 1 :d)

23:42 &(assoc [:a :b :c] 1 :d)

23:42 lazybot: ⇒ [:a :d :c]

23:42 xeqi: Seylerius: ^

23:45 Seylerius: Yes! That's it, exactly.

23:51 What's annoying about this project, and also why it's fun (and why I can't use an existing solver), is that I need to generate _all_ solutions, rather than just one.

23:57 Great. This code (http://ix.io/iCw) returns this error (http://ix.io/iCx).

23:57 build-branch works, and smallest-2d works.

23:58 xeqi, amalloy: Any guesses as to what broke it?

23:59 amalloy: Seylerius: build-branch obviously doesn't work, the stacktrace says it is calling assoc on a seq

23:59 you probably meant to be calling it on a vector

Logging service provided by n01se.net