2015-05-17
| 00:26 | tmtwd | is there a way to load files in the repl |
| 00:26 | tmtwd | ? |
| 00:26 | tmtwd | like :l hello.clj? |
| 00:56 | crocket | (:hell worlds) |
| 01:07 | heurist | tmtwd: (doc load-file) |
| 01:08 | tmtwd | thanks |
| 01:51 | ffwacom | brap cunts |
| 01:53 | crocket | cunt |
| 02:36 | chomwitt | can i ask a question about the ring library ? |
| 02:37 | andyf | ~ask |
| 02:37 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 02: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? |
| 03:29 | TimMc | chomwitt: Well, AJAX is just regular ol' HTTP calls from the server's point of view. |
| 03:29 | TimMc | I think there's a websocket adapter for ring but I haven't looked specifically. |
| 03:33 | TimMc | chomwitt: You will probably want a routing library on top of ring, such as compojure. And I haven't played with it myself. |
| 03:33 | TimMc | ...but clojure-liberator is apparently a great way to handle a lot of the complexities of HTTP. |
| 03:40 | chomwitt | TimMc: so ring is necessary even for a websocket baset webapp |
| 03:41 | chomwitt | so i guess i'll start with ring+compojurte and http-kit |
| 03: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 |
| 03:59 | wasamasa | wat |
| 03:59 | wasamasa | well, indeed |
| 04:00 | wasamasa | guess I've always combined it with a CS-related term |
| 04:00 | wasamasa | mind you, not *that* kind of CS |
| 04:04 | TimMc | Counterstrike? |
| 04:55 | dysfun | chomwitt: if you're using websockets, you may want to look into sente. or one of aleph and core.async |
| 04:56 | dysfun | https://github.com/ptaoussanis/sente |
| 06: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? |
| 07:43 | TimMc | wei: "subscription function"? What's the context? |
| 07: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 …) |
| 07:45 | wei | TimMc: ^ |
| 07:53 | TimMc | Hmm! No idea. |
| 07:56 | wei | Thanks anyway TimMc |
| 08:09 | benhuda | hello |
| 08:09 | benhuda | i'm looking for some opinion about json web tokens and authentication with them (JWT/JWS) |
| 08:29 | TimMc | benhuda: Huh, hadn't heard about this before. Looks like it's just an HMAC standard for JSON? |
| 08: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. |
| 08:30 | benhuda | it takes me back to oauth1/oauth2 times. they used it to replace "regular" token auth with a database |
| 08:30 | benhuda | something here feels broken architecturally but i cant point a finger |
| 08:31 | benhuda | i accept that it's a good way to do 3rd party API calls, but not internally in your own arch. |
| 08:34 | TimMc | benhuda: I dunno, the only issue I see is revocation. |
| 08:35 | TimMc | If you make a call back to the auth server you're incurring a network call but you get instant revocation of authn. |
| 08:37 | TimMc | (You can have either one with OAuth.) |
| 08:46 | benhuda | TimMc see here http://lucumr.pocoo.org/2013/11/17/my-favorite-database/ |
| 08:51 | TimMc | benhuda: Our OAuth2 service at work is running into token size limits *because* we're not using a database. "Small" is relative. |
| 08:52 | TimMc | I might like to see us move to a hybrid DB/signed-token model. |
| 08:53 | TimMc | Encoded token too bug to fit in an HTTP header or URL? Shove it in a DB. |
| 08:56 | TimMc | (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...) |
| 09:00 | benhuda | TimMc i'm seeing it how you see it. |
| 09:00 | benhuda | TimMc for some reason it feels this kind of solutions are escaping reality and just postponing the solution |
| 09:01 | benhuda | 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) |
| 09:01 | benhuda | 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) |
| 09:01 | benhuda | s/now reason/no reason |
| 09:02 | TimMc | Well, every dependency on the DB might turn into an ∞ ms latency at any time. |
| 09:02 | benhuda | if that stops working and doesn't "scale" - THEN try looking at those kind of solutions |
| 09:03 | benhuda | TimMc yep, but then again that's only one of many dependencies in today's systems |
| 09:03 | benhuda | 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 |
| 09:04 | benhuda | it is over engineering, but there's no argument i can take that can shed some light at this for them |
| 09:04 | benhuda | and i really believe in convincing rather than forcing everyone to not use this anymore |
| 09:05 | benhuda | revocation is good - but then, how often do you revoke registered users |
| 09:05 | TimMc | On logout. |
| 09:05 | TimMc | (Unless there are async operations still using the token.) |
| 09:05 | TimMc | Or you use short expiries. |
| 09: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 |
| 09:07 | benhuda | 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. |
| 09:07 | benhuda | it can be done server-to-server by RPC |
| 09:07 | TimMc | And every system has its own trust boundary because they're all accessed via the web? |
| 09:07 | benhuda | it can also be done by PKI. if the accounts service signed the token and the Dashboard service validated it. |
| 09:08 | benhuda | yes, they're all accessed from the web. there is no "unifying gateway" through which all clients access features of the system. |
| 09:08 | TimMc | or a datacenter where you have lots of trusted calls between servers |
| 09:09 | benhuda | TimMc feature services such as the Dashboard expose API to any kind of client. say a mobile phone. |
| 09:09 | TimMc | *nod* |
| 09: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 |
| 09:11 | TimMc | Or a hybrid, just to make things confusing. :-P |
| 09:11 | benhuda | yep :) |
| 09:11 | benhuda | there's nothing bad in adding a signature |
| 09:11 | benhuda | i'm not sure it's all good if signing is the only security mechanism here |
| 09:11 | TimMc | (e.g. fall back to signature when only recourse) |
| 09:12 | TimMc | We've gone the signature route and it has mostly worked fine. |
| 09:12 | TimMc | 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. |
| 09:13 | TimMc | but like I said, it turns out not to be sufficient either |
| 09:14 | TimMc | 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. |
| 09:20 | TimMc | benhuda: I feel pretty comfortable with signatures. I count three failure modes: |
| 09:21 | TimMc | 1) Someone compromises the signing keys. (Irrelevant because someone could compromise the user database or accounts server just as easily.) |
| 09:22 | TimMc | 2) Someone cracks the signing keys but not by gaining access. (Unlikely, I think, but different from the network call scenario.) |
| 09:23 | TimMc | 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.) |
| 09:25 | TimMc | (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!) |
| 09:28 | benhuda | TimMc your logic is sound |
| 09: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. |
| 09:54 | crocket | I think I'll read "Clojure Programming-O'Reilly Media" after braveclojure.com |
| 09:54 | crocket | 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 | m1dnight_ | or have an abstraction to do so or something? |
| 10:26 | crocket | Does #() support a rest-param? |
| 10:27 | crocket | 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 | justin_smith | 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 | borkdude | 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 | TEttinger | 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 | borkdude | 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 | Majenful | 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 | Majenful | 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 | justin_smith | ,(map #(repeatedly % rand) [1 3]) |
| 11:39 | justin_smith | 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 | justin_smith | ,(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 | Seylerius | Well, almost everything. |
| 13:02 | Seylerius | 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 | Seylerius | "Unable to resolve symbol""" |
| 13:09 | Seylerius | 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 | justin_smith | ? |
| 13:12 | justin_smith | 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 | justin_smith | ,(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 | justin_smith | ,(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 | justin_smith | ,(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 | oddcully | 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 | oddcully | 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 | Majenful | 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 | justin_smith | 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 | michaelr` | anyone familiar with this sort of problems? |
| 14:30 | michaelr` | Caused by: java.lang.NullPointerException: null |
| 14:30 | michaelr` | 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 | bensu | it looks like you need to specify a log class |
| 14:35 | michaelr` | No |
| 14:35 | michaelr` | 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 | michaelr` | URL testProps = Log.class.getClassLoader().getResource("jetty-logging.properties"); |
| 14:40 | michaelr` | This is the line from org.eclipse.jetty.util.log.Log |
| 14:40 | michaelr` | 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 | bensu | ? |
| 14:41 | bensu | michaelr`, sorry, I missread. getClassLoader() returns null |
| 14:42 | bensu | 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 | Seylerius | 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 | Seylerius | 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 | xeqi | 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 | holo | (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 | xeqi | 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 | jtmarmon | 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 | Seylerius | 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 | jtmarmon | &(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 | Seylerius | Now how does this become non-ugly? http://ix.io/iC5 |
| 17:37 | Seylerius | Maybe break it into two functions... |
| 17:40 | xeqi | Seylerius: is that outer loop equiv to mapcat? |
| 17:43 | Seylerius | xeqi: Hmm... |
| 17:44 | Seylerius | xeqi: Here it is in two functions. I think maybe. What do you think? |
| 17:44 | Seylerius | 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 | Seylerius | xeqi: I did forget the new paste, you're right. |
| 17:48 | Seylerius | That's it. |
| 17:54 | Seylerius | xeqi: Weird. break-box-row is failing on memory overload, demanding something in the neighborhood of 150+G of memory. |
| 17:54 | Seylerius | about 190G, give or take |
| 17:54 | Seylerius | 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 | Raynes | 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 | Raynes | 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 | Raynes | xeqi: Derpthnx |
| 17:59 | Raynes | 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 | Raynes | irctc_: Okay sir those previous messages were all directed at you. |
| 18:00 | Raynes | 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 | Seylerius | 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 | Seylerius | Right. |
| 18:02 | Seylerius | And the betterment of my wallet. |
| 18:03 | Seylerius | 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 | irctc_ | 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 | Raynes | It is not designed for this purpose. |
| 18:08 | Raynes | 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 | Seylerius | 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 | Seylerius | (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 | Seylerius | 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 | Seylerius | (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 | Raynes | 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 | irctc_ | like this (map (fn [x y z] [a side-effect1 b side-effect2...]) coll) |
| 18:24 | Seylerius | Damn. It's symmetric. |
| 18:24 | Seylerius | xeqi: Your solution, when combined with my mapcat, is completely symetric. |
| 18:24 | Seylerius | (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 | Seylerius | 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 | Seylerius | From a stylistic perspective... |
| 18:41 | Seylerius | Actually, nvm |
| 18:52 | devn | hello all |
| 19:00 | Seylerius | Damn, functional programming is easier to reason about in the long run. |
| 19:01 | Seylerius | 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 | wei | 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 | wei | 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 | Seylerius | (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 | Seylerius | 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 | amalloy | 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 | Seylerius | 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 | Seylerius | 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 | Seylerius | 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 | Seylerius | Right. That makes sense. |
| 20:12 | Seylerius | 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 | Seylerius | 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 | amalloy | ,(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 | Seylerius | What about slicing? |
| 20:15 | Seylerius | That's the other main thing I use. |
| 20:15 | Seylerius | 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 | Seylerius | I get how with a transpose I can get columns out of a sheet. |
| 20:17 | Seylerius | But getting sheets out of the cube, along an arbitrary axis, is a tougher one. |
| 20:18 | Seylerius | 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 | Seylerius | 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 | Seylerius | And then you branch on ambiguities. |
| 20:25 | Seylerius | amalloy: So, I just need to be able to, from an arbitrary direction, turn a 9x9x9 into a succession of 9x9s. |
| 20:26 | Seylerius | And reliably be able to put them back together. |
| 20:26 | Seylerius | Maybe a 3d transpose would do it. |
| 20:26 | Seylerius | Being able to essentially rotate the whole cube before slicing it. |
| 20:29 | Seylerius | TimMc: Any ideas on how to transpose in three dimensions? |
| 20:29 | Seylerius | (In a reversible way?) |
| 20:30 | Seylerius | Ah, fuck it. I |
| 20:30 | Seylerius | 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 | 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: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 | devn | but... |
| 20:48 | devn | ,(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 | devn | ,(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 | devn | these work in my repl |
| 20:50 | devn | ,*clojure-version* |
| 20:50 | clojurebot | {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true} |
| 20:50 | devn | oh, transducers? |
| 20:52 | devn | 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 | devn | not the most previous one, that's my bad |
| 20:55 | devn | 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 | Seylerius | 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 | xeqi | 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 | devn | perhaps |
| 20:58 | devn | ah yes, that's what happened |
| 20:58 | devn | d'oh |
| 20:58 | devn | 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 | Seylerius | 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 | devn | 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 | Seylerius | 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 | TimMc | Welcome to the club, kiddo. |
| 22:17 | Seylerius | xeqi: Not at the moment. |
| 22:17 | Seylerius | Need to gen one of those. |
| 22:17 | Seylerius | 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 | Seylerius | Yep |
| 22:25 | Seylerius | 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 | Seylerius | 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 | aravind | complicated alts!! ? |
| 22:29 | justin_smith | aravind: clojure or clojurescript? |
| 22:30 | justin_smith | 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 | aravind | 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 | justin_smith | like, if you can actually be notified of the thing you are waiting for |
| 22:45 | justin_smith | 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 | aravind | there is no real event to wait for. |
| 22:46 | justin_smith | yeah, just use sleep |
| 22:46 | aravind | cool. |
| 22:46 | aravind | 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 | kristof | 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 | aravind | 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 | kristof | 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 | aravind | 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 | kristof | 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 | Seylerius | Ah, crap. It worked in the repl, but I must've made a typo bringing it to the code. |
| 23:24 | Seylerius | Nope, it works, I forgot a step when testing it. |
| 23:24 | Seylerius | Okay. |
| 23:25 | Seylerius | http://ix.io/iCu |
| 23:25 | Seylerius | amalloy: That works. |
| 23:25 | Seylerius | It's kinda ugly, though. |
| 23:30 | Seylerius | 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 | Seylerius | 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 | Seylerius | Basically |
| 23:42 | xeqi | (assoc [:a :b :c] 1 :d) |
| 23:42 | xeqi | &(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 | Seylerius | 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 | Seylerius | Great. This code (http://ix.io/iCw) returns this error (http://ix.io/iCx). |
| 23:57 | Seylerius | build-branch works, and smallest-2d works. |
| 23:58 | Seylerius | 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 | amalloy | you probably meant to be calling it on a vector |