2013-12-21
| 00:13 | ddellacosta | can someone tell me what I'm misunderstanding here? https://www.refheap.com/22091 |
| 00:13 | ddellacosta | why can't I run the output of my macro the same way I run a normal function, if they are both PersistentLists? |
| 00:14 | alew | You are trying to run a list as a function |
| 00:15 | alew | If you called eval on (make-adder [2 2]) I think it would work |
| 00:15 | technomancy | yeah you need an eval |
| 00:16 | ddellacosta | slew, technomancy: yeah, that I already get...so let me ask a different question: is there any way for me to get something that looks like a list that I can run as a function? I suppose the answer is no |
| 00:16 | ddellacosta | slew -> alew |
| 00:16 | technomancy | wrap it in (fn [] ...) |
| 00:17 | ddellacosta | technomancy: okay, I guess that's the answer. I guess the thing I'm fundamentally not getting is why a list is a list when quoted, but becomes a function when called in the repl or in code. |
| 00:18 | alew | the list isn't a function |
| 00:18 | justin_smith | ,((fn [[f & args]] (apply f args)) (list + 1 2)) ; ddellacosta is this what you want? |
| 00:18 | clojurebot | 3 |
| 00:18 | alew | eval takes the list and performs an evaluation of it |
| 00:18 | alew | which it assumes the first element to be a function |
| 00:18 | alew | when you quote it, you esentially tell eval to ignore it |
| 00:18 | alew | and it stays as a list |
| 00:19 | ddellacosta | justin_smith: no, what I want is for me to be able to evaluate '(+ 1 1) without jumping through the hoops you're jumping through...a.k.a. for Clojure to work like my misconception of it...haha. |
| 00:19 | justin_smith | calling eval is really a heavyweight operation though, it is nice to avoid it if possible |
| 00:20 | ddellacosta | justin_smith: exactly...which is why I was hoping I could just pass a list around and call it when I wanted to. But I suppose I need to take the approach you and technomancy described. Okay, that's that...thanks technomancy, justin_smith and alew! |
| 00:28 | bitemyapp | ddellacosta: macros generate lisp data, not opaque functions. |
| 00:29 | ddellacosta | bitemyapp: doesn't that depend on the macro? |
| 00:29 | ddellacosta | bitemyapp: not trying to quibble, just not grasping what you mean by thatt. |
| 00:29 | ddellacosta | *that |
| 00:31 | tbaldridge | ddellacosta: the input and output of macros are data. Now after all macros have been run, that data may be eval'd and turned into functions, but macros do not create functions |
| 00:31 | tbaldridge | they create data that may be evaluated by the compiler as functions. |
| 00:31 | tbaldridge | , '(fn [x] 42) ; this is not a function |
| 00:31 | clojurebot | (fn [x] 42) |
| 00:31 | bitemyapp | ddellacosta: it doesn't depend on anything, it's axiomatic. |
| 00:32 | ddellacosta | bitemyapp, tbaldridge: thanks, that's a lot more clear now. |
| 00:43 | technomancy | a list doesn't really "become a function" when entered in the repl |
| 00:43 | technomancy | calling eval may be heavyweight, but it's what the repl does =) |
| 00:48 | ddellacosta | technomancy: yeah, after hearing what tbaldridge and bitemyapp were saying, I realize I was thinking...magically. None of this is stuff I didn't know but somehow I was forgetting when a macro actually does what it does. As bitemyapp said, "it's axiomatic." Now that I think back on my original question, I'm not really sure what I was thinking. |
| 00:48 | justin_smith | we had a template engine that would call eval on expressions, until we noticed the performance was shit. We switched up to read+apply and it was a big improvement |
| 00:49 | ddellacosta | but as usual, asking dumb questions on #clojure has brought me to enlightenment. ;-) |
| 00:49 | technomancy | the Magic of IRC |
| 00:49 | ddellacosta | justin_smith: ah, that's an interesting point. Why is that? |
| 00:50 | ddellacosta | technomancy: indeed. |
| 00:50 | tbaldridge | because he was only using data. No reason to eval the read forms if you only want the data |
| 00:50 | justin_smith | ddellacosta: eval has a bigger setup to do in terms of creating the evaluation context |
| 00:51 | justin_smith | tbaldridge: we were using helpers that were functions though, and allowed inline clojure |
| 00:51 | justin_smith | tbaldridge: but we didn't need full on namespaces and closures, so we gained by not paying for that |
| 00:51 | tbaldridge | right, but you went from compiling the templates to some sort of interpreting. |
| 00:51 | justin_smith | right |
| 00:51 | justin_smith | exactly |
| 00:51 | tbaldridge | did you reload the templates each time? |
| 00:52 | justin_smith | yeah, because the data was coming from the db |
| 00:52 | justin_smith | the smart way would be to compile the template into a function once, with all db data in the args |
| 00:53 | tbaldridge | yeah, or eval once and cache the results. that way the JIT actually has a chance to help you. |
| 00:53 | justin_smith | right, but the results aren't going to be any good if part of what is evaluated is coming from a db call that could give a different result next time |
| 00:59 | ddellacosta | I see, eval actually creates a PushbackReader and passes it to LispReader, where as read defaults to *in*... |
| 01:00 | ddellacosta | btw, what is the convention followed by the formatting in the Clojure (Java) source? I've never seen that kind of bracket indenting. I suppose it's reasonably readable...is that common in Java-land? |
| 01:00 | coventry | Eval doesn't do those things. Those are the Reading part of the REPL. |
| 01:03 | ddellacosta | huh, okay |
| 01:08 | technomancy | I think the general consensus around Clojure's Java source is that it isn't something to be emulated =) |
| 01:10 | ddellacosta | technomancy: gotcha...haha. |
| 01:10 | ddellacosta | I am certainly finding the source to Compiler.java a bit tricky to follow |
| 01:11 | technomancy | this is normal, heh |
| 01:11 | justin_smith | even the clojure clojure source isn't something to be emulated, in many places |
| 01:12 | technomancy | especially core.clj |
| 01:12 | technomancy | or anywhere it uses load-file |
| 01:12 | technomancy | anyone care to review a draft blog post? |
| 01:12 | technomancy | it's about keeeeyboards |
| 01:12 | ddellacosta | technomancy: definitely |
| 01:13 | technomancy | cool; it's http://technomancy.us/172 |
| 01:14 | technomancy | if you count XML as a language, every blog post I've written this year has introduced code in a new language |
| 01:19 | ddellacosta | technomancy: wow, you're making me want to 1) get one of these and 2) switch to Dvorak |
| 01:20 | technomancy | just don't do them both at the same time |
| 01:20 | justin_smith | I am using a kinesis freestyle 2, a split keyboard is a really nice thing |
| 01:20 | technomancy | unless you want to take a three-month sabbatical to re-learn how to computor |
| 01:20 | ddellacosta | ha, gotcha... |
| 01:21 | justin_smith | the transition period is nice for facilitating hammock driven development |
| 01:21 | technomancy | dvorak is nice, but it's not that different from colemak, which you can learn a lot more quickly |
| 01:21 | technomancy | I learned when I was a freshman in college with not a lot to do |
| 01:22 | ddellacosta | one thing you may want to mention (at least, I didn't see a mention) is Jesse Vincent's project, http://launch.keyboard.io...that said, you have a pretty good narrative flow already, and I don't know if it would make sense. |
| 01:22 | ddellacosta | whoops, bad link: http://launch.keyboard.io |
| 01:22 | technomancy | I also wonder if there's any point in sticking with a 12-inch laptop if I'm going to be toting around a keyboard with me everywhere I go, heh |
| 01:23 | technomancy | ddellacosta: oh yeah good call |
| 01:23 | ivan | http://mathematicalmulticore.wordpress.com/category/keyboards/ layout talk, also http://mkweb.bcgsc.ca/carpalx/ |
| 01:23 | technomancy | I read his blog post about all his various attempts and it floored me. a true pioneer! |
| 01:24 | ddellacosta | technomancy: yeah, ditto, I was really impressed by that! |
| 01:26 | ddellacosta | anyways, overall, I enjoyed your post technomancy ...I didn't know about the IBM Model M, I love that kind of history. |
| 01:26 | justin_smith | my coworker has a model m |
| 01:26 | justin_smith | so distracting |
| 01:26 | justin_smith | much click |
| 01:26 | technomancy | wow |
| 01:27 | ddellacosta | justin_smith: um, don't you mean "so click much distracting?" |
| 01:27 | Raynes | I'm still fine with my das. |
| 01:27 | Raynes | Nobody at work ever cared about the clickiness. |
| 01:27 | justin_smith | ddellacosta: yeah, pretty much |
| 01:27 | technomancy | Raynes: too young for RSI to set in =) |
| 01:27 | technomancy | Raynes: which switches is it though? |
| 01:27 | Raynes | amalloy_ would occasionally think about throwing things at me when trying to hear folks across the room. |
| 01:27 | ddellacosta | justin_smith: :-p |
| 01:27 | Raynes | technomancy: Cherry blues. |
| 01:27 | ddellacosta | Raynes: what's a das? |
| 01:27 | technomancy | Raynes: represent |
| 01:28 | Raynes | $google das keyboard |
| 01:28 | lazybot | [Das Keyboard] http://shop.daskeyboard.com/ |
| 01:28 | technomancy | I heart them so |
| 01:28 | Raynes | They're delicious. |
| 01:29 | justin_smith | if only they made a split das, but I guess that kit technomancy got is close to being that |
| 01:30 | ddellacosta | intriguing...I should really start using something other than this built-in laptop keyboard. :-( |
| 01:30 | technomancy | justin_smith: yeah, I held off for a long time because I didn't want to have to pick between mechanical and split |
| 01:30 | technomancy | (and the advantage was just too intimidating, heh) |
| 01:30 | justin_smith | ddellacosta: split is awesome, especially if you have wider chest/shoulders than average |
| 01:31 | technomancy | ddellacosta: actually in japan it's probably a lot easier to find good keyboards |
| 01:31 | justin_smith | patchwork uses an advantage |
| 01:31 | technomancy | strong otaku culture there =) |
| 01:31 | ddellacosta | technomancy, justin_smith: yeah, I've been kinda coveting split keyboards for a while...should head over to Akihabara and see what I can find! |
| 01:31 | justin_smith | split with a trackball in between is pretty sweet |
| 01:32 | pdk | where do you find those |
| 01:32 | pdk | that sounds pretty nice now |
| 01:33 | justin_smith | which? |
| 01:33 | technomancy | justin_smith: https://secure.flickr.com/photos/95666385@N02/8731901844/ |
| 01:33 | pdk | with a keyboard in the middle of the split |
| 01:33 | justin_smith | woah, that is fucking awesome |
| 01:33 | pdk | um |
| 01:33 | pdk | trackball |
| 01:34 | pdk | damn and it's got arcade buttons |
| 01:34 | justin_smith | pdk: I just manually put a kensington ball mouse between the halves of my kinesis freestyle |
| 01:34 | pdk | this is truly the everything keyboard |
| 01:34 | pdk | hm there's an idea |
| 01:35 | justin_smith | pdk: bonus, maximum flexibility for rearranging the halves / mouse to keep hand positions switching up |
| 01:35 | pdk | gonna have to look into this |
| 01:35 | technomancy | justin_smith: do you use any tenting? |
| 01:35 | justin_smith | technomancy: yes at work, no at home |
| 01:36 | technomancy | do you feel like it makes a big difference? |
| 01:36 | justin_smith | I am considering getting the tenting for home too, but not sold on needing it yet |
| 01:36 | technomancy | cool |
| 01:36 | justin_smith | for more extended typing it is nice |
| 01:36 | technomancy | I need to spend some more time gettinhg used to the matrix layout before getting any fancier =) |
| 01:37 | justin_smith | http://www.kinesis-ergo.com/freestyle-ascent-features.htm I use the ascent |
| 01:37 | technomancy | though I did just order some colored caps for the home row and homing bumps |
| 01:37 | justin_smith | that is a bonus with the freestyle, that the various risers are swappable |
| 01:37 | technomancy | nice |
| 01:37 | technomancy | what position do you mostly use? |
| 01:38 | technomancy | I mean which angle+ |
| 01:38 | technomancy | derp |
| 01:38 | justin_smith | a fairly shallow one |
| 01:39 | justin_smith | 20-30 |
| 01:39 | technomancy | gotcha |
| 01:39 | justin_smith | it would be funny to use the 90 degree tenting with the halves on either side of the monitor - like hugging the screen |
| 01:41 | justin_smith | I use the palm supports too |
| 01:41 | technomancy | that'd be awesome with a CRT |
| 01:41 | justin_smith | heh, yeah |
| 01:41 | justin_smith | you could just mount the keys to the side of the crt |
| 01:41 | justin_smith | lol |
| 01:58 | arrdem | has anyone used core.logic for optimization problems? |
| 01:59 | arrdem | just wondering if I can do better than a brute force search of my solution space here |
| 02:02 | logic_prog | is your space convex? |
| 02:02 | bitemyapp | arrdem: I don't think core.logic will know more about your problem than you, but it's possible. I think core.logic is more useful when you just want to quickly express something. |
| 02:02 | logic_prog | is it continuous? |
| 02:02 | logic_prog | is it np-complete? |
| 02:03 | technomancy | "quickly express something, as long as it's a search tree" |
| 02:03 | arrdem | bitemyapp: mmkay. I'll watch some of dnolen's stuff on it tomorrow. |
| 02:03 | arrdem | s/tomorrow/later today/ |
| 02:03 | arrdem | logic_prog: it's an ordering and selection problem, so it's at least combinatoric, but bounded, to n < 10. |
| 02:04 | technomancy | see also http://programming-puzzler.blogspot.com/2013/03/logic-programming-is-overrated.html for another perspective |
| 02:04 | technomancy | oops, the url is kind of a spoiler there |
| 02:04 | logic_prog | arrdem: do you know if it has a polynomial time solution? |
| 02:04 | arrdem | logic_prog: no effort has been made to rigorously analyze this algorithm/problem. |
| 02:05 | logic_prog | arrdem: waht is the input/output? |
| 02:05 | bitemyapp | arrdem: I'm more or less on board with what technomancy linked. |
| 02:05 | arrdem | logic_prog: input is a set of weapons with stats, a weilder and a victim |
| 02:06 | arrdem | logic_prog: output is a sequence of attacks |
| 02:06 | arrdem | maximized for projected damage |
| 02:06 | logic_prog | arrdem: I think you want dynamic programming |
| 02:06 | logic_prog | it's probably do-able in O(Wt) time, where W = # of weapons, and t = number of discrete "time steps" |
| 02:06 | logic_prog | oh, and damage is "additive" right? |
| 02:07 | arrdem | logic_prog: yes but it isn't monotonic because there's weirdness with a finite selection of "boosted" actions. |
| 02:07 | arrdem | it's complicated and domain specific :P |
| 02:07 | logic_prog | arrdem: how can we help you if we don't have a formal definition of ht eproblem? :-) |
| 02:08 | arrdem | logic_prog: as with bitemyapp and technomancy the expectation was vague "this is my gut" answers :P |
| 02:09 | bitemyapp | I'm good at spaghetti->wall Q&A sessions. |
| 02:09 | logic_prog | are you writing a world of warcraft bot? :-) |
| 02:09 | technomancy | bitemyapp: the author is a seajure member |
| 02:09 | bitemyapp | logic_prog: he's modelling a pen & paper game. |
| 02:09 | arrdem | logic_prog: with all the smart people in here, the community gut is really bright |
| 02:09 | logic_prog | figure out how to maximize damage vs this boss with these weapons :-) |
| 02:09 | technomancy | "that guy who uses Windows" |
| 02:09 | bitemyapp | technomancy: nifty. I like how they think. |
| 02:09 | bitemyapp | LOL |
| 02:09 | technomancy | he's been using clojure professionally longer than I have though, so who am I to judge |
| 02:09 | bitemyapp | there's always one. |
| 02:09 | arrdem | that one guy.... |
| 02:10 | technomancy | in this case two: he's started to bring his son in |
| 02:10 | arrdem | good. get 'em yong. |
| 02:11 | technomancy | his son gave a really cool talk about different optimization strategies for a certain mobile puzzle game a few months back |
| 02:12 | bitemyapp | technomancy: I talked to one of the founders of my company yesterday night. They'd like me to stick around for another ~6 months to put down some more roots, but in the end, I'm free to go remote tomorrow if I so desired. |
| 02:12 | technomancy | nice; good luck |
| 02:12 | arrdem | who mentioned dynamic? |
| 02:12 | arrdem | (inc logic_prog) |
| 02:12 | lazybot | ⇒ 1 |
| 02:12 | bitemyapp | arrdem: Logic Prog - dynamic programming is a good toolkit to have in mind. |
| 02:12 | bitemyapp | (inc logic_prog) |
| 02:12 | lazybot | ⇒ 2 |
| 02:13 | bitemyapp | technomancy: thanks. hopefully the IPO/mezzanine round that happens in 10-12 months goes well. |
| 02:13 | arrdem | logic_prog: good call there. I suspect that this is a perfect candidate for a two level dynamic approach. |
| 02:13 | logic_prog | arrdem: given that I don't have a formal defintion lf the problem you're working on, I can't argue the other side |
| 02:13 | logic_prog | :-) |
| 02:14 | logic_prog | but I think absically, all control problems |
| 02:14 | logic_prog | i.e. making decisitions at various tiem steps |
| 02:14 | logic_prog | are basically dynamic programming problems |
| 02:14 | arrdem | I mean I could slap one together if you're interested... there's even some Clojure in Python that's an old (working) prototype :P |
| 02:15 | TEttinger | arrdem, if your stuff is open source, hell I could probably use it |
| 02:16 | arrdem | TEttinger: there used to be a github repo with the python code, but I recycled the name for the clojure rewrite. |
| 02:16 | arrdem | lemme see if I can paste the relivant file.. |
| 02:16 | TEttinger | a while ago I made a list of 100 weapons in a spreadsheet, later figured out a way to get it into clojure but never did anything with it https://dl.dropboxusercontent.com/u/11914692/Weapons%20Spreadsheet%20Full%20100.PNG |
| 02:17 | TEttinger | ,(read-string (slurp "https://dl.dropboxusercontent.com/u/11914692/weapons-map-too-large.clj")) |
| 02:17 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 02:17 | bitemyapp | TEttinger: you play the same game? |
| 02:18 | TEttinger | heh not in any more than a metaphorical sense |
| 02:18 | arrdem | TEttinger: refheap.com/22092 |
| 02:18 | TEttinger | neat arrdem |
| 02:19 | bitemyapp | arrdem: if you're serious about scaling this up, you'll want to give some thought to rule/behavior composition. |
| 02:19 | arrdem | bitemyapp: ooh yeah |
| 02:19 | TEttinger | yeah, for my thing it would need to be scaled up, 80 columns on that spreadsheet |
| 02:19 | bitemyapp | arrdem: which often take the form of monoids and monads >:) |
| 02:19 | TEttinger | oh boy |
| 02:19 | arrdem | TEttinger: lol |
| 02:20 | TEttinger | you should see the dungeon project, haha |
| 02:20 | bitemyapp | spreadsheet evaluation lends itself nicely to loeb. |
| 02:20 | TEttinger | loeb? |
| 02:20 | TEttinger | lots of empty booleans? |
| 02:21 | logic_prog | wow |
| 02:21 | bitemyapp | TEttinger: http://math.stackexchange.com/questions/90781/something-like-recursive-harmonic-numbers-where-can-i-read-more http://www.haskell.org/haskellwiki/Blow_your_mind#Other |
| 02:21 | logic_prog | are you guys playing civ 5 with pencil paper ? |
| 02:21 | TEttinger | lol, one wasn't P&P |
| 02:21 | TEttinger | the weapons aren't, the dungeon thing (also manipulated with clojure) is |
| 02:23 | arrdem | logic_prog: see what it's doing? |
| 02:23 | arrdem | bitemyapp: and yeah I'm gonna have to come up with some capability based way of representing all these rules |
| 02:23 | bitemyapp | TEttinger: loeb is a nice brainfuck :) |
| 02:24 | logic_prog | arrdem: no, I saw the links by Tettinger, but nothing from you |
| 02:24 | arrdem | logic_prog: http://math.stackexchange.com/questions/90781/something-like-recursive-harmonic-numbers-where-can-i-read-more |
| 02:24 | arrdem | oops |
| 02:24 | arrdem | logic_prog: https://www.refheap.com/22092 |
| 02:25 | logic_prog | arrdem: I was about to ask: is this a game designed to be played between Fields Medalists? |
| 02:25 | TEttinger | https://dl.dropboxusercontent.com/u/11914692/Dungeon%20Vanguards.xls the spreadsheet is apparently not massive by any means, but is too large to fit in its entirety on google docs |
| 02:25 | TEttinger | each class is one paragraph, roughly |
| 02:25 | TEttinger | there are a lot of them. |
| 02:26 | arrdem | logic_prog: negative. this game is designed to be played by middle aged dudes with too much money and time who like tabletop miniature wargames. |
| 02:26 | arrdem | logic_prog: average IQ and sub-par math skills are accounted for. |
| 02:26 | arrdem | logic_prog: I'm just building an AI because I can :D |
| 02:27 | arrdem | also because an AI with provably optimal decisions provides a benchmark for the quality of my decisions.. |
| 02:29 | logic_prog | arrdem: http://en.wikipedia.org/wiki/Bellman_equation <-- I think this is what you want |
| 02:32 | arrdem | woah where'd logic_prog go Q_Q |
| 03:03 | nonuby | is there any issues with passing channels over channels? |
| 03:09 | ivan | nonuby: I heard that is an acceptable thing to do |
| 03:09 | nonuby | cool, so many approaches one can take with channels, with only limited guidance (todo and tic tac toe apps etc..) |
| 03:12 | ddellacosta | is it bad form for any reason to use clojure.test/function? in normal code? I'm doing something where I recurse through a list and evaluate any values which are functions before evaluating the final list itself. |
| 03:15 | bitemyapp | arrdem: typeclasses are capabilities >:) |
| 03:59 | logic_prog | clojure is too fucking badass |
| 04:00 | logic_prog | I think I'm down to think 1 hour, write 10 lines of code |
| 04:00 | logic_prog | the levels of abstraction possible are insane |
| 04:00 | Raynes | logic_prog: Deep breath. |
| 04:00 | Raynes | Inhale ... ... ... exhale |
| 06:07 | mi6x3m | hey clojure, if I have nested let's binding the same local, can I refer to the one from the outside let |
| 06:07 | cark | nope |
| 06:08 | mi6x3m | ok |
| 07:22 | Bronsa | k |
| 07:47 | anagrius | Is anyone using nrepl-ritz with cider. Or would I have to revert to nrepl.el? |
| 08:28 | danlentz | hey wow cider-inspect is quite nice! |
| 08:29 | danlentz | closes a little bit of the distance between ciderr and slime |
| 08:30 | danlentz | things have come a long way since one launched clojure repl with java -jar and prayed never to need backspace |
| 08:33 | danlentz | well done cider/nrepl team! |
| 09:27 | xeqi | cemerick: ooh, is it piggieback PR time? |
| 10:08 | cemerick | xeqi: yup |
| 10:09 | cemerick | xeqi: burning through the github queue in general |
| 10:39 | danlentz | so Java booleans appear to consume 128 bits of storage |
| 10:40 | danlentz | would be intertesting to know what the extra 127 bits are need for |
| 10:41 | andyf | danlentz: A Boolean object, you mean? |
| 10:41 | danlentz | why on earth should booleans require more space than any other primitive type-- longs, doubles included. |
| 10:42 | andyf | All Java Objects take a certain amount of overhead for each instance, including a synchronization lock (although I've heard some Java creators considered that overkill later) |
| 10:42 | danlentz | well a boolean primitive gets wrapped in Boolean |
| 10:42 | andyf | danlentz: I had not measured to see that they take more than others. |
| 10:42 | danlentz | a long primitive requires 64 bits |
| 10:43 | andyf | Compare against Integer, Long, not the primitives. |
| 10:43 | andyf | If it is indeed Boolean, not boolean you are comparing them to. |
| 10:43 | andyf | boxed values abound in typical Clojure code. |
| 10:44 | danlentz | hmm. well the actual heap space used by the wrapper class is unknown to me id think without some l;ow-level tool to inspect it |
| 10:45 | andyf | Yeah, the easiest way I know is to have a sample JVM session where you generate millions of them, and then use a memory profiler to see the size of the most frequently allocated object. |
| 10:45 | danlentz | but im really talking about the primitive type though |
| 10:45 | danlentz | ie int - |
| 10:45 | andyf | You can avoid the boxing overhead if you need to for some huge data set, e.g. boolean-array |
| 10:46 | danlentz | from what i understand that will require 128 bits per boolean element of the artray |
| 10:46 | andyf | How did you reach the conclusion that a primitive boolean takes 128 bits? I am not saying it is wrong, just wondering what the evidence is. |
| 10:47 | danlentz | docs -- although i just copied the table into my source file as commemts I dont have the url handy at the moment |
| 10:47 | danlentz | doh |
| 10:49 | danlentz | it was during the course of working with a lot of signed/unsigned numeric representation issues for my clj-uuid library |
| 10:49 | andyf | I don't have an authoritative answer for you, but at least some people discussing the question on StackOverflow believe a primitive boolean is the same as a 32-bit primitive int. http://stackoverflow.com/questions/1907318/java-boolean-primitive-type-size |
| 10:50 | andyf | But that JVM implementations probably use less than that for arrays of booleans, |
| 10:51 | andyf | As far as Clojure goes, that is a JVM implementation detail that Clojure can neither directly observe nor control. |
| 10:51 | danlentz | huh. well then thats better maybe i'm mistaken about it |
| 10:52 | danlentz | yeah but if we couldnt gripe about jvm issues we wouldnt have all that much to gripe about :) |
| 10:53 | andyf | There are Java classes and Clojure data structures for storing bit arrays more compactly, of course. |
| 10:54 | danlentz | y the next thing i think im going to write is a bit-vector type |
| 10:54 | andyf | Java BitSet http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html Clojure immutable-bitset https://github.com/ztellman/immutable-bitset |
| 10:54 | xeqi | for oracles jvm, the spec says booleans use ints, but that boolean[] use byte arrays |
| 10:54 | xeqi | http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.3.4 |
| 10:55 | danlentz | xeql: hmm cool. i stand corrected then |
| 10:56 | andyf | I believe both of the libraries I linked to can approach 1 bit per element, plus the fixed Object overhead. |
| 10:56 | hyPiRion | According to the JVM spec, arrays of booleans take 8 bit per element. So it's not only the Oracle JVM which does that |
| 10:57 | danlentz | ztellman has a lot of good stuff |
| 10:57 | andyf | Yes, yes he does :-) |
| 10:57 | andyf | inc ztellman |
| 10:57 | andyf | dang, forgot the syntax |
| 10:57 | danlentz | for bitwise byte munging |
| 10:58 | andyf | (inc ztellman) |
| 10:58 | lazybot | ⇒ 7 |
| 10:58 | danlentz | im using primitive-math. does anyone else notice though it seems to behave in a slightly contagheous fashion |
| 10:59 | danlentz | ie, any ns that uses a ns that uses p-m automatically gets its operators replaced |
| 10:59 | andyf | It is considered best practice to (:require [lib.name :as short-alias]) not :use |
| 11:00 | andyf | I have seen ztellman :require p-m as p, but it still leads to p/+ p/- etc in your code. |
| 11:00 | danlentz | it hasnt caused me any problems, but it is a kind of worrisome behaviiour |
| 11:00 | andyf | You get to pick whether you want the override or the namespace-aliased behavior yourself. |
| 11:01 | dsrx | you could refer those specific operators you need, no? |
| 11:02 | andyf | Oh, yes, and I don't personally use it much, but you can also rename the symbols you :refer, if you want to avoid needing the alias/symbol all of the time to refer to them, but don't want the names to override those in clojure.core |
| 11:03 | danlentz | i see now -- he has the ns-wrapper do automatically use-primitive-operators if the ns is :used |
| 11:04 | andyf | Bronsa: Is it fundamentally impossible to wish for an analyzer where I could tell from the results when portions of the result came from a macroexpansion, and even what the source code before macroexpansion was for that part of the result? |
| 11:05 | Bronsa | andyf: you can attach that info as metadata in macroexpand-1 if I'm understanding correctly what you're asking |
| 11:05 | andyf | Bronsa: Or maybe the existing tools.analyzer already provides that, and I haven't noticed it yet. |
| 11:06 | Bronsa | e.g. you can make so that (macroexpand-1 '(macro)) => ^{::source '(macro)} (expanded form) |
| 11:06 | andyf | Bronsa: I think I see what you mean. That may be useful. |
| 11:06 | danlentz | cross another item off my TODO-clojure.lang.PersistentList :) |
| 11:07 | andyf | Bronsa: Sometimes in writing a linter, if I use the ast I am left trying to use tree-shape recognition methods to guess whether it came from a particular macro expansion, but if I use the form read in I am missing out on important details that occur only after macro expansion is done. |
| 11:07 | andyf | Bronsa: What you suggest should be able to give me the best of both worlds if I use the ast with the extra annotations. |
| 11:08 | Bronsa | andyf: yeah, it would be cool to say "if this sub-expr is the result of macroexpanding defprotcool then ignore this particular linting warning" I agree |
| 11:08 | andyf | Bronsa: Oh, I am doing that already, just in the hackish way I described. |
| 11:08 | Bronsa | yeah, I saw the commit |
| 11:08 | andyf | Bronsa: I don't expect defprotocol to have its definition change any time soon, but it feels fragile |
| 11:09 | andyf | Bronsa: Hopefully seeing those commits didn't disgust you too much :-) |
| 11:11 | Bronsa | andyf: https://github.com/jonase/eastwood/commit/81b600ca740caf4c9edb5fb75a84c3f86a88db98 |
| 11:11 | andyf | Working on a linter now that tries to detect mistakes in the use of clojure.test that I have seen while looking through earlier warnings. It is amazingly easy to try to write unit tests as (= expr expected-value) and forget the (is (= ...)) completely. |
| 11:12 | Bronsa | yeah, I'm guilty of doing that myself |
| 11:12 | andyf | Bronsa: You, sir, are a scholar and a gentleman. Thanks for the help. |
| 11:12 | andyf | (inc Bronsa) |
| 11:12 | lazybot | ⇒ 15 |
| 11:14 | andyf | Bronsa: I recall you mentioning a possible soon-ish alpha release of tools.analyzer(.jvm). Any thoughts on when that might be? |
| 11:15 | andyf | It isn't 1.0 quality or anything, but I personally think the latest versions of it and Eastwood are getting reasonably useful. |
| 11:15 | Bronsa | andyf: I'd like to wait for the :tag situation to get solved but.. it doesn't look like we're going to get any ufficial response any time soon |
| 11:16 | andyf | by which I mean, ready to be beaten on by the masses of the world and thus shattering my illusion that it is as stable as it seems |
| 11:17 | Bronsa | andyf: speaking of eastwood, I think it should wait for https://github.com/jonase/eastwood/issues/29 to get fixed before a release |
| 11:17 | andyf | Bronsa: I would like an answer to that to, but there really isn't any way to predict when that might happen. It moves on their free time schedules, not our have-time-to-ask-a-question schedules. |
| 11:18 | Bronsa | andyf: the problem now is that jvm.tools.analyze didn't use c.c/eval, it just called .eval on the Compiler.java generated AST |
| 11:18 | andyf | Would it be any kind of solution to use something like tools.namespace to determine dependencies between analyzed namespaces, and analyze them in dependency order? |
| 11:19 | Bronsa | andyf: with tools.analyzer.jvm we have to analyze once && eval analyzes the form again -- we have deftype/protocol issues with the double analysis |
| 11:20 | Bronsa | analyzing the namespaces in order of dependency would solve those issues |
| 11:20 | andyf | Right now Eastwood's namespace order is fairly arbitrary - just the order of seq on a set. |
| 11:20 | andyf | I believe. |
| 11:20 | Bronsa | but I haven't had any time yet to see how to determine that order with tools.namespace |
| 11:21 | andyf | I can take a look at that after finishing my clojure.test linter a bit more, if it would help. MIght be a couple days before I can start. |
| 11:22 | andyf | IIRC tools.namespace simply looks at each source file and expects the first form to be an ns form, and then parses dependencies from that. |
| 11:22 | andyf | But I haven't looked at the details. Shouldn't take long, I would guess, with enough experimentation and caffeine. |
| 13:12 | yedi | im sure there has to be a better way for me to parse a file? https://github.com/yedi/rhyme-finder/blob/master/src/clj/rhyme_finder/core.clj#L3 |
| 13:19 | ryantm | yedi: slurp? http://clojuredocs.org/clojure_core/clojure.core/slurp |
| 13:21 | yedi | wow |
| 13:21 | yedi | ok |
| 13:52 | jergason | I'm confused by how this works (defn indexed [coll] (map-indexed vector coll)) |
| 13:52 | jergason | i thought vector was a data structure, but here it seems to be a function which returns a sequence of numbers |
| 13:54 | jergason | wait i get it |
| 13:54 | jergason | vector gets called with an index and each item in the collection |
| 13:54 | jergason | so this returns a sequence of [0 first-thing] [1 second-thing] etc |
| 14:03 | hyPiRion | jergason: yes. (vector a b) just returns [a b] |
| 14:05 | jowag | jergason: there is a function which returns a vector which will contain all the items you give it, and this function is called 'vector' |
| 14:05 | jergason | thanks hyPiRion and jowag, that is very helpful |
| 14:06 | jowag | jergason: so if you call (vector 1 2), it will create a new vector, put 1 and 2 into it and returns it back |
| 14:06 | jowag | jergason: ad because it is a function, you can used in in a higher order functions like map-indexed |
| 14:07 | hyPiRion | (and map-indexed is just a fancy way of saying (map f (range) coll) |
| 14:07 | hyPiRion | ) |
| 14:07 | dobry-den | is there a way to refer to the current function without naming it? for example (defn foo ([a] (foo a 1)) ([a b] (+ a b))) without repeating 'foo'? |
| 14:09 | hyPiRion | dobry-den: what do you mean by "without naming it"? (fn foo ([a] (foo a 1)) ([a b] (+ a b))) is an anynomous function |
| 14:09 | hyPiRion | but it's kind-of named, still. |
| 14:12 | dobry-den | hyPiRion: right, it's just brittle |
| 14:17 | justin_smith | how is that brittle? |
| 14:19 | alew | you can use recur |
| 14:19 | alew | if you are doing a tail-call |
| 14:26 | dobry-den | justin_smith: brittle in that it's a dependency on the name of the function. certainly trivial however. |
| 14:27 | dobry-den | but easier to acknowledge if you've ever renamed the function and it took you longer than you'd like to realize that you didn't rename it everywhere within the body |
| 14:27 | justin_smith | ahh |
| 14:28 | Lajjla | Raynes, |
| 14:28 | Lajjla | do you know where the Finn they call Chousuke hangs out? |
| 14:28 | dobry-den | i'm not saying it's a showstopper. it would just be cool if there was some `recur`-like semantic for it |
| 14:28 | justin_smith | "this" |
| 14:28 | dobry-den | pls anything but this |
| 14:28 | dobry-den | me |
| 14:29 | justin_smith | lol |
| 14:33 | andrei | How does one do xpath queries on html documents? clj-xpath wants an xml document |
| 14:36 | justin_smith | http://www.w3.org/TR/xpath/ by pretending html is xml maybe? |
| 14:38 | hyPiRion | html is not xml unfortunately |
| 14:39 | justin_smith | if I understand correctly, xpath is not well defined for html. Though I guess one could take the approach of renaming the html to .xml and hope things work... ? |
| 14:40 | pdurbin | that's what xhtml is for :) |
| 14:42 | jergason | that is a naughty word |
| 14:42 | hyPiRion | justin_smith: it's unlikely that it would work. <br> is legal html, but invalid xml |
| 14:46 | pdurbin | JSF is all about xhtml :) |
| 14:47 | jergason | that is another naughty word |
| 14:48 | justin_smith | jergason: what are the nice words? |
| 14:48 | jergason | whatever gets you the most upvotes on hacker news |
| 14:49 | justin_smith | "show hn:" is the universal nicifying prefix |
| 14:54 | wei__ | what's a quick way to check whether every element is unique in a collection? |
| 14:55 | dobry-den | wei__: naive solution is (= coll (set coll)) |
| 14:55 | dobry-den | but you'd want it to short-circuit |
| 14:56 | wei__ | that doesn't work for me |
| 14:56 | wei__ | dobry-den: ^ |
| 14:56 | dobry-den | oh yeah duh |
| 14:56 | wei__ | maybe (count ..)? |
| 14:56 | dobry-den | (= (count coll) (count (set coll))) |
| 14:57 | wei__ | good enough for now, thanks |
| 14:57 | wei__ | the collection isn't large |
| 14:58 | dobry-den | yeah it's simple |
| 15:01 | justin_smith | (fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c))) |
| 15:01 | justin_smith | that version short circuits with the first dup |
| 15:02 | justin_smith | ,((fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c))) [0 1 2 3]) |
| 15:02 | clojurebot | true |
| 15:02 | justin_smith | ,((fn [c] (boolean (reduce (fn [m x] (if (get m x) (reduced false) (assoc m x true))) {} c))) [0 1 2 3 2]) |
| 15:02 | clojurebot | false |
| 15:05 | Jarda | hmm |
| 15:06 | Jarda | please enlighten me |
| 15:06 | Jarda | lein deps downloads a lot of jars |
| 15:06 | Jarda | but then lein ring server-headless downloads more |
| 15:06 | dobry-den | how about this https://www.refheap.com/22099 |
| 15:06 | Jarda | I thought lein deps was supposed to donload everything |
| 15:07 | dobry-den | oh, i didnt see justin_smith's answer |
| 15:07 | justin_smith | dobry-den: nice, maybe the first/rest could be replaced with a destructuring |
| 15:07 | justin_smith | I agree that a set is better than hash map there |
| 15:07 | justin_smith | and contains is the right thing to call |
| 15:07 | justin_smith | rather than get |
| 15:08 | dobry-den | justin_smith: i tried if-let with [[x] coll] but it would just conj a nil to the set and i didnt bother trying harder |
| 15:09 | dobry-den | it would be cool if if-let checked for nil? on destructured values. |
| 15:09 | dobry-den | (unless i'm missing something) |
| 15:10 | justin_smith | https://www.refheap.com/22100 I meant this |
| 15:10 | justin_smith | it works, just tested it |
| 15:25 | jowag | ,(apply distinct? [1 2 3 4]) |
| 15:25 | clojurebot | true |
| 15:25 | jowag | ,(apply distinct? [1 2 4 3 4]) |
| 15:25 | clojurebot | false |
| 15:25 | jowag | wei__: ^^ for unique check |
| 15:26 | wei__ | oh nice, looks like it short-circuits too |
| 15:26 | wei__ | thanks jowag |
| 15:26 | jowag | wei__: yep |
| 15:26 | justin_smith | (inc jowag) |
| 15:26 | lazybot | ⇒ 2 |
| 15:26 | justin_smith | I knew that must have existed somewhere |
| 15:26 | jowag | thanks |
| 15:27 | justin_smith | $source distinct? |
| 15:27 | lazybot | distinct? is http://is.gd/FSRvej |
| 15:28 | justin_smith | very similar to what dobry-den and I ended up with |
| 15:28 | justin_smith | even down to the destructuring |
| 15:30 | jowag | but the variant with reduce should be faster, skips seq creation |
| 15:32 | jowag | ,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj s e))) #{} coll))) [1 2 3 4]) |
| 15:32 | clojurebot | true |
| 15:32 | jowag | ,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj s e))) #{} coll))) [1 2 3 4 4]) |
| 15:32 | clojurebot | false |
| 15:32 | angerman | what's the clojure in c state? |
| 15:32 | jowag | justin_smith: benchmark also that one :) ^^ |
| 15:33 | justin_smith | yeah, I am doing so :) |
| 15:33 | wei__ | love the dedication :) |
| 15:33 | wei__ | (inc justin_smith |
| 15:33 | wei__ | ) |
| 15:33 | wei__ | (inc justin_smith) |
| 15:33 | lazybot | ⇒ 19 |
| 15:34 | jowag | justin_smith: and don't forget the :jvm-opts ^:replace ["-server"] if using lein |
| 15:39 | jowag | ,((fn [coll] (boolean (reduce (fn [s e] (if (contains? s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4]) |
| 15:39 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentHashSet$TransientHashSet> |
| 15:39 | jowag | ,((fn [coll] (boolean (reduce (fn [s e] (if (get s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4]) |
| 15:39 | clojurebot | true |
| 15:40 | jowag | o_O |
| 15:40 | justin_smith | contains? on a transient? |
| 15:40 | justin_smith | you may need to call persistent! |
| 15:41 | jowag | official docs says: "Transients support the read-only interface of the source" |
| 15:41 | Bronsa | jowag: http://dev.clojure.org/jira/browse/CLJ-700 |
| 15:41 | jowag | so maybe I've just found a bug |
| 15:42 | jowag | heh |
| 15:44 | hyPiRion | returns true here |
| 15:45 | justin_smith | so far the reduce based in both versions is faster than apply distinct? |
| 15:45 | clojurebot | Gabh mo leithscéal? |
| 15:45 | justin_smith | trying the loop based version too |
| 15:45 | justin_smith | faster as in ~ half / third the time needed |
| 15:46 | hyPiRion | hm, that's probably a bug coming from 1.6 |
| 15:46 | hyPiRion | &*clojure-version* |
| 15:46 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 15:46 | justin_smith | loop version is equivalent to distinct? |
| 15:46 | hyPiRion | &((fn [coll] (boolean (reduce (fn [s e] (if (get s e) (reduced false) (conj! s e))) (transient #{}) coll))) [1 2 3 4 4]) |
| 15:46 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: reduced in this context |
| 15:49 | justin_smith | trying the version with a transient with get |
| 15:49 | justin_smith | since contains? fails |
| 15:50 | justin_smith | the version with transient/get is not as fast as the version with regular set and contains? |
| 15:50 | jowag | justin_smith: get on transient is buggy, always returns false |
| 15:50 | justin_smith | jowag: in that case I would have gotten an infinite loop! |
| 15:51 | justin_smith | I was using (concat (range 100) (range)) as my test input |
| 15:51 | justin_smith | to amplify any garbage related differences |
| 15:51 | justin_smith | https://www.refheap.com/22101 <- my results |
| 15:51 | hyPiRion | justin_smith: on 1.6 or 1.5.1? |
| 15:52 | justin_smith | 1.5.1 |
| 15:53 | justin_smith | https://www.refheap.com/22102 <- updated with jvm and clojure versions |
| 15:57 | amoe | hey, is there some library I can use to transparently persist hashmaps to disk? |
| 15:58 | justin_smith | amoe: if it is an edn-compatible hashmap, then pr-str and spit will almost always suffice |
| 15:58 | justin_smith | no library needed |
| 15:59 | jowag | ,(get (transient #{1 2}) 1) |
| 15:59 | clojurebot | nil |
| 15:59 | jowag | justin_smith: see ^^ |
| 16:03 | justin_smith | oh weird |
| 16:03 | amoe | justin_smith: I was hoping there was something that would automatically write the hashmap state to disk on every modification... yes, I'm lazy |
| 16:03 | justin_smith | ahh that is for sets only |
| 16:03 | justin_smith | ,(get (conj! (transient {}) [2 true]) 2) |
| 16:03 | clojurebot | true |
| 16:04 | justin_smith | amoe: you are in luck, the hash map is immutible and can never be modified :) |
| 16:04 | justin_smith | now if you want a var or atom or such to go on disk whenever it changes... |
| 16:05 | justin_smith | ,(get (transient {1 true 2 true}) 2) ; simpler |
| 16:05 | clojurebot | true |
| 16:06 | amoe | justin_smith: thanks, I'll hit the books :) |
| 16:07 | justin_smith | amoe: in caribou this is what we use caribou.model for (this puts a small but useful subset of hash maps into an sql db) |
| 16:07 | justin_smith | you may want to look into datomic or couchdb or neo4j or some other keystore for creating and using hashes that persist and can be shared |
| 16:08 | dobry-den | Is there a way to find out where the majority of time is being spent between request and response in a ring app? |
| 16:08 | amoe | justin_smith: this is for a really tiny script and I just want to maintain a list of "seen" URLs |
| 16:08 | dobry-den | in my head the ideal result would be a timeline breakdown per function |
| 16:08 | justin_smith | amoe: a keystore will make that easy, instead of a hash map you could just have keys, and you can add / check for their existence |
| 16:09 | justin_smith | or even a single table with a single string column + clojure.java.jdbc even |
| 16:10 | justin_smith | naively rewriting the file for each new piece of data is kind of a bad idea (unless you are going to have only one app instance ever and a very small set of seen urls) |
| 16:11 | kes_ | Can someone tell me what this type of data is? #<Inet4Address example.org/192.168.1.100> |
| 16:11 | dobry-den | mocker`: http://docs.oracle.com/javase/7/docs/api/java/net/Inet4Address.html |
| 16:11 | justin_smith | kes_: http://docs.oracle.com/javase/7/docs/api/java/net/Inet4Address.html |
| 16:12 | justin_smith | he is gone already? |
| 16:12 | dobry-den | namechange |
| 16:12 | mocker` | hehe, sorry about that. |
| 16:12 | justin_smith | ahh I hide that stuff |
| 16:13 | mocker` | justin_smith: Thanks, so I'm guessing I can do something like (str (InetAddress/getByName "example.org")) to get a string with the IP? |
| 16:13 | mocker` | (sorry, like third day with clojure) |
| 16:14 | justin_smith | (.getHostAddress add) |
| 16:14 | justin_smith | if add has that indet4address thing in it |
| 16:14 | dobry-den | Question: I store Markdown text in my database and currently render it to html one first request where it gets cached. But the markdown can be large and really test the patience of the first request. and the cache is a bit of a sparse map anyways, and it couldn't all fit in memory. |
| 16:14 | dobry-den | Would the solution to that be to prerender it all to html flatfiles? |
| 16:15 | justin_smith | dobry-den: maybe you could extend the core.cache protocol with a disk persistence cache? |
| 16:15 | justin_smith | if that does not exist already actually |
| 16:15 | dobry-den | cool, that is the kind of thing i was thinking about |
| 16:16 | mocker` | justin_smith: Thanks |
| 16:16 | mocker` | Need to take time and figure out this repl in emacs thing, compile and rerun to test command line arguments is slowing things down. |
| 16:17 | justin_smith | (do (require 'ns-with-code 'ns-with-tests :reload) (clojure.test/run-tests)) |
| 16:17 | justin_smith | what I do is basically the above |
| 16:17 | mocker` | justin_smith: Haven't gotten to "tests" yet. |
| 16:17 | justin_smith | M-p to flip back to commands you previously run |
| 16:17 | justin_smith | ahh |
| 16:18 | justin_smith | ahh you meant "test" as in run it and see what happens |
| 16:18 | justin_smith | clojure.test is very easy to use |
| 16:18 | mocker` | I was doing pretty well in the repl, but don't know how to do something like pass command line arguments while in it. |
| 16:18 | mocker` | like how does (-main) take --hostname ? |
| 16:19 | justin_smith | (core/-main "--hostname" "blah" "--other-arg" "ok") |
| 16:20 | justin_smith | the posix command line only provides the ability to pass in strings |
| 16:22 | justin_smith | (test/deftest -main-test (test/is (= (core/-main "--hostname" "localhost") "127.0.0.1"))) |
| 16:22 | justin_smith | something like that |
| 16:22 | mocker` | justin_smith: Ahh, awesome.. Thanks again! |
| 16:23 | mocker` | Got a free clojure class coming up next month, can't wait. |
| 16:23 | mocker` | Until then just diving in for fun. |
| 16:23 | justin_smith | after that you can run (test/run-tests) and all the ones you have defined will be run through again |
| 16:23 | justin_smith | assumption being you redefined some code they used in the meantime |
| 16:24 | yedi | whats the fn that does this: [1 2 3 4] => [[1 2][2 3][3 4]] |
| 16:25 | justin_smith | ,(partition 2 1 [1 2 3 4]) |
| 16:25 | clojurebot | ((1 2) (2 3) (3 4)) |
| 16:25 | yedi | (inc justin_smith) |
| 16:25 | lazybot | ⇒ 20 |
| 16:35 | mocker` | Ok, last question for the day. Any way to avoid doing (get options :foo) over and over again in this code snippet? https://gist.github.com/8075415 |
| 16:36 | justin_smith | mocker`: destructuring, I will show an example shortly |
| 16:37 | justin_smith | ,(let [{a :a b :b c :c} {:a 0 :b 1 :c 3}] [c b a b c a]) |
| 16:37 | clojurebot | [3 1 0 1 3 ...] |
| 16:37 | justin_smith | that works in the function args block too |
| 16:37 | mocker` | Awesome, thanks. |
| 16:38 | justin_smith | (defn new-message [{host :hostname username :username :as opts}] ...) |
| 16:38 | mocker` | Basically trying to switch from using set parameters in my function to command line arguments w/ tools.clj |
| 16:38 | mocker` | So that helps. |
| 16:38 | justin_smith | if you want names identical to keys: (fn [{:keys [hostname username ...] :as opts}] ...) |
| 16:39 | mocker` | I'll play, thanks again. :) |
| 16:52 | dobry-den | What's the simplest surrogate for a `pmap` that's intended for sideeffects? |
| 16:53 | justin_smith | a thread pool and a queue via core.async? |
| 16:53 | justin_smith | maybe |
| 16:53 | justin_smith | there could be something simpler |
| 16:55 | dobry-den | ill try fork/join |
| 16:57 | xeqi | (doseq [x ...] (future x)) ? |
| 16:57 | xeqi | hmm, not quite. need the fn call in there somewhere |
| 16:58 | dobry-den | xeqi: that wouldnt be pooled though, right |
| 16:58 | xeqi | right |
| 16:58 | xeqi | "simplest" |
| 16:58 | dobry-den | right, thanks |
| 16:58 | dobry-den | rollin with that for now |
| 17:02 | danielszmulewicz | Completely off-topic: the Twitter client on the web is a SPA, right? There used to be a #!/username when navigating. Where has the location hash gone? Would anyboddy clue me in? |
| 17:06 | xpera | I'm writing a function that takes byte-array as an argument (for Java interop). |
| 17:06 | xpera | I was hoping I could attach metadata, but obviously cannot since byte[] is a primitive. |
| 17:06 | xpera | I'm looking at the Apache Commons lang library to convert byte[] to Byte[] and thinking about the cost involved |
| 17:07 | TEttinger | xpera, isn't there make-array or amake or something? |
| 17:07 | TEttinger | ,(doc amake) |
| 17:07 | clojurebot | I don't understand. |
| 17:07 | TEttinger | ,(doc make-array) |
| 17:07 | clojurebot | "([type len] [type dim & more-dims]); Creates and returns an array of instances of the specified class of the specified dimension(s). Note that a class object is required. Class objects can be obtained by using their imported or fully-qualified name. Class objects for the primitive types can be obtained using, e.g., Integer/TYPE." |
| 17:09 | xpera | TEttinger: I should look at that, thanks. reading https://groups.google.com/forum/#!topic/clojure/k8ZkpvO5QcM |
| 17:09 | TEttinger | and there's the ugly option, ^"[Ljava.lang.Byte" |
| 17:09 | TEttinger | or something like that for type hints |
| 17:11 | dobry-den | danielszmulewicz: i'm not really in the know these days but i think #! is no the best practice anymore |
| 17:11 | TEttinger | xpera: http://asymmetrical-view.com/2009/07/02/clojure-primitive-arrays.html |
| 17:11 | dobry-den | twitter could be a SPA and use pushState or whatever the kids do these days to update url |
| 17:12 | xpera | TEttinger: thanks. the main thing I want is a way to get metadata on the byte array with minimal extra stuff happening |
| 17:12 | TEttinger | well I don't know if arrays can get metadata |
| 17:12 | xpera | I'm wondering about a minimal wrapper on top. what would be the simplest thing to wrap with that would let me have metadata |
| 17:12 | xpera | primitives cannot have metadata. that includes byte arrays |
| 17:13 | dobry-den | if you (dorun (map #(future (process-thing %)) things), and then (doseq [fu futures] @fu), how come CPU indicates things are still being processed after doseq returns? |
| 17:14 | TEttinger | here, xpera |
| 17:14 | TEttinger | ,(with-meta (make-array Byte 2) {:foo :bar}) |
| 17:15 | clojurebot | #<ClassCastException java.lang.ClassCastException: [Ljava.lang.Byte; cannot be cast to clojure.lang.IObj> |
| 17:15 | xpera | pu dessem si wodniw cri ym ,ces enoI |
| 17:15 | TEttinger | arrays aren't objects and can't have metadata |
| 17:15 | justin_smith | dobry-den: maybe process-thing created a thread? |
| 17:15 | xpera | sorry, IRC weirdness |
| 17:16 | xpera | that was really strange |
| 17:16 | TEttinger | [14:13:57] <xpera> pu dessem si wodniw cri ym ,ces enoI |
| 17:16 | TEttinger | I'll say |
| 17:16 | xpera | I use Colemak |
| 17:16 | dobry-den | justin_smith: oh, so deref wouldnt work like a Thread/join. |
| 17:16 | TEttinger | window is messed up, I see |
| 17:16 | xpera | I think Textual got hosed for a second and was using qwerty? who knows |
| 17:16 | TEttinger | but it was backwards, weird |
| 17:16 | dobry-den | xpera: seems like you would lose more than you gain by trying to get meta on [B |
| 17:17 | justin_smith | dobry-den: deref should block until the future is realized, but if something in the future created a thread, that is still out there |
| 17:17 | dobry-den | justin_smith: i see. i just have a `spit` in there |
| 17:17 | xpera | what is a minimal way to wrap a primitive? without copying? that's what I'm trying to ask :) |
| 17:18 | xpera | I've looked at the source for Apache Commons lang Byte wrapping. it copies stuff |
| 17:18 | xpera | and I think a make-array solution would be similar |
| 17:18 | xpera | maybe I can't put a primitive in an object. need to think about that |
| 17:18 | alandipert | xpera: for what purpose, to carry meta? |
| 17:18 | xpera | alandipert: yes |
| 17:19 | justin_smith | (def ^:foo parcel [some-byte-array]) |
| 17:19 | justin_smith | is one way to do it |
| 17:19 | justin_smith | maybe not the best |
| 17:19 | xpera | justin_smith: right. is there a simpler way? just a plain object? |
| 17:20 | justin_smith | hmm |
| 17:20 | justin_smith | well you need a field that the byte-array could be in |
| 17:20 | dobry-den | ^:foo {:stuff bytes} |
| 17:20 | justin_smith | you could make a one-field record |
| 17:20 | xpera | ,(new Object) |
| 17:20 | clojurebot | #<Object java.lang.Object@1755401> |
| 17:20 | justin_smith | you can't put anything in a plain object, because it doesn't have a place to put it |
| 17:21 | dobry-den | you can put it in a map |
| 17:21 | TEttinger | hell an atom could do it, or a var |
| 17:22 | dobry-den | i once wanted to put metadata on a bytearray and came up with a hilariously bad abstraction where my bytes were wrapped with maps |
| 17:22 | xpera | dobry-den: the simplest so far is just a list I suppose. still looking for the simplest type that will work and accept metadata |
| 17:22 | TEttinger | var containing byte array? |
| 17:23 | xpera | TEttinger: I don't want a var, I want a simple value |
| 17:23 | xpera | but let me think about that |
| 17:23 | alandipert | [bytes]? |
| 17:24 | xpera | ,(ancestors clojure.lang.PersistentVector) |
| 17:24 | clojurebot | #{clojure.lang.IEditableCollection clojure.lang.AFn clojure.lang.Indexed java.util.Collection clojure.lang.ILookup ...} |
| 17:24 | alandipert | so by simple, you mean for performance you need something? |
| 17:24 | xpera | alandipert: part of this is a learning exercise... to understand the Clojure/Java interaction |
| 17:26 | xpera | I have an idea from https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L207 |
| 17:26 | xpera | the simplest is clojure.lang.IObj |
| 17:26 | xpera | that would the most minimal thing that could work for a simple wrapper |
| 17:28 | xpera | ,(new clojure.lang.Obj) |
| 17:28 | clojurebot | #<InstantiationError java.lang.InstantiationError: clojure.lang.Obj> |
| 17:28 | xpera | ,(new clojure.lang.IObj) |
| 17:28 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: No matching ctor found for interface clojure.lang.IObj, compiling:(NO_SOURCE_PATH:0:0)> |
| 17:31 | alandipert | xpera: https://gist.github.com/alandipert/8075949 shows some stuff |
| 17:33 | xpera | alandipert: thanks, I'll play around with that |
| 17:34 | xpera | I can't be the only person who wants to find clean ways to attach metadata to primitives. I think JIRA is littered with questions along those lines. |
| 17:34 | danielszmulewicz | dobry-den: Yes, I think you nailed it. PushState seems to be the new thing. Thanks. |
| 17:35 | justin_smith | another option: (defn box [value] (let [p (promise)] (deliver p value) p)) |
| 17:35 | justin_smith | promise is not so heavy weight a class |
| 17:36 | xpera | justin_smith: I appreciate the brainstorming, but I think that complects too much |
| 17:37 | xpera | anyhow, this is a fun way to dig into some the Java underneath Clojure |
| 17:40 | xpera | just found clojure.lang.Box |
| 17:41 | xpera | ,(clojure.lang.Box. (byte-array (map byte [0 1 2]))) |
| 17:41 | clojurebot | #<Box clojure.lang.Box@845473> |
| 17:41 | xpera | ,(with-meta (clojure.lang.Box. (byte-array (map byte [0 1 2]))) {:charset "UTF-8"}) |
| 17:41 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Box cannot be cast to clojure.lang.IObj> |
| 17:42 | xpera | clojure.lang.Box does not extend IObj. I don't see it shouldn't. |
| 17:42 | xpera | I mean I don't see why it shouldn't |
| 17:46 | xpera | re: Box... probably because it is intended to be extremely minimal, only for use in maps and vectors |
| 17:47 | danielszmulewicz | noprompt: ping |
| 17:48 | noprompt | danielszmulewicz: yo |
| 17:48 | danielszmulewicz | Hi, quick question |
| 17:48 | danielszmulewicz | I've been using secretary quite happily with goog.history |
| 17:48 | danielszmulewicz | now I'm wondering if I can make it work with html5Hisotry |
| 17:49 | danielszmulewicz | I would like to get rid of the hash bang thing (location hash) |
| 17:50 | danielszmulewicz | Have you done something with pushState? |
| 17:54 | noprompt | danielszmulewicz: i have not done anything with pushState, no. |
| 17:54 | danielszmulewicz | noprompt: OK, just asking. Thanks. I'll be investigating further. |
| 17:55 | noprompt | danielszmulewicz: if you find a solution, be sure to share a gist. |
| 17:56 | danielszmulewicz | noprompt: I will. There is some good insights here: http://squirrel.pl/blog/2013/05/30/client-side-routing-with-pedestal/ |
| 17:57 | danielszmulewicz | noprompt: Although it doesn't address pushState. |
| 18:02 | Mandar | sorry, i'm a bit lost regarding an error message: http://pastie.org/private/ai4lc6mq5safzyg9sfija |
| 18:03 | Mandar | in which function does the error occur? at which line? |
| 18:03 | xpera | Mandar: the key is to look for files where you have control; e.g. your project |
| 18:03 | TEttinger | sangria/core.clj:20 probably |
| 18:03 | xpera | Mandar: that assumes your code is the problem, which is what I assume when I look at my code :) |
| 18:04 | TEttinger | it's a wrong argument, like if you do... |
| 18:04 | TEttinger | ,(repeat [1] 1) |
| 18:04 | Mandar | xpera, i'm sure that's the problem too... but i don't see which line |
| 18:04 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 18:04 | justin_smith | Mandar: I start from the top, and check out all the stuff in namespaces I own :) |
| 18:04 | justin_smith | usually the uppermost of the ones I control is the culprit |
| 18:04 | TEttinger | oh that's interesting |
| 18:04 | Mandar | TEttinger, i don't see the error yet |
| 18:05 | xpera | Mandar: start from top to bottom and find the lines that have your project. so... `/home/armand/dev/sangria/src/sangria/core.clj:20` |
| 18:05 | TEttinger | are you using type hints? |
| 18:05 | Mandar | no i'm not |
| 18:05 | Mandar | i'll post the source code somewhere |
| 18:05 | xpera | Mandar: gist, please :) |
| 18:05 | TEttinger | yeah, I'd like to see line 20 of core and 13 of guessing_game |
| 18:06 | Mandar | i don't want someone to tell me where exactly it is, just give some guidance |
| 18:06 | TEttinger | good, because I have to get going. |
| 18:08 | Mandar | http://pastie.org/private/huteprc4elaemskkrwxwrg |
| 18:08 | Mandar | i'm playing with lazy-seqs |
| 18:09 | Mandar | working version is there: https://github.com/agolp/sangria/tree/master/src/sangria |
| 18:10 | Mandar | the error happens when i call (get-question) |
| 18:12 | justin_smith | cons should have an open paren before it on line 13 |
| 18:12 | Mandar | wow |
| 18:12 | Mandar | thanks |
| 18:12 | justin_smith | np |
| 18:12 | justin_smith | that may be the problem right there |
| 18:12 | Mandar | it worked! |
| 18:12 | justin_smith | good news |
| 18:12 | Mandar | but how could i have found it? |
| 18:12 | Mandar | are there tools for these? |
| 18:13 | Mandar | to check syntax automatically? |
| 18:13 | justin_smith | by checking what random-questions returned |
| 18:13 | justin_smith | that is not a syntax error |
| 18:13 | justin_smith | ,((fn [] cons 1 2)) |
| 18:13 | clojurebot | 2 |
| 18:13 | Mandar | what does it mean? |
| 18:13 | justin_smith | you just put cons in an implict do |
| 18:13 | justin_smith | so it gets referenced, but nothing is done with it |
| 18:13 | Mandar | oh ok |
| 18:13 | Mandar | thank you, much clearer now |
| 18:13 | justin_smith | ,((fn [] (cons 1 [2]))) |
| 18:13 | clojurebot | (1 2) |
| 18:14 | justin_smith | this actually used it |
| 18:14 | justin_smith | also auto-indenting |
| 18:14 | Mandar | should i use recur inside a lazy-seq or is it ok to call the function name again? |
| 18:14 | justin_smith | if you use an editor that supports that |
| 18:14 | justin_smith | auto-indenting makes it clear where the nesting is not what you expected |
| 18:14 | justin_smith | (usually) |
| 18:14 | Mandar | i think i "fixed" it because it wasn't working automatically, but didn't think about it |
| 18:15 | Mandar | the indentation i mean |
| 18:15 | justin_smith | yeah, never manually fix indentation |
| 18:15 | justin_smith | if it auto-indents wrong, it is wrong |
| 18:15 | justin_smith | the magic of sexprs - the editor knows exactly how it is structured, no ambiguity |
| 18:15 | Mandar | good |
| 18:16 | justin_smith | recur is best, but only works in a tail position |
| 18:16 | Mandar | and regarding recur? is there a risk of stack overflows with lazy seqs as i wrote my function? |
| 18:16 | justin_smith | a tail position is the exit point of a function |
| 18:16 | justin_smith | a point where there is no more work to be done before returning |
| 18:17 | justin_smith | lazy-seqs will not stack overflow, but recursive calls that are not using recur can |
| 18:17 | justin_smith | lazy-seqs can run out of heap space thought, if you are too agressive about realizing them or hold on to the head when you don't need it |
| 18:17 | Mandar | thanks again |
| 18:17 | justin_smith | holding onto the head is assigning it somewhere so the item cannot be garbage collected |
| 18:17 | justin_smith | np |
| 18:18 | justin_smith | recur will throw an error if you call recur but not from the tail |
| 18:18 | justin_smith | if your algorithm can be expressed with recur, it is better to use it |
| 18:24 | SegFaultAX | justin_smith: That last point is probably arguable. If there is a more natural expression of your algorithm (perhaps using reduce), that's preferrable to explicit recursion. |
| 18:24 | justin_smith | SegFaultAX: fair enough, yeah |
| 18:25 | justin_smith | I meant if the alternative was a self call, but of course often you can refactor to a reduce |
| 18:25 | justin_smith | or map, for, etc. |
| 18:27 | SegFaultAX | In general, avoid explicit recursion in favor of the other existing sequence abstractions. |
| 18:27 | justin_smith | right |
| 18:32 | rads | https://github.com/swannodette/om/blob/master/src/om/core.cljs#L171 |
| 18:32 | rads | dnolen: looks like there is a typo there? cursor' instead of cursor |
| 18:34 | dnolen | rads: good catch fixed in master |
| 18:34 | rads | cool |
| 18:36 | bitemyapp | SegFaultAX: using recursion when a fold would've suited also tends to defeat optimization in Haskell. |
| 18:36 | bitemyapp | it's also less expressive to use recursion where it isn't strictly needed. |
| 18:37 | bitemyapp | the best use-case of recursion I can think of is parsing. |
| 18:38 | bitemyapp | which would figure, since I've been fucking with parsers in Python and the lack of TCO is wrecking my sanity. |
| 18:38 | pandeiro | dnolen: any idea if om and hoplon would play well together? |
| 18:38 | dnolen | pandeiro: you'd have to talk to alandipert and micha |
| 18:39 | alandipert | pandeiro: i dunno, talk to dnolen ;-) |
| 18:39 | dnolen | alandipert: haha |
| 18:39 | SegFaultAX | bitemyapp: I can think of infinitely many use cases for recursion. :) |
| 18:39 | pandeiro | i'm getting the recursive runaround |
| 18:39 | pandeiro | i was thinking react for the one-way stuff and javelin for when i want more magical two way binding |
| 18:40 | pandeiro | i still haven't used hoplon yet but i am anxious to try it out |
| 18:40 | alandipert | pandeiro: seriously though, i don't know, i haven't dug into om |
| 18:40 | dnolen | pandeiro: Om is primarily concerned with fast rendering and being able to represent components as EDN |
| 18:41 | dnolen | pandeiro: hopefully that means it easy to plugin to whatever |
| 18:41 | pandeiro | dnolen: the latter aspect seems similar to webfui |
| 18:41 | alandipert | hoplon is primarily concerned with conceptual simplicity, linear modification complexity, and designer friendliness |
| 18:41 | dnolen | pandeiro: yes |
| 18:41 | pandeiro | i am writing angular during the day right now |
| 18:42 | dnolen | alandipert: yeah Om isn't ever going to provide a particular template syntax, but I expect people layer whatever they like over it. |
| 18:42 | alandipert | by which i mean, large hoplon apps shouldn't be more complicated to change as they get larger |
| 18:42 | Mandar | is there a more idiomatic way to write this when you don't care about the result values? (doall (map ask questions)) |
| 18:42 | alandipert | for us it's a question of clojurescript syntax, as we don't templates |
| 18:42 | SegFaultAX | Mandar: doseq |
| 18:42 | pandeiro | i will be experimenting with the combo over the holidays |
| 18:42 | Mandar | SegFaultAX, thanks |
| 18:42 | pandeiro | alandipert: i think that is the major draw for me, i love the html as sexp idea |
| 18:43 | SegFaultAX | I consider it a code smell to use map for side-effecting code. |
| 18:43 | pandeiro | and i noticed that om has a dom ns doing something similar, at least syntactically |
| 18:43 | pandeiro | (i think) |
| 18:43 | alandipert | pandeiro: did you see the thing on ML about dom-as-lisp? |
| 18:43 | alandipert | pandeiro: err the message i posted elaborating on the concept |
| 18:43 | pandeiro | alandipert: no, let me dig that up |
| 18:44 | pandeiro | alandipert: but i will never think the dom the same again after watching your talk... |
| 18:44 | pandeiro | :) |
| 18:45 | bitemyapp | SegFaultAX: do ho ho |
| 18:45 | alandipert | pandeiro: https://groups.google.com/forum/#!msg/clojure/gRFyzvRfPa8/QY_HvjaVfvUJ |
| 18:45 | SegFaultAX | bitemyapp: Vidya? |
| 18:46 | bitemyapp | SegFaultAX: if that's an invitation, I'd be up for something. What do you have in mind? |
| 18:46 | roland_ | dnolen: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L174 |
| 18:47 | roland_ | dnolen: is there supposed to be some :true there? |
| 18:47 | SegFaultAX | bitemyapp: Dunno. Haven't really gamed in some time. What sounds good? |
| 18:47 | bitemyapp | SegFaultAX: I've been mostly playing CS:GO, Insurgency, Dota 2, and DayZ lately. |
| 18:48 | roland_ | dnolen: ie an else for cond expression |
| 18:51 | SegFaultAX | bitemyapp: DayZ is that the survival one? |
| 18:52 | dnolen | roland_: fixed thanks |
| 18:52 | roland_ | dnolen: np |
| 18:52 | bitemyapp | SegFaultAX: yeah, the standalone version finally came out. |
| 18:55 | bitemyapp | SegFaultAX: have a mumble and a teamspeak server we can hop into. |
| 18:56 | SegFaultAX | bitemyapp: Sorry, got caught up browsing the steam sale... |
| 18:57 | bitemyapp | SegFaultAX: s'no problem. Let me know when you want the talk server details. |
| 18:57 | bitemyapp | SegFaultAX: that deal on CS:GO is really good. |
| 18:58 | bitemyapp | I like that DayZ has been the top-seller for days on end, even during the holiday sale, with no discount offered. |
| 19:27 | Mandar | sorry to be a pain :( |
| 19:27 | Mandar | http://pastie.org/private/wfjvtnjadgwjxxn1md4t1q |
| 19:27 | Mandar | i don't get it, been searching for more than 15 min now |
| 19:27 | the-kenny | dnolen: Ping. May I ask you something about a bug/problem I have with the latest HEAD of Om? |
| 19:27 | SegFaultAX | Mandar: What don't you get? |
| 19:27 | SegFaultAX | Oh, looking at paste. |
| 19:27 | Mandar | SegFaultAX, why do I get this IllegalArgumentException? |
| 19:28 | the-kenny | Mandar: -> puts the 'previous' item at the *first* position of the current |
| 19:28 | Mandar | oh |
| 19:28 | SegFaultAX | Mandar: Use ->> |
| 19:28 | Mandar | thanks :( |
| 19:28 | the-kenny | so you have (count (map (doall (map ask questions)) identity)) |
| 19:30 | the-kenny | Mandar: also, you can drop the 'doall' here. While map & filter are lazy, count will realize the seq anyway |
| 19:30 | Mandar | the-kenny, thank you |
| 19:30 | bitemyapp | Mandar: try to avoid blind forcing. |
| 19:31 | Mandar | bitemyapp, "blind forcing"? |
| 19:31 | bitemyapp | preemptive optimization. |
| 19:31 | SegFaultAX | Well in this case ask is almost certainly doing side-effects. So without considering the rest of the ->> form, it makes sense here probably. |
| 19:31 | Mandar | bitemyapp, regarding the lazy seq you mean? |
| 19:32 | Mandar | and yes, ask is doing i/o |
| 19:34 | the-kenny | well, there shouldn't really be a big difference between forcing it before and after the filter |
| 19:36 | Mandar | the whole file is here: https://github.com/agolp/sangria/blob/master/src/sangria/guessing_game.clj |
| 19:36 | Mandar | i know i shouldn't use the console right there, but i'll make things better once i start adding a user interface |
| 19:47 | the-kenny | It's actually quite fine. At least that's what it looks to me ;) |
| 19:48 | the-kenny | You should think about rewriting `random-questions' though. Is lazy-seq in this case really necessary? |
| 19:54 | dnolen | the-kenny: what's up? |
| 19:55 | the-kenny | dnolen: Using latest Om, using {:path [:todos]} for om/build fails, while just [:todos] works fine. |
| 19:55 | Mandar | the-kenny, i don't know if it's necessary, i wanted to play with lazy-seqs and i find it quite nice |
| 19:55 | Mandar | but really i was looking for an excuse to use some |
| 19:55 | the-kenny | heh |
| 19:56 | the-kenny | Mandar: I usually prefer to implement such stuff in terms of other sequence functions (iterate or repeatedly comes to mind) than lazy-seq. It's likely a matter of taste |
| 19:57 | dnolen | the-kenny: try now |
| 19:57 | Mandar | the-kenny, i'll try them, thanks |
| 19:58 | the-kenny | dnolen: Works, thanks :) |
| 19:59 | the-kenny | Also, thanks again for building Om. I really like the approach for client-side development, and I'll definitely use it for some stuff soon. |
| 20:02 | dnolen | the-kenny: thanks, there still quite a few loose ends and honestly I'm not completely convinced by the design :) |
| 20:02 | dnolen | not sure how much more warning than pre-alpha software I can give |
| 20:02 | dnolen | the only thing I'm convinced about is the building UIs w/ EDN is a good idea and immutability is a nice perf boost |
| 20:03 | Mandar | dnolen, are you considering adding support for something like jsx too? |
| 20:03 | the-kenny | What I enjoy most is the 'easy' reactive approach. If you just want a simple 'dumb' ui, you get away with an atom plus a few functions. |
| 20:03 | dnolen | Mandar: nope, all sugar over React/Om DOM stuff should be provided by other people. |
| 20:03 | dnolen | people have different opinions about that stuff, and I don't want to get involved at all |
| 20:04 | Mandar | dnolen, fair enough |
| 20:04 | the-kenny | dnolen: I totally agree there. Not just because of different opinions, but also by the complexity |
| 20:04 | dnolen | the-kenny: yep |
| 20:04 | the-kenny | Something like hiccup/dommy looks easy, but there are really some pitfalls |
| 20:06 | the-kenny | dnolen: With which part of the design of Om (or a greater thing?) aren't you happy with? |
| 20:06 | Mandar | the-kenny, they are nice for developers, but most web designers just want to be able to edit html |
| 20:08 | the-kenny | Mandar: The html guy at my previous employer actually preferred hiccup-syntax over html |
| 20:08 | Mandar | the-kenny, i think that's the exception |
| 20:08 | Mandar | i've worked with quite a lot of frontend guys and they mostly prefer to be able to use their tools |
| 20:09 | Mandar | (i mostly work as a web developer) |
| 20:09 | the-kenny | yeah, of course. I just wanted to mention it :) |
| 20:09 | Mandar | but i understand that the lib shouldn't try to "bite more than it can chew" |
| 20:09 | Mandar | it would be a fun exercise to try and reimplement something like jsx |
| 20:15 | dnolen | the-kenny: the cursor concept is a little bit thorny, it's easy to have the "wrong" one if you're not careful about your design. |
| 20:15 | dnolen | the-kenny: so I'd like to figure out how to minimize that |
| 20:16 | dnolen | the-kenny: ideally eliminate that possibility |
| 20:16 | dnolen | if we can't eliminate it I'm thinking maybe throw an error to indicate your tried to update a stale cursor |
| 20:16 | the-kenny | What's 'the wrong one' in this case? From the top, cursors look just like an `get-in'-like interface |
| 20:17 | the-kenny | (plus the ability to mutate them though, I'm not sure if I like that yet) |
| 20:17 | dnolen | the-kenny: open to ideas about get rid of explicit update! but I couldn't come up w/ anything given how React works w/o building a lot more machinery |
| 20:18 | dnolen | the-kenny: the wrong one is if you some how forgot to make sure some nodes got updated, their cursors will be stale |
| 20:18 | dnolen | the-kenny: simplest example is deleting from a middle of a list of things |
| 20:18 | the-kenny | Well, you don't have to use update!, you can always mutate the top-level state atom, but update! is likely much better |
| 20:18 | dnolen | everyone after the deleted thing will have invalid cursors, they need to be re-rendered even though technically they didn't change. |
| 20:18 | dnolen | so something to think through |
| 20:18 | the-kenny | dnolen: ah. Haven't come up with something like this yet |
| 20:19 | dnolen | the-kenny: yes early on I had an API that included an explicit path |
| 20:20 | dnolen | I toyed w/ passing path and state via opts |
| 20:20 | dnolen | so I'm open to changing how it works if people hate it |
| 20:20 | dnolen | releasing Om was just trying to show people that UI + Immutable data can be rocking |
| 20:20 | dnolen | now we gotta figure out it should actually look like |
| 20:21 | the-kenny | I didn't mean to say I dislike update! or the approach in general, sorry! |
| 20:21 | dnolen | the-kenny: haha, it's OK if you do :) |
| 20:22 | dnolen | all feedback welcome at this point |
| 20:22 | the-kenny | It's actually quite nice. Useful to reduce the amount of the whole application every component sees. The update! was just something that caught my eye. |
| 20:22 | the-kenny | Delegating the event handling via an async-channel in the TodoMVC example was quite nice too. |
| 20:23 | the-kenny | Not sure if I'd pass the channel around via the component's state though |
| 20:23 | dnolen | the-kenny: yes, talking between logical components w/ core.async is pretty sweet |
| 20:24 | dnolen | the-kenny: I agree about passing channels via opts being OK probably something cleaner possible |
| 20:24 | xpera | i decided to roll a quick java class for the primitive boxing with metadata thing here: https://github.com/bluemont/clj-metabox |
| 20:24 | xpera | java source here: https://github.com/bluemont/clj-metabox/blob/master/src/java/metabox/MetaBox.java |
| 20:25 | justin_smith | if all you wanted was to box a number, why not use a class like Double or Integer? |
| 20:25 | xpera | justin_smith: see the bottom of the README |
| 20:26 | xpera | I wish it looked nicer in the REPL. (metabox/box 3) doesn't display just "3" |
| 20:26 | the-kenny | justin_smith: because java.lang.Number doesn't implement IObj, which implements meta-data |
| 20:26 | xpera | please let me know if I messed anything up. i was tempted to implement comparable until I realized that would not have made sense in general |
| 20:33 | justin_smith | xpera: would implementing IDeref make sense? |
| 20:33 | justin_smith | then @box would work |
| 20:34 | the-kenny | Ok, I'm heading to bed now. Let's see if I can use Om for some real stuff over Christmas :) I'm tempted to reimplement a Ember.js application from work just for fun. |
| 20:34 | the-kenny | dnolen: Thanks again for creating Om & fixing the problem in such a short time! Let me know if I can help you somehow. |
| 20:35 | dnolen | the-kenny: feedback after you've have had a chance to kick around would be great |
| 20:36 | dnolen | the-kenny: I think in the short term just going to focus on Om as rendering solution, there's a couple of patches I'd like to land in React to make things nicer |
| 20:36 | xpera | justin_smith: that has to do with reference types. I was interested in values |
| 20:36 | dnolen | like a React Iterator so we can pass seqs to React |
| 20:36 | dnolen | instead of putting things into arrays |
| 20:37 | dnolen | and a way to tell React exactly which children to look at, instead of considering all children (even though that's a cheap operations makes a different when you're showing a lot of data) |
| 20:38 | dnolen | s/different/difference |
| 20:40 | the-kenny | Rendering seems like a good focus, it's the most obvious and most useful part :) I'll send you some feedback when I've done something which is more than a todo list |
| 20:41 | dnolen | the-kenny: cool, thanks |
| 20:41 | the-kenny | Until then - Good night! |
| 20:41 | dnolen | the-kenny: later |
| 20:41 | Mandar | the-kenny, good night! |
| 20:42 | justin_smith | xpera: what it has in common with a reference type is that it is there to wrap a single value |
| 20:42 | xpera | justin_smith: but the key is what 'wrapping' means, right :) |
| 20:43 | xpera | reference types wrap for a different reason, even though the english word is still 'wrap' |
| 20:43 | justin_smith | reference types wrap for multiple reasons |
| 20:43 | justin_smith | because the target needs coordinating, because it is not ready yet |
| 20:44 | xpera | that's an interesting way of looking at it |
| 20:45 | xpera | i put together the MetaBox class after looking at how some of the value types did things |
| 20:45 | xpera | i didn't want any other added semantics or meaning attached |
| 20:46 | xpera | alandipert thanks for your gist, that got my brain thinking |
| 20:50 | alandipert | xpera: np! |
| 20:50 | xpera | justin_smith: you got me thinking though. just re-read the O'Reilly section on reference types. I'm thinking about what would happen if the underlying value changed |
| 20:50 | alandipert | xpera: what did you end up doing? |
| 20:50 | xpera | alandipert: I wrote a Java class: https://github.com/bluemont/clj-metabox/blob/master/src/java/metabox/MetaBox.java |
| 20:51 | justin_smith | xpera: delays, futures, and promises never change |
| 20:52 | alandipert | xpera: nice! any reason for java? |
| 20:52 | xpera | justin_smith: are we just talking as an idea/alternative... or are you recommending the IDeref way strongly? |
| 20:53 | justin_smith | The commonality of course is that they are a semi-opaque container for a value, the difference is in your case the value is immediately ready for usage and does not change - with the built in reference types they are either alterable or held for later in some way. |
| 20:53 | justin_smith | xpera: brainstorming, I don't have a strong opinion, just working out the case for / against. |
| 20:53 | xpera | alandipert: deftype would probably work just as well |
| 20:53 | alandipert | xpera: cool, def. worth exploring the other side of interop anyway |
| 20:53 | xpera | and would be better for clojurescript |
| 20:54 | xpera | justin_smith: yes, I don't want people changing the val -- I went to some trouble in the Java class to hide the val in _val |
| 20:55 | xpera | justin_smith: when I think of reference types, I think of identity and state, which seems like more than was needed for my use case |
| 20:55 | xpera | my goal was immutability, now that I think about it |
| 20:55 | justin_smith | how do delay / future / promise / relate to identity and state? |
| 20:56 | xpera | alandipert: I haven't really dug into clojurescript. might be a good thing to try next |
| 20:56 | xpera | justin_smith: time! |
| 20:56 | xpera | they can change |
| 20:57 | justin_smith | a promise or delay or future do not change |
| 20:57 | justin_smith | they may make you wait until they are ready |
| 20:57 | justin_smith | but they do not ever change |
| 20:57 | xpera | ok, fair point |
| 20:57 | xpera | but time matters for them |
| 20:57 | justin_smith | yes |
| 20:58 | xpera | and underneath, things ARE changing |
| 20:58 | justin_smith | maybe that is the key point |
| 20:58 | alandipert | xpera: in cljs, it's neat, you can just extend imeta to whatever types since cljs is all protocols |
| 20:58 | justin_smith | xpera: underneath every calculation is a change, period |
| 20:58 | xpera | justin_smith: but when is that change ready and expected? |
| 20:58 | justin_smith | as far as the CPU is concerned even identity is a mutation |
| 20:58 | xpera | with values, operations happen and are ready immediately (more or less) |
| 20:59 | xpera | with the reference types, time is a factor underneath |
| 20:59 | justin_smith | unless they are lazy |
| 20:59 | xpera | justin_smith: yeah, but still, when you evaluate, it happens to the degree it happens. no time involvement. |
| 20:59 | justin_smith | not with delay - delay gets set once, it is just that the calculation is lazy |
| 21:00 | justin_smith | but regardless of time it will calculate the same calculation |
| 21:01 | xpera | justin_smith: well I stiil feel pretty good about a simple class that implements IObj :) |
| 21:01 | xpera | but I appreciate the interconnections and discussion |
| 21:01 | yedi | whats the most idiomatic way to aadd something to the end of the last vec in a vec of vecs? aka [[1 2] [3 4]], 5 => [[1,2][3 4 5]] |
| 21:05 | alandipert | yedi: (conj (pop v) (conj (peek v) x)) maybe? |
| 21:06 | alandipert | yedi: where v is the vec of vecs and x is the new item |
| 21:07 | justin_smith | ,(map (fn update-deepest-vector [e v] (if (vector? (peek v)) (conj (pop v) (update-deepest-vector e (peek v))) (conj v e))) (range) [[0 1] [0 [1]] [0 [[1]]]]) |
| 21:07 | clojurebot | ([0 1 0] [0 [1 1]] [0 [[1 2]]]) |
| 21:08 | justin_smith | maybe I misunderstood the question |
| 21:08 | alandipert | or maybe (update-in v (dec (count v)) conj x) |
| 21:08 | xpera | ,(let [v [[1 2] [3 4]] x 5] (conj (pop v) (conj (peek v) x))) |
| 21:08 | clojurebot | [[1 2] [3 4 5]] |
| 21:09 | xpera | yedi: what alandipert said ^ |
| 21:09 | alandipert | err (update-in v [(dec (count v))] conj x) |
| 21:12 | yedi | (inc alandipert) |
| 21:12 | lazybot | ⇒ 1 |
| 21:13 | yedi | is there a fn partition-vec that does the equivalent of (vec (map vec (partition _ _ coll)) ? |
| 21:13 | yedi | so it returns of vector of vectors instead of a list of lists |
| 21:13 | yedi | don't wanna have to recreate what might already exist |
| 21:13 | justin_smith | well mapv is (vec (map ...)) |
| 21:14 | justin_smith | so you are down to (mapv vec (partition ...)) at worst |
| 21:14 | justin_smith | mapvv would be an OK name for #(mapv vec %) |
| 21:27 | arrdem | bitemyapp: I suspect you're right that I need some sort of higher order structure here. damnit. |
| 21:29 | bitemyapp | arrdem: http://i.imgur.com/IUoMA1y.jpg |
| 21:30 | bitemyapp | arrdem: on that note: http://ocharles.org.uk/blog/guest-posts/2013-12-21-24-days-of-hackage-contravariant.html |
| 21:30 | bitemyapp | arrdem: fyi: contravariants and profunctors have applications in probability mass functions... |
| 21:31 | `cbp`` | bitemyapp: im officially free for two weeks.. kinda! Time to finish revise and eris and something else :-) |
| 21:31 | bitemyapp | `cbp: awesome :) |
| 21:31 | arrdem | `cbp: I was about to ask you to simplify your name. thank you. |
| 21:31 | bitemyapp | `cbp: I'm hacking with noprompt and another friend tomorrow on Frak++. Probably using vacation time to do some hacking on Simonides too. |
| 21:32 | `cbp | bitemyapp: what-s Frak |
| 21:32 | bitemyapp | arrdem: but seriously, look at that article about contravariant. |
| 21:35 | bitemyapp | `cbp: noprompt's regex generation thingy. He wants to rewrite it in Haskell to get a mental model for compare/contrast. |
| 21:35 | bitemyapp | `cbp: you should join me in the doters :3 |
| 21:36 | `cbp | bitemyapp: someone else beat you in inviting me unfortunately :S |
| 21:36 | bitemyapp | NOOOOOOOOOOOOOO |
| 21:37 | bitemyapp | `cbp: toss me invite? |
| 21:37 | `cbp | its for europa universalis 4 |
| 21:37 | bitemyapp | nuts. |
| 21:42 | danlentz | hey bitemyapp: i liked your 'exception' macro in brambling and posted about it on google+ |
| 21:44 | danlentz | both as a good example of how to make effective use of the destructuring and for its intended purpose |
| 21:45 | danlentz | my question is if there is a similar technique whereby optional args also can have default values when not provided |
| 21:45 | bitemyapp | danlentz: wasn't even mine! yogthos lent it to me :) |
| 21:45 | bitemyapp | danlentz: appreciate it though, glad somebody is looking at brambling. |
| 21:45 | justin_smith | danlentz: destructuring with :or only works when destructuring maps iirc |
| 21:46 | danlentz | datomic is really mind-blowing i'm very excited about it |
| 21:49 | danlentz | your destructuring way of optional args is a hell of a lot more convenient than fn with multiple bodies approach |
| 21:49 | danlentz | srry i droppped off for av sec colloquy is shit |
| 21:49 | justin_smith | ,(let [[a & [b c] :as all :or {b 2 c 3}] [1]] [a b c]) |
| 21:49 | clojurebot | [1 nil nil] |
| 21:50 | justin_smith | ,(let [{:keys [a b c] :as all :or {b 2 c 3}} {}] [a b c]) |
| 21:50 | clojurebot | [nil 2 3] |
| 21:50 | danlentz | whoa cool |
| 21:50 | justin_smith | notice with the vector the :or is a noop |
| 21:50 | justin_smith | it doesn't complain, it is just a noop |
| 21:50 | justin_smith | but with a map it works |
| 21:50 | danlentz | sombidy needs to make a list of these usefgul destructuring templates |
| 21:50 | justin_smith | http://clojure.org/special_forms |
| 21:52 | danlentz | ok i gues reading the docs could also work :) |
| 21:52 | `cbp | a noop? |
| 21:52 | justin_smith | `cbp: it does nothing, silently |
| 21:53 | danlentz | i think when i read it i blew through it w/o fully appreciating the importance |
| 21:56 | bitemyapp | `cbp: no-op |
| 21:56 | bitemyapp | `cbp: or nop |
| 21:58 | danlentz | clojures universal destructueing is really quite wonderful |
| 21:59 | Apage43 | I'm often tempted to use it in a fn sig though, which typically means it shows up in generated API docs. A bit icky =P |
| 21:59 | Apage43 | easy enough just to drop that down into a let tho |
| 21:59 | justin_smith | Apage43: only icky if people don't know how to read it |
| 22:00 | Apage43 | justin_smith: more that internal details of the fn are leaked into the docs |
| 22:00 | Apage43 | like |
| 22:01 | justin_smith | with a vector I can kind of see the point, but with a destructured map, the destructuring is the api |
| 22:01 | Apage43 | (fn [some args {:as options :keys [foo bar baz] bar-baz :name-that-was-inconvenient}] ..) |
| 22:01 | Apage43 | where in most cases I just want to see "options" there, and the docstring explain wtf you can pass |
| 22:02 | justin_smith | renaming of keys is another question, yeah |
| 22:26 | logic_prog | in cljs, is there a wya to get goog.dom/getElementById to be able to find elemnt, by id, of elements taht are (1) created (via js/documente create ...), but NOT yet attahed to the document? |
| 22:26 | logic_prog | right now, goog.dom/getElemtnById seems to only return elements that are actually attached to the DOM tree |
| 22:53 | bitemyapp | in case anyone was wondering, Sean McDirmid of Microsoft Research is a massive prick. |
| 23:06 | tbaldridge | okay, I'll bite, how so? |
| 23:09 | arrdem | bitemyapp: do tell |
| 23:27 | rubber-duck | anyone knows why clojurescript compile time goes up to 13 seconds from 1 second just from placing a .clj file inside the .cljs folder ? |
| 23:28 | rubber-duck | the .cljs files don't even reference the .clj files just putting a .clj file in the clojurescript source folder makes cljsbuild take 13 seconds |
| 23:31 | bitemyapp | tbaldridge: btw, are persistentarraymap and treemap in clojure-py supposed to be broken? Could only get hashmap working. |
| 23:31 | bitemyapp | tbaldridge: PAM breaks with an indexing exception if you try to assoc. Didn't see any tests. |
| 23:32 | tbaldridge | no they aren't supposed to be broken. But I haven't worked on clojure-py for over a year now. Feel free to submit a patch |
| 23:32 | bitemyapp | spooky. k. |