2012-05-18
| 00:00 | fil512 | it kinda feels like you have to be above-average smart to develope in it, and it's easy to write code that's hard to understand... |
| 00:00 | PeregrinePDX | I don't think I am above average smart for a programmer. |
| 00:00 | PeregrinePDX | I'm also pretty new to clojure and it takes me awhile but I can figure out a lot of clojure. |
| 00:01 | ivan__ | fil512: i think you have to be open minded more than smart - so many developers never seem to want to try anything new |
| 00:01 | fil512 | I want to have the confidence that anyone from any team could walk up to the clojure code and understand what it's doing. but I worry this is not the case with clojure the way it is with more structured languages like java |
| 00:02 | fil512 | I work on million dollar software projects. Our code has to be maintainable. |
| 00:02 | fil512 | I'm always keeping an eye out for the next big thing. |
| 00:02 | fil512 | Clojure is a candidate right now. |
| 00:03 | fil512 | But is it a "business grade" programming language. |
| 00:03 | fil512 | That's what I'm trying to figure out... |
| 00:03 | ivan__ | fil512: should watch the infoq presentation the guardian did on there move to scala - its maybe not directly related to clojure but it was interesting about java guys trying something new |
| 00:04 | fil512 | I've heard disastrous things about scala. Definitely not an option for us. |
| 00:04 | fil512 | My impression of scala is some guy got impatient with java not having all the stuff he wanted in a language and so he invented a way to extend java so he could put all that cool stuff in... |
| 00:04 | ivan__ | haha i dont think thats true at all |
| 00:05 | fil512 | clojure feels orders of magnitude better thought out than scala |
| 00:05 | fil512 | variable immutability as a way to deal with multi-core |
| 00:05 | fil512 | super-clean kernel |
| 00:06 | fil512 | when the robot overlords take over the world, they will code in clojure |
| 00:06 | brehaut | immutable data is a way to deal with reason in general. multi-core happens to fall out of that |
| 00:06 | brehaut | but its far more valuable than just that |
| 00:06 | ivan__ | clojure is nice - but scala has its good points to. One of them is that its easy for java guys to get started |
| 00:07 | eggsby | ya ivan__ |
| 00:07 | fil512 | C# is easy for Java guys to learn too. That's not a criteria for me. |
| 00:07 | eggsby | we have a lot of scala guys at work, only a few clj |
| 00:07 | ivan__ | yeah, immutable data is the way to go - scala provides nice things for that too |
| 00:07 | fil512 | been good chatting |
| 00:07 | fil512 | gtg |
| 00:07 | fil512 | thanks for the help! |
| 00:08 | ivan__ | seeya |
| 00:08 | ivan__ | idk, im all for clojure - but if you have 120 guys that dont know it, but know java - it seems like it would be a big deal to move to it heh |
| 00:08 | eggsby | I think the biggest practical difference between clojure and scala, while both can mostly implement the features of the other without too much pain, if you switch from java to scala you don't need to learn anything, just a bit of syntax |
| 00:09 | mtkoan | I shudder at the thought of 120 programmers |
| 00:09 | eggsby | but if you switch to clojure, you'll have to completely change how you think about writing programs |
| 00:09 | eggsby | i.e. you can have 10 years of java experience and pick up scala in a few days, clojure would probably take a few weeks/months if you haven't had prior FP experience |
| 00:09 | ivan__ | there arent many scala guys at work (and no clojure), but i can get away with using scala as long as I keep it nice and clean and dont try and do stuopid stuff with type system - java guys can read the code |
| 00:10 | eggsby | if you are using groovy you could probably switch to scala without people really noticing :p |
| 00:10 | ivan__ | eggsby: yeah - for me I started by writting scala in a very java way, over time i learnt how to work with immutable data, fp stuff etc |
| 00:11 | ivan__ | not that i want to rant on about scala in #clojure haha - but i was just finding it wierd the objections that guy has to it |
| 00:11 | eggsby | I liked fogus' talk about macros, where he implemented BASIC as a DSL in scala, then showed how because it didn't have macros parts of the language peeked through in the implementation |
| 00:12 | ivan__ | this was before 2.10? |
| 00:12 | ivan__ | (2.10 has macros) |
| 00:13 | ivan__ | macros in scala dont make a lot of sense to me yet - ive seen one example but i understood the use in clojure a lot easier |
| 00:13 | eggsby | ah, must've been |
| 00:13 | eggsby | but ya lol @ scala not being enterprise grade, hi twitter |
| 00:14 | eggsby | ONE MILLION DOLLARS |
| 00:14 | eggsby | :) |
| 00:14 | ivan__ | The Guardian... they started out by using scala for doing the java test code - to make it interesting |
| 00:14 | ivan__ | would be cool if i could do the same thing with clojure |
| 00:15 | eggsby | Clojure has been an enlightening experience. Kind of a lesson in the power of abstractions |
| 00:16 | eggsby | I've been making the finishing touches to a system I built for work in clojure, the architecture from it was lifted from ring's middleware implementation, seemed like a good way to model transformations over data... then I ran into this article today: stuartsierra.com/2012/05/16/syntactic-pipelines |
| 00:16 | eggsby | I had a lot of the same problems, repeated logic deep inside function bodies, seeing that repetition just plucked away with macros is so beautiful |
| 00:17 | eggsby | I guess any language with metaprogramming capabilities can make something like that happen, but it just seems so elegant/general in clj/lisp |
| 02:09 | Raynes | People should be talking in this channel. |
| 02:10 | PeregrinePDX | Sorry I was reading Clojure Programming |
| 02:14 | PeregrinePDX | I suppose I could put my random thoughts regarding learning clojure in here rather then in a PM window to someone I know. |
| 02:14 | PeregrinePDX | But really I don't know that people are that interested that I find the existance of empty as a pleasant surprise. |
| 02:20 | PeregrinePDX | Although my cat seems to think learning clojure is a poor choice of my time and it would be better spent petting her. |
| 02:21 | Raynes | PeregrinePDX: It is late enough and quiet enough that your random thoughts should be socially acceptable. |
| 02:21 | Raynes | And if they serve to keep me entertained, rest assured that I will hold off the beasts. |
| 02:43 | PeregrinePDX | Oh I like the existance of transients although I imagin some people prematurely optimize things by using them too much. |
| 02:50 | amalloy | PeregrinePDX: i don't think that happens very often |
| 02:51 | amalloy | clojure is very...firm on the topic of immutability, and nobody uses transients just for fun. records, now...those get used prematurely all the time |
| 02:51 | PeregrinePDX | Then clojure programmers are far more disciplined then some of my former coworkers. |
| 02:52 | amalloy | as a nice aside, i (and probably you) often write code that benefits from transients without having to think about it: ##(doc into) uses a transient under the hood |
| 02:52 | lazybot | ⇒ "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined." |
| 02:52 | PeregrinePDX | Yeah, the clojure programming book I am reading was explaining that about into. |
| 03:02 | aperiodic | speaking of records, i have a thing (bezier curve) that i want to be able to use like a map is basically every way besides when it's invoked |
| 03:02 | aperiodic | what's the easiest way to do that? |
| 03:03 | aperiodic | s/is basically/in basically/ |
| 03:20 | amalloy | aperiodic: maybe (defrecord Bezier [] clojure.lang.IFn (invoke [this arg] ...))? |
| 03:30 | kral | namaste |
| 03:33 | aperiodic | amalloy: is that sufficient? i remember hearing something about a gotcha if you don't implement all the arities for invoke in BG's clojure/west talk, but it might've been minor |
| 03:33 | amalloy | i guess you probably also have to implement applyTo |
| 03:36 | aperiodic | i should really get in the habit of checking clojure's source |
| 03:38 | amalloy | good habit to have |
| 03:41 | aperiodic | yeah, i'm just a little irrationally reluctant about reading java, and the style will probably take me a little getting used to |
| 05:50 | xumingmingv | can some one explain this: http://stackoverflow.com/questions/4921566/clojure-returning-a-vector-from-an-anonymous-function |
| 05:50 | xumingmingv | (explain the accepted answer) |
| 05:50 | xumingmingv | i know list is function call |
| 05:51 | xumingmingv | vector is also function call? |
| 05:52 | babilen | &([1 2 3] 0) |
| 05:52 | lazybot | ⇒ 1 |
| 05:52 | Borkdude | xumingmingv: ##([1 2 3]) ;; calling a vector from function position with no args |
| 05:52 | lazybot | clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector |
| 05:52 | Borkdude | xumingmingv: ##(vector 1 2 3) ;; calling the vector "function" to construct a vector |
| 05:52 | lazybot | ⇒ [1 2 3] |
| 05:52 | babilen | xumingmingv: You can use (vector index) to get an element at the given index |
| 05:54 | xumingmingv | ah, ok, i got it |
| 05:54 | xumingmingv | do you guys feels it confusing? |
| 05:55 | Borkdude | xumingmingv: anonymous function with #-notation tricked me before as well |
| 05:55 | babilen | Not much -- The same works with maps (i.e. ##({:a 1} :a} == (get {:a 1} :a) |
| 05:55 | Borkdude | xumingmingv: ,((fn [] [1 2 3])) |
| 05:55 | Borkdude | xumingmingv: ##((fn [] [1 2 3])) |
| 05:55 | lazybot | ⇒ [1 2 3] |
| 05:56 | Borkdude | xumingmingv: with this notation #( … how to return a vector directly? I think you can't ) |
| 05:57 | Borkdude | xumingmingv: a literal that is. by calling the vector "fn" you can |
| 05:57 | Borkdude | ,(#(vector 1 2 3)) |
| 05:57 | clojurebot | [1 2 3] |
| 05:59 | xumingmingv | thanks you guys, Borkdude babilen |
| 06:00 | Borkdude | wow this is ugly… ##(+ 1 2 3 nil) |
| 06:00 | lazybot | java.lang.NullPointerException |
| 06:03 | myarray | please, can anyone explain, what is the motivation of max-key / min-key functions in returning the *last* match instead of first? |
| 06:03 | myarray | (apply max-key count [[1 2] [3 4] [5] [6 7] [8]]) |
| 06:04 | Borkdude | ,(doc max-key) |
| 06:04 | clojurebot | "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest." |
| 06:04 | Borkdude | myarray: it probably uses reduce |
| 06:05 | Borkdude | myarray: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4419 |
| 06:06 | Raynes | Well, it has too... |
| 06:06 | Raynes | I mean, if you want a sane algorithm. |
| 06:06 | Borkdude | Raynes: yes |
| 06:06 | Raynes | It has to go through all of them to know what the greatest is, so it makes sense for it to return the last greatest it finds. |
| 06:07 | Raynes | Though it could return the first it finds. |
| 06:08 | Borkdude | Raynes: or all the maxima |
| 06:09 | Borkdude | (what is the plural of maximum in English? maximums?) |
| 06:10 | Raynes | &(apply (fn [k & xs] (reduce #(if (> (k %2) (k %)) %2 %) xs)) count [[1 2] [3 4] [5] [6 7] [8]]) |
| 06:10 | lazybot | ⇒ [1 2] |
| 06:11 | Raynes | myarray: ^ |
| 06:11 | Raynes | If you need that behavior. |
| 06:17 | Borkdude | Raynes: sleep well |
| 06:17 | Borkdude | TEttinger: did you see my refactoring yesterday of your function? |
| 06:19 | myarray | &(apply max-key count [[1 2] [3 4] [5] [6 7] [8]]) |
| 06:19 | lazybot | ⇒ [6 7] |
| 06:19 | myarray | it returns the last matching element |
| 06:20 | myarray | imho its not very intuitive |
| 06:20 | Borkdude | myarray: it is because it has to traverse all of the collection |
| 06:20 | myarray | should be [1 2]. I am curious why it is so, what is the idea behind returning the last |
| 06:21 | Borkdude | myarray: see the source https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4419 |
| 06:21 | Borkdude | myarray: if you want it the other way, use Raynes his variation |
| 06:21 | myarray | no its not. Well, it does have to traverse, but it can keep the already found max value if it has found the same max value |
| 06:21 | Borkdude | myarray: this is what Raynes his version does |
| 06:23 | myarray | My question is not "how to". My question is why it does it, what is the motivation? |
| 06:24 | myarray | other FP languages that have max-key like functions return the first match if there are few equal max values |
| 06:24 | myarray | is it some kind of Lisp behavior legacy? |
| 06:25 | Borkdude | myarray: I think with these kinds of functions you should not depend on order anyway, so what's the big deal? |
| 06:26 | Borkdude | myarray: it's just a choice. the version in core is a short elegant version, which produces a valid result |
| 06:26 | myarray | There is only one character in max-key function that should be changed in order to get the intuitive behavior. |
| 06:27 | TEttinger | Borkdude, yes! thanks for that. |
| 06:27 | babilen | I don;t necessarily find that behaviour to be more intuitive. max-key makes no promises regarding the order. |
| 06:29 | myarray | well, may be it should :-) |
| 06:29 | myarray | consider a solution for this task http://www.4clojure.com/problem/53 |
| 06:29 | Borkdude | myarray: you mean replace > with >= ? |
| 06:30 | myarray | one of them would be building a sequence of all possible seqs and then getting the first max |
| 06:31 | myarray | otherwise, you have to "reverse" it before. But returning the first "winner of the hill" seems to be more intuitive to me |
| 06:31 | myarray | Borkdude: yes |
| 06:31 | TEttinger | Borkdude, just so you know, it won't compile as-is |
| 06:31 | myarray | Borkdude: or swapping left and right args |
| 06:33 | myarray | Borkdude: it depends on reduce1 which private, if you are trying to make a copy of max-key in your own ns, you should have your reduce1 as well |
| 06:35 | Borkdude | TEttinger: ah yes, you have to reverse the order of the function definitions |
| 06:36 | TEttinger | Borkdude, yeah, all it took was that, and changing a call to left? to left-col? |
| 06:39 | Borkdude | TEttinger: ok changed it |
| 06:39 | Borkdude | TEttinger: I think the algorithm can be much simpler though ;-) |
| 06:39 | TEttinger | thanks, yeah |
| 06:40 | TEttinger | how do you think it would, though? |
| 06:41 | TEttinger | oh. i think i have a bug already |
| 06:41 | TEttinger | (path-in-matrix 0 11) will walk over a corner, which it isn't supposed to do |
| 06:42 | Borkdude | TEttinger: I don't know what your algorithm is supposed to do exactly |
| 06:42 | TEttinger | yeah, it is meant to be a highlighter for a 1D-imitating-2D vector |
| 06:43 | TEttinger | so it should highlight the line between a starting corner square and a target square |
| 06:43 | Borkdude | TEttinger: it should walk also in diagonals or smth? |
| 06:43 | Borkdude | TEttinger: so the shortest path? |
| 06:43 | TEttinger | i could use bresenham, but for some reason i thought making one turn would look better to the user (which is a goal in this) |
| 06:44 | TEttinger | and with orthogonal-only movement, it currently does highlight the shortest line, except when it walks over corners |
| 06:44 | Borkdude | TEttinger: good luck, the only thing I wanted to point out is that making a giant function into more smaller functions is easier to test =) |
| 06:44 | TEttinger | ah ok |
| 06:45 | TEttinger | i will look into how to implement bresenham's line algorithm in clojure, i think it isn't very complex |
| 06:48 | mduerksen | myarray: i think the preference of max-key is more intuitive the way its implemented now: left-to-right, just like e.g. merge. but intuition aside (which may vary), it should be explicitely written in the doc. |
| 06:53 | hyPiRion | Would jumping directly over Leiningen 1.x to Leiningen 2 be smart? I haven't used any, and I'm going to port a 1.2 project over to 1.4. |
| 06:53 | Borkdude | haha |
| 06:54 | Borkdude | technomancy: http://twitpic.com/9mc9aw ;-) |
| 06:54 | hyPiRion | Borkdude: yeah, I noticed as well. :p |
| 07:00 | hyPiRion | Well, I cannot see why it shouldn't be smart. |
| 07:02 | xumingmingv | a silly question |
| 07:02 | xumingmingv | we know that we use ; for comments in clojure |
| 07:02 | xumingmingv | why most clojure code use ;; ... |
| 07:02 | xumingmingv | double ; |
| 07:03 | ejackson | haha, I guess due to // from java |
| 07:04 | ejackson | and still having ; mean line end, so not wanting to put it at the front of a line :) |
| 07:04 | hyPiRion | Lisp convention. ; is for comments in code, ;; is for comments before/after code |
| 07:04 | ejackson | well that makes more sense ! |
| 07:05 | xumingmingv | after code? |
| 07:06 | hyPiRion | As in, after the closing paren of an expression. E.g. after a defn. |
| 07:29 | TEttinger | gah, why is there no floor function? org.clojure/math.numeric-tower has some issue that prevents floor from working |
| 07:31 | TEttinger | http://pastebin.com/Ha8vkKsS my lengthy error |
| 07:31 | Borkdude | TEttinger: ##(int 3.567) ? |
| 07:31 | lazybot | ⇒ 3 |
| 07:31 | TEttinger | ,(int 15/2) |
| 07:31 | clojurebot | 7 |
| 07:31 | TEttinger | oh ok |
| 07:31 | TEttinger | thanks |
| 07:34 | Borkdude | ,(* (int 3.5) 2.3) |
| 07:34 | clojurebot | 6.8999999999999995 |
| 07:37 | babilen | TEttinger: ##(Math/floor 42.23) |
| 07:37 | lazybot | ⇒ 42.0 |
| 08:16 | Borkdude | sometimes I wonder about clojuredocs, if I search for "def", why doesn't "def" turn up.. http://clojuredocs.org/search?x=0&y=0&q=def |
| 08:19 | foxdonut | Borkdude: strange indeed.. it shows up in the autocomplete but not in the search results :/ |
| 08:20 | Borkdude | foxdonut: I have had this with other searches as well |
| 08:21 | Borkdude | foxdonut: also the autocomplete representation is broken in Chrome on my system |
| 08:22 | foxdonut | Borkdude: works on Chrome/Ubuntu and Chrome/Mac.. what are you on? |
| 08:23 | Borkdude | foxdonut: Chrome / OSX |
| 08:23 | Borkdude | foxdonut: http://twitpic.com/9md5xd <-- I get this |
| 08:24 | Borkdude | foxdonut: try typing a "d", let the autocomplete come up and then press "e" |
| 08:24 | foxdonut | Borkdude: huh. that's whacked. |
| 08:25 | Borkdude | foxdonut: you don't get this? |
| 08:25 | foxdonut | Borkdude: I don't get any truncated autocomplete, but doing the d-then-e thing makes 'def' not show up. |
| 08:26 | Borkdude | foxdonut: with me the autocomplete results get positioned over the search box |
| 08:51 | solussd_ | Could anyone tell me why this won't compile (I get a java.lang.InstantiationException when it tries to compile the macrolet form): https://www.refheap.com/paste/4fb64515e4b0225aed0333ec |
| 09:01 | hyPiRion | solussd_: I don't know why, but I would've tried to get rid of that macro: https://www.refheap.com/paste/4fb647aae4b0225aed0333ed |
| 09:03 | hyPiRion | I screwed up the indentation, but the idea is that if you're able to make a macro into a function by using apply, then do that istead. |
| 09:04 | neotyk | solussd_: where did you get macrolet from, I want one as well |
| 09:06 | TimMc | foxdonut: The autocomplete and search results most notably differ on things with hyphens. |
| 09:06 | solussd_ | macrolet is in clojure.tools.macro |
| 09:07 | solussd_ | hyPiRion: I cant use apply-- the args list is conditional on the args, and simply building the arg list and then applying the command is no better than the macro. I like macrolet. :) |
| 09:08 | solussd_ | I'm concerned about what looks like perfectly valid code not compiling.. :/ |
| 09:14 | foxdonut | TimMc: ic |
| 09:15 | mmarczyk | solussd_: actually the expansion seems to depend on the runtime values of dest-name and submodule-recursive -- so, not valid code at all |
| 09:15 | mmarczyk | solussd: ^ |
| 09:16 | mmarczyk | solussd: CLHS says "the consequences are undefined if the local macro definitions reference any local variable or function bindings that are visible in that lexical environment" (i.e. the lexical environment where the macrolet form appears) http://www.lispworks.com/documentation/HyperSpec/Body/s_flet_.htm -- that applies to CL, but I'd expect the same from tools.macro |
| 09:25 | goodieboy | I'm having the problem described here: http://stackoverflow.com/questions/10289617/clojure-ring-jetty-i-am-using-lein-ring-server-how-do-i-configure-the-jetty |
| 09:26 | goodieboy | I have to keep using "lein ring server", so somehow I need to configure jetty within my project.clj -- I tried the example in that ^^ link, but nothing is working |
| 09:27 | goodieboy | anyone know how to deal with this -- summary: In development mode, jetty is giving me a "FULL HEAD" response |
| 09:27 | mmarczyk | goodieboy: http://stackoverflow.com/questions/9285096/clojure-ring-using-the-ring-jetty-adapter-large-requests-give-me-a-413-full-h/9286288#9286288 |
| 09:28 | goodieboy | mmarczyk: thanks! I'll give that a shot. |
| 09:28 | weavejester | goodieboy: If you specify the configurator as a symbol, that might work. |
| 09:29 | weavejester | goodieboy: e.g. {:ring {:adapter {:configurator some.config/foo}}} |
| 09:29 | goodieboy | weavejester: ahh, ok |
| 09:29 | mmarczyk | I'd still expect unquote to be necessary |
| 09:30 | mmarczyk | but if it isn't, I'll be interested to learn that :-) |
| 09:30 | weavejester | mmarczyk: I believe the adapter arguments are passed as-is to eval-in-project |
| 09:31 | weavejester | So in theory they should be evaluated. |
| 09:32 | mmarczyk | weavejester: ah, then it shouldn't matter, fns are self-evaluating currently |
| 09:33 | weavejester | mmarczyk: Yes… an anonymous function should work in theory... |
| 09:33 | michaelr525 | weavejester: hi |
| 09:34 | michaelr525 | weavejester: i don't want to bother you with this, but can you tell me whether you've seen my comment here: https://github.com/weavejester/lein-ring/issues/10 |
| 09:35 | goodieboy | weavejester mmarczyk: hmm, i can't get it to work. Using :ring {:adapter {:configurator app/configure etc.. doesn't ever execute my function |
| 09:35 | weavejester | goodieboy: Which version are you using? |
| 09:35 | goodieboy | weavejester: of lein-ring? |
| 09:35 | weavejester | goodieboy: Yep |
| 09:35 | goodieboy | weavejester: 0.7.0 |
| 09:35 | weavejester | michaelr525: I have, but haven't had time to look into it. |
| 09:37 | michaelr525 | weavejester: ok, thanks.. i intent to tackle this problem myself sooner or later anyways, thought maybe you have an idea what could it be |
| 09:37 | weavejester | michaelr525: No idea, since I wasn't able to reproduce the original issue. Which version of Tomcat are you using, btw? |
| 09:38 | michaelr525 | 7.0.21 |
| 09:39 | weavejester | goodieboy: Hm, not sure why that wouldn't be working, but I haven't tested using configurator with lein-ring before |
| 09:40 | goodieboy | weavejester: ok. Using ~(prn "configure!") does work, but I guess that doesn't really mean that lein-ring is doing anything with the :configurator value, just that the prn is getting evaluated immediately right? |
| 09:41 | goodieboy | like this: {:ring {:adapter {:configurable ~(prn "configure!")}}} |
| 09:42 | weavejester | goodieboy: This might need a patch for it to work |
| 09:43 | goodieboy | weavejester: if you could point me in the right direction, i could attempt doing this if you'd like |
| 09:44 | weavejester | goodieboy: I'm afraid the only direction I can point you in is the lein-ring source code |
| 09:44 | goodieboy | weavejester: gotcha ok, checking that out now |
| 09:45 | weavejester | goodieboy: Out of interest, why are your headers so big? |
| 09:46 | goodieboy | weavejester: we store a lot of data in cookies, i'm assuming that's it? |
| 09:46 | weavejester | goodieboy: That's probably it. |
| 09:52 | solussd | mmarczyk: thanks! |
| 10:06 | goodieboy | weavejester: is this function called somewhere when running "lein ring server" ? |
| 10:06 | goodieboy | https://github.com/weavejester/ring-server/blob/master/src/ring/server/standalone.clj#L56 |
| 10:07 | goodieboy | it looks like lein-ring recognizes :adapter here: https://github.com/weavejester/lein-ring/blob/master/src/leiningen/ring/server.clj#L27 |
| 10:08 | goodieboy | sorry wrong link, ring-jett-adapter: https://github.com/mmcgrana/ring/blob/master/ring-jetty-adapter/src/ring/adapter/jetty.clj#L61 |
| 10:09 | goodieboy | anyway, that config setting is getting lost somewhere along the way |
| 10:10 | jsabeaudry_ | Is there any point to doing @(future (dostuff)) instead of (dostuff)? |
| 10:14 | rhc | jsabeaudry_: not that i can see, just extra overhead |
| 10:15 | jsabeaudry_ | rhc, thanks for the confirmation, that was my impression too |
| 10:19 | gfredericks | (-> (dostuff) future deref future deref future deref future deref) ;; make sure |
| 10:24 | pjstadig | gfredericks: needs syntax shorthand like caadar |
| 10:29 | jsabeaudry_ | hehhehe |
| 10:34 | gfredericks | googling caadar tells me nothing. This is some mashup of car and cdr? |
| 10:34 | gfredericks | (def caadar (comp first first rest first))? |
| 10:34 | jweiss | I think it's (car (car (cdr (car x)))) |
| 10:34 | jweiss | or maybe i got that backwards |
| 10:35 | gfredericks | lisp complects forwards with backwards |
| 10:36 | pjstadig | common lisp lets you use any combination of a's and d's between the c and r |
| 10:36 | gfredericks | O_O |
| 10:36 | gfredericks | wtf. |
| 10:36 | pjstadig | and it just becomes the composition of all the cars and cdrs |
| 10:36 | jweiss | pjstadig: you mean, even caaadadaddaddadaddddddaaaar ? |
| 10:36 | gfredericks | so you can't name anything #"c[ad]+r" because it will be misinterpreted? |
| 10:36 | pjstadig | sure i think so, i'm not sure if there is some theoretical or practical limit |
| 10:37 | llasram | Is that really true? In /LoL/, one of the things the author does is define a macro w/in which one can use any #"c[ad]+r" |
| 10:37 | llasram | Wouldn't think he'd need to do that if support already existed, but I don't know my CL v well.. |
| 10:37 | pjstadig | to the hyperspec! |
| 10:38 | pjstadig | http://www.lispworks.com/documentation/HyperSpec/Body/f_car_c.htm#car |
| 10:38 | pjstadig | looks like only up to four compositions of car and cdr |
| 10:38 | gfredericks | #"c[ad]{1,4}r" |
| 10:38 | jweiss | i have some data. most of the data is fixed, iow, always evaluates to the same thing. pieces of it are not - for instance it evaluates to a timestamped string. so far i've been enclosing this literal in (fn [] ...) so that i can call the fn and get a "new" piece of data each time. but that creates an awful lot of functions to compile. i'm wondering if i can implement this where the data is consumed, maybe with protocols. |
| 10:38 | llasram | That seems... er, sensible? |
| 10:39 | hyPiRion | pjstadig: There's a practical limit. Most of the common lisp implementations is limited at around 4 or 5. |
| 10:39 | hyPiRion | Though that being said, nothing limits implementators to have more. |
| 10:39 | gfredericks | reminds me of the generated IFn primitive interfaces or whatever that was |
| 10:41 | llasram | Oh yeah. Those make me slightly sad every time I think about them. But generating them dynamically seems pretty fraught with peril |
| 10:43 | llasram | jweiss: Like have an object which represents "the time at which you examine the object"? |
| 10:43 | misislavski | neotyk: with today's bleeding edge cljs, I'm seeing Unaught Error on robots discussed here about a month ago / CLJS-35. Do you know a workaround? |
| 10:44 | jweiss | llasram: yeah, but i don't see how i can do it. some of the data need to refer to the same timestamped string. |
| 10:45 | llasram | jweiss: Yeah, I was thinking that would make it kind of problematic... What's the down-side of having a function generate the data? Do you have a v large number of these functions being dynamically `eval`ed or such? |
| 10:46 | jweiss | llasram: as i add more data i'm adding more functions that need compiling, doesn't seem very scalable. functions seem a little heavyweight here |
| 10:48 | ibdknox | Hey folks |
| 10:48 | Borkdude | hi ibdknox |
| 10:48 | llasram | jweiss: So really your data are essentially templates? And you need something to generate the actual data from the templates? (thinking out loud) |
| 10:48 | ibdknox | I have an exciting announcement :) Light Table was accepted late to YC |
| 10:49 | llasram | ibdknox: Congratulations! And since I haven't been on #clojure since the Kickstarter project got funded, congratulations on that too! |
| 10:49 | jweiss | llasram: yeah, when you put it that way, sounds like we're talking about macros |
| 10:49 | ibdknox | can a couple people help me spread the word: http://news.ycombinator.com/newest |
| 10:50 | timvisher | hey all |
| 10:50 | ibdknox | It's important that people know circumstances have changed :) |
| 10:50 | ibdknox | llasram: thanks! |
| 10:50 | timvisher | how would you go about converting an io/input-stream into a byte[]? |
| 10:50 | llasram | jweiss: Wellll. Not necessarily. That might be an easy way to implement things at first, but still locks your data into executable code. I don't know -- it probably depends on the details of the data |
| 10:50 | raek | timvisher: use the read method of the InputStream class |
| 10:51 | TimMc | ByteArrayOutputStream + a pumper? |
| 10:52 | raek | (.read input-stream buffer) |
| 10:52 | timvisher | raek: recursively, i suppose? |
| 10:52 | timvisher | i'm trying to understand how I would terminate |
| 10:52 | timvisher | ah yes |
| 10:52 | timvisher | while |
| 10:52 | jweiss | llasram: have stuff like (fn [] {:a (unique-name "joe")}) which produces a different value each time. but then sometimes i need to refer to the same thing twice: (let [x {:a (unique-name "foo")}] (dothing x)) |
| 10:52 | raek | timvisher: how much data do you need to read each time? |
| 10:53 | timvisher | few megabytes |
| 10:53 | timvisher | or less |
| 10:53 | jweiss | sorry llasram forgot to add (dootherthing x) :) |
| 10:53 | raek | do you need to fill the buffer completely, or do you just want to read what's available? |
| 10:53 | timvisher | only what's available |
| 10:53 | gfredericks | if he wants a byte[] doesn't he have to read everything first? |
| 10:53 | Borkdude | ibdknox: can I ask a dumb question, does this mean you don't need the kickstarter money anymore? |
| 10:53 | raek | timvisher: how are you using the byte-array? |
| 10:53 | timvisher | i'm trying to read a file from the web once, then turn it into both a bufferedimage as well as an md5 hash |
| 10:54 | gfredericks | ibdknox: I can take the kickstarter money if you don't need it |
| 10:54 | gfredericks | I don't mind |
| 10:54 | llasram | jweiss: What's the data ultimately being used for? |
| 10:54 | timvisher | i don't believe i can use just the stream anymore because one or the other would consume it |
| 10:54 | raek | timvisher: if you want to put all the bytes into an output-stream, use clojure.java.io/copy |
| 10:54 | timvisher | so my thought is to read it once an then use it both places |
| 10:54 | ibdknox | Borkdude: it's still very useful, but it is not *needed*. The project is safe. That's why I'm letting people know it's ok if for them that means they no longer feel the need to pledge |
| 10:54 | raek | ah |
| 10:54 | jweiss | llasram: functional tests. the reason i need unique values, is so I can run the same test twice, and the data being used doesn't collide with data that's already in the system under test. |
| 10:55 | timvisher | and i don't think it'll be possible for me to download the data twice, especially in quick succession |
| 10:55 | Borkdude | ibdknox: what happens if people take their pledge back and the sum gets below 200k? |
| 10:55 | timvisher | if that were possible then i could probably just stick with opening 2 streams |
| 10:55 | goodieboy | anyone know if it's possible to add repositories for "lein plugin install xxx" ? |
| 10:55 | raek | I would repeatedly fill the buffer (say 2048 bytes) using the read method and give the array (and size) to the two sinks that need it |
| 10:56 | ibdknox | Borkdude: then the project isn't funded and no money transfers |
| 10:57 | Borkdude | ibdknox: so what about Python support now, already safe as well? |
| 10:57 | raek | so something like (loop [] (let [n (.read input-stream buffer)] (when-not (neg? n) (... buffer ... n ...) (recur))) |
| 10:57 | ibdknox | Borkdude: That I'm not sure about |
| 10:57 | timvisher | seems reasonable |
| 10:57 | llasram | jweiss: Ah, so generated text fixtures? Functions actually seems a perfectly sensible way to go. Esp if you're ultimately just generating Clojure data-structures. You can compose them, refer to the same generated value multiple times... They seem pretty much perfect |
| 10:57 | Borkdude | ibdknox: and how about licensing? or will it be free? |
| 10:58 | llasram | jweiss: I guess I'm not seeing the scalability problem, unless you're creating 100ks of them? |
| 10:59 | ibdknox | Borkdude: if the KS fails a few of the details around that might change, I'm not sure. In the long run maybe it isn't worth charging for the distributions |
| 10:59 | cmiles74 | Has anyone see a Clojure library for working with Hazelcast? I don't want to reinvent the wheel. |
| 10:59 | jsabeaudry_ | When lein uberjar fails with a compilaiton error, it seems like I'm still in the process, is there a way to tell it to retry without C-c'ing it and restarting it? |
| 10:59 | Borkdude | ibdknox: anyway, congrats! |
| 11:00 | jweiss | llasram: i'm not sure it's a problem, just thought there might be another way. i'm ok with leaving it as is, just sometimes gets confusing as to exactly when something gets evaluated, because as i compose data, each level needs to be wrapped in a function. and then of course i need a construct to explicitly call it. |
| 11:01 | jweiss | llasram: seems like lisp's quote/unquote constructs kind of do the same thing |
| 11:03 | llasram | jweiss: Do you have an example of where it gets confusing? The version I have in my head of just normal functions returning and composing normal data-structures seems fairly straightforward to me |
| 11:04 | Borkdude | ibdknox: I don'tknow the details of ycombinator's process, but I read they invest 18k and you get to be three months over there.. isn't 200k better? |
| 11:04 | solussd | dependency question: I'm using a version of (lein-marginalia dev-dependency) marginalia in my project that itself depends on hiccup 0.3.7 (in this version escape-html is in hiccup.core), in my project I use hiccup 1.0.x. Running marginalia (lein marg) results in an exception complaining about not being able to find escape-html. it seems that marginalia is using hiccup 1.0, even though it has a dependency on hiccup 0.3.7. How do I get it to us |
| 11:04 | solussd | the older hiccup while continuing to use hiccup 1.0 in my project? |
| 11:04 | ibdknox | Borkdude: there's another guaranteed 150k as well. But the value of YC isn't the money, it's the guidance, the name, and the network. |
| 11:04 | jweiss | llasram: https://github.com/weissjeffm/katello.auto/blob/master/src/katello/tests/permissions.clj#L97 |
| 11:05 | ibdknox | Borkdude: those things in combination are worth untold sums of money |
| 11:05 | Borkdude | ibdknox: I guess Arc support is now closer than Python ;-P |
| 11:05 | ibdknox | lol |
| 11:06 | ibdknox | Borkdude: certainly not :p |
| 11:07 | llasram | jweiss: Ahhhhh. Why the nested functions? Are those actually intended to be functions in the "final" data-structure, or are they evaluated before being used as fixtures? |
| 11:09 | jweiss | llasram: well, the outer fn's need to be functions because of data like starting line 97. and the inner ones often need to be functions too, because of line 122 |
| 11:09 | jweiss | so the test harness needs to either take maps or functions. at both levels it has to take functions |
| 11:10 | jweiss | actually the inner fn's have to be fn's no matter waht |
| 11:11 | jweiss | but they can't be partials, they really have to be fn's |
| 11:11 | llasram | jweiss: The code ultimately under test consumes functions, or the existing test harness needs them to be functions? |
| 11:12 | timvisher | is it possible to clear the slime repl buffer? |
| 11:12 | jweiss | llasram: the harness is my code too, so it's not required in that sense. |
| 11:13 | jweiss | timvisher: M-x slime-repl-clear-buffer |
| 11:13 | llasram | timvisher: which is bound to C-c M-o by default |
| 11:13 | jweiss | llasram: i guess there's no getting around things needing to be evaluated at runtime. |
| 11:14 | llasram | Though of course thinking about bindings always makes me unable to correctly apply them... |
| 11:14 | misislavski | Is anybody else having problems with the Uncaught error with robots.txt from clojurescript master? |
| 11:14 | misislavski | I can't get my browser to connect to the repl. |
| 11:14 | timvisher | jweiss, llasram: very cool |
| 11:14 | misislavski | both chrome and ff throw: "Uncaught Error: URI file:/robots.txt is invalid for field ppu" |
| 11:14 | llasram | jweiss: Right. I think the part I'm questioning is the function nesting. It seems like the whole system would be really straightforward if you ultimately just have functions which produce fully evaluated datastructures |
| 11:15 | llasram | jweiss: You could compose those functions by having higher-level functions call lower-level ones, just like in normal code |
| 11:15 | foxdonut | who wants to be Light Table backer #5000 ? |
| 11:17 | jweiss | llasram: that's what it's doing. the inner fn's i have no choice - they really are functions no matter what, even if there's no |
| 11:17 | jweiss | u |
| 11:17 | jweiss | unique data in them |
| 11:17 | jweiss | the test is "assign this user these permissions, then as that user, run these functions" |
| 11:18 | jweiss | so the test is sort of a HOF |
| 11:18 | TimMc | foxdonut: 4,998 backers now. |
| 11:19 | foxdonut | TimMc: yeah saw that, didn't know you could back out of being a backer! |
| 11:20 | TimMc | That's what ibdknox was saying in his post, though: You can back out now, it's OK. There's guaranteed funding. |
| 11:20 | TimMc | I'm keeping mine in. It's still an investment. |
| 11:21 | llasram | jweiss: Oh, ok. Well. Seems good as-is to me then :-) Or at least, I can't contribute any ideas as to how it could be simpler |
| 11:21 | llasram | jweiss: It's an interesting problem though -- curious to find out if you settle on some other way of doing it |
| 11:22 | jweiss | llasram: certainly seems possible to me that there is no better way, but i'm not totally convinced of that yet :) i'll let you know if i find anything |
| 11:22 | jweiss | thanks for your time |
| 11:23 | foxdonut | TimMc: what does this YC thing imply? and why might one not be a backer anymore because of it? |
| 11:23 | gfredericks | &(->> [oh boy] quote cycle (take 10)) |
| 11:23 | lazybot | ⇒ (oh boy oh boy oh boy oh boy oh boy) |
| 11:23 | pbostrom | KS backers still get early access I believe |
| 11:23 | gtrak` | ibdknox: congrats |
| 11:24 | ibdknox | gtrak`: thanks! :) |
| 11:24 | gtrak` | I'd like to do some cool startup one of these days, too :-), sounds exciting |
| 11:25 | ibdknox | foxdonut: the main thing is that before people threw in money to ensure that the project had a chance, now it does, so the circumstances under which that "investment" was made have changed. |
| 11:25 | ibdknox | foxdonut: ultimately getting YC is a very, very good thing for the project |
| 11:25 | TimMc | foxdonut: I know nothing about YC. :-P |
| 11:25 | pbostrom | ibdknox: just curious, did you approach YC, or did they come after you? |
| 11:25 | jweiss | i'm a little confused, KS and YC seem totally different. i thought KS was "if you really want this thing built, contribute so you can get it". and then for all the developer might care, everyone else can get it for free. YC doesn't seem like they would want anyone getting it for free. |
| 11:25 | llasram | ibdknox: OOC, was the successful Kickstarter effort a factor in getting YC? |
| 11:26 | foxdonut | ibdknox: thanks for the explanation. my contrib remains, for sure. |
| 11:26 | ibdknox | pbostrom: we applied, though the whole thing was very interesting. we'll probably blog about it at some point |
| 11:26 | ibdknox | llasram: definitely. Half the partners had actually contributed :) |
| 11:27 | ibdknox | jweiss: there's tons of potential for a business even if the platform is open source :) |
| 11:28 | rkz | ibdknox: was the interview intense or were they sold before you even walked in? did they ask you how you were going to make money? |
| 11:28 | `fogus | ibdknox: We? |
| 11:28 | ibdknox | rkz: it was rough as hell |
| 11:28 | ibdknox | `fogus: best friend from high school (ibdthor) :) |
| 11:29 | `fogus | ibdknox: Congratulations to both of you. Huge news! |
| 11:29 | ibdknox | rkz: they really laid into us, I found out later that was because they really liked us, but boy it didn't seem like it when we walked out of that room |
| 11:30 | rkz | ibdknox: i had an interview too, one of the most intense things I've ever done in my life |
| 11:30 | rkz | this was when all the partners were in the same room |
| 11:31 | rkz | so it was like 11 people |
| 11:31 | rkz | grilling 3 of us |
| 11:31 | rkz | questions from all directions |
| 11:31 | TimMc | How does YC work? They invest money and get partial ownership? |
| 11:32 | TimMc | Is it a loan? |
| 11:32 | rkz | no, cash |
| 11:32 | mmarczyk | ibdknox: wow, congrats!!! :-) |
| 11:32 | rkz | for 5-7 % |
| 11:32 | ejackson | am i reading this correctly - KS got YC ! |
| 11:33 | TimMc | yes |
| 11:33 | TimMc | All of the acronyms! |
| 11:33 | ejackson | BRILLIANT ! |
| 11:33 | ejackson | s/KS/LT/ |
| 11:33 | ejackson | of course :) |
| 11:34 | TimMc | That too. |
| 11:34 | foxdonut | VFC! |
| 11:34 | ibdknox | mmarczyk: thanks :) |
| 11:34 | TimMc | LT's KS probably helped them get VC from YC. |
| 11:34 | ejackson | OK |
| 11:34 | TimMc | :-D |
| 11:34 | foxdonut | IIRC RTFM OMG WTF BBQ |
| 11:34 | RickInGA | ibdknox: congrats! |
| 11:35 | ejackson | i hope this doesn't mean Clojure loses one if its most prolific project contributors |
| 11:35 | ejackson | but am thrilled nevertheless |
| 11:35 | TimMc | foxdonut: No, only DAs. (Dyadic Acronyms) |
| 11:36 | TimMc | ejackson: Eh, we'll get spinoffs. |
| 11:37 | foxdonut | TimMc: so no TLA then, huh |
| 11:37 | TimMc | right |
| 11:38 | Borkdude | ibdknox: maybe you should explain now what happens to the "reward structure" |
| 11:38 | foxdonut | TimMc: RO. TF. LM. AO. |
| 11:39 | RickInGA | foxdonut: LOL |
| 11:39 | ibdknox | Borkdude: yeah, I'll be posting a second update about that |
| 11:39 | ache | ibdknox: will LT be able to support LP some time in the future, perhaps with a plug-in? (literate programming) |
| 11:40 | ibdknox | ache: there's some neat stuff you could do with an LP plugin |
| 11:40 | ibdknox | ache: not sure I'll be the one to build it, since I'm already stretched pretty thin |
| 11:40 | ibdknox | but I imagine someone will :) |
| 11:40 | ache | as long as the door's open :) |
| 11:41 | ache | it would be a dream within a dream. congrats! |
| 11:46 | cldwalker | hi all, does leiningen support an rc file i.e. leiningenrc? I'm calling (load-file my-file) each time I start lein repl |
| 11:47 | TimMc | cldwalker: There's some sort of init.clj or user.clj in ~/.lein |
| 11:47 | TimMc | One is for running code in Lein itself, the other is run for your repl session. |
| 11:48 | cldwalker | TimMc: Thanks! |
| 11:49 | bhenry | has anyone had the following problem? with :main in project.clj lein repl gives "REPL server launch timed out" but with no :main in project.clj it works fine. this is lein2 |
| 11:50 | foxdonut | RickInGA: :) |
| 11:50 | bhenry | even stranger is that i can run the (-main) function defined in the :main namespace from the repl that works. |
| 11:56 | gfredericks | bhenry: it might be trying to load the repl in your main ns. Does than ns do anything interesting at load-time? |
| 11:57 | gfredericks | (e.g., read a config file that is missing) |
| 11:57 | TimMc | bhenry: Try increasing Lein's REPL-start timeout. I forget how... |
| 11:58 | bhenry | it reads a config file, but it's not missing. and i can run (-main) from that namespace just fine once i load the repl after deleting the :main line from project.clj |
| 12:01 | zakwilson | ibdknox: congratulations on YC. Just don't forget about Korma and stuff! |
| 12:02 | TimMc | and us! |
| 12:03 | TimMc | bhenry: I used to have that problem. It's basically just slow JVM startup. |
| 12:03 | hyPiRion | ibdknox: Seems like I'm late to the party, but congratulations from me too. :) |
| 12:04 | ibdknox | thanks guys :) |
| 12:04 | y3di | holeeee shittt |
| 12:04 | y3di | gratz |
| 12:05 | ejackson | well done Chris, awesome |
| 12:05 | ibdknox | zakwilson: Korma is really orthogonal to what I'll need to be doing in the near future, so I'm going to be looking for someone to help keep it moving forward |
| 12:05 | ibdknox | Yeah, exciting times ahead |
| 12:05 | zakwilson | I'd volunteer, but I'm bad at SQL. |
| 12:05 | ibdknox | zakwilson: me too, don't tell anyone ;) |
| 12:05 | zakwilson | Heh. |
| 12:06 | eggsby | I showed a db friend who is learning clojure korma and he got excited |
| 12:07 | eggsby | composable sql... mm |
| 12:07 | zakwilson | As he should. SQL is a really terrible language. |
| 12:07 | eggsby | meh, it's not bad or hard or anything, just limited |
| 12:07 | fliebel | ibdknox: Congrats. It seems some people wonder about Python. Are you still lurking in the HN thread? |
| 12:07 | pipeline | korma is the reason i wanted to learn clojure, no joke |
| 12:07 | zakwilson | Yes, that's why it's terrible. |
| 12:08 | pipeline | i heard about clojure a couple years ago and it sounded neat but there was no particular reason i wanted to learn it |
| 12:08 | eggsby | woah YC changed their mind about light table? |
| 12:08 | eggsby | sup pipeline cobol4life |
| 12:08 | zakwilson | I can't remember why I wanted to learn Clojure now. I was using Common Lisp at the time. |
| 12:08 | eggsby | ibdknox: I thought you initially got rejected from yc? |
| 12:08 | ibdknox | eggsby: we were haha |
| 12:09 | eggsby | heh |
| 12:09 | ibdknox | eggsby: for a different idea though |
| 12:09 | zakwilson | A dev tool written in a lisp that's at the top of HN every time it's mentioned is kind of a natural fit for YC. |
| 12:09 | eggsby | pg looked at the kickstarter results... 'welp' |
| 12:09 | ibdknox | I got recognized at a restaurant the other day |
| 12:09 | ibdknox | this whole thing is a bit surreal |
| 12:09 | eggsby | nice |
| 12:10 | eggsby | you are dev famous now |
| 12:10 | ibdknox | haha |
| 12:10 | zakwilson | I'm assuming this is in the bay area? |
| 12:10 | eggsby | you work at msft right ibdknox ? |
| 12:10 | ibdknox | used to |
| 12:10 | ibdknox | zakwilson: yeah |
| 12:10 | eggsby | ah |
| 12:11 | llasram | zakwilson: That's funny -- I too forgot for a while what had motivated me to learn Clojure in the first place. I'm now pretty sure it was Yegge's forward to /JoC/, although I couldn't tell you why exactly |
| 12:11 | eggsby | Did they let you use clojure there... |
| 12:12 | llasram | s,forward,foreword, |
| 12:28 | gfredericks | if ibdknox is famous, then I am famous because I am in the same IRC channel he is. So I will henceforth expect recognition. |
| 12:30 | zakwilson | I don't want to be famous. Just rich. |
| 12:31 | TimMc | zakwilson: Best is to be rich but not famous. Then people don't ask you for money. |
| 12:31 | zakwilson | Yeah, but I'd buy a Ferrari and ruin it. |
| 12:32 | gfredericks | I didn't ask for fame, but here I am having to deal with it anyways. |
| 12:32 | jodaro | i can't complain, but sometimes i still do |
| 12:33 | zakwilson | I said Ferrari, not Maserati! |
| 12:33 | gfredericks | thanks ibdknox for ruining all our lives. damn paparazzi won't leave me alone. |
| 12:33 | ibdknox | 's my job. Making the world a little bit more awful one blind step at a time :D |
| 12:34 | gfredericks | it's nobody's business which movie star I'm marrying this month |
| 12:36 | wink | gfredericks: that's the quick route to "not having money" |
| 12:37 | zakwilson | So I came up with this idea for a Clojure-inspired replacement for C. Should I quit drinking? |
| 12:37 | gfredericks | what would it take to make the CLJS compiler emit C? just a GC impl? |
| 12:38 | zakwilson | No idea, but that's far from what I have in mind. |
| 12:38 | jodaro | either quit drinking, or drink more |
| 12:39 | zakwilson | Actually, I think that would be hard. CLJS uses Google's java->js thing, IIRC. |
| 12:39 | gfredericks | zakwilson: if someone needs the performance of C can they afford all the dynamicity and immutability? |
| 12:39 | yoklov | zakwilson: no, it doesn't |
| 12:39 | llasram | zakwilson: Basic idea has been done, if I understand. I'm trying to find it... |
| 12:39 | zakwilson | jodaro: http://xkcd.com/323/ |
| 12:39 | yoklov | zakwilson: it uses googles js->js optimizer |
| 12:40 | progo | gambit-clojure is in the works |
| 12:40 | llasram | zakwilson: Here we go: http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html && https://github.com/deplinenoise/c-amplify |
| 12:41 | jodaro | hah |
| 12:42 | zakwilson | llasram: yeah, I remember something called SC that was, I think similar to that. |
| 12:43 | jodaro | hah |
| 12:43 | jodaro | todays xkcd is good |
| 12:43 | zakwilson | Anyway, what I have in mind is slightly more ambitious than just compiling to C or doing C with Lisp syntax, but less ambitious than trying to do systems programming with Clojure semantics. |
| 12:43 | llasram | What's the middle ground? |
| 12:44 | krawitz | hi, does anyone knows a convenient way to parse multipart responses in clj-http, except using commons-fileupload? i found only functions to make multipart requests, but not to parse responses. :-( |
| 12:44 | TimMc | zakwilson: Taken a look at Rust, by the way? |
| 12:46 | zakwilson | Clojure-like syntax, avoidance of complecting whenever possible, LLVM backend, static typing (but the option of an unchecked cast if you really need it), pointers, ad-hoc hierarchies... just some brainstorming at the moment. |
| 12:46 | ibdknox | we should just do LLVM clojure :) |
| 12:49 | llasram | +1 |
| 12:49 | zakwilson | I like that idea, but so much Clojure depends on Java libraries. |
| 12:54 | llasram | zakwilson: Well, ClojureScript and clojure-py are having a go of it |
| 12:55 | llasram | Maybe start by creating a native-feeling C FFI layer which works in JVM Clojure by dynamically mapping to JNA, but could directly generate native code for an LLVM version |
| 13:03 | TimMc | And since we've seen LLVM compile to JS... |
| 13:03 | TimMc | We could run Clojure in the browser! :-D |
| 13:05 | pjstadig | llasram & zakwilson: there's also this http://nakkaya.com/2011/06/29/ferret-an-experimental-clojure-compiler/ |
| 13:11 | TimMc | "Since there is no support for vectors, they are converted to lists." |
| 13:12 | TimMc | Ummm... there goes most Clojure code right there. |
| 13:12 | zakwilson | Wouldn't any of many dynamic array implementations do for that? |
| 13:13 | gfredericks | TimMc: most? |
| 13:14 | TimMc | zakwilson: Not if they use mutation... |
| 13:14 | gfredericks | does it mean vectors in code or vectors the data structures? |
| 13:15 | TimMc | Presumably the data structure. |
| 13:15 | zakwilson | Well, there is that. I think compiling Clojure to C or C++ sounds like a terrible idea, personally. |
| 13:40 | dnolen` | ibdknox: congrats on YC12! |
| 13:40 | ibdknox | dnolen`: thanks! |
| 13:50 | dnolen` | ibdknox: your talk for Strange Loop looks cool :) |
| 13:50 | ibdknox | did he post it? |
| 13:51 | ibdknox | ah he did |
| 13:51 | ibdknox | :) |
| 13:52 | gfredericks | there are a lot of SL talks O_O |
| 13:53 | technomancy | they should just make it a full week conference |
| 13:53 | dnolen` | gfredericks: yeah they run like 3 tracks or something. |
| 13:53 | hiredman | sl is totally sweet |
| 13:53 | technomancy | I think it was more like six tracks last year |
| 13:53 | gfredericks | ibdknox: the "Kodowa" link under your name goes nowheres |
| 13:53 | gfredericks | yes it was like six |
| 13:54 | gfredericks | my favorite six talks were all at the same time |
| 13:54 | ibdknox | hm |
| 13:54 | dnolen` | technomancy: heh, misremembered. |
| 13:54 | Licenser | ibdknox congrats to the LightTable startup :) |
| 13:54 | technomancy | it's wild |
| 13:54 | clojurebot | It's greek to me. |
| 13:55 | technomancy | that too |
| 13:55 | ibdknox | gfredericks: there's nothing there yet anyways: http://kodowa.com/ |
| 13:57 | zakwilson | ibdknox: your stuff is always so pretty. |
| 13:57 | ibdknox | I have on idea what that site looks like on a non-mac |
| 13:57 | ibdknox | probably pretty shitty |
| 13:57 | ibdknox | lol |
| 13:58 | gfredericks | pritty shetty |
| 13:59 | ibdknox | man the reddit community is so depressing |
| 13:59 | solussd | ibdknox: congrats, btw. :D Can't wait to play with light table |
| 13:59 | ibdknox | well, sounds like you'll get to play with some of it in not too long :) |
| 14:03 | zakwilson | Yes, reddit can be depressing. I've been there for nearly seven years and moderate a largish subreddit. Did I mention I drink? |
| 14:03 | technomancy | 21st-century slashdot |
| 14:03 | solussd | currently using emacs/swank- i don't know if I can untrain myself of paredit mode. wonder if codemirror supports something similar. :) |
| 14:04 | zakwilson | reddit actually did replace slashdot for me, so... yes. |
| 14:04 | technomancy | slashdot was never that slow though |
| 14:04 | TimMc | Ugh, being a moderator kind of sucks. |
| 14:04 | technomancy | well, maybe it was and I just didn't notice because everything was slow back then |
| 14:05 | zakwilson | I wonder if I pointed a text classifier at the reddit API if I could stop moderating by hand... |
| 14:05 | gfredericks | TimMc: I bet it's more fun to be an extremerator |
| 14:07 | neotyk | dnolen`: attached reduced patch to cljs-204 |
| 14:09 | dnolen` | neotyk: it looks good. Will apply later today. |
| 14:13 | TimMc | gfredericks: There are subreddits like that. |
| 14:14 | TimMc | zakwilson: One of these days I will write a ROBOT9000 bot that has reddit mod credentials. |
| 14:15 | weavejester | Does anyone know of a good way to block until a trigger in Clojure? |
| 14:15 | technomancy | weavejester: promise is good for that |
| 14:15 | hiredman | a queue? |
| 14:15 | weavejester | technomancy: Yeah, but a promise only works once |
| 14:16 | technomancy | sure |
| 14:16 | LauJensen | Evening gents |
| 14:16 | technomancy | a seq of promises =) |
| 14:16 | weavejester | I was thinking a lazy seq or a promise in an atom that keeps changing |
| 14:16 | zakwilson | TimMc: that could be hillarious. I've done quite a bit with text classification lately. Even used it to write a chat bot. |
| 14:16 | technomancy | a queue would be better I think |
| 14:16 | weavejester | A queue isn't really what I want because each trigger resets the event. |
| 14:17 | hiredman | resets the event? |
| 14:17 | weavejester | I basically want to block until a file has been changed, or until a timeout. |
| 14:17 | hiredman | sounds like a queue to me |
| 14:17 | weavejester | So I don't care how many files have been changed |
| 14:18 | hiredman | http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html |
| 14:18 | weavejester | But if I get 10 file changes all at once I don't want to keep triggering the refresh. |
| 14:19 | weavejester | Maybe I just want a lock |
| 14:19 | hiredman | you have a source of events > queue > a consumer of the events, which component has the responsibility to throttle? |
| 14:19 | zakwilson | pg says "When we realized that multiple YC partners had already independently contributed to the Kickstarter project because they wanted to use Light Table themselves, it was not a hard decision." |
| 14:20 | zakwilson | I'd contribute too if I wasn't poor. |
| 14:20 | weavejester | I was thinking of having a thread that watches a filesystem, and then to raise events when something changes. |
| 14:21 | weavejester | And then I'd have a route that blocks until a file is changed, or until a timeout. |
| 14:21 | nDuff | Hrm. |
| 14:21 | mebaran151 | weavejester: have you seen the WatchService in JRE7? |
| 14:21 | nDuff | Looks like shutting down swank-clojure and starting a new thread later is still reusing some state (particularly, a classloader) |
| 14:22 | hiredman | weavejester: it really sounds like a queue to me, you just have a particular consumer that has sme throttling requirements |
| 14:22 | weavejester | mebaran151: I don't really want to rely on Java 1.7... |
| 14:22 | y3di | dnolen`: where did you see chris's SL talk? I can't seem to find it |
| 14:22 | hiredman | so the consumer can look at the time from the "file modified" event from the queue and decide "well the last one was less than M minutes ago, so I will do nothing" |
| 14:22 | mebaran151 | weavejester: a quick google found an Apache port that is supposed to be pure java |
| 14:23 | mebaran151 | Apache VFS |
| 14:24 | weavejester | mebaran151: I'll look into that |
| 14:25 | mebaran151 | it doesn't give you resolution as precise as the WatchService, but its DefaultFileMonitor polls once a second, and I think you can register multiple files too |
| 14:26 | weavejester | mebaran151: I think it would be easier for me to use ibdknox's watchtower |
| 14:26 | weavejester | I'm just not certain what's the best way to block... |
| 14:27 | mebaran151 | weavejester: watchtower looks neat |
| 14:27 | mebaran151 | couldn't you just do a promise and deliver it from the on-change handler? |
| 14:28 | weavejester | mebaran151: Yep, and that would work once… but when a promise has been delivered, the value doesn't change. |
| 14:29 | weavejester | I guess... |
| 14:29 | weavejester | What I want to say is "has the filesystem changed since time X" |
| 14:29 | weavejester | That could be the promise. |
| 14:31 | neotyk | dnolen`: thanks |
| 14:31 | mebaran151 | throw the promise in an atom and reset it everytime? |
| 14:32 | weavejester | mebaran151: Yeah, but that somehow seems a little… wrong, maybe |
| 14:33 | weavejester | From a functional point of view, I'm asking when the filesystem last changed. |
| 14:34 | weavejester | I think I need to mull this over a bit. I've a feeling I should tie this to a time somehow. |
| 14:34 | clojurebot | multimethods are http://clojure.org/multimethods |
| 14:34 | gtrak | mul? |
| 14:35 | gtrak | whatcha talking about, clojurebot? |
| 14:35 | Chousuke | "mull this" -> multi? :P |
| 14:35 | gtrak | lol |
| 14:35 | gtrak | I think I need to mull this |
| 14:35 | raek | I think clojurebot has a built-in probability of randomly interpreting an irc message as directed to itself |
| 14:35 | Chousuke | yeah |
| 14:35 | pjstadig | ~mull |
| 14:35 | clojurebot | Pardon? |
| 14:35 | pjstadig | and i don't think the content of the message matters |
| 14:35 | hiredman | weavejester: seriously, an event queue, and the consumers can keep some kind of state if they wish |
| 14:36 | weavejester | Each time we think we understand Clojurebot, it because something even more inscrutable |
| 14:38 | weavejester | hiredman: Hmm... |
| 14:38 | hiredman | the way it got from what weavejester said to the bit about multimethods is 3-4 (faulty) inferences |
| 14:39 | hiredman | "..time.." -> something chouser said about time -> something chouser said about multimethods -> multimethods |
| 14:41 | gfredericks | ~time |
| 14:41 | clojurebot | multimethods seperate the 20% from the 80% |
| 14:41 | gfredericks | so the fact that "time" is a substring of "multimethods" is an unrelated coincidence? |
| 14:41 | hiredman | I think so |
| 14:42 | hiredman | but I dunno, the inference seems be acting more generally than intended |
| 14:42 | weavejester | hiredman: It doesn't really feel like a queue. I mean, if I don't care about how many events there are when I poll. |
| 14:43 | hiredman | I don't follow how caring about "how many" has anything to do with a queue |
| 14:43 | weavejester | hiredman: I guess I could have a queue of size 1 :) |
| 14:44 | weavejester | hiredman: Well, if there are zero events, I want to block until an event. If there are many events, I return immediately. |
| 14:45 | mwillhite | hey all - pretty new to clojure here…I'm trying to get some ring middleware going so that I can process params in the form of json in my compojure app |
| 14:45 | mwillhite | in my project.clj I have the following: [ring-middleware-format "0.1.1"] |
| 14:45 | hiredman | weavejester: seems reasonable |
| 14:45 | mwillhite | ran lein deps and it pulled down the repo |
| 14:45 | mwillhite | in my core.clj in the use call I have this: [ring.middleware.format-params :only [wrap-json-params] |
| 14:46 | mwillhite | as specified in the readme |
| 14:46 | mwillhite | but when I go to boot up the app I get the following error: |
| 14:46 | mwillhite | Caused by: java.lang.RuntimeException: No such var: clojure.core/ring.middleware.format-params |
| 14:46 | mwillhite | am I missing something super obvious here? |
| 14:46 | hiredman | weavejester: you have some kind of file watcher thread that generates filesystem events, that thread has a list of weak or soft references to queues, you have listeners on each side of the queues |
| 14:46 | hiredman | the listeners don't have to consumer their entire queue |
| 14:47 | weavejester | mwillhite: Are you using (ns … (:use )) or just (use …)? |
| 14:47 | mwillhite | the former |
| 14:47 | weavejester | mwillhite: I'd need to see your whole ns declaration, I think... |
| 14:48 | mwillhite | sure lemme pastie it |
| 14:48 | raek | "clojure.core/ring.middleware.format-params" sounds suspicious |
| 14:48 | weavejester | hiredman: I'm still not sure why I'd want a queue when I don't care about the events themselves, just if there are any. |
| 14:49 | weavejester | hiredman: It feels more like a concurrency primitive than a queue. |
| 14:50 | TimMc | There's gotta be a way to use core.logic here. |
| 14:50 | mwillhite | oh jeez, I'm an idiot…I had tacked it on after the closing paren :P |
| 14:50 | mwillhite | thanks! haha |
| 14:50 | hiredman | weavejester: the queue approach is more general and provides a better separation between the event generator and the consumer |
| 14:50 | hiredman | weavejester: if you ever think some day you might care about the events |
| 14:51 | hiredman | if you are set on using something else, maybe a cyclicbarrier? |
| 14:52 | mebaran151 | a promise that unpromises itself after reference would have some utility |
| 14:52 | hiredman | :( |
| 14:52 | hiredman | that's not a promise |
| 14:52 | clojurebot | Titim gan éirí ort. |
| 14:53 | hiredman | the power of a promise is the one shot nature |
| 14:53 | weavejester | hiredman: But it kinda feels like the wrong solution. I mean, I'd need to either poll and then clean the queue each time, ignore events, or set the queue size to 1 or something. |
| 14:53 | weavejester | hiredman: And a queue of size 1 doesn't seem like a queue anymore. |
| 14:54 | hiredman | http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html |
| 14:56 | weavejester | hiredman: That doesn't seem quite right either… It feels one step too complex - it still cares about the number. |
| 14:58 | eggsby | so... I'm trying to dip my feet into macro lake, I have something passed to a macro, I want it passed in as a value to another function, but not evaluated... do I want to use ~ ? |
| 14:59 | eggsby | ~@ will evaluate it, right? |
| 14:59 | clojurebot | @ is like the macro version of apply |
| 15:00 | Caffeine | How to keep the REPL open? I would like to start the REPL with a script (passing it a clj file in param) and keep it opened after. Can I do that??? |
| 15:00 | lazybot | Caffeine: Yes, 100% for sure. |
| 15:00 | AimHere | eggsby, you probably want ` to keep code from evaulating inside a macro |
| 15:00 | AimHere | Then you use ~ or @ for the bits you DO want to evaluate |
| 15:00 | eggsby | AimHere: this is inside the body of a `() statement |
| 15:01 | eggsby | oh, ok |
| 15:01 | raek | eggsby: do you know enough about macros to write one without syntax-quote? |
| 15:01 | TimMc | It's not about evaluating, it's about syntax transformation! |
| 15:01 | eggsby | raek: mm, this is my first time writing a macro, and a lot of it is code borrowed from an article :3 |
| 15:02 | eggsby | so say I have a list inside a `() form... would I go `(my-func ~@(first my-list) ~@(rest my-list)) if I wanted it to expand to (my-func first (rest-my-list)) ? |
| 15:02 | raek | I think it best to start with thinking of macros as functions from that is applied to the source code data structures |
| 15:03 | stuartsierra | Caffeine: Pass the -r option to clojure.main |
| 15:03 | raek | eggsby: do you have a simple example of a call to your macro and what it should expand to? |
| 15:03 | eggsby | I don't really want the (rest-my-list) to be evaluated, I just want it passed in as a list minus the head |
| 15:03 | hiredman | weavejester: if you have a design with an X shaped hole, and it turns out no one has ever created an X, what does it say about the design? |
| 15:03 | stuartsierra | Check the command-line syntax by running clojure with -h |
| 15:03 | eggsby | let me make one raek |
| 15:04 | raek | eggsby: the macro code is executed at compile time. it does not know about the runtime values. |
| 15:05 | Caffeine | stuartsierra: It works! Thanks! |
| 15:06 | stuartsierra | 'welcome |
| 15:06 | raek | eggsby: one important thing that you need to know is that syntax quote is not tied to macros in any way. it's just a template language for lists, vectors and other data structures |
| 15:07 | TimMc | ,(let [x [1 2 3]] `[a b ~@x c d]) |
| 15:07 | clojurebot | [sandbox/a sandbox/b 1 2 3 ...] |
| 15:07 | amalloy | i'm hopping in late here, but weavejester's problem sounds like a queue to me too |
| 15:08 | eggsby | raek: https://www.refheap.com/paste/2790 |
| 15:08 | eggsby | that's an inner function used by a macro |
| 15:08 | weavejester | It would have to be a queue of capacity 1 |
| 15:09 | eggsby | oops, every occurance of myargs should be 'real-args' |
| 15:09 | weavejester | Which seems like not a queue |
| 15:09 | eggsby | derp... so many syntax errors there |
| 15:10 | eggsby | raek: https://www.refheap.com/paste/2791 is what I meant |
| 15:10 | raek | eggsby: ok, so the macro should look at action and generate either a call to do-something or do-something else? |
| 15:10 | eggsby | yes raek |
| 15:10 | raek | ah |
| 15:11 | raek | basically (my-macro :otheraction <a> <b> <c>) ==> (do-something-else <a> (list <b> <c>))? |
| 15:12 | eggsby | ya, but looking back maybe I should just rewrite how 'do-something-else' works... |
| 15:12 | eggsby | and just use ~@ to flatten the remainder of the args, then have do-something-else use & to splat |
| 15:13 | eggsby | cause just going '(some-call ~@(real-args)) results in (some-call my real args) expanded, right? |
| 15:13 | raek | do you want do-something-else to take <b> and <c> as separate args? |
| 15:13 | eggsby | ya basically |
| 15:13 | Raynes | Refheap is getting lots of paste love lately. |
| 15:13 | raek | ok, let's wait with the implementation details a bit |
| 15:14 | eggsby | but I think I should just manage that in the implementation of do-something and do-something-else, right raek ? |
| 15:14 | eggsby | ok |
| 15:14 | raek | I just want to understand what the macro should to first :-) |
| 15:14 | gtrak | Raynes: mmm paste love |
| 15:14 | eggsby | raek: basically I have some expression that I want to pass to a function to conditionally evaluate |
| 15:15 | raek | eggsby: a macro can rewrite an expression into another one. is (my-macro :otheraction <a> <b> <c>) ==> (do-something-else <a> <b> <c>) fine? |
| 15:15 | raek | so this will "compile away" the conditional that checks for :otheraction |
| 15:15 | eggsby | right |
| 15:16 | muhoo | i love it. an exception in projectname.views.something/eval24214 |
| 15:16 | raek | the defmacro form could look like this then: (defmacro my-macro [action & args] ...) |
| 15:17 | raek | action will be a keyword and args will be a sequence of code expressions |
| 15:17 | amalloy | eggsby: you know this macro can only recognize :some-action if you pass it as a compile-time literal, right? you can't do (let [action (if foo :some-action :other-action)] (my-macro action a b c)) |
| 15:18 | raek | if the call looks like (my-macro :someaction (+ 1 2)), action will be bound to :someaction and args to '((+ 1 2)), and not '(3) |
| 15:19 | raek | (defmacro my-macro [action & args] (case action :someaction ... :otheraction ...)) |
| 15:19 | weavejester | A promise in an atom might be the best solution |
| 15:19 | raek | the ...s should return data that looks like (do-something <arguments-here...>) or (do-something-else <arguments-here...>) |
| 15:20 | hiredman | weavejester: :( |
| 15:20 | raek | so let's build some lists and symbols |
| 15:20 | weavejester | hiredman: I don't think there's a way to use a LinkedBlockingQueue to do what I want |
| 15:20 | eggsby | hm |
| 15:20 | hiredman | weavejester: why don you just create a singe element array and lock it |
| 15:20 | weavejester | hiredman: If I poll, I can get the head of the queue |
| 15:21 | weavejester | hiredman: How would that be different from an atom with a single value? |
| 15:21 | mebaran1` | weavejester: you have two elements of state anyway, so it seems like you would need two concurrency primitives |
| 15:21 | raek | (defmacro my-macro [action & args] (case :someaction (cons 'do-something args) :otheraction (cons 'do-something-else args))) |
| 15:21 | mebaran1` | whether the atom has been read and whether the filesystem has changed |
| 15:22 | eggsby | cons... hm |
| 15:22 | hiredman | weavejester: I don't know, a promise in an atom is just so disgusting |
| 15:22 | weavejester | hiredman: I know… :( |
| 15:22 | raek | now, instead of building lists like (cons 'foo (cons x (list 'bar 'baz))), we can use `(foo ~x bar baz) |
| 15:22 | raek | &'`(foo ~x bar baz) |
| 15:22 | lazybot | java.lang.ClassNotFoundException: clojure.core |
| 15:23 | TimMc | Yeah, lazybot is down for the count. |
| 15:23 | raek | that is actually expanded to this by the reader: (seq (concat (list 'foo) (list x) (list 'bar) (list 'baz))) |
| 15:24 | amalloy | huh |
| 15:24 | eggsby | what in the |
| 15:24 | eggsby | hm |
| 15:25 | weavejester | hiredman: Well, I don't know. A promise is for a value we don't yet know, like… when's the next file going to be changed? |
| 15:25 | raek | if we instead write `(foo ~@x bar baz) then we would get this: (seq (concat (list 'foo) x (list 'bar) (list 'baz))) |
| 15:25 | weavejester | hiredman: So ideally you'd want to tie it to a time... |
| 15:26 | eggsby | hmm |
| 15:26 | S11001001 | ,'`(foo ~@x bar baz) |
| 15:26 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo)) x (clojure.core/list (quote sandbox/bar)) (clojure.core/list (quote sandbox/baz)))) |
| 15:27 | weavejester | hiredman: And an atom ties a value to an identity at a certain time. |
| 15:27 | hiredman | I think I may jsut stick my fingers in my ears and say "queue queue queue queue ..." |
| 15:27 | weavejester | hiredman: But the queue would only have one element! That's not really a queue, right? |
| 15:27 | hiredman | weavejester: why would it only have one element? |
| 15:27 | amalloy | i put a delay in an atom recently. not as weird as a promise, but still feels a little weird |
| 15:28 | raek | eggsby: the macro can the be written like: (defmacro my-macro [action & args] (case :someaction `(do-something ~@args) :otheraction `(do-something-else ~@args))) |
| 15:28 | hiredman | weavejester: your current consumer may only care about 1 element |
| 15:28 | eggsby | raek: what if x was a primitive and couldn't be "flattened" like that |
| 15:28 | weavejester | hiredman: Because I want to trigger a refresh when any amount of files change |
| 15:29 | TimMc | ,(let [x 5] `[a b ~@x c d]) |
| 15:29 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 15:29 | eggsby | so if x were (2 3) `(1 ~x 4) would be (1 (2 3) 4) and `(1 ~@x 4) would be (1 2 3 4), right? |
| 15:29 | pjstadig | don't do that |
| 15:29 | TimMc | eggsby: Just what you'd expect. |
| 15:29 | raek | eggsby: like 123? then the code would expand to (seq (concat (list 'foo) 123 (list 'bar) (list 'baz))) and you would get an error when that is evaluated |
| 15:29 | weavejester | hiredman: But there's no atomic operation to block and consume all of a blockingqueue |
| 15:29 | eggsby | ah, okay raek |
| 15:29 | eggsby | that helps a lot, thanks |
| 15:29 | raek | the macro constructs new code that is sent back to the compiler |
| 15:29 | weavejester | hiredman: I can poll it to get the head |
| 15:29 | eggsby | so what is the difference between ' and ` ? |
| 15:30 | ieure | Is there a Clojure/Java equivalent to Python's cmd library? http://docs.python.org/library/cmd.html |
| 15:30 | ieure | It's a REPL building framework. |
| 15:30 | raek | eggsby: with ' you can't have "holes" like ~ and ~@ |
| 15:30 | raek | also, ` makes symbols namespace safe |
| 15:30 | eggsby | ah, I see |
| 15:30 | weavejester | hiredman: But I don't see how I can use a blockingqueue to do this |
| 15:30 | TimMc | raek: Don't forget gensyms. |
| 15:31 | hiredman | weavejester: https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html http://linux.die.net/man/7/inotify http://c2.com/cgi/wiki?EventQueue |
| 15:32 | hiredman | you pull a message from the queue, check it meets some set of conditions, and if it does you trigger some action, then go back to polling |
| 15:33 | TimMc | and throw timeouts into the queue as well? |
| 15:33 | hiredman | TimMc: most queues let you poll with a timeout |
| 15:33 | hiredman | lbq definitely does, and so does every messagebus I know of |
| 15:34 | weavejester | hiredman: That's a point... |
| 15:35 | hiredman | weavejester: you can even push the state management even farther down, by making it all internal to the refresh function, so refreshing is always throttled no matter how you call it |
| 15:35 | hiredman | throttled to 60hz or something :) |
| 15:37 | hiredman | refresh can be a scheduled function that checks a "re-render" flag |
| 15:37 | hiredman | so refresh runs every S seconds and just looks at an atom to see what needs to be redrawn |
| 15:38 | weavejester | Hm... |
| 15:39 | weavejester | Because the "refresh" is a response returned, I can't do that exactly |
| 15:44 | weavejester | Hm, also, a queue wouldn't work because there could be multiple consumers. |
| 15:47 | TimMc | weavejester: To recap, you need to take an action iff at least one event has occurred since the last time you took action, but only once x milliseconds have passed since the first such event? |
| 15:48 | hiredman | weavejester: that does not preclude a queue |
| 15:48 | TimMc | (with the delay intended to allow grouping) |
| 15:48 | hiredman | you each consumer gets a queue |
| 15:49 | weavejester | TimMc: I basically have a route in my web app that tells a javascript function whether or not to refresh the current page. |
| 15:49 | weavejester | So the javascript sends an XHR to the route |
| 15:50 | weavejester | If no files are changed it waits up until a timeout before returning false |
| 15:50 | weavejester | If any files are changed it returns true |
| 15:51 | TimMc | I think you can separate the blocking -- "taking action" could mean signaling all waiters on an object. |
| 15:52 | weavejester | Right... |
| 15:53 | hiredman | http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#wait%28long%29 |
| 15:53 | weavejester | But because each consumer is temporary, I can't assign them a queue. |
| 15:53 | TimMc | weavejester: False positives are bad? |
| 15:53 | hiredman | http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#notifyAll%28%29 |
| 15:53 | weavejester | hiredman: Yeah, I was thinking about that... |
| 15:54 | weavejester | hiredman: But is keeping an lock object any better than a promise? |
| 15:54 | weavejester | TimMc: Well, I don't want to change 10 files, and then have it refresh 10 times |
| 15:54 | hiredman | weavejester: yes |
| 15:55 | TimMc | weavejester: So each waiter needs to have its own notion of a timeout, but they all rely on the same event stream. |
| 15:55 | weavejester | TimMc: Yes... |
| 15:56 | hiredman | "spurious wakeup" ugh |
| 15:57 | weavejester | This is making me feel dumb. It feels like such an easy problem :) |
| 15:58 | TimMc | I'm having trouble with the idea of uses queues here. Queue read timeouts are a different *kind* of timeout than what you need. |
| 15:58 | hiredman | you need broadcast queues, which java.lang.concurrent doesn't have, but you can build them |
| 15:59 | weavejester | I think I need a broadcast something, but I don't see why it should be a queue, when I don't care about the items being queued. |
| 16:00 | hiredman | right, which is why you want a broadcast queue that goes away when no one is listening |
| 16:00 | weavejester | A promise seems like the right way of delivering a single value to multiple threads when it's ready. |
| 16:00 | weavejester | I mean, that's what it's for, right? |
| 16:01 | hiredman | for a one shot value |
| 16:01 | weavejester | Yes, but you could have a function returning a promise |
| 16:03 | weavejester | Like… (next-modification-date dirs) |
| 16:03 | weavejester | Which would return a promise of the next modified date in the directories |
| 16:03 | weavejester | I guess it would be more like (next-modified dirs timestamp) |
| 16:05 | weavejester | I guess I'll think about it. |
| 16:08 | TimMc | weavejester: When a waiter comes in, it creates an atom and registers a closure over it with the notification service, then sleeps for 100 ms. Each time a file event happens, all the closures are called with the event info. In this case, each closure sets its atom's state to true. When the timeout is over, the waiter returns the atom's value. |
| 16:08 | TimMc | (Oh, and unregisters its atom.) |
| 16:12 | TimMc | weavejester: Alternatively, the notification service maintains a file event count. Client-side code keeps this as an opaque data value and sends it along with the XHR, getting a replacement value back each time -- along with whether to refresh as calculated by (!= old new). |
| 16:12 | Raynes | TimMc: Man, I thought you were talking about a restaurant for a moment there. |
| 16:13 | TimMc | This approach does not rely on any queue, and each waiter simply sets a timeout and does that simple calculation when the timer fires. |
| 16:14 | TimMc | Raynes: I'm not? :-( |
| 16:14 | Raynes | I see what you did there./ |
| 16:19 | TimMc | Raynes: What I did == killed the channel? |
| 16:19 | gtrak | is there a = that treats nested seqs/vectors within a map the same? |
| 16:19 | Raynes | TimMc: Yes. |
| 16:19 | gtrak | like... I don't want it to fail if the thing's a vector instead of a seq |
| 16:20 | TimMc | &(= {:a [1]} {:a (seq [1])}) |
| 16:20 | lazybot | ⇒ true |
| 16:21 | TimMc | gtrak: vectors and seqs are in the same equality partition |
| 16:21 | gtrak | ah, I'm just doing something wrong :-) thanks |
| 16:21 | gtrak | that's good to know anyway |
| 16:21 | TimMc | gtrak: Last table: http://www.brainonfire.net/files/seqs-and-colls/main.html |
| 16:22 | gtrak | neato |
| 16:22 | TimMc | Technically it only shows a list vs. a vector, but whatevs. :-P |
| 16:22 | gtrak | what i did was I used defn vs def accidentally, so it tried to equate a map and a function xD |
| 16:22 | gtrak | but i've never seen a defn without an arglist, why would that work? |
| 16:23 | gtrak | ,(defn parsed {:graphs '("graph1" "graph2") :endpoint "http://url" :all? true}) |
| 16:23 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 16:23 | gtrak | &(defn parsed {:graphs '("graph1" "graph2") :endpoint "http://url" :all? true}) |
| 16:23 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 16:23 | gtrak | &(fn {:graphs '("graph1" "graph2") :endpoint "http://url" :all? true}) |
| 16:23 | lazybot | java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap |
| 16:23 | gtrak | hmm.. |
| 16:52 | devn | Raynes: do you know off the top of your head, is it possible to capture *out* from (sandbox (safe-read "(println 1)"))? I'm using (with-out-str and I'm just getting back empty string. How would I capture *out* here? |
| 16:54 | ibdknox | devn: you can supply a set of bindings to the sandbox, you need to bind *out* to your own thing and then read from that |
| 16:54 | Licenser | devn not sure how it is in raynes sandbox but for clj-sandbox stuff like *out* and stuff were bound on the creation of a sandbox |
| 16:57 | devn | ibdknox: im not seeing where |
| 16:58 | muhoo | it is so funny how much the vc/tech business reminds me of the music business |
| 16:58 | devn | Licenser: yeah im not sure that happens anymore |
| 16:58 | dgrnbrg | what's the easiest way to print a double w/ 2 digits of decimal places? |
| 16:58 | muhoo | you develop an indie following, then you get signed by a major |
| 16:58 | dgrnbrg | or just to convert a double to a string w/ 2 digits of decimal places? |
| 16:59 | technomancy | ,(format "%0.2f" (/ 2 3)) |
| 16:59 | clojurebot | #<MissingFormatWidthException java.util.MissingFormatWidthException: 0.2f> |
| 16:59 | technomancy | ,(format "%.2f" (/ 2 3)) |
| 16:59 | clojurebot | #<IllegalFormatConversionException java.util.IllegalFormatConversionException: f != clojure.lang.Ratio> |
| 16:59 | Raynes | devn: lazybot has examples of rebinding *out*. |
| 16:59 | technomancy | ,(format "%.2f" (float (/ 2 3))) ; FINE CLOJUREBOT |
| 16:59 | clojurebot | "0.67" |
| 16:59 | Raynes | What ibdknox said is spot on. |
| 17:00 | devn | Raynes: thanks, and thanks ibdknox |
| 17:00 | dgrnbrg | technomancy: thanks |
| 17:00 | devn | and thanks Licenser for starting the whole thing :) |
| 17:00 | Raynes | devn: Also, I showed an example in my talk. Did you not pay attention? :(! |
| 17:00 | Licenser | ^^ |
| 17:00 | Raynes | I'm hurt, devn. |
| 17:00 | devn | Raynes: lol. i have that one coming. |
| 17:00 | devn | i was out until 4am the night before and walked in near the end :X |
| 17:01 | Licenser | Raynes if there's one thing you should have learned ins school it's: students never listen to what the teacher sais |
| 17:01 | Raynes | I slept through most of the conference, so totally understandable. |
| 17:01 | muhoo | ok, so snoir send-request blows up with clojure.lang.Var$Unbound when there is a noir.session/flash-get in the page |
| 17:02 | muhoo | apparently *noir-flash* doesn't exist when send-request is used |
| 17:02 | devn | Raynes: wicked. thanks. |
| 17:05 | TimMc | &(defn oops {:some :map}) |
| 17:05 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 17:06 | Raynes | muhoo: Those things are only bound inside of a request. |
| 17:06 | TimMc | Urr... right. ANyway, if you then do (oops), you get a NPE |
| 17:06 | devn | Raynes: seems like some of the stuff in lazybot could maybe be brought over to clojail? maybe? |
| 17:06 | Raynes | devn: Perhaps. |
| 17:07 | devn | seems like someone like me could do that... |
| 17:07 | devn | ;) |
| 17:07 | Raynes | :p |
| 17:07 | devn | what does box? do? |
| 17:07 | devn | (skimming the lazybot clojure.clj plugin) |
| 17:08 | Raynes | devn: You can run lazybot and let his eval plugin work without a sandbox. It is useful in private company channels and stuff where you know your employees and coworkers aren't going to delete your machine. |
| 17:08 | Raynes | Or if you run it on a work machine or something. |
| 17:08 | muhoo | so i'm confused then how to mock/test a noir app. i figured send-request would do it, but i guess not. |
| 17:08 | Raynes | I added it because we do at Geni. |
| 17:08 | devn | Raynes: gotcha |
| 17:08 | Raynes | devn: It probably isn't particularly elegant. I sometimes add things on the fly without really thinking them through. |
| 17:08 | Raynes | It's a character flaw. |
| 17:09 | Raynes | muhoo: There is a way to mock all of those things, but I sure don't remember what it is. |
| 17:09 | Raynes | ibdknox: |
| 17:09 | Licenser | Raynes you trust your coworkers enough for that? |
| 17:09 | Raynes | ^ |
| 17:09 | Raynes | Licenser: Sure, it runs on a company server. |
| 17:09 | Raynes | Not my problem if they delete stuff on that. :p |
| 17:10 | Licenser | wow I'd not trust any of my colegues furthen then I can throw them - and many of them are rather heavy |
| 17:10 | Licenser | hah |
| 17:10 | TimMc | "Raynes' bot deleted some stuff on the server!" |
| 17:10 | devn | It could be a lot of fun. send messages to raynes by popping up swing guis |
| 17:10 | Raynes | Haha |
| 17:11 | TimMc | "Including its own logs, mysteriously!" |
| 17:11 | devn | i actually ran everything from #clojure *without* safe-read the first time |
| 17:11 | devn | and no issues |
| 17:11 | technomancy | now that you said that though... |
| 17:11 | Raynes | TimMc: You should send me a lazybot pull request fixing the escaping problem in the logs. |
| 17:11 | devn | technomancy: lol |
| 17:11 | TimMc | devn: I remember when you found out about *read-eval*... |
| 17:12 | Raynes | Man, watching Stuart Sierra's talk was the scariest thing about the Conj. |
| 17:12 | TimMc | Raynes: Why so concerned about it suddenly? |
| 17:12 | Raynes | We all thought he was going to pretty much cover the topic of my talk. It turned out to be an excellent primer for my talk though. |
| 17:12 | Raynes | He talked about *read-eval* and stuff which is highly relevant to how clojail works. |
| 17:13 | muhoo | aha! (with-noir (send-request "/")) ftw |
| 17:13 | Raynes | TimMc: because you're malevolent and I'd rather have you on my side. |
| 17:14 | TimMc | Also, OMG, you haven't <b>fixed</b> that yet? |
| 17:16 | TimMc | I don't know where that code even lives. Not up for archaeology at the moment. |
| 17:16 | Raynes | TimMc: src/lazybot/plugins/logger.clj |
| 17:17 | TimMc | But it logs to text file, yeah? Not the place to escape stuff, really. |
| 17:17 | TimMc | At least, not the place for HTML-encoding. |
| 17:18 | TimMc | What's broken is the web server, perhaps the JS. |
| 17:19 | Raynes | TimMc: Yeah, but it'd be cool if lazybot served the text files himself. So do that. |
| 17:20 | TimMc | OK, but I'll make it only respond to SPARQL queries. |
| 17:21 | TimMc | Raynes: $('#log').html(lines.join("\n")); is the culprit. Map over lines with an html-encoding function, then join on "<br>". |
| 17:22 | TimMc | I also shudder to think what kind of path traversal exploits you might have in the server. |
| 17:26 | TimMc | Raynes: Or hell, you may be able to just dump the contents in via .text() and use a CSS style to force line breaks to be respected. |
| 17:28 | eggsby | hey raek with your help I was able to get my macro working, thanks! |
| 17:29 | raek | eggsby: np :) |
| 17:32 | muhoo | now, if only there were a way to maintain a cookie store through several (with-noir (send-request)) requests, hmm |
| 17:32 | muhoo | putting several send-requests inside one (with-noir) does not cut the mustard |
| 17:58 | fil512 | how can I turn a string into a BufferedInputStream? |
| 17:58 | fil512 | when I try (io/input-stream string) |
| 17:59 | fil512 | it interprets my string as a filename |
| 17:59 | weavejester | ByteArrayInputStream |
| 17:59 | fil512 | what would the syntax be? |
| 17:59 | S11001001 | fil512: there's no syntax, it's just normal java calls |
| 17:59 | fil512 | I've never made a normal java call before |
| 18:00 | fil512 | in clojure |
| 18:00 | S11001001 | http://clojure.org/java_interop |
| 18:00 | weavejester | fil512: (ByteArrayInputStream. (.getBytes s)) |
| 18:00 | weavejester | So (.getBytes s) is equivalent to the java s.getBytes() |
| 18:00 | weavejester | And (ByteArrayInputStream. foo) is equivalent to: new ByteArrayInputStream(foo) |
| 18:03 | nDuff | What's the CCW equivalent to paredit's ctrl+right, ie. [(foo|) bar] => [(foo| bar)] |
| 18:05 | fil512 | weavejester: thank you |
| 18:09 | fil512 | is there a quick way to turn my map keys to keywords? |
| 18:09 | fil512 | from strings |
| 18:11 | raek | fil512: clojure.walk/stringify-keys |
| 18:14 | devn | Raynes: hehe -- just found out why all the stuff in my DB started to magically get "I'm a string: ..." in them: |
| 18:14 | devn | Raynes: http://clojure-log.n01se.net/date/2008-11-09.html#16:34 |
| 18:15 | Raynes | Hahahaha |
| 18:15 | devn | lol |
| 18:16 | devn | Raynes: other question for you: are these sandbox local? WARNING: next already refers to: #'clojure.core/next in namespace: sandbox5320, being replaced by: #'clojure.zip/next |
| 18:16 | espeed | is there a way to define a default value to return if a record doesn't contain a key? |
| 18:16 | devn | I'm allowing def, those won't persist will they? |
| 18:16 | hiredman | devn: that's the result of someone doing (use 'clojure.zip) |
| 18:16 | TimMc | espeed: ##(doc get) |
| 18:16 | lazybot | ⇒ "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present." |
| 18:17 | devn | hiredman: any idea what would cause this one? WARNING: map already refers to: #'clojure.core/map in namespace: sandbox5320, being replaced by: #'clojure/map |
| 18:17 | devn | hiredman: that's just all alone |
| 18:17 | TimMc | espeed: And records probably support that syntax directly, too. |
| 18:17 | hiredman | devn: that is just weird |
| 18:17 | devn | happened somewhere around 10-22 |
| 18:17 | devn | (2008) |
| 18:18 | hiredman | (do (in-ns 'clojure) (def map 1) (in-ns 'sandbox) (use 'clojure)) |
| 18:18 | hiredman | oh |
| 18:18 | hiredman | 2008 would have been around the time the clojure ns became clojure.core |
| 18:18 | hiredman | maybe late 2008 |
| 18:20 | technomancy | late 2008; the scars were still fresh when I joined. |
| 18:22 | espeed | TimMc: thanks. I am for something more like __getattr__, which is a function that's called if an object doesn't contain an attribute; so that the default value doesn't have to be explicitly passed to "get" |
| 18:22 | espeed | (__getattr__ in Python) |
| 18:22 | devn | hiredman: so, still -- how did that happen? |
| 18:22 | devn | hiredman: do you see what did it here? http://clojure-log.n01se.net/date/2008-10-22.html |
| 18:24 | hiredman | devn: http://clojure-log.n01se.net/date/2008-10-22.html#00:59 |
| 18:24 | hiredman | if sometime ealier someone had done (in-ns 'clojure) (defn map ...) or similar |
| 18:25 | devn | hiredman: bingo. thanks |
| 18:28 | yoklov | espeed: if you implement IFn, and use the record as a function (as you also often do with maps and such), you can handle it the way you would like. there might be another way, but I'm not aware of it |
| 18:40 | espeed | yoklov: thanks |
| 18:41 | TimMc | espeed: "implement IFn" is a minor nightmare, by the way |
| 18:42 | nDuff | espeed: ...oh, hey, you're the one porting the graph library? Think I've seen a few of your questions over on StackOverflow |
| 18:42 | espeed | nDuff: yes, as a Clojure learning exercise |
| 18:42 | nDuff | espeed: ...very much IMHO, but trying to Python idioms over to a non-Pythonic language seems a bit silly. |
| 18:42 | yoklov | TimMc: why is implement IFn a nightmare? You don't have to implement all the arities |
| 18:42 | nDuff | s/trying to/trying to port/ |
| 18:43 | espeed | nDuff: part of this process if figuring out the "Clojure-way" of doing things |
| 18:43 | TimMc | yoklov: No? |
| 18:43 | espeed | *is |
| 18:44 | yoklov | TimMc: at least, you don't in ClojureScript, though maybe it's different because in cljs IFn is a protocol and not a java interface? |
| 18:45 | hiredman | (for [i (range 20) :when (not= arity-I-care-about i)] `(invoke ~(vec (repeat i '_)) (throw (IllegalSomethingOrOther.)))) |
| 18:45 | hiredman | then you just copy and paste the output of that for into your deftype |
| 18:47 | hiredman | https://github.com/hiredman/clojure/blob/41df324e8e6699af82d6d3d2ccaae4ae840904ad/src/jvm/clojure/lang/RIC.java#L1864 |
| 18:50 | amalloy | don't forget the this-arg |
| 18:50 | hiredman | sure |
| 18:50 | hiredman | that |
| 18:54 | devn | Raynes: i conj'd 'defmethod onto secure-tester-without-def, but it still seems to eval it |
| 18:57 | devn | Raynes: maybe not |
| 19:27 | eggsby | hmm, say I have a sequence of functions, how can I expand those out into individual function calls? |
| 19:28 | eggsby | like (list even? (partial = 2)) etc and I have some value I want to apply to every function |
| 19:28 | eggsby | more specifically I want to say (and (pred1 data) (pred2 data) (pred3 data)) etc |
| 19:29 | eggsby | so it'd be expanded to something like (and (even? 2) (= 2 2)) |
| 19:30 | amalloy | (every? #(% data) fns) |
| 19:31 | technomancy | couldn't you use juxt for that? |
| 19:32 | technomancy | (apply every? ((juxt f1 f2 f3) x)) |
| 19:33 | technomancy | that's wrong, but it uses juxt, so it's better |
| 19:33 | raek | :) |
| 19:33 | eggsby | grr this stupid problem won't bend to my will |
| 19:34 | eggsby | every works amalloy thanks, I'll just have to make stuff play nice with it |
| 19:35 | amalloy | technomancy: laziness, though |
| 19:36 | amalloy | i think a version with juxt that works (laziness aside) is like (every? identity ((apply juxt fs) x)) |
| 19:36 | technomancy | every? true? |
| 19:39 | raek | juxt is better - even when it's wrong |
| 19:39 | raek | that should be the motto of the juxt fan club |
| 19:40 | amalloy | technomancy: i'm pretty sure we want identity here, unless you're insisting on every function returning a boolean |
| 19:41 | technomancy | guess it depends on the domain |
| 19:41 | clojurebot | excusez-moi |
| 20:46 | gfredericks | I was shown speclj for the first time today and cannot figure out why the (with) macro creates a derefable |
| 20:49 | nDuff | Is ccw.clojure available as part of any published Maven repository? |
| 21:25 | dnolen` | a page describing how to extend core.logic http://github.com/clojure/core.logic/wiki/Extending-core.logic-(Datomic-example) |
| 23:22 | ForSpareParts | Is there any way to examine a clojure function from clojure? Like as a list of function calls, maybe? |
| 23:27 | xeqi | ForSpareParts: are you looking for ##(doc source) or something like https://github.com/frenchy64/analyze |
| 23:27 | lazybot | java.lang.RuntimeException: Unable to resolve var: source in this context |
| 23:27 | xeqi | &(doc clojure.repl/source) |
| 23:27 | lazybot | ⇒ "Macro ([n]); Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)" |
| 23:28 | ForSpareParts | Not sure which would do it. I'm thinking about unit testing and regression -- it would be useful to be able to list all the functions called by a given function. |
| 23:29 | ForSpareParts | Unless there's a much better way of doing that sort of thing that I'm just missing...? |
| 23:29 | dnolen` | ForSpareParts: it's possible but you would need to adapt an analyzer like the one that ships with ClojureScript |
| 23:30 | ForSpareParts | hm. Does vanilla Clojure not come with one? |
| 23:31 | brehaut | not currently |
| 23:31 | ForSpareParts | Interesting. |
| 23:32 | ForSpareParts | Am I missing a better approach to this problem? I was thinking about a Java implementation, but it turned into a big OOP mess in my head. |
| 23:32 | brehaut | clojurescript is sort of a proof of concept for clojure in clojure. its also clojure implemented with 3 or so years hindsight, so its got tricks that jvm clojure does not |
| 23:34 | dnolen` | ForSpareParts: I believe Clojure does have an analyzer but I don't think it's very easy to use. |
| 23:34 | dnolen` | ForSpareParts: just use the one in ClojureScript, analyzer is like <500 lines of code or something. |
| 23:34 | brehaut | ambrosebs has a port of it to clojure doesnt he? |
| 23:35 | ForSpareParts | Yeah, I found something about the Clojure analyzer on dev.clojure.org that links to the Frenchy64 project that xeqi linked me to. |
| 23:39 | zakwilson | I can't find the new comment reader syntax with google. What is it? |
| 23:40 | dnolen` | zakwilson: new? |
| 23:40 | zakwilson | dnolen`: there's something new in 1.4, as I recall. |
| 23:41 | dnolen` | zakwilson: tagged literals |
| 23:44 | zakwilson | dnolen`: found it in the reader source: #_ |
| 23:45 | dnolen` | zakwilson: that's not new |
| 23:46 | zakwilson | dnolen`: I'll take your word for that. I only learned about it recently and I made a mental note of it being new. |