2012-11-21
| 00:00 | flying_rhino | atom_: to me seven consequtive closed parens look psychotic. |
| 00:03 | atom_ | flying_rhino: Perhaps. I'm likely not a very good source. I'm new to programming in general, I have seen both perspectives and I think it may be as much culture as it is structure. |
| 00:03 | amalloy | (inc atom_) |
| 00:03 | lazybot | ⇒ 1 |
| 00:03 | flying_rhino | atom_: look this way: Thera aren't many lispers around. One of the reasons is that code looks weird. Making code looking less weird is imho the cheapest way to make lisp more approachable. |
| 00:04 | atom_ | amalloy: Thanks! I guess I can now say I'm inc'd. |
| 00:04 | egghead | heh that's like alman style braces for lisp |
| 00:04 | egghead | wait what are these dangling -- oh |
| 00:04 | amalloy | there's no reason parens *have* to go the way they do. but everyone who's spent any amount of time writing lisp has agreed that's the way they should go. that's why the arguments about code formatting in lisp are between the experts and the newcomers, and not between experts and other experts like in C/java/etc |
| 00:05 | flying_rhino | atom_: marketing is something I am ionterested in |
| 00:05 | flying_rhino | *interested |
| 00:05 | augustl | flying_rhino: I recommend "simple made easy" by Rich Hickey, he has a lot of great things to say about the importance of familiarity |
| 00:06 | flying_rhino | hope no one will get heart attack when they see my code. |
| 00:07 | egghead | flying_rhino: your second example is inconsistent tho, why not finish the let statement on another line as well |
| 00:07 | augustl | flying_rhino: the tl;dr is that familiarity is relatively unimportant, and I tend to agree |
| 00:08 | amalloy | egghead: don't forget the ] from the start of the let-bindings. why is it trapped behind the later )? |
| 00:08 | flying_rhino | amalloy: since it is [ it already stands out from ( |
| 00:09 | flying_rhino | amalloy: so no need for new line there |
| 00:09 | amalloy | flying_rhino: perhaps a useful criticism is that you're trying to make the parens stand out. they're supposed to fade into the background so you can pay attention to the important stuff, like actual code |
| 00:09 | atom_ | flying_rhino: Well, Lisp is based off of Lambda Calc if I remember correctly. You could just as easily tie it to the degradation in mathematical rigor, especially the absence of proofs, in many high school and university mathematics. Thus, less familiarity with that structure and by happenstance less familiarity with the structure of Lisp. |
| 00:10 | royaldark | the stacked ) vs newline ) is one reason I think comparing lines of code for Cish languages vs Lisp-like languages is deceptive |
| 00:10 | nilmethod | any recommendations for whirlwind tours on clojure or resources for me to learn enough clojure to be dangerous in about 8 days? |
| 00:10 | amalloy | early, early on, when you're struggling to see what's going on, it can be useful to have that extra emphasis so that you can make sense of anything at all. but long-term, it's bad for you |
| 00:10 | nilmethod | 8 evenings, that is |
| 00:11 | flying_rhino | atom_: comparison with math doesn't really work since lisp insists on prefix notation which is unusuall for math. |
| 00:12 | flying_rhino | I compare it to XML and JSON |
| 00:13 | mrowe | flying_rhino: that is an odd thing to do :) |
| 00:13 | jkkramer | nilmethod: there are several good clojure books - clojure programming, joy of clojure, etc |
| 00:13 | atom_ | flying_rhino: It's the structure I think you're concerned with here. The structure of a proof doesn't change much wether you're using prefix or standard notation. |
| 00:13 | flying_rhino | mrowe: that's my story and I am sticking to it. At bottom, LISP is programmable data. |
| 00:14 | mrowe | er |
| 00:15 | egghead | flying_rhino: xml and json are programmable data as well? I don't much see the similarity besides them being tree structures |
| 00:15 | egghead | that's like saying lisp is just like c because both have ASTs |
| 00:15 | nilmethod | jkkramer: i've got the pragmatic press book. may just plow through it |
| 00:15 | flying_rhino | egghead: xml and json are representation of data. Lisp is just more executable :) |
| 00:16 | jkkramer | nilmethod: also clojure.org, clojure-doc.org, 4clojure.com |
| 00:17 | jkkramer | nilmethod: and rich hickey videos, for the big picture |
| 00:18 | flying_rhino | amalloy: I am not trying to make parens to stand out. I am trying to make CODE stand out. In my example (* @x @y @z) is the place where stuff from let block comes together. It deserves it's own line. |
| 00:18 | technomancy | nilmethod: try clojurebook.com |
| 00:19 | flying_rhino | amalloy: it is also, incidentally function that returns value |
| 00:20 | haruki_zaemon | mrowe *waves* |
| 00:21 | miclorb | I think to close off all parens )...) or )<->). The ruby guys led the way http://d.hatena.ne.jp/ku-ma-me/20110718/p1 |
| 00:21 | haruki_zaemon | miclorb genius! |
| 00:22 | miclorb | I like the close parens - someone had the rule "more than 5 to close and you need to refactor" - which seems handy |
| 00:22 | miclorb | if it looks bad, need to rethink |
| 00:25 | atom_ | flying_rhino: You mentioned marketing. Are you hoping to make functional more palpable by making it look more like OOP? |
| 00:26 | flying_rhino | atom_: look just becuase we can't make everything more palpable doesn't mean we shouldn't try with some stuff. And clojure does have multimethods which should make OOP guys a little less grouchy. |
| 00:27 | mrowe | flying_rhino: I still don't get why you're so keen to use clojure, then want to make it just like java/scala/etc. |
| 00:28 | muhoo | when in rome |
| 00:30 | flying_rhino | mrowe: because (1) Functional programming is good for a lot of things. I would like more mutable state here and there but still prefer functional for a lot. (2) Macros and code as data philosophy rules (3) Scala syntax looks like crap. (4) using multicore more efficiently is something I like. |
| 00:30 | egghead | clojure can look pretty ugly |
| 00:30 | flying_rhino | mrowe: do I need to go on? |
| 00:31 | mrowe | flying_rhino: you can avoid mutable state and write functional code in java and scala |
| 00:31 | clojurebot | scala is https://twitter.com/#!/timbray/status/153996532952203264 |
| 00:31 | mrowe | flying_rhino: what about macros and "code as data" rules? |
| 00:31 | Sgeo | flying_rhino, if you want a language with Lisp macros and lots of mutable state, go with Common Lisp |
| 00:31 | flying_rhino | mrowe: makes easier to parse code and write your own tools if you are so inclined. |
| 00:32 | mrowe | flying_rhino: you can write efficient parallelisable code in many languages |
| 00:32 | Sgeo | CL is OO to a good extent |
| 00:32 | egghead | lisp as a programming language for programming languages. mmm |
| 00:32 | flying_rhino | Sgeo: I doubt CL has immutable structures as sophisticated as clojure. |
| 00:33 | Sgeo | I'm sure you could implement them. |
| 00:33 | Sgeo | ^^a bit trollish |
| 00:33 | egghead | lol |
| 00:33 | Bergle_1 | thats like a bit pregnant ? |
| 00:34 | flying_rhino | Sgeo: I'm sure you guys could implement slightly more mutablility, huh? |
| 00:34 | egghead | flying_rhino: but whyyy |
| 00:34 | mrowe | flying_rhino: so can you. it's a lisp, after all :) |
| 00:34 | Sgeo | flying_rhino, we don't want to, but the tools are there for you to implement highly mutable data structures if you wish. |
| 00:35 | Sgeo | Or just use the native Java data structures. |
| 00:35 | flying_rhino | Sgeo: I will, probably. Won't use them all or even most of the time, but they will be there. I would prefer someone else does it so it is more standardized. |
| 00:36 | atom_ | flying_rhino: That sounds like feature creep that is unnecessary. |
| 00:36 | Sgeo | The native Java data structures are pretty "standard" |
| 00:36 | egghead | Heh, reminds me of tao, don't swim against the river |
| 00:36 | Sgeo | Not used all that often, but anyone who wants to use them would use them in the same way. |
| 00:37 | egghead | flying_rhino: have you seen the hickey talks on 'place oriented programming' or encounted that term in something like SICP ? |
| 00:37 | Sgeo | Does place-oriented programming have anything to do with CL's setf? |
| 00:38 | flying_rhino | Sgeo: I guess java structures are the way to go then :) So we are all happy. |
| 00:39 | egghead | Sgeo: you tell me :) |
| 00:39 | Sgeo | Except for any other Clojure programmer who touches your code, who will curse you out for needless mutability. |
| 00:39 | flying_rhino | Sgeo: happy ending, end credit music plays etc etc... |
| 00:39 | Sgeo | egghead, I don't really know what "place-oriented programming" is |
| 00:39 | egghead | flying_rhino: http://www.infoq.com/presentations/Value-Values |
| 00:39 | egghead | Sgeo: basically dealing with addresses of things instead of the values of things |
| 00:40 | egghead | if you have a value you don't have to worry about it slipping out from under you, when you only have an address you can never be sure what will be there at any given time |
| 00:41 | Sgeo | Tcl's append is place-oriented |
| 00:41 | Sgeo | Seriously, I think Tcl's great, except for all the mutability. |
| 00:42 | Sgeo | And fun fact, Tcl values (aka strings) are immutable, but variables etc. are all highly mutable and often passed around like candy |
| 00:44 | Sgeo | Tcl arrays (basically hash maps) are not first-class things. Dictionaries are, but those were added in recently |
| 00:44 | Sgeo | Arrays in Tcl are just a collection of similarly named variables |
| 00:44 | Sgeo | :/ |
| 00:59 | augustl | FYI, programmers of europe! http://techmeshconf.com/ |
| 00:59 | augustl | seems like there are still tickets left. Very relevant for Clojure programmers |
| 01:00 | atom_ | Is there a place where tickets are filed for bugs/patches etc. and marked with beginner tags for clojure? |
| 01:01 | augustl | atom_: afaik there's only the jira |
| 01:01 | tpope | devn: I've been 80% through for about 2 weeks :/ |
| 01:03 | amalloy | atom_: if you have submitted a contributor agreement (which you must, to be allowed to help), you can read andy fingerhut's weekly summaries on the clojure dev mailing list |
| 01:04 | amalloy | eg http://groups.google.com/group/clojure-dev/browse_thread/thread/d98c4c3841bfd4b2/1972bd1b90178008?q=#1972bd1b90178008 but i think you need to have a CA to even read it |
| 01:05 | atom_ | amalloy: Thank you. I'll print it out and save it for when I feel like I could contribute back productively. |
| 01:21 | flying_rhino | Sgeo: what's basic difference of hash map and dictionary? |
| 01:22 | lynaghk` | ure |
| 01:23 | lynaghk` | dnolen: just pushed up a patch for the core.logic walk stuff. Right now it walks over map keys just for completeness, though unification won't work with lvars inside of a complex map key because of how that process works. |
| 01:35 | Sgeo | flying_rhino, in what language? |
| 01:36 | flying_rhino | Sgeo: is there a general difference? |
| 01:36 | Sgeo | Different languages tend to use the same term to mean different things |
| 01:37 | Sgeo | Array is a frequent offender, but there are others. |
| 01:37 | Sgeo | "Functor" is particularly bad |
| 01:37 | Sgeo | "hash" map does somewhat imply something about the internals of how it works |
| 01:37 | Sgeo | That it hashes the key |
| 01:37 | Sgeo | And uses that for efficiency purposes. |
| 01:41 | brainproxy | why is it I get cool insights about the time I really should go to bed ... and just must stay up coding lest I lose the spark? :p |
| 01:43 | Sgeo | What is this "bed" of which you speak? |
| 01:43 | brainproxy | i dunno, it could be like (sqrt -1) |
| 01:45 | brainproxy | Sgeo: any good w/ call-cc? |
| 01:45 | Sgeo | Um, I understand it at a basic level |
| 01:46 | Madsy | brainproxy: Some people are naturally more awake and creative at night |
| 01:46 | Madsy | Which makes sense to me. It's perhaps dark outside, little background noise, no traffic and everything is calm |
| 01:46 | brainproxy | Madsy: yeah, I'm definitely one of those ... will often work until 4/5am in the morning |
| 01:47 | Madsy | Seconded |
| 01:47 | brainproxy | but can create ... issues ... in a world where things need to get done during the day |
| 01:47 | Madsy | Just sleep a bit in the afternoon. That's what I do |
| 01:48 | Madsy | I often go to bed at 3 or 4 am. Then I sleep for 4 hours. After work I sleep for 2-3 hours, then I wake up at 6-7 pm and do chores. |
| 01:48 | brainproxy | sometimes that helps, but after i hit my mid 30s I find I've pretty much got to get 8 hours of sleep |
| 01:49 | Madsy | Yeah, age definitely plays a role. |
| 01:50 | Madsy | What was your question about call/cc ? |
| 01:51 | brainproxy | oh, it's just that protocol-monads needs call-cc implemented, but I don't understand the concept well enough to pull it off, though I've made progress w/ other parts of the library |
| 01:51 | Madsy | call/cc In Clojure? |
| 01:52 | brainproxy | well, something that works like it |
| 01:52 | Madsy | Not sure if that's possible. Afaik, Clojure doesn't support full continuations due to limitations with the JVM |
| 01:52 | brainproxy | see algo.monads, it has it |
| 01:52 | Madsy | Monads.. brr. The name scares me D: |
| 01:52 | brainproxy | :) |
| 01:54 | amalloy | $google swannodette delimc |
| 01:54 | lazybot | [swannodette/delimc · GitHub] https://github.com/swannodette/delimc |
| 01:54 | amalloy | brainproxy: ^ |
| 01:55 | Madsy | brainproxy: I'm sure algo.monads managed to make an approximation |
| 01:55 | Madsy | But proper call/cc lets you jump *anywhere* |
| 01:55 | brainproxy | amalloy: awesome, delim'd conts are, I've heard, "better" than call/cc |
| 01:56 | brainproxy | saw an interesting presentation on them a few months ago, but didn't know any Haskell at the time, so I was a bit lost |
| 01:56 | amalloy | well, they're a bit "weaker", in that there's some stuff you can't do. but in general the stuff you can't do is an unspeakably bad idea to do |
| 01:56 | brainproxy | i think there's a paper "call/cc considered harmful" |
| 01:57 | brainproxy | or something like that, which advocates for delim'd conts |
| 01:57 | Madsy | It's "kind of" harmful |
| 01:57 | Sgeo | Any monad-based Continuation system is going to be delimited continuations I think |
| 01:57 | amalloy | ∀x∃p such that p is a paper titled "x considered harmful" |
| 01:58 | brainproxy | hehe |
| 01:58 | Sgeo | I should also note that that delimc library is a bit broken in some ways |
| 01:58 | Sgeo | For starters, anything wishing to use it must use all the vars |
| 01:58 | Sgeo | And there might be other flaws |
| 01:58 | Madsy | The problem with call/cc is that it allows you to jump both forwards and backwards. It guarantees that optimization is close to impossible |
| 01:58 | Sgeo | It's a not thoroughly executed port of a Common Lisp library |
| 01:59 | brainproxy | the impl in algo.monads looks deceptively simple |
| 01:59 | brainproxy | just a couple lines of code |
| 01:59 | brainproxy | building on top of its continuation monad impl, of course |
| 02:04 | amalloy | Sgeo: use all the vars? |
| 02:05 | Sgeo | amalloy, as in, (:use) in the ns macro or (use) |
| 02:06 | Sgeo | Or... well, just the ones you intend to use, I guess. The problem is that it won't, say, see delimc.core/shift as shift, it will only see shift as shift |
| 02:07 | amalloy | i have to say, the macro forms there look a bit bonkers. but it's not totally unprecedented; reset introduces an anaphor named shift, in the same way that loop introduces one named recur, or try introduces one named catch |
| 02:25 | alex_baranosky | does anyone have experience with serving dynamically generated files (such as CSVs) from a Ring app? |
| 02:27 | alex_baranosky | WE've been using the 'wrap-resource' ring middleware to server static files, but it looked like it wouldn't recognize something generated dynamically |
| 02:34 | amalloy | alex_baranosky: just find out the http headers you need to set, and set them, while making the :body be whatever you need. eg, 4clojure generates image files on the fly with {:response 200 :headers {"Content-Type" "image/png"} :body (...some input stream with the right bytes...)} |
| 02:35 | amalloy | to make the files "downloadable" you probably need to set content-disposition as well, or something |
| 02:35 | alex_baranosky | amalloy: thanks , I'll look at that |
| 02:35 | Apage43 | Content-Disposition: attachment would force a type that would normally be displayed to be downloaded |
| 02:36 | Apage43 | if you need that sort of thing |
| 02:36 | clojurebot | most horrible thing is http://tinyurl.com/b65o8e |
| 02:42 | alex_baranosky | APAge43: thanks looking into Content-Disposition: attachment |
| 03:11 | alex_baranosky | amalloy & Apage43 - thanks guys that worked |
| 03:22 | augustl | http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure could use some multimethods or protocols |
| 03:25 | augustl | and there we go, reading the whole article before posting it is a good idea :) |
| 04:36 | thorwil | ,(map #(identity %) [{:a 1 :b "bert"} {:a 3 :b "jim"}]) |
| 04:36 | clojurebot | ({:a 1, :b "bert"} {:a 3, :b "jim"}) |
| 04:37 | thorwil | ,(map #(cons % %) [{:a 1 :b "bert"} {:a 3 :b "jim"}]) |
| 04:37 | clojurebot | (({:a 1, :b "bert"} [:a 1] [:b "bert"]) ({:a 3, :b "jim"} [:a 3] [:b "jim"])) |
| 04:37 | thorwil | i do not understand at all what happens in the second case |
| 04:38 | ucb | ,(doc cons) |
| 04:38 | clojurebot | "([x seq]); Returns a new seq where x is the first element and seq is the rest." |
| 04:38 | ucb | ,(seq {:a 1}) |
| 04:38 | clojurebot | ([:a 1]) |
| 04:38 | ucb | thorwil: ˆˆˆˆ |
| 04:39 | ucb | ,(cons {:a 1 :b 2} {:a 1 :b 2}) |
| 04:39 | clojurebot | ({:a 1, :b 2} [:a 1] [:b 2]) |
| 04:39 | ucb | cons takes the 2nd argument as a seq (my guess is that it even calls seq on it) and hence you end up with a seq of [k v] from your map |
| 04:39 | ucb | ,(source cons) |
| 04:39 | clojurebot | Source not found |
| 04:40 | ucb | &(source cons) |
| 04:40 | lazybot | ⇒ Source not found nil |
| 04:40 | ucb | pah |
| 04:43 | thorwil | hmm. i need something that allows me to assemble (:b %) and % |
| 04:44 | Bergle_1 | I am looking at http://clojuredocs.org/clojure_core/clojure.core/spit - it has a type hint of #^java.io.Writer - what is the '#' ? I've just done a dozen plus searches in google but not finding any enlightenment |
| 04:44 | thorwil | ah, seq or vec |
| 04:55 | cemerick | Bergle_1: #^ was the original type-hint prefix. |
| 04:55 | Bergle_1 | ahhhh. |
| 04:55 | Bergle_1 | i couldnt find that :) thanks. |
| 04:55 | Bergle_1 | i thought it might be the case. |
| 04:56 | thorwil | ,(apply hash-map (mapcat #(vec [(:b %) %]) [{:a 1 :b "bert"} {:a 3 :b "jim"}])) |
| 04:56 | clojurebot | {"bert" {:a 1, :b "bert"}, "jim" {:a 3, :b "jim"}} |
| 04:56 | thorwil | is there a ncer way from the 2 maps to that result? |
| 04:56 | thorwil | nicer, even |
| 05:03 | ucb | thorwil: maybe this http://clojuredocs.org/clojure_core/clojure.set/index |
| 05:06 | thorwil | interesting, but that seems to be a much more complex mechanism with some other goals |
| 05:15 | ucb | you would end with a map where the keys are maps like {:b value} |
| 05:16 | ucb | it's not that much more different; but perhaps you don't need that complexity in the real code :) |
| 05:17 | thorwil | it must be string keys. not my choice :) |
| 05:51 | borkdude | hello guys (and maybe girls) |
| 05:52 | borkdude | the last two years I have put two groups of students (2 to 4) on a "research" project involving clojure |
| 05:52 | borkdude | the first was about the differences in OO and functional approach to a common/random application |
| 05:52 | borkdude | the second focussed more on web frameworks |
| 05:53 | borkdude | but this year I want to have a similar group at work. any nice ideas about what they could research? they don't know clojure yet, only Java |
| 05:53 | borkdude | so in the first few weeks I'll teach them clojure, and then they can go into something specific |
| 05:56 | thorwil | borkdude: at work? shouldn't that suggest some specific areas of interest already? |
| 05:56 | borkdude | thorwil education |
| 05:57 | thorwil | ah, parsed with wrong context |
| 05:57 | borkdude | thorwil my mistake |
| 05:58 | thorwil | nah, no worries anyway |
| 05:59 | thorwil | to just throw something out: database -> text reports. think stock market or sport reports |
| 06:03 | borkdude | maybe I could let them investigate smth about clojurescript |
| 06:03 | borkdude | because I don't know much about it myself yet |
| 06:03 | borkdude | maybe they could port some libs as an exercise |
| 06:04 | thorwil | i think yesterday someone asked about a clojurescript version of trammel |
| 06:09 | borkdude | if you have any good ideas, please e-mail them to (apply str (interleave ["michiel" "borkent" "hu" "nl"] ["." "@" "." ""])) |
| 06:16 | deg | What are good packages for doing chart/plot style graphics in Clojure? I'm looking at incanter now; which others are good too? |
| 06:29 | babilen | deg: I've used incanter, but it has serious problems with its charts and I abandoned it. I am currently playing with https://github.com/quil/quil which is a different approach |
| 06:30 | babilen | deg: If you find something good that is more like mathplotlib (Python), matlab or ... let me know. Clojure seems to lack a good graphing library |
| 06:33 | babilen | deg: See http://tgk.github.com/2012/11/visualising-gcse-statistics-using-datomic-and-quil.html for an example -- It is still a bit too "manual" for my taste, but that might just be because I haven't mastered processing yet |
| 06:34 | deg | thanks. |
| 06:34 | deg | What problems did you find with incanter? |
| 06:34 | deg | The first issue I hit is that I need a way to replace the contents of a chart from time to time (like a dashboard display) and that appears to be non-trivial, at best. |
| 06:38 | babilen | deg: A common issue is, for example, that graphs are not labelled ... This has been discussed on the mailing list and the "solution" was to use the underlying API directly. https://groups.google.com/forum/?fromgroups=#!topic/incanter/g2k2M6JllYE |
| 06:39 | babilen | deg: I also have the impression that incanter is a bit, well, undermaintained. |
| 06:41 | bordatoue | has anyone figured out a way to work with local jar files using lein ver 2 , in version 1 it was easy as the local requirement could be added to lib directory . |
| 06:42 | bordatoue | i don't wat the local jar to be installed , it should be just temporary |
| 06:43 | deg | babilen: thanks. I'll look at quil and see what else I can find. |
| 06:45 | xeqi | bordatoue: while not recommended, you can abuse :resource-paths for that |
| 06:45 | bordatoue | xeqi seriously, you are picking up on me |
| 06:50 | bordatoue | xeqi thanks , |
| 07:07 | Chiron | Hi, where can i find a sample profiles.clj file ? |
| 07:07 | Foxboron | Chiron, 2 sec and ill pastebin mine :) |
| 07:08 | andrewmcveigh|wo | Chiron: https://github.com/technomancy/leiningen/blob/master/sample.project.clj |
| 07:08 | Chiron | that is project.clj sample |
| 07:08 | Foxboron | O.o didnt know about those |
| 07:09 | Chiron | i'm talking about .lein/profiles.clj |
| 07:09 | andrewmcveigh|wo | Ah, sorry. Reading blindness. |
| 07:09 | Chiron | no, thanks any way :) |
| 07:10 | babilen | Chiron: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md -- Not sure if there is a sample as it very much depends on what /you/ want :) |
| 07:10 | babilen | (lein2 btw) |
| 07:11 | Chiron | profiles.clj isn't available for lein 1.7 ? |
| 07:11 | babilen | Chiron: No |
| 07:11 | thorwil | all my profiles.clj contains is: {:user {:plugins [[lein-immutant "0.12.0"]]}} |
| 07:22 | Chiron | it is deprecated :) |
| 07:22 | Chiron | Please use ~/.lein/credentials.clj.gpg instead. |
| 07:23 | josteink | if I define an object as a map of keywords and functions |
| 07:23 | josteink | (def foo { :test (fn [x] (+ 1 x)) }) |
| 07:23 | josteink | do I have to go ((:test foo) 1) or is there a shorthand I can use? |
| 07:23 | josteink | a special form? |
| 07:24 | bordatoue | i find this lein really painfull, is there any other command to get detailed help on localrepo, when i type lein help localrepo ==> work with local Maven repository, is that it |
| 07:24 | bordatoue | is it something to do with my version of lein |
| 07:25 | bordatoue | which is leing lines. |
| 07:25 | bordatoue | ^E or * Search multiple files (pass thru END OF FILE). |
| 07:26 | bordatoue | sorry, lein 2.0.0-preview10 |
| 07:27 | mishok13 | hey guys, how would you achieve the following in Clojure: given a list of indices and a vector, extract a seq that contains items referenced by those indices? |
| 07:28 | mishok13 | e.g. indices = [1 3], vector = [42 :foo 12 :bar :baz], result -- [:foo :bar] |
| 07:29 | pyr | mishok13: (map (partial nth my-vector) my-indices) |
| 07:30 | pyr | ,(map (partial nth [:a :b :c :d :e]) [1 3]) |
| 07:30 | clojurebot | (:b :d) |
| 07:30 | mishok13 | thanks, pyr |
| 07:30 | mishok13 | I started looking into some and juxt for some reason |
| 07:31 | josteink | pyr: oooh. nice "trick" :) |
| 07:32 | xeqi | bordatoue: try `lein localrepo` |
| 07:33 | bordatoue | xeqi: is that the recommended way to get help |
| 07:34 | babilen | Is anybody aware of how the PDFs of the clojure cheatsheet are generated? The current version is horribly aligned and just unusable and I wanted to see if I can improve it. |
| 07:36 | josteink | link? |
| 07:36 | clojurebot | your link is dead |
| 07:36 | babilen | Also: is https://github.com/jafingerhut/clojure-cheatsheets/ the source for the cheat sheet linked on http://clojure.org/cheatsheet |
| 07:36 | josteink | horrible or not |
| 07:36 | babilen | heh |
| 07:37 | josteink | ive seen bigger marvels of design |
| 07:37 | josteink | but still contains quite a bit of compact information :) |
| 07:37 | xeqi | bordatoue: depends on how the plugin implements it, in this case it looks like localrepo built its own help system |
| 07:37 | xeqi | which would have been needed until recently |
| 07:38 | bordatoue | xeqi: thanks very much, how would you go about getting help on lein |
| 07:40 | xeqi | bordatoue: combination of `lein help`, https://github.com/technomancy/leiningen/tree/master/doc , sample.project.clj, and asking here or #leiningen |
| 07:40 | xeqi | depending on what you need help with |
| 07:44 | ambrosebs | That's weird. It seems doing a `lein install` on a git project with zero commits gives this error: /home/ambrose/Projects/lein-typed/.git/refs/heads/master (No such file or directory) |
| 07:44 | bordatoue | xeqi: finding it quite hard to get a grip on lein, i don't know where to start from. What would be the recommened way to understand lein |
| 07:45 | ambrosebs | Whoops, wrong room |
| 07:46 | bordatoue | xeqi: i have got a set of depencies on one project A, i would like to have the same set of depencies when i create the second project, is there any way i could do it with manually editing project.clj |
| 07:47 | xeqi | bordatoue: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md ? |
| 07:47 | xeqi | bordatoue: with or without? |
| 07:47 | bordatoue | with |
| 07:47 | xeqi | copy the :dependencies in project A's project.clj to project B's |
| 07:51 | bordatoue | xeqi: there any way a project.clj file to refer to another project.clj file |
| 07:51 | xeqi | nothing builtin |
| 07:53 | xeqi | and no plugins that come to mind |
| 07:53 | bordatoue | xeqi: just one more question if i specify a directory under "resource-path" will it add all the .jar files under that directory |
| 07:53 | xeqi | though I can imagine a way to do it.. though its not great |
| 07:54 | xeqi | bordatoue: no |
| 07:55 | bordatoue | xeqi: so its a vector of files that i want to add to the class path . |
| 07:56 | xeqi | its meant to be a directory the jvm can use to find resources; adding jars is just abuse that happens to work due to the way the resources are added to the classpath |
| 07:56 | xeqi | * directories |
| 07:58 | bordatoue | xeqi: thanks very much for your time |
| 08:51 | gauravag | how do I iterate over a map with key value? |
| 08:54 | xumingmingv | ,(for [[k v] {:james :bond :jack :rose}] [k v]) |
| 08:54 | clojurebot | ([:james :bond] [:jack :rose]) |
| 10:02 | maleghast | Afternoon |
| 10:03 | jcrossley3 | maleghast: morning! :) |
| 10:04 | xeqi | today |
| 10:07 | jsabeaudry | What is the correct way to do this: (defn foo [& [{:or {b 10 c 15} :as all}]] (list (:b all) (:c all))) |
| 10:07 | dysinger | hrm. I'm trying to get paredit to automatically hook in on nrepl in emacs. it's not working. anyone have tips for me? |
| 10:08 | broquaint | What have you got at the moment, dysinger? |
| 10:09 | bordatoue | \who bordatoue |
| 10:11 | dysinger | broquaint: I have (add-hook 'nrepl-interaction-mode-hook 'paredit-mode) which I found on stackoverflow. |
| 10:13 | broquaint | You may want nrepl-connected-hook instead there, dysinger. |
| 10:14 | dysinger | ah - I'll try it |
| 10:14 | broquaint | WFM at least :) |
| 10:17 | dysinger | that didn't work for me :( |
| 10:24 | dysinger | broquaint: yes that did work. I was doing it wrong. |
| 10:24 | dysinger | thanks! |
| 10:24 | dysinger | actually I added the hook to nrepl-mode |
| 10:24 | dysinger | seems to work |
| 10:25 | dysinger | where as connected-mode didn't |
| 10:26 | mmitchell | I just installed leiningen 2 as lein2, created a new project, but "lein2 deps" doesn't seem to do anything at all? |
| 10:27 | mmitchell | "lein2 test" works, hmm |
| 10:27 | babilen | mmitchell: Have you actually added any dependencies for which something needs to be done? |
| 10:27 | mmitchell | babilen: yes, a few of them |
| 10:27 | xeqi | mmitchell: lein2 uses jars from your ~/.m2 cache |
| 10:27 | xeqi | if you have them there already it doesn't do anything |
| 10:27 | mmitchell | xeqi: so it doesn't put anything in your project's lib dir? |
| 10:28 | babilen | mmitchell: And have they already been downloaded? Dependencies are handled differently in leiningen2 in that it uses a central repo for all projects |
| 10:28 | xeqi | also, `lein deps` should get called automatically when needed, you shouldn't have to manually invoke it |
| 10:28 | xeqi | mmitchell: correct |
| 10:28 | babilen | mmitchell: No, $proj/lib is not used anymore |
| 10:28 | mmitchell | ahh nice. OK all is well then. I just launched the repl without problems |
| 10:28 | mmitchell | thanks! |
| 10:29 | babilen | mmitchell: Do you actually have a problem that is caused by missing dependencies or did you just expect lein2 to behave like lein1? |
| 10:29 | mmitchell | babilen: i was expecting it to behave like v1 |
| 10:29 | Raynes | But then it wouldn't be lein 2! |
| 10:30 | babilen | ack - well, there have been quite some changes. You might want to read https://github.com/technomancy/leiningen/wiki/Upgrading |
| 10:30 | mmitchell | Raynes: exactly! |
| 10:31 | mmitchell | babilen: thanks, I'll check that out |
| 10:32 | mmitchell | I want to create a few tasks in my project. Is it possible to use code from my project in the tasks? Is there a wiki page somewhere for creating custom lein tasks? |
| 10:34 | xeqi | mmitchell: lein2 keeps a good seperation between the project jvm and lein jvm |
| 10:34 | xeqi | usually tasks go in plugins, but if they *really really* are project specific https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#project-specific-tasks |
| 10:35 | mmitchell | xeqi: yeah, these are definitely project specific |
| 10:45 | enigmeta | Is there an easy way to flatten one "level" of a nested structure? |
| 10:45 | enigmeta | I have something like: [[[1 2] [3 4]] [[5 6] [7 8]]] |
| 10:45 | enigmeta | And I would like: [[1 2] [3 4] [5 6] [7 8]] |
| 10:46 | tufflax | Maybe concat? |
| 10:46 | tufflax | ,(apply concat [[[1 2] [3 4]] [[5 6] [7 8]]]) |
| 10:46 | clojurebot | ([1 2] [3 4] [5 6] [7 8]) |
| 10:47 | enigmeta | Thanks! (apply concat [...]) seems to work. I was looking for something called "combine". |
| 10:47 | tufflax | Hm, did you get that from another language or something? |
| 10:48 | enigmeta | No, just guessing. |
| 10:48 | tufflax | ok :p |
| 10:48 | jballanc | Anyone know if clojurebot or lazybot's source is available somewhere? |
| 10:48 | tufflax | jballanc, i think they are, search github |
| 10:49 | jballanc | hmm...there's a few forks looks like |
| 10:52 | Chiron | Hi, are Clojure functions serializable ? |
| 10:54 | nDuff | ChiralSym: not out-of-the-box, but see https://github.com/technomancy/serializable-fn |
| 10:54 | nDuff | err |
| 10:54 | nDuff | Chiron: ^^ |
| 10:55 | chronno | jballanc: http://www.clojure-toolbox.com/ look under "IRC Bots" |
| 10:55 | nDuff | ...or do you mean implementing Serializeable? |
| 10:55 | Chiron | nDuff: thanks! |
| 10:56 | Chiron | i mean implementing Serializable |
| 10:58 | nDuff | ,(supers (class (fn [] 1))) |
| 10:58 | clojurebot | #{java.lang.Runnable clojure.lang.IObj clojure.lang.Fn clojure.lang.AFunction clojure.lang.AFn ...} |
| 10:59 | nDuff | ...ahh, the bot doesn't print the whole thing -- but java.io.Serializable is there. |
| 10:59 | Chiron | first time i know about supers |
| 10:59 | Chiron | super! |
| 10:59 | jweiss | is it possible to add an interface implementation to someone else's record type? |
| 11:00 | jweiss | extend-type requires a protocol, not an interface |
| 11:00 | jules2 | is there a way to get basic clojure out of clojurescript, with all macros expanded, stdlib imported, etc., but without any javascript bits? |
| 11:02 | Foxboron | Is there any great way on Windows to reduce Clojure startup time? |
| 11:02 | Foxboron | Googling around but wanna see what people recommend ^^ |
| 11:03 | Raynes | Not really. |
| 11:03 | ambrosebs | Chiron: see also `bases` and `ancestors` |
| 11:03 | Raynes | The JVM is slow to start up. Not really a way to mitigate it. |
| 11:03 | Chiron | that could be changed in JVM 9 ? |
| 11:04 | Raynes | I guess. Pigs could also grow wings eventually, given evolution. |
| 11:04 | Foxboron | I know drain stores the stuff in memory so the overall startup time is reduced by 1 sec, but its not available on windows :/ |
| 11:04 | Raynes | drain? |
| 11:04 | Foxboron | Lemme find source :) |
| 11:04 | Raynes | You mean drip? |
| 11:05 | Foxboron | was it drip..? hmm |
| 11:05 | Raynes | It doesn't work like that though. |
| 11:05 | Foxboron | ah, drip. |
| 11:05 | Raynes | All drip does is start a new jvm when you run a command, warming it up for your next command. It gives the appearance of fast startup time by having a JVM already running when you're ready to use it. |
| 11:05 | nooooo | If I have a list of 2-element vectors, is there a more idiomatic way of transforming them into a map then just reducing across the list? |
| 11:05 | Raynes | It could also probably be ported to Windows if someone cared enough. |
| 11:06 | Foxboron | Raynes, i see. I'll try google some more. |
| 11:06 | Chiron | ambrosebs: thanks! |
| 11:07 | ambrosebs | Chiron: np |
| 11:08 | nDuff | ,(into {} [[:a :b] [:c :d] [:e :f]]) |
| 11:08 | clojurebot | {:a :b, :c :d, :e :f} |
| 11:08 | nDuff | nooooo: ^^^ |
| 11:09 | scriptor | nDuff: what about it? |
| 11:09 | nDuff | scriptor: it's an answer to nooooo's question |
| 11:09 | scriptor | ah, heh |
| 11:10 | jsabeaudry | Is there a lein-outdated that also checks plugins? |
| 11:18 | PudgePacket | where can i find info about string manipulation with clojure ? |
| 11:20 | nDuff | PudgePacket: http://clojure.github.com/clojure/clojure.string-api.html and http://docs.oracle.com/javase/6/docs/api/java/lang/String.html are the bulk of what there is. |
| 11:20 | nDuff | PudgePacket: Looking for anything particular? |
| 11:21 | nDuff | PudgePacket: ...well, you might also see the "strings" section on the cheatsheet at http://clojure.org/cheatsheet |
| 11:22 | jweiss | is there a way to extend ILookup to other types so that when i do (:mykeyword theirtypeobj) i get my own behavior for the lookup? |
| 11:29 | nDuff | jweiss: Unfortunate that ILookup isn't a protocol -- that _would_ be shiny, but I don't think it's possible. |
| 11:29 | jweiss | darn, was hoping there was some avenue i was missing. |
| 11:30 | jweiss | i wonder if there's any plan to make some of the internal interfaces into protocols? |
| 11:36 | dnolen | jweiss: a JVM backend for CLJS would be a good start ;) |
| 11:37 | dnolen | Bronsa: have you considered putting Blind into contrib - it would be nice to have all the necessary pieces for bootstrapping in contrib. |
| 11:43 | Bronsa | dnolen: honestly, I hadn't thought about it |
| 11:45 | dnolen | Bronsa: I'd definitely +1 that. Would love to switch ClojureScript to use a pure Clojure reader that doesn't have to wait for modification to the Clojure one. |
| 11:47 | Bronsa | dnolen: ok, i will check out what's the process to get it into contrib and do it in the next few days |
| 11:47 | dnolen | Bronsa: sweet, not much beyond pinging the dev ML really. I'd get behind it and I'm sure all the folks doing tooling (LightTable) would too. |
| 11:48 | Bronsa | what should the contrib name be then? |
| 11:49 | dnolen | Bronsa: I'm sure that can get sorted on the ML - tools.reader ? |
| 11:49 | Bronsa | mmh, yeah |
| 11:49 | scriptor | cljs's reader isn't pure clojure already? |
| 11:49 | abp | neat :D |
| 11:50 | dnolen | scriptor: cljs reader just does EDN, we want a full Clojure source reader |
| 11:51 | Bronsa | dnolen: the fact is, blind is currently an order of magnitude slower than clojure's reader |
| 11:51 | scriptor | ah, all cljs is valid EDN, right? |
| 11:51 | Bronsa | and i suck at profiling. |
| 11:51 | abp | dnolen: Wouldn't it be much easier and more expandable to do closure style dead code elimination in clojure? |
| 11:51 | dnolen | Bronsa: order of magnitude isn't a bad start - I'm sure we can optimize. Even then - I seriously doubt that time would dominate analysis, compilation etc. |
| 11:52 | scriptor | Bronsa: your repo mentioned that it used to be faster? |
| 11:52 | Bronsa | yeah |
| 11:52 | scriptor | any idea around when the slow-down started to happen? |
| 11:52 | Bronsa | sadly, no |
| 11:52 | dnolen | abp: I have no idea - never looked at tree-shaking. But yes, it would be nice to have some system for compiler passes for pluggable optimizations. |
| 11:52 | scriptor | hmm |
| 11:53 | scriptor | I guess theoretically it's possible to take a repo and go through it from the first commit, all the while running benchmarks, it'd be cool to automate that |
| 11:53 | scriptor | be hell to do it manually |
| 11:53 | Bronsa | scriptor: i was so dumb that i didn't use git. |
| 11:53 | nDuff | sounds like the kind of thing git bisect is good for. |
| 11:53 | dnolen | Bronsa: fortunately it's not that much code |
| 11:54 | Bronsa | if i did, i would have already done that |
| 11:55 | dnolen | the most loved CLJS commit yet http://github.com/clojure/clojurescript/commit/cd66e6b9e63ad5ef1896a9c7a117148beb04301d |
| 11:57 | egghead | oh nice dnolen |
| 11:58 | egghead | might be time to give cljs another shot |
| 11:58 | dnolen | egghead: source map work is moving along - getting close |
| 11:59 | egghead | last time I tried I was turned off by having to marshall clj -> js/dom back and forth when using gclosure stuff |
| 11:59 | egghead | is everyone just using jayq these days? |
| 12:00 | egghead | I think I will pick up http://shop.oreilly.com/product/0636920025139.do |
| 12:01 | dnolen | egghead: I know that ibdknox has moved on to a much lighter weight solution - jQuery is dead weight. |
| 12:01 | dnolen | IMO |
| 12:02 | egghead | ya I didn't want to add it, especially since it can't eliminated by gclosures tree shaking, but last time I used cljs it was just so painful to have to write helper functions over around every dom interaction |
| 12:03 | egghead | that commit looks like it'd get rid of a lot of that boilerplate, however :) |
| 12:04 | dysinger | what's the point free version of haskell's flip in clojure again? I'm super rusty |
| 12:06 | egghead | dysinger: flip reverses the argument order? |
| 12:10 | technomancy | dysinger: you have to pull in useful for flip |
| 12:10 | technomancy | also, hey |
| 12:11 | egghead | technomancy: does useful have any documentation anywhere |
| 12:12 | technomancy | not sure |
| 12:13 | egghead | at least it's got a full test suite :3 |
| 12:13 | Raynes | It has docstrings. |
| 12:14 | Raynes | Whether or not they're useful depends on whether or not amalloy_ or ninjudd was putting the function in there because they wanted to use it in two different projects without duplicating effort and get it all done in 5 seconds or if they honestly thought other people would use it. |
| 12:16 | egghead | heh, thanks Raynes |
| 12:16 | seangrove | ,(apply str (interleave ["a" "b" "c"] ["." "-" "."])) |
| 12:16 | clojurebot | "a.b-c." |
| 12:16 | seangrove | Wow, cool stuff |
| 12:17 | Raynes | Far out and funky. |
| 12:17 | egghead | ,(apply str (interpose ["a" "b" "c"] ", ")) |
| 12:17 | clojurebot | ",[\"a\" \"b\" \"c\"] " |
| 12:17 | egghead | oops |
| 12:17 | egghead | :) |
| 12:18 | Raynes | &(clojure.string/join "," [\a \b \c]) |
| 12:18 | lazybot | ⇒ "a,b,c" |
| 12:19 | egghead | hmm, kind of cool that interpose considered ", " as a list of chars |
| 12:19 | Raynes | Well, it is. |
| 12:19 | Raynes | If you call seq on it. |
| 12:19 | Raynes | &(seq ",") |
| 12:19 | lazybot | ⇒ (\,) |
| 12:21 | egghead | aah, didn't know interpose was defined in terms of interleave either, neat |
| 12:28 | kevincolyar | I'm writing a simple ray tracer to learn clojure... what would you guys recommend I use to store screen of rays/pixels? A 2d vector of refs? |
| 12:28 | abp | Is there something like a unified "jump to line in file"-url invoker for existing editors and IDEs? With wich editors is this even possible? |
| 12:29 | seangrove | abp: you mean jump to line in either a fil or a url? |
| 12:29 | seangrove | file* |
| 12:29 | qerub | abp: For the record, TextMate has txmt://open?url=…&line=…&column=… |
| 12:29 | abp | seangrove: No, communicating, please jump to line x in file y. To an editor, programmaticaly. |
| 12:30 | abp | qerub: Noted. Just in case I need to write that by myself. :x |
| 12:34 | dnolen | kevincolyar: I would just use Java arrays for a raytracer. |
| 12:39 | kevincolyar | dnolen: I'm not worried about performance right now, just learning clojure. |
| 12:41 | dnolen | kevincolyar: I wouldn't use refs, probably one big vector of ints. |
| 12:44 | kevincolyar | I'm kind of stuck trying to figure out the best way to update the state of the screen when I cast each ray |
| 12:45 | wingy | i am converting a curl request to cljhttp code . is this correct https://www.refheap.com/paste/6892 |
| 12:45 | dnolen | kevincolyar: you can treat the vector just like you would an array. (set-pixel vector-of-ints x y new-value) |
| 12:45 | wingy | im not sure about the attachment field |
| 12:45 | abp | Hm, I can't use e* on lein repl with Clojure 1.5.0 Beta1? |
| 12:45 | dnolen | kevincolyar: use x and y to index into the array, and update it with assoc. |
| 12:45 | dnolen | ,(assoc [0 1 2 3] 0 5) |
| 12:45 | clojurebot | [5 1 2 3] |
| 12:47 | kevincolyar | dnolen: ahh, i thought could only use assoc with maps |
| 12:49 | dakrone | wingy: no, you need to look into :form-params. you also have two basic-auth things when only one is needed |
| 12:49 | kevincolyar | dnolen: wont that give me a new vector each time since it's immutable? |
| 12:50 | kevincolyar | dnolen: seems like i could be updating the vector via a reference type |
| 12:50 | wingy | dakrone: oh yeah i missed that i already added one basic auth |
| 12:51 | ghadishayban | anyone know what happened to fill-queue from old contrib? |
| 12:52 | dnolen | kevincolyar: if you want understand Clojure - this is what you want to do. you can probably construct your raytracer so that it doesn't need any real mutation at all. |
| 12:52 | wingy | dakrone: seems that i need to use :multipart and not :form-params in this case since its sending files |
| 12:52 | wingy | https://github.com/dakrone/clj-http |
| 12:53 | dnolen | kevincolyar: that in fact should be constraint - can you construct the raytracer without using reference types. |
| 12:53 | dnolen | "should be the constraint" |
| 12:54 | dakrone | wingy: it depends on what your server is expecting |
| 12:54 | dakrone | curl's -F is :form-params I beleiev |
| 12:54 | dakrone | *believe |
| 12:54 | wingy | dakrone: ok |
| 12:55 | kevincolyar | dnolen: cool, i'll give it a try. thanks for the help |
| 13:03 | alexnixon | kevincolyar: I wrote a raytracer in clojure on a hackday, it used a for comprehension over x and y values, and a function taking the pixel x y and returning a color |
| 13:24 | kevincolyar | alexnixon: it used a? |
| 13:27 | lynaghk | kevincolyar: I think he meant a "for comprehension". In Clojure for is a list comprehension that returns a value, not a control flow operator like in other langugaes |
| 13:28 | lynaghk | ,(for [x (range 3) y [:a :b :c]] [x y]) |
| 13:28 | clojurebot | ([0 :a] [0 :b] [0 :c] [1 :a] [1 :b] ...) |
| 13:28 | kevincolyar | lynaghk: ah, ok |
| 13:28 | dnolen | lynaghk: thanks for patch - one unimportant enhancement would be to throw on the presence of lvars in map keys - but it's not critical. |
| 13:30 | lynaghk | dnolen: I did that initially, but I realized it would take quite a bit of change in the implementation and thought it'd be worth some discussion |
| 13:31 | lynaghk | dnolen: i.e., to support that you would need to seq over all of the keys of the target map and try to unify each one with the key-in-hand of the source map. |
| 13:32 | dnolen | lynaghk: like I said - would be nice - but not a priority. |
| 13:32 | lynaghk | dnolen: ah, sure. yeah, I'd wait til you get some feature requests about it before throwing unifier perf out the window =P |
| 13:33 | lynaghk | dnolen: thanks for the fast merge turnaround, btw. |
| 13:34 | abp | Hey lynaghk, how can I render directed svg-graphs with c2? |
| 13:34 | abp | lynaghk: Would that be hard? I have basically no expierience with writing visualization algorithms. |
| 13:34 | lynaghk | abp: there isn't a graph layout engine in c2, if that's what you're asking about. If you're using c2 on cljs you can just use the force-layout engine from d3 |
| 13:35 | lynaghk | abp: though in that case you would need to use mutable javascript objects since D3's engine just has a tick routine and updates the x and y properties of graph objects. |
| 13:35 | abp | lynaghk: Not cljs only. |
| 13:36 | abp | lynaghk: And that's something I can't imagine to consider. |
| 13:36 | lynaghk | abp: graph layout is a very tricky problem; I'm not sure what's avaliable on the JVM side---you could probably do the layout calculations with graphviz |
| 13:37 | lynaghk | abp: A friend of mine at AT&T research also mentioned that there are some really good new algorithms based on shortest-path distances rather than the physics-y stuff |
| 13:37 | abp | lynaghk: Yes, I render svg now using lacij, but that's just to inflexible. Undocumented wrapper of a bunch of java-libs. A big bunch actually. |
| 13:37 | lynaghk | abp: but yeah, if you can get a list of nodes and connections with x & y coordinates already you can use c2 to draw them in SVG no problem. Take a look at the c2 svg namespace for some arc generation stuff |
| 13:39 | dnolen | lynaghk: on thought about yesterday's conversation - perhaps it would be uniform to only have symbols or vectors of symbols on the left handside instead of fns as keys. |
| 13:42 | lynaghk | dnolen: I'm not sure you'd be able to support all possible constraints in that case |
| 13:44 | lynaghk | dnolen: say you have predA and predB that both constrain vars ?x and ?y. If you allow functions on the left you can say {predA [?x ?y], predB [?x ?y]}. If you don't allow functions on the left, how could you express it? |
| 13:45 | lynaghk | dnolen: {[?x ?y] #(and (predA %1 %2) (predB %1 %2))} ? |
| 13:46 | dnolen | lynaghk: yes |
| 13:48 | lynaghk | dnolen: I think each of the syntaxes we've discussed has some awkward situations. Making lvars or vectors of lvars the map keys seems as good as any to me. |
| 13:49 | lynaghk | dnolen: sugar-wise, maybe people will want to write {#{?x ?y ?z} numeric?} to mean that those three vars should all be numeric |
| 13:49 | lynaghk | dnolen: but that's just something nice to have instead of having to write {?x numeric?, ?y numeric?, ?z numeric?} |
| 13:50 | lynaghk | dnolen: the thing I do like about having functions as keys in the constraint map is that it makes it easier for people to add/remove classes of constraints. |
| 13:50 | dnolen | lynaghk: yes special handling of set keys would probably be ok. I just want what appears on the left hand side to be consistent - vars or collections of vars. |
| 13:50 | lynaghk | dnolen: in my use case I can imagine wanting to talk in terms of constraint predicates more often than talking in terms of individual variables or sets of variables. |
| 13:52 | seangrove | Are there any cljs interface libraries wrapping goog.ui.*? |
| 13:52 | lynaghk | dnolen: also, I tend to have a nicer handle on predicate fns (which are usually toplevel vars created by defn) than I have on lvars (which I don't usually have a reference to at all---they're created for me by prep) |
| 13:53 | dnolen | lynaghk: yeah I don't really see any expressiveness issues here - just going for consistency. |
| 13:53 | dnolen | {?x numeric? |
| 13:53 | dnolen | er |
| 13:54 | dnolen | {'?x numeric? '[?x ?y] complex-constraint} |
| 13:54 | lynaghk | dnolen: yeah, I agree with you on consistency. Now it's just a question of whether we want to talk in terms of lvars or constraints |
| 13:55 | lynaghk | dnolen: this is something that folks can solve for themselves using clojure.set/map-invert, though. |
| 13:56 | dnolen | lynaghk: yep, it's also about making it simpler / cleaner to process. |
| 13:58 | lynaghk | dnolen: is one of these forms easier to handle internally? |
| 13:58 | lynaghk | dnolen: I'd have thought in either case you are just doing something like (doseq [[vars pred] constraint-map] ...) |
| 14:03 | trinakria | Hello |
| 14:05 | dnolen | lynaghk: no it's not a matter of easier to handle - it's about picking just one thing, also it's pattern everywhere in core.logic for vars to appear on the left hand side |
| 14:05 | dnolen | whether in substititons or when calling bindings-map etc |
| 14:05 | lynaghk | dnolen: that's good enough for me, then; lvars or collections of lvars on the left, preds on the right |
| 14:06 | dnolen | lynaghk: I agree that at first glance constraints on left seem ok, but I think in the long run systemic consistency trumps conveniences. |
| 14:07 | lynaghk | dnolen: agreed; as I said, if it's a big enough problem consumers can manipulate the constraint maps themselves. |
| 14:07 | lynaghk | dnolen: good call on that vs. metadata. |
| 14:07 | dnolen | lynaghk: yes :) |
| 14:12 | bbloom | dnolen: how do you maintain the cljs version of core logic? |
| 14:12 | bbloom | dnolen: i want to release a lib for both clj and cljs, but i'm not super excited about the idea of copy pasting a whole file and then extracting the macros |
| 14:13 | dnolen | bbloom: copy & paste |
| 14:14 | bbloom | dnolen: :-( |
| 14:14 | lynaghk | bbloom: you can check out my cljx leiningen plugin. It's a hack, but so is every other solution to that problem. |
| 14:14 | bbloom | dnolen: I'm almost positive I could pull this off with make and sed ... |
| 14:14 | dnolen | bbloom: not much to be done until we get compiler support for feature expressions. |
| 14:15 | bbloom | dnolen: so i was following the feature expressions discussion |
| 14:15 | bbloom | but i wasn't sure why that couldn't be added as a macro |
| 14:16 | Sgeo | I think nREPL might be a bit slow for me |
| 14:16 | bbloom | Kevin Downey pointed on in that thread that common lisp's issues don't affect clj here |
| 14:16 | Sgeo | Sometimes if I leave it running for long then do something it takes a while |
| 14:16 | seangrove | <p class="integration_menu full_contact_integration_menu active" style="top: 54.80000305175781px; overflow: hidden;"><div class="link_list_menu"> |
| 14:16 | seangrove | <h3>FullContact Profile</h3> |
| 14:16 | seangrove | <div> |
| 14:16 | seangrove | Social Profiles <small>(91% confidence)</small> |
| 14:16 | seangrove | <table class="zenbox-table"> |
| 14:16 | seangrove | <tbody><tr> |
| 14:16 | seangrove | <td class="link-action"> |
| 14:16 | Sgeo | I tried (time (+ 1 1)) and it said it took 22 ms but it seemed on the order of seconds. |
| 14:16 | seangrove | <span class="social vimeo"> |
| 14:16 | Sgeo | So what's going on |
| 14:16 | seangrove | <img src="https://www.zenboxapp.com/assets/service_icons/vimeo.png"> |
| 14:16 | seangrove | </span></td> |
| 14:16 | seangrove | <td> |
| 14:16 | Sgeo | seangrove, /flushq |
| 14:16 | seangrove | <a href="http://vimeo.com/user9118251" target="_blank">user9118251</a> |
| 14:16 | seangrove | </td> |
| 14:16 | seangrove | </tr> |
| 14:16 | Sgeo | Then use a pastebin |
| 14:17 | seangrove | <tr> |
| 14:17 | seangrove | <td class="link-action"> |
| 14:17 | seangrove | <span class="social plancast"> |
| 14:17 | seangrove | <img src="https://www.zenboxapp.com/assets/service_icons/plancast.png"> |
| 14:17 | seangrove | </span></td> |
| 14:17 | seangrove | <td> |
| 14:17 | seangrove | <a href="http://plancast.com/yayitswei" target="_blank">yayitswei</a> |
| 14:17 | Sgeo | @ops |
| 14:17 | Sgeo | ~ops |
| 14:17 | clojurebot | Gabh mo leithscéal? |
| 14:17 | seangrove | </td> |
| 14:17 | seangrove | </tr> |
| 14:17 | seangrove | <tr> |
| 14:17 | uvtc | How did all this html get in here? :) |
| 14:17 | seangrove | <td class="link-action"> |
| 14:17 | seangrove | <span class="social facebook"> |
| 14:17 | seangrove | <img src="https://www.zenboxapp.com/assets/service_icons/facebook.png"> |
| 14:17 | seangrove | </span></td> |
| 14:17 | seangrove | <td> |
| 14:17 | seangrove | <a href="http://facebook.com/yayitswei" target="_blank">yayitswei</a> |
| 14:17 | seangrove | </td> |
| 14:17 | seangrove | </tr> |
| 14:17 | nDuff | Someone mention when the flood is over so I can unignore. :) |
| 14:17 | seangrove | <tr> |
| 14:17 | seangrove | <td class="link-action"> |
| 14:18 | seangrove | <span class="social gravatar"> |
| 14:18 | seangrove | <img src="https://www.zenboxapp.com/assets/service_icons/gravatar.png"> |
| 14:18 | seangrove | </span></td> |
| 14:18 | seangrove | <td> |
| 14:18 | seangrove | <a href="http://gravatar.com/yayitswei" target="_blank">yayitswei</a> |
| 14:18 | seangrove | </td> |
| 14:18 | seangrove | </tr> |
| 14:18 | seangrove | </tbody></table> |
| 14:18 | seangrove | </div> |
| 14:18 | seangrove | </div> |
| 14:18 | seangrove | ahem... |
| 14:18 | seangrove | Sorry about that... command-v right next to M-v |
| 14:18 | mefisto | nDuff: flood complete |
| 14:18 | seangrove | Just meant to scroll up |
| 14:18 | seangrove | I pasted instead of hitting M-v (in erc) |
| 14:18 | bbloom | dnolen: lynaghk: https://www.refheap.com/paste/6896 |
| 14:18 | Sgeo | Oh |
| 14:19 | Sgeo | Does ERC have an equivalent to XChat's flushq? |
| 14:20 | dnolen | bbloom: dunno just seems uglier than CL syntax for that. |
| 14:20 | Sgeo | Who was Nosrat and why was e telling me not to say bullsh*t? |
| 14:20 | bbloom | dnolen: what does feature expressions buy us except for splice? |
| 14:20 | Sgeo | Only noticed it now |
| 14:20 | Sgeo | Name seems familiar |
| 14:21 | dnolen | bbloom: shipping one code base to multiple implementations of Clojure |
| 14:22 | nDuff | Sgeo: a bot that said the same thing to everyone, and not just in this channel. |
| 14:23 | Raynes | seangrove: You are hereby exiled from all of Clojure. Begone. |
| 14:23 | Raynes | If you're going to flood the channel, at least do it with Clojure and not HTML. |
| 14:23 | hiredman` | Kevin Downey is me, fyi |
| 14:23 | seangrove | I just see HTML as a subset of Clojure |
| 14:23 | Apage43 | What about hiccup? |
| 14:23 | bbloom | lynaghk: I saw cljx, but I'm going to refrain from using it so that i don't need to manually change all that stuff when a real solution comes along :-P until then, i'll just ignore the jvm for this one task |
| 14:25 | lynaghk | bbloom: yeah, for sure. I wrote it to get some stuff out the door, but I'll be the happiest of anyone to tear that shit down once a real solution lands in core = ) |
| 14:26 | bbloom | lynaghk: lots blocking a "real solution" sadly. from the simple (there needs to be a uniform way to raise an error) to the complex (macro system) |
| 14:27 | hiredman` | I would much rather "feature expressions" introduce a new special form or macro than make backwards incompatible changes to the reader |
| 14:28 | Sgeo | Ooh, feature expressions coming to Clojure soon? |
| 14:28 | bbloom | Sgeo: no change on status, just discussion |
| 14:34 | bbloom | dnolen: i want to extend IMeta and IWithMeta to javascript functions. if I just do a simple aset/aget with a "__meta" string on the function, would that destroy perf? or be relatively harmless? |
| 14:35 | dnolen | bbloom: won't work because of advanced optimization, ohpauleez has a proper patch |
| 14:35 | bbloom | dnolen: although i think i might prefer to do a little wrapper object that implements IFn |
| 14:36 | bbloom | dnolen: ah. is there a ticket for it? |
| 14:36 | dnolen | bbloom: yes |
| 14:36 | bbloom | funny how we all run into the same issues :-) |
| 14:38 | hiredman` | metadata on functions is kind of gross |
| 14:38 | bbloom | hiredman`: why? |
| 14:38 | hiredman` | there are identity issues |
| 14:39 | bbloom | i have a hash table of symbols to functions and a *small* percentage of functions are going to have some metadata on them |
| 14:39 | hiredman` | functions have identity equality, but at least with clojure functions implement the same metadata stuff as values |
| 14:39 | bbloom | i basically want to ask (-> f meta :some-flag) on dispatch |
| 14:39 | hiredman` | not the reference metdata stuff |
| 14:40 | bbloom | hiredman`: ah. yeah, dnolen mentioned ohpauleez' patch, which i found has this wrapper object: https://github.com/shoreleave/shoreleave-core/blob/master/src/shoreleave/efunction.cljs |
| 14:40 | Sgeo | When they should be on functions |
| 14:40 | bbloom | hiredman`: seems to be lacking equality |
| 14:41 | hiredman` | yeah, you cannot do equality |
| 14:41 | hiredman` | because adding metadata returns a "new" wrapper function with the metadata |
| 14:41 | hiredman` | so, as I said, gross |
| 14:41 | bbloom | hiredman`: couldn't you just define equality on the wrapper and the built in and make them co-dependent? when comparing, just compare the unwrapped functions |
| 14:41 | technomancy | that's not metadata's fault |
| 14:41 | bbloom | hiredman`: doesn't seem to gross |
| 14:41 | technomancy | it's clojure's fault for doing a crappy job of equality |
| 14:41 | bbloom | too* |
| 14:41 | Sgeo | If you comp a bunch of functions, the result should have the same argslist as the first function to be applied. |
| 14:42 | Sgeo | arglists |
| 14:42 | amalloy | Sgeo: and indeed it does, in that neither of them have an arglist key |
| 14:42 | bbloom | amalloy: heh. |
| 14:42 | amalloy | (or, indeed, any metadata at all, on the function object) |
| 14:43 | bbloom | Sgeo: consider type hints too. you'd want the arglist of first and the return type hint of the last. the comp function suddenly gets quite expensive and complex.... |
| 14:45 | Sgeo | I don't see a problem with comp doing that, but I guess it could be a PITA dealing with similar considerations for people writing their own functions? |
| 14:46 | llasram | Typed Clojure to the rescue? |
| 14:46 | bbloom | Sgeo: the performance cost would add up. quick. and you'd have to either A) throw away unknown keys or B) have a mechanism for comping them |
| 14:46 | bbloom | B implying an *open* mechanism |
| 14:46 | technomancy | llasram: I don't want to have to annotate everything to get simple things like that |
| 14:46 | bbloom | seems absurdly complex and yes, llasram, get's into the typing world :-) |
| 14:47 | bbloom | dnolen: if i took a crack at a function wrapper object with meta and equality working correclty, would you take that patch? :-) |
| 14:48 | llasram | I really agree with technomancy, but it seems like a type system is the endgame. Otherwise every function-returning function is doing the same legwork to correctly generate and propogate metadata |
| 14:48 | llasram | Or just live without it :-) |
| 14:48 | bbloom | I'd argue that (let [f (fn)] (= f (with-meta f {:x 1}))) is bugged in clojure |
| 14:48 | technomancy | clojure just needs better inference built-in |
| 14:51 | technomancy | bbloom: with serializable-fn you could theoretically have equivalence between two functions that do the same thing but have different argument names |
| 14:51 | Sgeo | technomancy, um, not really? |
| 14:51 | technomancy | though of course true operational equivalence is undecidable |
| 14:51 | technomancy | Sgeo: ? |
| 14:51 | Sgeo | technomancy, was thinking of operational equivalence |
| 14:51 | bbloom | technomancy: yeah, down that path lies dragons :-P i just want reference equality to work with-meta |
| 14:56 | dnolen | bbloom: I'm not in the least bit concerned about equality. |
| 14:57 | dnolen | bbloom: if the patch supports Clojure's behavior that's good enough for me. |
| 14:57 | bbloom | dnolen: ok, let me take a crack at it |
| 14:58 | dnolen | bbloom: or look at the ticket and just implement ohpauleez's code |
| 14:58 | bbloom | dnolen: yup, i see his code. was going to grab that and then extend-protocol to function & should be done |
| 15:04 | bbloom | dnolen: presumably fn? should work too |
| 15:04 | dnolen | bbloom: does it work in clojure> |
| 15:05 | dnolen | ? |
| 15:05 | bbloom | #(fn? (with-meta (fn) {:x 1})) |
| 15:05 | bbloom | ,(fn? (with-meta (fn) {:x 1})) |
| 15:05 | clojurebot | true |
| 15:05 | bbloom | yup |
| 15:06 | dnolen | bbloom: you could make a marker protocol Fn, and change fn? to check that too |
| 15:07 | bbloom | dnolen: good idea |
| 15:11 | bbloom | ,(let [f (fn)] (= (hash f) (hash (with-meta f {:x 1})))) |
| 15:11 | clojurebot | false |
| 15:11 | bbloom | dnolen: gonna ignore hashcode too then |
| 15:18 | bbloom | dnolen: core.cljs is kinda hard to navigate… kinda wished it was divided up and layered :-/ |
| 15:18 | abp | Periodically posting, just in case anybody likes to yell at me for it: https://gist.github.com/4115467 |
| 15:19 | dnolen | bbloom: would require something like load which doesn't exist - even then not sure if it's worth it. |
| 15:30 | bbloom | dnolen: the file is large enough to slow down vim, presumably due to some slow parens/ident logic in vimclojure…. where's tpope when you need him? :-) |
| 15:31 | dnolen | bbloom: heh I don't have that problem |
| 15:34 | dnolen | jamii: looking forward to your presentation! |
| 15:37 | bbloom | dnolen: debugging advanced mode is still making me want to weep. we need source maps and we need them tied into the assert mechanism badly :-) gg get lunch before i do battle with single letter variable names |
| 15:37 | dnolen | bbloom: heh yep working on that right now |
| 15:42 | jamii | dnolen: :-S |
| 15:52 | thorwil | "Could not locate tlog/test/data/account__init.class or tlog/test/data/account.clj on classpath" |
| 15:53 | thorwil | how's the stuff below "test" handled, different from "src"? |
| 15:53 | defa | new to emacs/nrepl… after adding deps to lein's project.clj, how to make them available inside emacs nrepl? Need to run "lein repl"? After connecting to the new nrepl evaluating expressions sometimes does not work and I have to restart emacs. Am I missing something essential here? |
| 15:55 | thorwil | defa: there are several ways to run an nrepl server |
| 15:56 | thorwil | defa: if evaluating an expression does not work, you should get an error message. you can close error buffers. no need to restart emacs |
| 15:57 | thorwil | defa: you repl session is in a namespace. starts in "user". you can do (in-ns project.your.ns) to switch into one o fthe namespaces defined in your clj files |
| 15:58 | defa | thorwil: terhmial: "lein repo" emacs M-x nrepl … after adding a dependency to project.clj how do I make these symbols available in emacs nrepl? |
| 15:58 | defa | thorwil: I ment "lein repl" |
| 15:59 | Hodapp | thorwil: didn't know you were here, haven't seen you since #lad... |
| 16:00 | thorwil | doesn't "lein repl" start a server and client right there? haven't used it in a long time |
| 16:00 | thorwil | Hodapp: heh, if i'm here, i'm also in #lad |
| 16:00 | Hodapp | haven't been in #lad in awhile |
| 16:01 | thorwil | defa: the repl works with namespaces just like in your clj files. besides the ns form, you can use "use" and "require" |
| 16:02 | thorwil | still wondering how i get my test file unto the classpath |
| 16:03 | defa | thorwil: it's not a namespace issue… thanks anyway. |
| 16:04 | thorwil | defa: there seems to be a misunderstanding |
| 16:05 | defa | thorwil: never mind… I'll find out… something like: http://immutant.org/builds/LATEST/html-docs/interactive.html#sec-4 |
| 16:10 | llasram | defa: That's an immutant-specific feature. You can do it yourself piecemeal by pulling pomegranate into your dependencies, but AFAIK there isn't a general-purpose "reload by project.clj deps w/ restarting the REPL server" library |
| 16:11 | xeqi | ritz has something similar |
| 16:11 | xeqi | they all suffer from possibly loading incompatible libraries |
| 16:11 | thorwil | defa: i assumed the case where the dependencies are actually in place. whenever i add a dependency here, i restart immutant, to be honest :/ |
| 16:12 | llasram | Oh yeah, that's right! I need to try that. I think it didn't stick because it blew up during hugod's Conj talk *sadface* |
| 16:12 | defa | xeqi: okay, thanks… good to know… so simply start "lein repl" again in reconnect in emacs? |
| 16:13 | xeqi | I use M-x nrepl-jack-in rather then `lein repl` and M-x nrepl, but either way works |
| 16:13 | jcromartie | ~seen ignacy |
| 16:13 | clojurebot | excusez-moi |
| 16:14 | thorwil | xeqi: nrepl-jack-in starts an nrepl server, right? if so, it's the wrong choice for immutant which provides ones |
| 16:15 | xeqi | thorwil: I didn't think `lein repl` was a choice for using immutant anyways; though it started its own nrepl server |
| 16:15 | xeqi | tcrawley: ^ ? |
| 16:15 | hugod | xeqi: ritz is supposed to check if any of the dependencies have been replaced, and create a new instance of the clojure runtime if so |
| 16:16 | tcrawley | xeqi: correct. nrepl-jack-in/lein repl will not work with immutant, since you have to deploy to it with nrepl enabled for the app |
| 16:16 | tcrawley | at that point, it starts an nrepl server for you |
| 16:16 | thorwil | xeqi, defa : yes, it's "lein immutant run" and just "nrepl" in emacs |
| 16:16 | tcrawley | if you aren't in immutant, I recommend ritz |
| 16:17 | Foxboron | mmm, Going to buy 2 clojure books. The Joy of Clojure and Programming Clojure should be the two best for a beginner? |
| 16:17 | xeqi | I recommend http://www.clojurebook.com/ |
| 16:18 | Urthwhyte | Foxboron: I really enjoyed Programming Clojure and am starting Joy this weekend |
| 16:18 | Foxboron | umm, yeah. I mixed Programming Clojure with Clojure Programming... |
| 16:18 | Urthwhyte | the former + my roommate had me up and running in a few days |
| 16:18 | Foxboron | Like srsly, why did they name those two books the same? |
| 16:19 | cemerick | We unfortunately had no input on the name. :-( |
| 16:19 | Raynes | Theyd idn't. |
| 16:19 | cemerick | xeqi: and, thanks :-) |
| 16:19 | technomancy | could be worse; could be Programming Scala |
| 16:19 | Raynes | cemerick: As if you don't pay him each time he says that. |
| 16:20 | Foxboron | technomancy, what about programming php? |
| 16:20 | cemerick | xeqi: Your 25¢ is in the mail! |
| 16:20 | Sgeo | I like what I've read of The Joy of Clojure |
| 16:20 | xeqi | hurray! |
| 16:20 | technomancy | clojurebot: Programming Scala is <reply>wait, do you mean Programming Scala, Programming Scala, or Programming in Scala? |
| 16:20 | clojurebot | scala is val foo = bar ~-> 45 <~< "Fred" %% x |
| 16:20 | technomancy | aw come on |
| 16:20 | technomancy | clojurebot: Programming Scala |is| <reply>wait, do you mean Programming Scala, Programming Scala, or Programming in Scala? |
| 16:20 | clojurebot | flatten |is| rarely the right answer. What if your "base type" is a list |
| 16:20 | brehaut | cemerick: the side effect of having no control on the name is that everyone refers to it by domain |
| 16:20 | technomancy | clojurebot: jerk |
| 16:20 | clojurebot | you cut me deep, man. |
| 16:21 | Urthwhyte | brehaut: but there's no do before it |
| 16:21 | Sgeo | What should I name a converter function? |
| 16:21 | Foxboron | If there is any Sublime uesers here, i just updated my collection of snippets with new triggers. Should be easier to type them naow :3 |
| 16:21 | Sgeo | flat-to-shaped, or shaped<-flat (the latter is a convention I saw somewhere, which makes sense I guess if you're nesting) |
| 16:21 | cemerick | brehaut: Indeed; it should have just been titled "The Clojure Book", and everything would have worked out nicely. |
| 16:22 | Sgeo | or flat->shaped and just use -> for nesting? |
| 16:23 | brehaut | Urthwhyte: err…? |
| 16:25 | Urthwhyte | brehaut: it was a joke - you said there was a side effect of naming it in that manner, so I was riffing on the need for a do for functions with side effects |
| 16:25 | brehaut | Urthwhyte: ah. well thats wrong. you do not |
| 16:26 | brehaut | Urthwhyte: you need a dosync to do STM transactional side effecting stuff, but any function can just go ahead and mutate anything anywhere |
| 16:28 | amalloy | Sgeo: flat->shaped is by far the more common if you're choosing from those three options |
| 16:28 | brehaut | ,(repeatedly 5 #(rand-int 5)) ; Urthwhyte, side effects without do |
| 16:28 | clojurebot | (1 1 3 2 0) |
| 16:28 | Sgeo | amalloy, well, if there are other options for the name I'm open to them |
| 16:28 | Sgeo | I'm not really restricted here, except ideally the name should be clear |
| 16:28 | amalloy | or you could just call it shaped, or something equally basic, if in context that still makes sense |
| 16:29 | Sgeo | Well, there's no other conversions except shaped->flat, but I want to refer to the results as flat or shaped, so |
| 16:29 | Sgeo | Clearer to just use the longer name |
| 16:30 | gfredericks | brehaut: how about (println "foo")? |
| 16:30 | brehaut | gfredericks: well yes obviously that too |
| 16:33 | technomancy | eh; non-referentially-transparent functions aren't necessarily side-effecting |
| 16:33 | bbloom | dnolen: http://dev.clojure.org/jira/browse/CLJS-359 |
| 16:34 | gfredericks | technomancy: I was just having a side-argument with him about that |
| 16:34 | technomancy | side-argument? are you in new zealand? |
| 16:34 | gfredericks | no; the internet has other communication channels |
| 16:34 | technomancy | lies |
| 16:34 | gfredericks | but now that you've taken my side I think that means I get 15 kiwi-points |
| 16:35 | technomancy | redeemable for delicious kiwi at any roadside stand? |
| 16:35 | gfredericks | not sure yet |
| 16:35 | brehaut | wait, you people eat kiwis‽ |
| 16:35 | gfredericks | I love how much I have no idea if he's actually surprised |
| 16:35 | technomancy | oh did I say that out loud; oops |
| 16:36 | brehaut | gfredericks: but they are endangered |
| 16:36 | dnolen | bbloom: I don't think we should use a Function type, just use reify for now. |
| 16:36 | gfredericks | they make the bald-eagle tacos a little less bland |
| 16:37 | bbloom | dnolen: ok |
| 16:40 | bbloom | dnolen: hmm that makes me wish there was a way that extending a protocol to function would also affect the reified value |
| 16:40 | bbloom | dnolen: ie reify and delgate |
| 16:40 | bbloom | dnolen: but anyway, i can't just reify |
| 16:40 | bbloom | dnolen: because -with-meta needs to call Function. |
| 16:42 | dnolen | bbloom: you can make anon reify constructor fn |
| 16:42 | dnolen | (fn [f meta] (reify ...)) |
| 16:43 | bbloom | dnolen: hm ok |
| 16:43 | dnolen | hmm actually you do want to share that, so you probably need to name it, still not a big deal |
| 16:44 | dnolen | oh take that back - I don't think you do |
| 16:44 | dnolen | you only with need that in the IWithMeta case |
| 16:44 | dnolen | so yeah anon ctor fn will work |
| 16:45 | bbloom | dnolen: you need it in *two* IWithMeta cases |
| 16:45 | dnolen | er ... it needs a local name - but you get the idea. |
| 16:45 | bbloom | dnolen: yeah |
| 16:45 | bbloom | doing it |
| 16:46 | bbloom | deeply indented reify looks ugly as sin, but it's ok :-P |
| 16:47 | dnolen | bbloom: also your fn? looks wrong, you need still need to call goog.isFunction as well |
| 16:47 | bbloom | dnolen: nope, tested that |
| 16:47 | bbloom | and looked at goog.isFunction |
| 16:47 | bbloom | dnolen: it's testing typeof x === 'function' |
| 16:48 | bbloom | this will basically be testing x.prototype._some_magic_protocol_thing |
| 16:48 | bbloom | dnolen: note that I do (extend-type function Fn) |
| 16:48 | dnolen | bbloom: yeah you don't want to do that. do both tests - perf thing. |
| 16:49 | dnolen | that will make testing regular JS fns crazy slow |
| 16:49 | dnolen | typeof x === 'function' is crap JS engines optimize |
| 16:49 | dnolen | don't want to lose that and go through all those tests in satisfies? for JS natives |
| 16:49 | bbloom | dnolen: is satisfies? really slow? i thought it was pretty fast !!x.protocol.y |
| 16:49 | dnolen | bbloom: we don't mess w/ natives |
| 16:50 | bbloom | dnolen: oh duh. the hash lookup |
| 16:50 | bbloom | of course |
| 16:50 | bbloom | you're right |
| 16:50 | dnolen | bbloom: separate lookup after the optimized stuff fails |
| 16:50 | bbloom | dnolen: forgot :-) |
| 16:50 | bbloom | dnolen: sadly then, this will slow down fn? tests against primitives that aren't functions |
| 16:50 | bbloom | dnolen: so if you're doing fn? and expect it to *usually* return false, then that's slower |
| 16:51 | dysinger | technomancy: remind me what the equiv of flip is in clojure again |
| 16:51 | dysinger | Prelude> let divBy3 = flip (/) 3 |
| 16:51 | dysinger | Prelude> divBy3 12 |
| 16:51 | dysinger | 4.0 |
| 16:52 | bbloom | dnolen: could do something like (or (goog/isFunction f) (and (not (primitive? f)) (satisfies? Fn f)) if we had a fast primitive? test |
| 16:53 | dnolen | bbloom: eh don't really think it's worth it, don't see how you can make primitive? any faster than satisfies? |
| 16:54 | bbloom | typeof x != "object" ? |
| 16:54 | dnolen | bbloom: or much faster anyway. |
| 16:54 | bbloom | dnolen: ^^ |
| 16:55 | dnolen | bbloom: typeof everything that is not native is "object", so how would that work? |
| 16:56 | bbloom | dnolen: assumption being if typeof anything is "object" then you need to run satisfies? to see if it's a function. but i won't pretend to have fully internalized the subtlies of javascript's odd typeof and instanceof and primitives and what not |
| 16:58 | dnolen | bbloom: I think goog.isFunction + satisfies? is good enough for now, just remember to hint the return value of goog.isFunction in the or. |
| 16:58 | dnolen | (or ^boolean (goog.isFunction f) (satisifes? Fn f)) |
| 16:58 | bbloom | dnolen: got it |
| 17:00 | dysinger | I'm too rusty |
| 17:01 | brehaut | dysinger: (/ 3) ? |
| 17:03 | gfredericks | clojure don't got no flip |
| 17:03 | dysinger | it needs a point free flip |
| 17:03 | dysinger | user=> (def one-third (partial / 3)) |
| 17:03 | dysinger | #'user/one-third |
| 17:03 | dysinger | user=> (one-third 12) |
| 17:03 | dysinger | 1/4 |
| 17:03 | dysinger | user=> |
| 17:03 | dysinger | wrong answer with that |
| 17:03 | gfredericks | I think flatland/useful has it |
| 17:03 | dysinger | k |
| 17:04 | gfredericks | dysinger: partial is just so much effort compared to haskell currying :/ |
| 17:04 | dysinger | just curious |
| 17:04 | Sgeo | You probably want (def one-third #(% / 3)) |
| 17:04 | Sgeo | Although that's not pointfree |
| 17:05 | brehaut | yeah, if you need to reach for partial and flip in clojure #(…) is better |
| 17:05 | dysinger | I was trying to do cobbling together comp, partial & reverse |
| 17:05 | dysinger | but yeah - I know I can do it with # & % but that's cheating |
| 17:05 | gfredericks | oh man guys we need to try to define flip point-free |
| 17:05 | gfredericks | just to be obscene |
| 17:05 | Sgeo | Clojure doesn't even have $ you have to write #(%1 %2) |
| 17:05 | brehaut | incidentally, haskell calls the partial application of infix operators 'sections' ;eg, (/), (/ 3) and (3 /) are sections of / |
| 17:06 | Sgeo | Or #(apply %1 (rest %&)) or something depending on circumstances |
| 17:08 | ChongLi | there's a tradeoff here |
| 17:08 | ChongLi | Haskell functions are curried by default |
| 17:08 | ChongLi | whereas Clojure functions have variable args |
| 17:08 | ChongLi | at least that's my understanding of it |
| 17:10 | dnolen | Clojure functions also have the benefit of being backed by something malleable - they are not primitive. |
| 17:11 | dnolen | comparing Haskell fns & Clojure fns just doesn't make any sense |
| 17:11 | ChongLi | yeah, they are very different animals |
| 17:11 | ChongLi | and support different abstractions |
| 17:11 | gfredericks | what malleable thing are clojure fns backed by? |
| 17:12 | dnolen | gfredericks: IFn |
| 17:12 | ChongLi | so to really compare them you need to make a judgment about which abstraction is important to you |
| 17:12 | bbloom | dnolen: duuurrrrr reify automatically adds meta support |
| 17:13 | gfredericks | yeah anytime I thought about trying to port parts of clojure.core to haskell the vararg thing came back making everything ugly |
| 17:13 | gfredericks | or impossible |
| 17:13 | gfredericks | you just can't do apply in haskell |
| 17:14 | dnolen | lots of things are impossible like this "function": http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L3853 |
| 17:14 | ChongLi | or how about clojure's map? |
| 17:14 | Raynes | You can, but for concrete numbers of args. |
| 17:14 | ChongLi | it's way more general than haskell's in some ways |
| 17:15 | dnolen | bbloom: ah right heh :) |
| 17:15 | dnolen | bbloom: so that patch is trivial :) |
| 17:15 | bbloom | dnolen: yes :-) |
| 17:15 | bbloom | dnolen: i was staring at the generated javascript… wondering "wtf is all this extra meta meta shit in here?" |
| 17:15 | dnolen | bbloom: haha |
| 17:15 | gfredericks | Raynes: that's what I mean by "can't" :) |
| 17:16 | bbloom | dnolen: oh this is much nicer :-) |
| 17:20 | bbloom | dnolen: updated http://dev.clojure.org/jira/browse/CLJS-359 |
| 17:20 | bbloom | dnolen: hopefully that does the trick because id like to go back to making what i hope will become the jquery of clojurescript :-) |
| 17:21 | gfredericks | cljquery |
| 17:22 | dnolen | bbloom: I hope by that you mean, something everyone uses - and not actual analog of jQuery which a complected mess. |
| 17:22 | bbloom | dnolen: yeah, i mean the library that is so good and obviously the the right way to do it that everybody uses it |
| 17:22 | bbloom | dnolen: very clojury: data all the things! |
| 17:23 | gfredericks | data the whole dom? webfui? |
| 17:24 | bbloom | gfredericks: the idea is to treat dom manipulations as little programs in postfix notation :-) |
| 17:24 | gfredericks | are you inventing the dom monad? |
| 17:24 | bbloom | gfredericks: not a monad, think factorcode.org |
| 17:24 | dnolen | boom, fns w/ metadata in CLJS now http://github.com/clojure/clojurescript/commit/6ce3b1cef3824fd36e75402f5a8ed5053252b15e, thanks bbloom |
| 17:25 | bbloom | dnolen: sweet thanks |
| 17:25 | dnolen | bbloom: pleasingly simple change. |
| 17:26 | bbloom | gfredericks: yeah, the idea is that stacks and trees like the dom play nice together. clojure is all about immutibility, but the dom is this big mutable mess. so the premise is to treat it like a remote service: you send it programs written in a notation similar to how you send printers postscript |
| 17:27 | bbloom | gfredericks: being a postfix notation means you can compose programs trivially via concatonation |
| 17:27 | bbloom | factor is to forth as clojure is to common lisp |
| 17:27 | bbloom | entertainingly enough, factor started out as what is no called JFactor ;-) |
| 17:28 | gfredericks | bbloom: that is an intriguing approach |
| 17:29 | bbloom | gfredericks: here's a working example |
| 17:29 | bbloom | "root" get-element "div" tag "button" class "i am a button" text append |
| 17:29 | bbloom | clearly you'd format that with newlines, etc |
| 17:29 | bbloom | but that adds a button to the "root" element |
| 17:30 | bbloom | with the right class, text, etc |
| 17:30 | bbloom | get-element pushes the element onto the stack |
| 17:30 | bbloom | all the jquery transformations can be implemented as applying a map function to a list of elements on the top of the stack |
| 17:30 | bbloom | so you don't even need to wrap each dom element in some kinda of monad thing |
| 17:31 | brehaut | …other than the list |
| 17:31 | bbloom | brehaut: well yeah, but this also works: |
| 17:31 | bbloom | ".button" select |
| 17:31 | bbloom | which has stack effect ( selector -- elements ) |
| 17:32 | gfredericks | as long as a list of elements is a different thing from a single element then I'm happy :) |
| 17:32 | bbloom | gfredericks: it will be, but all of the transformation operators will wrap and unwrap elements in lists as necessary |
| 17:35 | bbloom | this brings up an interesting thought tho |
| 17:36 | bbloom | eh nevermind, i need to noodle to myself more first |
| 17:38 | gfredericks | is it roughly accurate to call jquery's approach "weak typing"? |
| 17:38 | gfredericks | at least at a high-level |
| 17:39 | bbloom | gfredericks: in what sense? |
| 17:40 | gfredericks | hmm |
| 17:40 | gfredericks | I recant everything |
| 17:41 | hugod | wow, core.logic has working inequalities - thanks dnolen! |
| 17:41 | gfredericks | either dnolen is the man or that term is not very useful. |
| 17:43 | bbloom | hugod: w00t! somebody likes my 1 and only patch to core.logic! :-) (granted, dnolen did all the hard work to make that possible, i just added some inequality symbols to a map, heh) |
| 17:43 | hugod | bbloom: oh, didn't realise - thanks bbloom! |
| 17:44 | bbloom | hugod: heh, my pleasure, but really all dnolen on the meaty bits. core.logic is damn awesome |
| 17:44 | gfredericks | bbloom: I have one patch to core logic, and it made its way into dnolen's strange loop presentation; his commentary was "don't pay any attention to that part some guy added it" :D |
| 17:44 | bbloom | gfredericks: heh, what part was that? |
| 17:45 | gfredericks | oh um (run [a b c] ...) |
| 17:45 | gfredericks | multiple query variables |
| 17:46 | gfredericks | I got real tired of (run [q] (fresh [a b c] (== q [a b c]) ...)) |
| 17:49 | dnolen | gfredericks: haha, oh right :) I didn't mean that patch wasn't useful of course - I've been thinking about a few more enhancements along those lines. |
| 17:50 | dnolen | hugod: yeah the finite domain stuff is more or less working but it'll be some time before it's efficient ... but I'm not going to let that hold up a release. I think as soon as I get lynaghk enhancements and I fix tabling - 0.8.0 will be wrapped up. |
| 17:50 | gfredericks | dnolen: it did make me wish I had factored the patch a bit better so it didn't get in your way :) |
| 17:53 | hugod | dnolen: I'm not too worried about efficency at the moment - look forward to a release ;) |
| 17:53 | dnolen | hugod: cool, not far off. |
| 18:10 | Raynes | FYI, I just broke the crap out of refheap. It'll be down for a minute while I sort it out. |
| 18:11 | Raynes | Fixed. |
| 18:11 | Raynes | Okay, so. |
| 18:11 | Raynes | Dear everybody and persons, I have finished moving refheap to compojure and have deployed it for a trial run before I release to my master branch. |
| 18:12 | Raynes | Please report any issues promptly, and I will pretend to fix them immediately. |
| 18:15 | Bronsa | dnolen: ping |
| 18:15 | dnolen | Bronsa: pong |
| 18:16 | Bronsa | i got blind to run 5x times slower than clojure LispReader |
| 18:16 | Bronsa | the bottleneck was my implementation of StringPushbackReader |
| 18:17 | dnolen | Bronsa: nice |
| 18:19 | Bronsa | dnolen: right now the bottleneck is satisfies? |
| 18:19 | Bronsa | without calls from satisfies to attach line/column metadata, it runs as fast as LispReader |
| 18:21 | dnolen | Bronsa: yes you don't want to use satisfies? it's slow as crap |
| 18:21 | Bronsa | dnolen: should i use instance? instead? |
| 18:21 | dnolen | Bronsa: use instance? to check the interface directly |
| 18:21 | dnolen | yes |
| 18:22 | dnolen | the problem is that is satisfies? fails, it tries to walk the entire class hierarchy to find a type that satisfies the protocol :( |
| 18:22 | Bronsa | yeah |
| 18:22 | dnolen | inheritance I mean |
| 18:23 | dnolen | but that's SWEET |
| 18:23 | dnolen | fast as LispReader and in pure Clojure :) |
| 18:23 | dnolen | gotta run that's good news |
| 18:23 | Bronsa | :) |
| 18:26 | tomoj | satisfies? is slow in cljs? |
| 18:26 | tomoj | or jvm? |
| 18:27 | Sgeo | Blah, how do I take a seq of characters and turn it into a string |
| 18:27 | gfredericks | apply str |
| 18:27 | gfredericks | ,(->> "foo" seq (apply str)) |
| 18:27 | clojurebot | "foo" |
| 18:27 | Sgeo | Hmm |
| 18:28 | gfredericks | ,(str \a \space \+ \space \b) |
| 18:28 | clojurebot | "a + b" |
| 18:30 | Sgeo | Could also do clojure.string/join I guess |
| 19:04 | seancorfield | in the incanter docs it suggests (use '(incanter core stats charts)) as a way to pull in all the appropriate names for casual use... what would be the 'modern' equivalent with require and :refer :all ? |
| 19:04 | Raynes | callen: You might be particularly interested in my move of refheap to compojure, since you used it as something of a reference. |
| 19:07 | tomoj | (pprint #'AProtocolVar) prints endlessly |
| 19:07 | tomoj | since (= #'AProtocolVar (:var AProtocolVar)) |
| 19:09 | Sgeo | Anyone experienced with JNA and JNAerator here? |
| 19:09 | Sgeo | I have a function that accepts a const char * |
| 19:09 | gfredericks | tomoj: I think of pretty printing as just for data |
| 19:09 | Sgeo | JNAerator made a method that takes a String |
| 19:10 | Sgeo | The C function will make a copy of the C string that it's passed in, so I should free the memory that JNA used for its copy of the C string. How do I do that? |
| 19:10 | Sgeo | Or will the memory not leak for some reason if I don't? |
| 19:10 | tomoj | was trying to pprint analyze's output |
| 20:01 | Frozenlock | Will the clojure-conj presentations be uploaded to blip.tv? |
| 20:02 | ChongLi | I sure hope so! |
| 20:06 | wingy | cant wait for it |
| 20:09 | Frozenlock | We want clojure-conj videos! When do we want them? Now! |
| 20:12 | Frozenlock | Any good struct/record/protocols introductions around? Something for children would be terrific! |
| 20:12 | Frozenlock | 'cause for adult hurt ma brain |
| 20:14 | ChongLi | http://oredev.org/2012/sessions/expressing-yourself-polymorphism-in-clojure |
| 20:14 | ChongLi | there you go :) |
| 20:15 | ChongLi | it doesn't cover structs, however, but they are deprecated afaik |
| 20:15 | technomancy | Frozenlock: use maps |
| 20:15 | technomancy | and defns |
| 20:15 | Frozenlock | ChongLi: Thank you very much! |
| 20:15 | ChongLi | yeah listen to technomancy |
| 20:15 | ChongLi | use maps |
| 20:15 | egghead | until you don't need to :) |
| 20:15 | ChongLi | unless you need to do some polymorphic stuff |
| 20:15 | egghead | until you can't* |
| 20:16 | Frozenlock | I agree that listening to technomancy is usually a smart thing to do :) |
| 20:16 | ChongLi | turning your data into records should be viewed as an optimization step |
| 20:17 | ChongLi | and so the rule of thumb against "premature optimization" applies |
| 20:17 | Frozenlock | I'm trying to make a clojure wrapper around a java library with maaaaaany classes, each with multiple methods and I still don't know where to begin. |
| 20:17 | ChongLi | unless of course you need to dispatch on the type |
| 20:17 | technomancy | probably don't want to begin by repeating their mistakes =) |
| 20:17 | ChongLi | why are you wrapping a library? |
| 20:18 | Frozenlock | ChongLi: I don't like it :P |
| 20:18 | ChongLi | just build a new, higher level library above it |
| 20:18 | ChongLi | a wrapper (to me, anyway) implies a dumb repeating of work |
| 20:32 | Frozenlock | Hmmm... is there a way to eval a function when retrieving a value in a map? {:a 1 :b 2 :c (get-some-value)} |
| 20:32 | ChongLi | Frozenlock: not sure what you mean |
| 20:32 | clojurebot | Excuse me? |
| 20:32 | gfredericks | Frozenlock: ditto |
| 20:32 | Frozenlock | The value is time sensitive. I would like to 'look it up' only when necessary. |
| 20:33 | ChongLi | you're associating :c with the value returned by applying (get-some-value) |
| 20:33 | gfredericks | you could make the value an atom? or a function? |
| 20:33 | brehaut | or a delay |
| 20:33 | ChongLi | yeah, a delayed function |
| 20:34 | gfredericks | ,(let [m {:a (partial rand-int 15)}] [((:a m)) ((:a m))]) |
| 20:34 | clojurebot | [9 11] |
| 20:34 | brehaut | ,(let [m {:a (delay (rand-int))}] [(@(:a m) @(:a m)]) |
| 20:34 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: ]> |
| 20:34 | loliveira | is there any way to the macro ->> return nil if any part returns nil? (->> %2 :attrs :x:num utils/toDouble). For example, if :x:num return nil, toDouble should be never called. |
| 20:35 | Frozenlock | (let [m {:a (partial rand-int 15) :b 1 :c 3}] [((:a m)) ((:b m))]) |
| 20:35 | Frozenlock | &(let [m {:a (partial rand-int 15) :b 1 :c 3}] [((:a m)) ((:b m))]) |
| 20:35 | lazybot | java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn |
| 20:35 | brehaut | ,(let [m {:a (delay (rand-int 1))}] [@(:a m) @(:a m)]) |
| 20:35 | clojurebot | [0 0] |
| 20:36 | brehaut | delay has slightly different semantics to just a fun; it caches the result i believe, rather than reevaluating |
| 20:36 | Frozenlock | :/ |
| 20:36 | ChongLi | you can write your own delay |
| 20:37 | wingy | do you add a doc-string to all your functions? |
| 20:37 | gfredericks | loliveira: I think what you want is called -?>> |
| 20:37 | gfredericks | and it might be in the incubator lib |
| 20:37 | gfredericks | loliveira: thought -?> would work just as well in your example |
| 20:37 | brehaut | ChongLi: but why would you? if you dont want delays semantics, then a function of no arguments probably does it just fine |
| 20:38 | ChongLi | brehaut: yeah |
| 20:38 | ChongLi | delay is just a macro that wraps a function of no arguments in a memoizer |
| 20:38 | Frozenlock | Suppose I've written my own delay function which re-evaluates each time. Is there a way to avoid the @ (or deref call) |
| 20:39 | ChongLi | and then force just calls that function on no arguments |
| 20:39 | ChongLi | you can avoid deref |
| 20:40 | Frozenlock | I suppose what I want is a lazy map that re-evaluates each time... |
| 20:40 | loliveira | gfredericks: thank you! |
| 20:45 | Sgeo | user=> (clj-vp.attributes/produce-getset-map) |
| 20:45 | Sgeo | CompilerException java.lang.IllegalArgumentException: Malformed member expressio |
| 20:45 | Sgeo | n, expecting (. target member ...), compiling:(NO_SOURCE_PATH:1) |
| 20:45 | Sgeo | Sorry |
| 20:45 | Sgeo | That's... not really a helpful error message :( |
| 20:48 | ChongLi | what is clj-vp.attributes? |
| 20:48 | ChongLi | the . seems to be invoking java interop |
| 20:49 | Sgeo | clj-vp.attributes is the namespace of the code in question |
| 20:49 | Sgeo | And there is a lot of Java interop involved |
| 20:49 | ChongLi | ah |
| 20:49 | ChongLi | can you require with :as |
| 20:49 | ChongLi | to give a shorter name |
| 20:49 | ChongLi | so that it won't have a . in it? |
| 20:50 | gfredericks | Sgeo: any chance the exception was from your previous command? |
| 20:51 | Sgeo | Same error |
| 20:52 | ChongLi | then you'll have to work your way back through the stacktrace |
| 20:53 | ChongLi | you have some malformed java interop expression |
| 20:53 | Sgeo | But... the stack trace gives little useful information |
| 20:54 | Sgeo | Looking at the output of a function that the macro calls, where any errors are most likely |
| 20:54 | Sgeo | (It's horrific ugly and repetitive code) |
| 20:55 | ChongLi | produce-getset-map is a macro? |
| 20:55 | ChongLi | expand it |
| 20:55 | Sgeo | I did |
| 20:56 | ChongLi | and...? I don't have enough information to help you |
| 20:58 | wingy | to mock or not to mock, that is the question |
| 21:00 | gfredericks | wingy: the revered hickey says something about your mock objects mocking you for needing them |
| 21:00 | gfredericks | so the answer is unquestionably "not to mock" |
| 21:00 | xeqi | except when you should mock |
| 21:00 | wingy | gfredericks: is there a presentation about that? |
| 21:00 | wingy | it takes a lot of time to mock .. im mocking http request responses |
| 21:02 | jamesmacaulay | Hi folks, I'm looking to package up my first clojure lib and I have zero Maven experience. Is there a good guide somewhere? I figure I should test locally first by packaging and including as a dependency of another project.clj, to make sure everything works before pushing to clojars or whatever. I found lein-localrepo, am I on the right track here? |
| 21:02 | wingy | gfredericks: i mock for some reasons: 1. sometimes you can't automate eg. you need to manually interact with UI 2. sometimes you can't set up the correct testing env in the service you are using (eg. can't reset the state of the service) |
| 21:02 | gfredericks | wingy: maybe somewhere; I really don't know :/ |
| 21:02 | wingy | gfredericks: would be cool to hear what the legendary hickey says about testing/mocking |
| 21:03 | gfredericks | wingy: I think the OOP people have maybe a more specific definition of mocking than what you're using? but I couldn't say for sure |
| 21:06 | amalloy | you don't need to mock http responses, if your business code doesn't make http requests of its own accord. it could, for example, return a function that expects a map representing an http response |
| 21:06 | amalloy | in prod you call that function with actual http responses, and in a test you call it with mock data |
| 21:07 | amalloy | that's a simplistic version, but you can elaborate as needed |
| 21:08 | ChongLi | things become a lot simpler when you try to put the bulk of your code in pure functions |
| 21:08 | gfredericks | usually |
| 21:09 | gfredericks | I imagine in extreme cases you might end up just reinventing the IO monad |
| 21:12 | wingy | amalloy: sounds advaned |
| 21:12 | wingy | advanced |
| 21:12 | wingy | but some code has to do the http requests |
| 21:13 | amalloy | you're mocking, man. attempting to redefine arbitrary pieces of your business code from outside is pretty "advanced" too |
| 21:13 | wingy | im wrapping the http api for a service |
| 21:14 | wingy | amalloy: so you are saying my api functions should not make the http requests themselves but be passed a response map? |
| 21:15 | wingy | hmm .. their job is to return the response map :) |
| 21:16 | Sgeo | Sorry, dealing with RL BS right now |
| 21:17 | wingy | if everyone was using datomic we would have it easier writing tests |
| 21:17 | wingy | s |
| 21:17 | wingy | ince |
| 21:18 | wingy | since there would be no changed state .. so you setup a database value and then you use that one to test against .. that db value will never change |
| 21:19 | gfredericks | wingy: I realized the other day that "database as a value" could make it a lot easier for a web server to be a pure function |
| 21:19 | gfredericks | at least for the read-only requests |
| 21:20 | wingy | yeah .. in -> out |
| 21:22 | wingy | really cool if you think about it .. no side effects .. the same http request give exactly the same browser view |
| 21:22 | Frozenlock | ChongLi: Thank you very much for the video, I'm really enjoying it! |
| 21:22 | wingy | making it easier to catch bugs .. just give me the http request and i can produce the same view |
| 21:23 | Sgeo | Spitting the pretty-printed macroexpansion to a file |
| 21:23 | Sgeo | Maybe that will help me |
| 21:23 | muhoo | "Your mock object is mocking you.... for needing it" -- Rich Hickey |
| 21:23 | Sgeo | Avoid losing my sanity |
| 21:23 | ChongLi | Frozenlock: that's good! |
| 21:23 | ChongLi | it's a nice presentation |
| 21:23 | Sgeo | Is a macro that expands into 29kb of code a bad idea |
| 21:23 | Sgeo | >.> |
| 21:23 | ChongLi | wow |
| 21:23 | gfredericks | probably |
| 21:24 | ChongLi | Sgeo: perhaps you want to step through evaluation a bit |
| 21:24 | gfredericks | are you expanding to (def one 1) (def two 2) (def three 3) ...? |
| 21:24 | Sgeo | gfredericks, I'm expanding into a map of maps of functions |
| 21:25 | wingy | i so want to watch that presentation https://twitter.com/ybits/status/173225782678794241 |
| 21:26 | ChongLi | wingy: haha |
| 21:26 | gfredericks | Sgeo: what fer? |
| 21:26 | Sgeo | This is what I'm expanding into https://www.refheap.com/paste/bca9e92373ae550f90e473e9c |
| 21:27 | gfredericks | Sgeo: one thing to keep in mind is that each of those fn's is a separate class on the jvm |
| 21:28 | gfredericks | Sgeo: is there any reason you can't create this at runtime with a regular function? |
| 21:28 | Sgeo | Would it be better to use Java reflection to try to do (. vp.VPLibrary$VPFloatProperty x) where x is supplied at runtime? |
| 21:28 | Sgeo | Because I have no idea how to do that |
| 21:29 | Kowboy | so, all Clojure functions implement java.lang.Runnable, right? Isn't that only useful if the fn has no args? |
| 21:29 | ChongLi | just call class on the object |
| 21:29 | ChongLi | and dispatch on the result |
| 21:29 | gfredericks | Sgeo: ah ha so it's that you have a big pile of instance methods you want to call? |
| 21:29 | ChongLi | (to do reflection) |
| 21:29 | ChongLi | or write a protocol for that matter |
| 21:29 | Sgeo | gfredericks, well, they're static |
| 21:29 | gfredericks | Kowboy: probably so |
| 21:30 | gfredericks | Sgeo: ah ha |
| 21:30 | Sgeo | Wait, no |
| 21:31 | Sgeo | vp_float is a method on a thing that always stays the same, which is why I have call-vp |
| 21:31 | Kowboy | seems like most fns would simply throw ArrityException if you passed them to a thread |
| 21:31 | amalloy | Sgeo: what is clj-vp.private/call-vp? |
| 21:31 | Kowboy | unless I'm missing something, it simply seems like a shortcut for creating a Runnable when that is actually what you want |
| 21:32 | Sgeo | amalloy, very trivial macro |
| 21:32 | amalloy | Kowboy: yes |
| 21:32 | Sgeo | https://www.refheap.com/paste/f9d6cf4df13fdb64d671332e2 |
| 21:33 | Sgeo | ...I'm not supposed to be using call-vp here at all. |
| 21:33 | Sgeo | It's fine for the set but not for the get |
| 21:34 | Sgeo | But I don't see how that mistake would cause this error, hmm |
| 21:35 | ChongLi | you said all those were static methods? |
| 21:37 | Sgeo | .vp_float is not static, it's called on +INSTANCE+ |
| 21:37 | ChongLi | oh |
| 21:37 | Sgeo | vp.VPLibrary$VPFloatProperty/VP_OBJECT_X for example, though, is a static field |
| 21:42 | ChongLi | where are you getting the keys (such as :avatar-name) to look up in this map? |
| 21:42 | wingy | http://www.exampler.com/blog/2011/09/29/my-clojure-problem says rich hickey is not fond about tdd .. what does he suggest? |
| 21:43 | ChongLi | this seems like protocols or multimethods would solve this issue |
| 21:43 | Sgeo | Obtained via reflection on vp.VPLibrary$VPStringProperty and massaged to be a keyword |
| 21:43 | Sgeo | Maybe I'm doing the . form wrong |
| 21:44 | Sgeo | Apparently not |
| 21:44 | amalloy | Sgeo: tbh your code looks good to me |
| 21:44 | xeqi | jamesmacaulay: https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md or https://github.com/clojuredocs/cds/blob/master/articles/ecosystem/libraries_authoring.md |
| 21:44 | amalloy | have you tried macroexpanding one of the clj-vp.private/call-vp forms? |
| 21:45 | jamesmacaulay | xeqi: thanks! |
| 21:45 | ChongLi | or how about macroexpand-all on the entire thing? |
| 21:46 | ChongLi | and then just testing one of the resulting expressions a bit in the repl |
| 21:47 | amalloy | ChongLi: no good, because macroexpansion is what's throwing the exception |
| 21:47 | amalloy | &(macroexpand-1 '(.foo)) |
| 21:47 | lazybot | java.lang.IllegalArgumentException: Malformed member expression, expecting (.member target ...) |
| 21:47 | ChongLi | oh |
| 21:48 | Sgeo | I just wish it says what it saw |
| 21:49 | Sgeo | That would be nice |
| 21:49 | ChongLi | hmmm |
| 21:51 | ChongLi | what does throw-rc do? |
| 21:51 | Sgeo | It's a function, if the result is not 0, throws an exception based on it |
| 21:52 | Sgeo | Erm, if its argument |
| 21:53 | ChongLi | what if you get rid of call-vp so it's just (.vp_string ...) |
| 21:53 | ChongLi | just for testing |
| 21:53 | ChongLi | then we'll know if it's call-vp causing the failure to expand |
| 21:54 | wingy | "These are the facts as I know them: Rick doesn’t practice TDD (in fact he finds it a “waste of time”), but several other clojure/core contributors actually do. " |
| 21:54 | wingy | i don't get how he test that his code works without testing :) |
| 21:54 | ChongLi | that doesn't mean he does no testing |
| 21:55 | ChongLi | just that he doesn't write tests first |
| 21:55 | gfredericks | clojure has tests |
| 21:55 | Kowboy | one thing I like about TDD is that it puts you immediately in the seat of the person that is using the public api of your library |
| 21:56 | wingy | to TDD or not to TDD, that is the question |
| 21:56 | ChongLi | Kowboy: on the other hand, it forces you to make decisions before you might feel ready to do so |
| 21:57 | bbloom | is there some way to use clojure.walk/prewalk but cull a branch of the walk? |
| 21:57 | wingy | but shouldn't we design before implement |
| 21:57 | Sgeo | Got rid of call-vp |
| 21:57 | Kowboy | true |
| 21:57 | Kowboy | there are good things about top-down and bottom-up |
| 21:57 | wingy | how can you build Eiffel tower without a blueprint |
| 21:57 | Kowboy | starting small, you get nice, reusable chunks of coide |
| 21:57 | ChongLi | wingy: according to Gerald Jay Sussman; no |
| 21:58 | wingy | so perhaps if you can't make design calls then you have to study design first |
| 21:58 | Kowboy | but how to compose them together to build a nice api for the user can be tricky |
| 21:59 | Sgeo | https://www.refheap.com/paste/769824be706624249f57b547c |
| 21:59 | Kowboy | I think starting top down, with your public functions defined at a high-level, and working tests, you can then break up these functions as you go and be confident that you haven't changed the behavior |
| 21:59 | Kowboy | so both ways have benefits |
| 22:00 | ChongLi | Sgeo: ok, does this still fail? |
| 22:00 | Sgeo | Yes |
| 22:00 | Sgeo | I'm going to comment out this macro and do the reflection thing |
| 22:01 | Kowboy | wingy: that's not very agile. I mean, some design is required, but only as much as is necessary to solve today's problem |
| 22:01 | wingy | here he explains what he means http://www.codequarterly.com/2011/rich-hickey/ but it seems that he is against testing overall |
| 22:01 | ChongLi | Sgeo: macros are very tricky to get right in situations like this |
| 22:02 | ChongLi | wingy: no, he's against writing a lot of tests |
| 22:02 | wingy | ok |
| 22:02 | wingy | sounds fair |
| 22:02 | ChongLi | I don't think he has any problem with writing some regression tests |
| 22:02 | wingy | im not very fond of writing a lot of tests myself |
| 22:03 | ChongLi | that's totally different from designing your entire system by writing all of the tests |
| 22:03 | ChongLi | before writing any code |
| 22:03 | wingy | yeah |
| 22:03 | ChongLi | a lot of what I see in TDD could be called pathological testing |
| 22:03 | ChongLi | testing of things which are obvious |
| 22:04 | wingy | yeah i have seen that a lot |
| 22:04 | ChongLi | which is silly, because real problems are usually not so obvious |
| 22:04 | wingy | yepp |
| 22:04 | Kowboy | ChongLi, I think that is more white box testing |
| 22:04 | ChongLi | if you write pure functions you can avoid a lot of test-writing |
| 22:04 | ChongLi | by using generative testing |
| 22:05 | Kowboy | possibly, but you have boundary conditions in pure functions as well |
| 22:07 | ChongLi | a particularly good generative testing framework can really help you with the corner cases |
| 22:07 | wingy | ChongLi: http://stackoverflow.com/questions/562845/what-is-a-generative-unit-test-framework |
| 22:07 | ChongLi | yeah I know |
| 22:08 | ChongLi | quickcheck et al |
| 22:08 | wingy | have a look at the first test .. so it's just asserting that the sum is a integer? |
| 22:08 | wingy | how can i be sure that the integer returned is the sum of the values |
| 22:08 | ChongLi | wingy: subtraction |
| 22:08 | ChongLi | you simultaneously test addition and subtraction |
| 22:09 | wingy | cool :) |
| 22:09 | ChongLi | that leaves only the case where they're both broken in such a way as to give false negatives |
| 22:09 | wingy | so that example was a pretty bad one |
| 22:09 | ChongLi | this is usually tests like this work |
| 22:10 | ChongLi | another example is reversing a list |
| 22:10 | Kowboy | so, at what point do you recommend writing your tests? |
| 22:10 | ChongLi | if you reverse a list twice you should get back the same list |
| 22:10 | Kowboy | after a feature is "complete"? After a bug has been discovered? |
| 22:10 | gfredericks | are there any common clojurescript templates for lein-newnew? |
| 22:10 | ChongLi | after a bug has been discovered = regression testing |
| 22:11 | wingy | but you get false positive if the fn is not doing anything at all |
| 22:11 | ChongLi | wingy: sure, but that's only one test |
| 22:11 | ChongLi | another test is to reverse a list and check if the last element has become the first |
| 22:12 | Kowboy | so, I don't see TDD and generative testing being mutually exclusive |
| 22:12 | ChongLi | combine those two tests and you start to get a pretty good picture |
| 22:12 | ChongLi | Kowboy: they're orthogonal |
| 22:12 | ChongLi | TDD is a development methodology |
| 22:12 | ChongLi | generative testing is just a framework |
| 22:13 | ChongLi | TDD says you're only allowed to write code in order to satisfy a test |
| 22:13 | Kowboy | so what I'm trying to get out of you is, what is a reasonable alternative, well-defined methodology for writing tests |
| 22:14 | Kowboy | well, I guess that's the extreme definition |
| 22:14 | wingy | then i guess im doing TDD |
| 22:14 | Kowboy | I guess I'm more TFD |
| 22:14 | wingy | i write test for all public fns |
| 22:14 | wingy | Kowboy: TFD? |
| 22:15 | Kowboy | test first |
| 22:15 | Kowboy | subtly different |
| 22:15 | wingy | whats that about .. sounds the same |
| 22:15 | Kowboy | strict TDD, as ChongLi points out, says that you only write code to satisfy a test |
| 22:15 | tomoj | https://www.refheap.com/paste/e2cffd71eaa8fee108469f1a6 doesn't clojure.tools.macro make an effort for this not to happen? |
| 22:16 | wingy | so TDD :) |
| 22:17 | Kowboy | lol, honestly I sometimes write tests first, other times I play with the code a bit until I know what it is I really want to do, then I write the test |
| 22:18 | Kowboy | still, you can test your code at the REPL, or you can save those tests in a file that can be executed many times for ever and ever, amen |
| 22:19 | Kowboy | project automation is not made obsolete by functional programming |
| 22:19 | ChongLi | Kowboy: sure, that's fine |
| 22:19 | ChongLi | but that's not what Rich is against |
| 22:19 | tomoj | it seems like symbol-macrolet respects let*, but macrolet doesn't? |
| 22:19 | Kowboy | non-trivial functions have a tree of dependencies on other functions |
| 22:20 | Kowboy | some of those may be in 3rd party libraries you do not control, or they may be maintained by other people on your team who do stupid things like change the behavior |
| 22:20 | Kowboy | without telling you |
| 22:21 | Kowboy | I think if you are Rich Hickey, and you've written your own language, you've earned the right to write code without tests. |
| 22:21 | Kowboy | but for us mere mortals who work on teams with other mere mortals, tests save lives |
| 22:21 | ChongLi | again, that's not what Rich is against |
| 22:22 | ChongLi | he is not against writing tests; he just doesn't do TDD |
| 22:23 | Kowboy | ChongLi, should tests only be written as a response to a defect? |
| 22:23 | Kowboy | if not, what is the discipline? |
| 22:23 | Kowboy | what (and when) do you test? |
| 22:23 | ChongLi | you write tests according to what you anticipate will fail |
| 22:24 | ChongLi | but you don't have to do TDD |
| 22:24 | Kowboy | most software developers, in my opinion, are terrible at anticipating what their code will do |
| 22:24 | ChongLi | it's silly, though |
| 22:25 | ChongLi | if you can't anticipate what will fail, how can you write a test? |
| 22:25 | Kowboy | if you don't test, how do you know your software is correct? |
| 22:25 | ChongLi | you prove it correct |
| 22:26 | Kowboy | maybe that works if you live in a bubble of really awesome developers |
| 22:26 | ChongLi | testing doesn't tell you your code is correct |
| 22:26 | ChongLi | it only tells you whether the tests pass/fail |
| 22:27 | Kowboy | that is true |
| 22:27 | ChongLi | it's like a virus scanner |
| 22:27 | wingy | what is like a virus scanner? i disconnected |
| 22:27 | ChongLi | wingy: writing tests |
| 22:28 | Kowboy | ChongLi, what are your thoughts on code coverage? |
| 22:28 | Kowboy | assuming we are not doing TDD |
| 22:28 | Kowboy | because I think there is something very valuable with having good code coverage |
| 22:29 | ChongLi | sure, though I think 100% code coverage is pathological |
| 22:29 | Kowboy | In many cases I have had a developer tell me that they would have checked in a terrible bug if my unit test hadn't been there |
| 22:29 | ChongLi | what language are they writing in? |
| 22:29 | ChongLi | just curious |
| 22:30 | Kowboy | I just think that having a formal discipline for testing is a good thing, even if it isn't TDD |
| 22:30 | Kowboy | but if it isn't formal, then it becomes easy to "do it later" |
| 22:30 | Kowboy | and then later never happens |
| 22:31 | Kowboy | that would be Java in my case, and I get that FP is a different animal |
| 22:31 | wingy | i test all public functions |
| 22:31 | ChongLi | yeah, I think a lot of the testing you do in Java comes as a result of shortcomings in the language |
| 22:31 | Kowboy | but I don't think writing tests, even first, is a bad habbit |
| 22:31 | Kowboy | sure, but it's all executable code |
| 22:32 | Kowboy | its just that in Java, much of our testing is devoted to changes in state |
| 22:32 | wingy | if you think about it it's just telling that certain inputs generate certain outputs |
| 22:32 | wingy | if i don't have a test for a fn .. i don't get how i would know that it works |
| 22:32 | Kowboy | what I really would rather focus on is testing the behavior |
| 22:33 | wingy | i can manually test it in the repl or in app .. but that is unsaved testing |
| 22:33 | Kowboy | I think TDD ought to be much easier in Clojure |
| 22:33 | Kowboy | because you don't have to worry as much (not at all in most cases) about state changes |
| 22:34 | Kowboy | wingy, well, not totally true. Have you heard of Session? |
| 22:34 | wingy | have a link? |
| 22:35 | Kowboy | it's like a persistent repl |
| 22:35 | Kowboy | saves the inputs and outputs |
| 22:35 | Kowboy | you can go to any of the lines that were saved and re-run them |
| 22:36 | Kowboy | Kovas Boguta presented on this at the Clojure/conj |
| 22:36 | wingy | i thought about skipping the mocking and use live responses from other services .. advantages: 1. don't need mock data 2. if api changes my tests fail and i can update the code |
| 22:36 | Kowboy | https://github.com/kovasb/session |
| 22:36 | wingy | any inputs/feedback on ditching mocking and use live responses from services? |
| 22:37 | Kowboy | search google for Kovas Boguta session |
| 22:37 | xeqi | wingy: so you have to have internet access to run the tests? |
| 22:37 | Kowboy | some presentations on youtube and such |
| 22:37 | wingy | xeqi: yeah but that is reasaonble |
| 22:38 | Kowboy | wingy: depends on how frequently you run the tests |
| 22:38 | Kowboy | also, are all the service calls read-only |
| 22:38 | Kowboy | because you can't control the initial state of an external syste, |
| 22:38 | wingy | nope .. some are write .. which means i have to be able to reset the service state |
| 22:39 | Kowboy | ok, so this works in this particular case |
| 22:39 | wingy | eg. create -> read -> update -> delete |
| 22:39 | Kowboy | I'm not sure that automated testing for external services is always a worth-while exercise, though |
| 22:39 | wingy | all services should imo have a RESET api so we can reset the state |
| 22:40 | Kowboy | but testing the layer immediately beneath that is a good place to start |
| 22:40 | Kowboy | well, that's certainly not practical in many cases |
| 22:40 | wingy | Kowboy: nah .. they should have a testing account like Braintree payment |
| 22:41 | wingy | for testing only |
| 22:41 | Kowboy | *should* |
| 22:41 | wingy | in that case you can make charges etc |
| 22:41 | wingy | or .. i just do mocking and can test whatever i want :) |
| 22:43 | Kowboy | again, external services to me represent the "edge" of a program, where you may have to deal with some mutable state. Just beneath that we should have a functional core which we want to be solid. |
| 22:43 | Kowboy | so not sure whether that's a part of the system I want to test, although it may end up being the most volatile part of the system |
| 22:44 | Kowboy | I don't know... it's a case-by-case thing |
| 22:50 | wingy | perhaps that problem is not in our end .. its in those services |
| 22:57 | Kowboy | right, but all we can gain from that is how our code *might* behave under external failure conditions |
| 22:57 | Kowboy | I think that's the worst part of mocking |
| 22:58 | Kowboy | you can't really know how the external system might fail |
| 22:58 | Kowboy | maybe some common cases, like 404's or what not |
| 22:58 | wingy | so perhaps the question is not how will it look like if it fails, but what does it look like when we get what we need |
| 22:59 | Kowboy | ChongLi, you still here? |
| 22:59 | wingy | if it fails we debug .. perhaps the server is down, or they are having a bug etc .. but that won't help our app, we just show "something went wrong, we will fix it ASAP" .. and we debug it |
| 23:00 | Kowboy | I'd be interested to know what (if anything) generative testing can do for us if our inputs are nested data structures (like maps of maps) |
| 23:00 | wingy | so all my tests are just testing that one scenario my app wants, not all the scenarios that are not wanted since that can be infinite |
| 23:04 | ChongLi | Kowboy: it sounds like you may need some data abstraction |
| 23:05 | ChongLi | doing a lot of complex destructuring is a code smell |
| 23:11 | Kowboy | well, what if you are consuming XML or JSON from a service? |
| 23:13 | Kowboy | if you use cheshire you can get it as a nested Clojure data structure. What is the general approach for extracting data from a nested data structure? |
| 23:13 | ChongLi | do you expect the data to take on some specific form or is it totally arbitrary? |
| 23:15 | ChongLi | if the data is in a predictable shape, you can build abstractions out of it |
| 23:16 | ChongLi | otherwise you're sort of stuck with this blob |
| 23:17 | Sgeo | Does into force sequences? |
| 23:17 | amalloy | Sgeo: into is (reduce conj) |
| 23:18 | Kowboy | I'm not sure what "build abstractions out of it" means exactly |
| 23:18 | Kowboy | it is a predictable shape |
| 23:19 | ChongLi | you design your project as a bunch of layers of abstraction |
| 23:19 | ChongLi | at the bottom you are dealing with the concrete data |
| 23:19 | ChongLi | it's entirely dependent on what you're doing, exactly |
| 23:20 | Kowboy | say we are transforming a JSON document into some cononical data format |
| 23:21 | Kowboy | in some cases, there may be a straight 1-to-1 key mapping, but some parts might be flattened or "normalized" in the canonical format |
| 23:21 | ChongLi | right |
| 23:22 | Frozenlock | Ah damnit... I tried to make my own protocol for a custom hash-map. Then I added a new record with 'get'.... and overwritten the default get function -_- |
| 23:23 | Kowboy | I feel this is one of those common and practical "recipes" that you don't get simply by learning the language |
| 23:24 | Frozenlock | Is protocol and record the right way if I want my own hash-map datatype with a special get function? |
| 23:25 | ChongLi | that seems odd |
| 23:25 | ChongLi | why would you do that? |
| 23:26 | Frozenlock | To solve my everlasting problem of course! :) I want a map that updates itself on lookup. http://stackoverflow.com/questions/4568875/overloading-a-clojure-hash-map-in-an-stm-transaction seems to want something similar. |
| 23:27 | ChongLi | updates itself on lookup? |
| 23:27 | ChongLi | why? |
| 23:27 | clojurebot | why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone |
| 23:28 | Sgeo | Is Java reflection slow? |
| 23:28 | Sgeo | Because I'm considering creating closures in order to avoid repeatedly performing reflection |
| 23:28 | ChongLi | Sgeo: yep |
| 23:28 | Raynes | It depends on how fast it turns around and sees itself. |
| 23:28 | amalloy | phenomenally slow, yes |
| 23:28 | ChongLi | there's a reason *warn-on-reflection* exists |
| 23:28 | Sgeo | Well, I need to use some reflection to maintain my sanity |
| 23:28 | Frozenlock | ChongLi: I want to link it with an outside value, for example a stock price. |
| 23:29 | Sgeo | I could try to get that huge macro working again |
| 23:29 | ChongLi | Frozenlock: so you want an object? |
| 23:29 | Sgeo | So, making closures is worth it here? |
| 23:29 | Sgeo | This way, all reflection should occur when the library is loaded |
| 23:30 | Frozenlock | ChongLi: I honestly don't know how I could call it... |
| 23:32 | ChongLi | Sgeo: I'm still unsure what this is all doing |
| 23:32 | ChongLi | you're interop'ing with an existing java codebase? |
| 23:32 | Sgeo | Existing C API |
| 23:32 | ChongLi | ohh |
| 23:32 | Frozenlock | I think I'm getting near a solution... http://stackoverflow.com/a/5586959/1642155 |
| 23:33 | Sgeo | Made Java stuff for it with JNAerator |
| 23:33 | ChongLi | Frozenlock: why does this have to be a map? |
| 23:34 | ChongLi | Sgeo: a generated java wrapper? |
| 23:34 | Sgeo | Yes |
| 23:34 | ChongLi | no wonder it's so hard to work with |
| 23:34 | ChongLi | haha |
| 23:34 | ChongLi | Frozenlock: listen to Stuart Sierra |
| 23:35 | ChongLi | Clojure prefers pure data structures over objects that combine data and behavior. You can get the behavior you want by accessing your data structure through a function: |
| 23:35 | Frozenlock | ChongLi: I have multiple values, only some of them need to have this behavior. Seemed like an easy way to handle it. {:a 1 :b 2 :c (update-value-on-lookup)} |
| 23:38 | Frozenlock | Like using my-own-get-fn? But then I won't be able to do assoc and merge and all the other sweet map functions. |
| 23:39 | ChongLi | yeah, which is why you shouldn't make some weird variant of a map with custom methods |
| 23:40 | ChongLi | (defn a [] {:a 1 :b 2 :c (rand-int 100)}) |
| 23:40 | ChongLi | now just do (a) |
| 23:40 | ChongLi | you'll get a different one each time |
| 23:41 | Frozenlock | Sure. (defn a [] {:a 1 :b 200ms-fn :c 300ms-fn :d 10m-ram}). Now if I do (a) only to get :b, I'll be very sorry. |
| 23:43 | amalloy | do you need any features other than lazy computation of values? |
| 23:44 | ChongLi | would a lazy-seq vector instead of a map work? |
| 23:44 | Frozenlock | It needs to update every time. Unless I'm mistaken, all lazy-x in clj keep their value once realized. |
| 23:45 | amalloy | so it's a map that's in fact not a value at all? |
| 23:46 | ChongLi | yeah this shouldn't be a map |
| 23:46 | ChongLi | or any clojure collection |
| 23:46 | amalloy | ie, you give it to someone, and they use it for a while, and it mutates out from under them? that's a fine thing to do in some cases, i suppose, but i would recommend against making it act like a map |
| 23:46 | ChongLi | it should be a java object |
| 23:48 | ChongLi | how about a protocol which you simply reify when you need to? |
| 23:48 | Frozenlock | A custom datatype that uses the same map functions is bad? |
| 23:49 | ChongLi | well what you're creating is not really a map |
| 23:49 | ChongLi | a map is a value |
| 23:49 | ChongLi | you're creating a computational object that has state |
| 23:52 | Frozenlock | I don't get the distinction. It sill has a key-'value' form. Inside I intend to store a function. To this point it's still a map. Difference is with the lookup function; instead of returning the function, evaluate it. |
| 23:55 | Frozenlock | I'm also very new to defprotocol/deftype/reify... like I said earlier, I ended up overwritting my get function. |
| 23:55 | ChongLi | https://www.refheap.com/paste/6911 |
| 23:56 | ChongLi | here's an example |
| 23:56 | Frozenlock | So what you propose might be the right way, I'm just not there yet. |
| 23:56 | ChongLi | a is an object |
| 23:56 | ChongLi | it has 2 methods: stock-price and random-stuff |
| 23:56 | ChongLi | stock-price takes 1000ms to run and returns 20 |
| 23:56 | ChongLi | random-stuff returns a random-int up to 100 every time it is invoked |
| 23:59 | ChongLi | to use it you do this |
| 23:59 | ChongLi | (.stock-price a) |
| 23:59 | Frozenlock | Ok, so (stock-price a) ---> 20 |
| 23:59 | ChongLi | yeah |
| 23:59 | ChongLi | note that if you call it again |
| 23:59 | ChongLi | it'll take the same amount of time |
| 23:59 | ChongLi | it is re-computing the value |