2012-07-03
| 00:03 | TimMc | Hi Fare! |
| 00:04 | TimMc | This is my writeup of how collections are organized in Clojure: http://www.brainonfire.net/files/seqs-and-colls/main.html |
| 00:05 | TimMc | Fare: I'd say the biggest pitfalls/tradeoffs (in my personal view) are nil-punning for empty seqs, the similar-yet-different nature of seqs and lists, and the lack of a way to ask whether an object can be seq'd. |
| 00:08 | TimMc | Fare: Also, maps have a weird dual nature as collections of pairs of values vs. collections of values. They make the collections API kind of bumpy. |
| 00:10 | TimMc | Fare: As for docs: http://clojure.org/data_structures#Data%20Structures-Collections and http://clojure.org/sequences |
| 00:10 | Fare | TimMc, thanks a whole lot! |
| 00:10 | michaelr525 | good morning clojurians! |
| 00:10 | Fare | quite some reading for me |
| 00:11 | Fare | I'm meeting with my co-author tomorrow, so I'll try to read it all tonight / tomorrow morning |
| 00:11 | talios | Fare: book writing? |
| 00:11 | michaelr525 | Fare: writing another clojure book?! |
| 00:12 | Fare | nah, writing a library for common lisp |
| 00:12 | michaelr525 | a library of books?! |
| 00:12 | TimMc | haha |
| 00:13 | carlo_au | TimMc: those tables are good |
| 00:13 | carlo_au | with the ticks and crosses |
| 00:13 | TimMc | carlo_au: They need better icons. :-/ |
| 00:13 | michaelr525 | we call them light tables! |
| 00:13 | locojay | hi i have a clojure noir entry point (defpage '_someentry' [& options]...) when i do (assoc hash-map options) i get java.lang.IllegalArgumentException: No value supplied for key: [:iDisplayStart "0"] |
| 00:13 | TimMc | How does one represent logical booleans? |
| 00:14 | TimMc | I was thinking of idealized on/off symbols, like |/O |
| 00:14 | carlo_au | TimMc: what's wrong with coloured T and F? |
| 00:14 | michaelr525 | locojay: hash-map is core function i think and assoc requires 3 arguments |
| 00:15 | michaelr525 | locojay: (assoc a-map key value) |
| 00:15 | TimMc | carlo_au: Too visually similar in shape. Something like 10% of people won't see the color difference clearly enough. |
| 00:16 | locojay | michaelr525 : i mean (apply hash-map options) |
| 00:16 | carlo_au | TimMc: ah, true. |
| 00:16 | locojay | i only what they args (options) as a dict |
| 00:17 | Fare | TimMc: what's this seq'd thing? (sorry, I'm not familiar with clojure) |
| 00:17 | TimMc | ,(seq "foo") |
| 00:17 | clojurebot | (\f \o \o) |
| 00:17 | locojay | also tried [& {:as options}] but that raises that exception imediatly |
| 00:17 | carlo_au | TimMc: google image search for "icons true false" gives green ticks with red crosses |
| 00:18 | michaelr525 | locojay: try pprinting options, looks like something is wrong there |
| 00:18 | TimMc | Fare: If you give seq a thing that it knows how to make into a sequence, it will hand you back something that implements ISeq, or nil if empty. |
| 00:18 | TimMc | Fare: But if someone hands you a random object, e.g. the number 17, you can't tell if seq will throw an error on it. :-/ |
| 00:19 | wingy | yezz .. clojure is so concise that its being used as the query syntax in datomic |
| 00:19 | wingy | lol |
| 00:20 | michaelr525 | ,(hash-map [:a 1]) |
| 00:20 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: [:a 1]> |
| 00:20 | michaelr525 | locojay: see the problem? |
| 00:20 | wingy | doesn't that mean that all coders from other langs will be using clojure when they are using datomic .. what a great marketing for clojure |
| 00:20 | michaelr525 | locojay: you have to explode(?!) the vector in order to pass it to hash-map |
| 00:20 | Fare | so it's an ISeq, nil, or an error? |
| 00:20 | michaelr525 | ,(hash-map :a 1) |
| 00:20 | clojurebot | {:a 1} |
| 00:20 | Fare | and you don't have ignore-errors or something to catch the error? |
| 00:21 | nDuff | wingy: One can use datomic without any Clojure; it's just a lot more work and boilerplate. |
| 00:21 | nDuff | wingy: ...but then, I expect that Java programmers would feel uncomfortable if they *didn't* need boilerplate to get things done. |
| 00:21 | wingy | yeah and convert to clojure :) |
| 00:21 | Fare | is datomic free software or a trade secret? |
| 00:21 | locojay | michaelr525: explode? |
| 00:22 | dnolen | Fare: not free software. |
| 00:22 | wingy | Fare: free for Open Source projects |
| 00:22 | nDuff | ...free-of-cost |
| 00:22 | TimMc | Fare: As far as I know, no. The best I know of is to check whether the object is nil?, coll?, array?, or string?. |
| 00:22 | michaelr525 | locojay: options in your case is a vector of vectors, it has to be just a vector if you use (apply hash-map.. |
| 00:22 | nDuff | which is certainly not Free |
| 00:22 | technomancy | wingy: that's not what free software means |
| 00:22 | michaelr525 | locojay: maybe flatten |
| 00:23 | wingy | technomancy: oh :) |
| 00:23 | michaelr525 | ,(apply hash-map (flatten [[:a 1] [:b 2]])) |
| 00:23 | clojurebot | {:a 1, :b 2} |
| 00:23 | locojay | michaelr525 thanks |
| 00:23 | locojay | works |
| 00:23 | michaelr525 | my pleasure :) |
| 00:23 | wingy | is that a good or bad thing that its not free software? |
| 00:23 | Fare | ,(file-contents "/etc/passwd") |
| 00:23 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: file-contents in this context, compiling:(NO_SOURCE_PATH:0)> |
| 00:23 | TimMc | Fare: If Clojure were rewritten today, I'm sure the boundaries of what seq accepts would be much clearer. |
| 00:24 | wingy | or doesnt it matter |
| 00:24 | adu | hry |
| 00:24 | TimMc | Fare: clojurebot isn't the most secure thing, but it is backed by the JVM SecurityManager sandbox. |
| 00:25 | adu | i.m trying to use ring |
| 00:25 | TimMc | Until recently you could still get your paws on eval. |
| 00:25 | dnolen | TimMc: I doubt it. |
| 00:25 | TimMc | dnolen: No protocol? |
| 00:25 | dnolen | TimMc: ISeqable protocol maybe, but Clojure will never validate inputs. |
| 00:26 | TimMc | Like 80% of this would be cleaned up with protocols: https://github.com/clojure/clojure/blob/1.3.x/src/jvm/clojure/lang/RT.java#L462 |
| 00:26 | dnolen | TimMc: at runtime anyhow. |
| 00:26 | dnolen | TimMc: well ... actually never say never ... but I don't see it happening in the near future. |
| 00:26 | TimMc | dnolen: I'm not asking seq to validate inputs, I just want something that can tell me whether a thing is seqable if *I* want to know. |
| 00:26 | technomancy | it could certainly be clearer |
| 00:27 | Fare | how closely do clojure and clojurescript keep in sync with each other? |
| 00:27 | technomancy | that's what TimMc said |
| 00:27 | dnolen | Fare: as close as possible, concerning data structures pretty much identical. |
| 00:27 | Fare | does clojurescript implement all the interface infrastructure of clojure? |
| 00:27 | technomancy | that's different from stricter |
| 00:27 | Fare | is it the same compiler code base? |
| 00:28 | dnolen | TimMc: yes CLJS already has ISeqable |
| 00:28 | TimMc | dnolen: Good to hear! |
| 00:28 | xeqi | TimMc: I've fairly certain you could still get your hands on eval if you tried |
| 00:28 | dnolen | Fare: no, CLJS compiler infrastructure is written in Clojure, Clojure compiler infrastructure in Java |
| 00:29 | dnolen | Fare: interface instructure is actually improved in CLJS |
| 00:29 | dnolen | er infrastructure |
| 00:29 | adu | Fare? from TUNES? |
| 00:37 | amalloy | ~flatten |
| 00:37 | clojurebot | flatten just means you failed to use ->> and mapcat correctly |
| 00:37 | amalloy | locojay, michaelr525: ^ |
| 00:37 | brehaut | haha that sounds snarker than it used to |
| 00:37 | Fare | adu: yes |
| 00:37 | adu | Fare: I'm a big fan of your writings |
| 00:37 | Fare | thanks :) |
| 00:37 | amalloy | yeah, that's not very helpful :P |
| 00:37 | Fare | <blush> |
| 00:37 | adu | I think we talked about 3 years ago |
| 00:38 | amalloy | ~flatten list |
| 00:38 | clojurebot | list* doesn't actually make a `list?` |
| 00:38 | amalloy | i hate you, clojurebot |
| 00:38 | Fare | we did |
| 00:38 | TimMc | ~flatten |
| 00:38 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 00:41 | brehaut | thats much better |
| 00:45 | amalloy | brehaut: it's what i put there before you taught him your nonsense :P |
| 00:46 | brehaut | me‽ |
| 00:46 | amalloy | was it not you? i thought it was you |
| 00:47 | brehaut | well it might have been me, but i dont thing so |
| 00:47 | amalloy | i wonder what kind of detective work i'd have to go through to figure out the magic words to make him unlearn that |
| 00:47 | TimMc | amalloy: It was you. |
| 00:48 | amalloy | directed by M. Night Shyamalan |
| 00:48 | TimMc | directed by M. Night Shyamalog is more like it. |
| 00:49 | brehaut | the man reason i dont think it was me is that i dont believei have ever successfully taught him anything |
| 00:49 | amalloy | 2011-11-21.txt:[19:34:19] brehaut: ~flatten |just means| you failed to use ->> and mapcat correctly |
| 00:49 | brehaut | haha well bugger |
| 00:50 | brehaut | im very sorry |
| 00:50 | amalloy | haha |
| 00:50 | brehaut | (dec brehaut) |
| 00:50 | lazybot | You can't adjust your own karma. |
| 00:50 | brehaut | bah |
| 00:50 | brehaut | you shuld be able to decrement your own karma |
| 00:50 | technomancy | agreed |
| 00:50 | amalloy | clojurebot: forget flatten |just means| you failed to use ->> and mapcat correctly |
| 00:50 | clojurebot | I forgot that flatten just means you failed to use ->> and mapcat correctly |
| 00:50 | amalloy | brehaut: you're just being encouraged to use the clojurebot workaround |
| 00:51 | amalloy | ,(println "(dec amalloy")) |
| 00:51 | clojurebot | (dec amalloy |
| 00:51 | amalloy | ,(println "(dec amalloy)") |
| 00:51 | clojurebot | (dec amalloy) |
| 00:51 | lazybot | ⇒ 23 |
| 00:51 | amalloy | clojurebot: you're my own little tor relay on the way to lazybot |
| 00:51 | clojurebot | the best way to represent X is as a regular clojure map. (for most values of x) |
| 00:51 | TimMc | This is amazing. |
| 00:52 | brehaut | ,(println "(dec brehaut)") |
| 00:52 | clojurebot | (dec brehaut) |
| 00:52 | lazybot | ⇒ 6 |
| 00:52 | TimMc | (referring to the provenance of those two factoids) |
| 00:52 | amalloy | TimMc: how so? |
| 00:52 | brehaut | ive got to stop being an idiot. my karma is going through the floor |
| 00:52 | technomancy | brehaut: must conserve vital whuffie |
| 00:53 | brehaut | that ones lost on me |
| 00:53 | TimMc | amalloy: Unless I misunderstood one of your msgs, I took it that both of you were wrong about who had authored each factoid. |
| 00:53 | amalloy | TimMc: i was spot-on, bro |
| 00:53 | technomancy | brehaut: admittedly quite obscure: http://en.wikipedia.org/wiki/Whuffie |
| 00:53 | TimMc | Hmm, OK. "it" is a tricky pronoun. |
| 00:54 | brehaut | technomancy: thats far my sophisticated than my usual reading allows for |
| 00:56 | amalloy | Raynes: any idea what's up with lazybot? |
| 00:56 | Raynes | amalloy: That'd be me. |
| 00:56 | Raynes | amalloy: I'm done now. Was upgrading his clojail. |
| 00:57 | amalloy | k |
| 00:57 | amalloy | did xeqi hack us again? |
| 00:57 | Raynes | Nope, this was just something I forgot in the last release. |
| 00:57 | Raynes | Well, I'm sure he did, but this is unrelated to that. |
| 00:57 | Raynes | :p |
| 00:58 | michaelr525 | ,(apply hash-map (->> [[:a 1] [:b 2]] (mapcat identity))) |
| 00:58 | clojurebot | {:a 1, :b 2} |
| 00:58 | michaelr525 | i'd still use flatten instead of this |
| 00:58 | michaelr525 | much more concise |
| 00:58 | amalloy | michaelr525: flatten is anathema |
| 00:59 | amalloy | do not do it unless you want your program to break the moment it gets more complicated |
| 00:59 | xeqi | I try not to actually break anything |
| 00:59 | amalloy | &(into {} [[:a 1] [:b 2]]) |
| 00:59 | lazybot | ⇒ {:a 1, :b 2} |
| 00:59 | michaelr525 | ok, you win :) |
| 01:00 | michaelr525 | but why would a program break with flatten? |
| 01:00 | TEttinger | it undoes ALL nesting |
| 01:00 | TEttinger | not just one layer |
| 01:00 | michaelr525 | ok, i can see when it can be a problem |
| 01:01 | michaelr525 | then there must be flatten-1 in core or something like this |
| 01:01 | amalloy | it's apply concat, mate |
| 01:01 | michaelr525 | 'cause all i wanna do is flatten |
| 01:01 | brehaut | that would be concat |
| 01:02 | michaelr525 | ,(apply concat [[:a 1] [:b 2]]) |
| 01:02 | clojurebot | (:a 1 :b 2) |
| 01:02 | brehaut | the other gotcha with flatten is that some times people expect it will flatten maps |
| 01:02 | brehaut | ,[(flatten {:a 1}) (flatten [{:a 1}])] |
| 01:02 | clojurebot | [() ({:a 1})] |
| 01:02 | michaelr525 | ,(flatten {:a 1 :b {:c 2}}) |
| 01:02 | clojurebot | () |
| 01:03 | michaelr525 | ooh ugly ;) |
| 01:03 | brehaut | i recall lazybot / clojail being caught by that one for a while |
| 01:03 | adu | ,(->> [[:a 1] [:b 2]] (concat) (hash-map)) |
| 01:03 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@2e4f937f> |
| 01:03 | adu | ,(->> [[:a 1] [:b 2]] (apply concat) (hash-map)) |
| 01:03 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@1038a40f> |
| 01:03 | adu | ,(->> [[:a 1] [:b 2]] (apply concat) (apply hash-map)) |
| 01:03 | clojurebot | {:a 1, :b 2} |
| 01:04 | adu | sorry, I'm learning about ->> |
| 01:04 | michaelr525 | <amalloy> &(into {} [[:a 1] [:b 2]]) |
| 01:04 | michaelr525 | ^^^^^^^^^ best so far |
| 01:04 | brehaut | thats because its the idiomatic way to do it |
| 01:04 | michaelr525 | brehaut: who says? |
| 01:04 | brehaut | the clojure community |
| 01:05 | michaelr525 | i want to talk with him |
| 01:05 | amalloy | the clojure language |
| 01:05 | adu | idioms are by definition, not one person |
| 01:05 | brehaut | well, rhickey can define any idiom he wants for clojure and we all ussually follow along |
| 01:05 | michaelr525 | brehaut: that's acceptable |
| 01:05 | michaelr525 | ;) |
| 01:06 | adu | not all idioms are nice, for example, birthday punches |
| 01:07 | michaelr525 | but seriosly the (into) solution is the most _simple_ one, it does exactly what it says (unlike flatten) |
| 01:07 | amalloy | i <3 into/for |
| 01:07 | brehaut | i <3 outof/doseq |
| 01:08 | brehaut | not really |
| 01:08 | xeqi | who is it that <3 juxt ? |
| 01:08 | Raynes | amalloy: |
| 01:08 | brehaut | EVERYONE |
| 01:08 | Raynes | You did see my talk! |
| 01:08 | Raynes | :D |
| 01:08 | brehaut | free all the points |
| 01:08 | amalloy | technomancy founded the juxt fan club |
| 01:09 | adu | Juxtaposition? |
| 01:09 | brehaut | yup |
| 01:09 | adu | yup |
| 01:09 | brehaut | ,((juxt inc dec) 1) |
| 01:09 | clojurebot | [2 0] |
| 01:09 | adu | wow |
| 01:10 | technomancy | it's so gooooood! |
| 01:10 | adu | that is incredibly pointless |
| 01:10 | brehaut | ~rimshot |
| 01:10 | clojurebot | Badum, *tish* |
| 01:10 | amalloy | ~rimshot |
| 01:10 | clojurebot | Badum, *tish* |
| 01:10 | amalloy | damn you, brehaut! |
| 01:10 | adu | er i mean points-free |
| 01:10 | brehaut | its hard to snipe from this side of the world! |
| 01:13 | michaelr525 | ,((juxt inc inc inc) 0) |
| 01:13 | clojurebot | [1 1 1] |
| 01:13 | michaelr525 | what's so good about it? |
| 01:14 | michaelr525 | (except the cool name) |
| 01:16 | michaelr525 | ,(juxt juxt juxt inc 0) |
| 01:16 | clojurebot | #<core$juxt$fn__2476 clojure.core$juxt$fn__2476@241bd8cd> |
| 01:16 | michaelr525 | ,((juxt juxt juxt inc 0)) |
| 01:16 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$juxt> |
| 01:17 | amalloy | we should see if TimMc can develop a turing-complete clojure dialect using only juxt |
| 01:17 | brehaut | lol |
| 01:21 | brehaut | ,((comp (partial apply +) (memfn invoke) (partial apply juxt) (partial map (constantly (constantly 1)))) [1 2 3 4]) |
| 01:21 | clojurebot | 4 |
| 01:23 | brehaut | im slightly amazed that that worked |
| 01:23 | amalloy | that looks like count |
| 01:23 | xeqi | ,(doc memfn) |
| 01:23 | clojurebot | "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn." |
| 01:23 | brehaut | it is the worlds dumbest count yes |
| 01:23 | brehaut | i had to force the juxt in unnecessarily |
| 01:23 | technomancy | stylin' |
| 01:27 | brehaut | ,(require 'clojure.reducers) |
| 01:27 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/reducers__init.class or clojure/reducers.clj on classpath: > |
| 01:27 | brehaut | ,(require 'clojure.core.reducers) |
| 01:27 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/core/reducers__init.class or clojure/core/reducers.clj on classpath: > |
| 01:28 | amalloy | brehaut: they're both on 1.4 |
| 01:28 | brehaut | amalloy: and i got the NS wrong the first time |
| 01:29 | talios | brehaut - you just hurt my brain. |
| 01:30 | brehaut | talios: i do what i can |
| 01:31 | brehaut | talios: its the dumb version of ##(apply + (map (constantly 1) [1 2 3 4])) |
| 01:31 | lazybot | ⇒ 4 |
| 01:32 | brehaut | but that has no juxt, so who would want that |
| 01:33 | talios | sane people not from the 'tron |
| 01:33 | brehaut | same people would call count ;) |
| 01:33 | brehaut | s/m/n/ |
| 01:33 | xeqi | ,(map apply [inc dec] ((juxt inc dec) 0)) |
| 01:33 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 01:35 | brehaut | ,(map apply [inc dec] ((juxt (comp vector inc) (comp vector dec)) 0)) ; xeqi |
| 01:35 | clojurebot | (2 -2) |
| 01:36 | brehaut | &(use 'useful.fn) |
| 01:36 | lazybot | ⇒ nil |
| 01:36 | xeqi | blah, I was hoping for a closer equivalent to &&& |
| 01:36 | brehaut | ,((knit inc dec) ((juxt inc dec) 0)) |
| 01:36 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: knit in this context, compiling:(NO_SOURCE_PATH:0)> |
| 01:36 | brehaut | &((knit inc dec) ((juxt inc dec) 0)) |
| 01:36 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: knit in this context |
| 01:37 | brehaut | xeqi: useful has 'knit which is what you want |
| 01:38 | xeqi | &useful.fn/knit |
| 01:38 | lazybot | java.lang.RuntimeException: No such var: useful.fn/knit |
| 01:38 | brehaut | amalloy: does lazybot roll with an archaic version of useful? |
| 01:38 | amalloy | i'm not sure he has useful at all |
| 01:39 | amalloy | oh, he does |
| 01:39 | amalloy | yes, probably ancient |
| 01:40 | brehaut | xeqi: https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L94-100 |
| 01:41 | brehaut | also http://swannodette.github.com/mori/#knit |
| 01:41 | michaelr525 | what would you use to format a date into string in this format: "10/10/2012" ? |
| 01:42 | amalloy | $javadoc java.util.text.SimpleDateFormatter |
| 01:42 | amalloy | was i close? maybe not |
| 01:42 | amalloy | $javadoc java.text.SimpleDateFormatter |
| 01:43 | amalloy | i guess for starters i'd advise that you make sure the date is always the same as the month, if you're going to format it that way |
| 01:43 | amalloy | cuz europeans and americans will disagree about what that date means |
| 01:43 | brehaut | well, not that date |
| 01:44 | brehaut | thats the tenth of october no matter how you slice it |
| 01:44 | augustl | are there any systems for "environments" for Ring apps? Like "development", "test", "production", etc, with different db settings and what not |
| 01:44 | brehaut | but 1/10/2012 would the the tenth of jan here |
| 01:44 | augustl | there's always environment variables I guess |
| 01:45 | brehaut | ring itself doesn't concern itself with settings, but yes, env vars are a common approach |
| 01:45 | brehaut | err apparently i have been americanized |
| 01:45 | brehaut | it woudl the the first of october here |
| 01:45 | amalloy | you can also put your config into a .clj file on the classpath and read it at startup |
| 01:45 | xeqi | augustl: env vars, or some fun use of lein2's profiles |
| 01:46 | augustl | xeqi: looking up lein2 profiles, tnx |
| 01:46 | xeqi | basically used as a way to seperate configs in different resource paths, and read it on startup like amalloy mentioned |
| 01:47 | xeqi | clojars does something like that |
| 01:47 | augustl | makes sense, so I can have stuff in project.clj without checking it in to git, basically |
| 01:51 | michaelr525 | i really like the interop stuff in clojure, easier to write java in clojure-java interop than java in java |
| 01:54 | michaelr525 | ,(-> (java.text.SimpleDateFormat. "MM/dd/yyyy") (.format (java.util.Date.))) |
| 01:54 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class java.util.Currency> |
| 01:56 | xeqi | of course, the Currency class is required for one of those |
| 02:00 | amalloy | &(-> (java.text.SimpleDateFormat. "MM/dd/yyyy") (.format (java.util.Date.))) |
| 02:00 | lazybot | ⇒ "07/02/2012" |
| 02:07 | michaelr525 | (diff lazybot clojurebot) |
| 02:07 | michaelr525 | ,(clojure-version) |
| 02:07 | clojurebot | "1.4.0-master-SNAPSHOT" |
| 02:07 | michaelr525 | &(clojure-version) |
| 02:07 | lazybot | ⇒ "1.4.0" |
| 02:10 | amalloy | really? i thought for sure clojurebot was on 1.4.0 |
| 02:23 | Raynes | michaelr525: lazybot is a totally different bot. |
| 02:23 | Raynes | You'd have one hell of a diff to look at. |
| 02:26 | gtuckerkellogg | ahh, it was |
| 03:27 | augustl | how do I access the full request in compojure routes? All I can find is how to access path parameters from the URL. |
| 03:27 | weavejester | augustl: (GET "/blah" request …) |
| 03:28 | weavejester | augustl: Or: (GET "/blah" [x y :as request] …) |
| 03:28 | augustl | ah |
| 03:28 | augustl | where x and y are keys in the request map? |
| 03:28 | weavejester | augustl: No, where x and y are parameters |
| 03:29 | augustl | I want to access more than the parameters, like the request body |
| 03:29 | weavejester | augustl: ":as" raises you up, like normal destructuring |
| 03:29 | augustl | but that's what 'request' does? |
| 03:30 | weavejester | augustl: Yes, so with normal destructuring you could bind "request" or "{:as request}" |
| 03:30 | weavejester | augustl: With the vector bindings you can also use [:as request] |
| 03:31 | augustl | I see |
| 03:38 | kral | namaste |
| 03:56 | augustl | hmm, cheshire doesn't like a org.eclipse.jetty.server.HttpInput |
| 03:57 | augustl | should I turn it into a string or something by hand? |
| 04:00 | augustl | slurp to the rescue |
| 04:02 | augustl | where are the options I can pass to slurp documented? the docs for slurp refer to clojure.java.io/reader, but the docs for that one does not document the options either |
| 04:19 | amalloy | augustl: perhaps just in the source, though i imagine clojuredocs has some supplementary explanation |
| 04:19 | augustl | amalloy: I'll look that up, thanks |
| 04:33 | dsabanin | hey guys |
| 04:34 | fmw | this piece of code is irking me somehow: http://paste.lisp.org/display/130373 - there must be a prettier way to write this with the standard functions? |
| 04:35 | augustl | fmw: what's the x and y symbols? |
| 04:35 | fmw | it feels like I'm missing something very obvious as to how to implement this cleanly |
| 04:35 | fmw | augustl: just ignore those, its basically a simplified version of some code I'm working on |
| 04:36 | augustl | (merge {:bar foo :barfoo :foobar} your-map) |
| 04:37 | fmw | augustl: http://paste.lisp.org/display/130374 that is the full version, but the sample should do |
| 04:37 | augustl | if I'm reading it correctly |
| 04:37 | fmw | augustl: what about the conditionals? |
| 04:37 | augustl | ah :) |
| 04:37 | fmw | I meant to ignore the values of x/y, should've been clearer there, sorry ;) |
| 04:38 | fmw | because I still need the conditionals |
| 04:39 | augustl | the symbols come from a destructured map, perhaps you should work directly on the map instead of on the destruct values |
| 04:39 | fmw | I'm sure I could write a macro to make this prettier, but imho that is overkill, but somehow I have the feeling that I'm overlooking a much prettier solution using the standard stuff that is available in Clojure |
| 04:39 | augustl | they don't come from a map and now I'll shut up |
| 04:40 | fmw | augustl: don't worry, I'm happy someone is responding ;) |
| 04:40 | fmw | reading other peoples code is always a pain. |
| 04:41 | augustl | especially when you're not very familiar with the language ;) |
| 04:41 | fmw | augustl: liking Clojure so far? |
| 04:43 | augustl | very much so |
| 04:43 | augustl | it's mostly just the lispyness that's causing trouble |
| 04:43 | augustl | fmw: loving the separation of values, identity and time! |
| 04:44 | fmw | it takes some getting used to, but once the pieces starting falling into place and you wrap your head around it, it feels so natural |
| 04:45 | fmw | s/starting/start |
| 04:45 | augustl | fmw: btw have you considered changing your API to take a map instead of a large vector? |
| 04:45 | noidi | the CCW documentation states that "Once you have started a REPL for your project, eclipse will use a backdoor connection to this REPL to automatically compile and load the files you edit (if the eclipse Project > Build automatically option is selected, of course)." |
| 04:45 | augustl | that will solve your problem and make for a better api imo :) |
| 04:45 | noidi | and "In conjunction with auto-compile functionality, compilation problems are reported as problem markers" |
| 04:45 | noidi | does that work for anyone else? I can't get it to work. |
| 04:46 | augustl | fmw: indeed, it feels very natural. Like Rich Hickey said in a talk, it doesn't really make much sense to change the date of a month (like with date.setMonth in Java), immutability maps much better to the real world as long as you leave time out of the equation |
| 04:46 | fmw | augustl: the API isn't taking a vector, I'm just using it for destructuring optional values |
| 04:46 | noidi | I've tried this on two boxes now (Linux and Windows) and neither report compilation problems, even if the source is not valid and I get an error if I try to load it |
| 04:46 | augustl | and in most programs, you do want to leave time out of the equation, usually in the form of locks |
| 04:47 | fmw | you call it like e.g. (get-documents-for-feed "vix" "en" "blog" 10) |
| 04:47 | fmw | where 10 is the first optional argument, you can have two more (i.e. startkey and startkey_docid) |
| 04:47 | augustl | fmw: well, a list of some kind, if not a vector |
| 04:48 | augustl | it's just that in general I prefer APIs like (get-documents_for_feed {:db "vix" :language "en"}) etc |
| 04:48 | augustl | I've programmed too much Objective-C I guess |
| 04:48 | fmw | augustl: I see. I'm not sure if that is idiomatic in Clojure, but I guess it is a matter of taste. |
| 04:49 | augustl | fmw: perhaps a multi-method is better in your case |
| 04:49 | fmw | it is practical for some functions, but doesn't have added value for most, yet still adds a lot of cruft you have to type all the time |
| 04:50 | fmw | augustl: that could work, yes! |
| 04:52 | augustl | fmw: iirc the syntax is something like this http://paste.lisp.org/display/130375 |
| 04:52 | augustl | not sure if there's a clever way other than named refs to avoid duplication of the defaults |
| 04:52 | augustl | and obviously some definitions are missing from that example |
| 04:52 | fmw | augustl: a multimethod is with (defmulti ...) |
| 04:53 | augustl | yeah not sure what the difference is there.. |
| 04:53 | augustl | I think my paste is a valid method for creating a function that dispatches based on the number of args though |
| 04:54 | fmw | augustl: the syntax you pasted is nice for simple cases, defmulti gives control over the dispatch if you want to dispatch by custom things, like type |
| 04:54 | fmw | yes, it is |
| 04:54 | fmw | augustl: its actually exactly like my original implementation of the dispatch: https://github.com/fmw/vix/blob/master/src/vix/db.clj#L204 |
| 04:55 | fmw | I'm currently refactoring that code to make it cleaner, with the knowledge I gained since I wrote it |
| 04:55 | fmw | e.g. fixing silly things, like (map #(:value %) some-map) into (map :value some-map) |
| 04:56 | augustl | clojure does have a gazillion small features |
| 04:57 | fmw | I'm actually refactoring those (defn some-fn ([x y] (some-fn x y nil)) ([x y z] (do-something x y z))) into (defn some-fn [x y & [z]] (do-something x y z)) |
| 04:58 | fmw | I prefer the latter, because it is more concise and arguably makes it more clear which variables are optional at a glance |
| 05:00 | fmw | augustl: I'm quite fond of multimethods for more complicated dispatch scenarios, though, like https://github.com/fmw/alida/blob/master/src/alida/lucene.clj#L90 |
| 05:00 | dsabanin | fmw: what about http://paste.lisp.org/display/130376? |
| 05:01 | fmw | dsabanin: I think that must be the solution, thanks. let me adapt it into my code and see |
| 05:02 | dsabanin | fmw: cool, np |
| 05:02 | dsabanin | well, actually it's even better |
| 05:02 | dsabanin | merge accepts nil as arguments |
| 05:03 | dsabanin | so it's just http://paste.lisp.org/display/130377 |
| 05:04 | dsabanin | damn, not, you just can do (if x {:bar :foo}) |
| 05:04 | fmw | dsabanin: I think you can, but I'd use when? |
| 05:04 | dsabanin | yep |
| 05:04 | augustl | what's the #^ part of this? `(defn #^IndexWriter create-index-writer` |
| 05:04 | augustl | the docs for defn doesn't seem to mention it |
| 05:04 | dsabanin | augustl, it's a type hint for performance optimization |
| 05:05 | dsabanin | it specifies the kind of java type that is being returned |
| 05:05 | fmw | augustl: that is like soft typing (telling Clojure what type to expect, for performance gains) |
| 05:05 | augustl | it's not documented for `def` either, where is it documented? |
| 05:05 | clgv | augustl: #^IndexWriter is deprecated! use ^IndexWriter instead |
| 05:06 | augustl | clgv: and where's _that_ documented? :P |
| 05:06 | clgv | augustl: it is called a typehint |
| 05:06 | fmw | augustl: http://clojure.org/java_interop#Java Interop-Type Hints |
| 05:07 | clgv | augustl: you'll only need those if clojure complains when compiling and having set *warn-on-reflections* to true |
| 05:07 | fmw | clgv: that was my code actually, thanks for pointing it out, will have to fix that at some point |
| 05:08 | fmw | I actually like type hints as semi-documentation in java glue code too, not just for performance gains |
| 05:08 | fmw | because it makes it instantly clear what your fn is supposed to return |
| 05:08 | augustl | fmw: out of curiousity, do you do any locking etc to make the IndexWriter work across threads? I'm currently writing an HTTP API that will write to Lucene indexes actually, and need to handle that. |
| 05:09 | fmw | augustl: which version of Lucene? |
| 05:09 | augustl | 3.6 |
| 05:09 | fmw | augustl: Lucene 4.0 has built-in stuff for that |
| 05:09 | fmw | (so does 3.x, afaik, but you really should be using 4.0) |
| 05:10 | augustl | hmm, IndexWriter is thread safe it says for the 3.6 docs |
| 05:10 | fmw | 4.0 has been used in production for a while and should be released soon with a lot of backwards compatibility breakage and all sorts of improvements, so best to use it for new code already |
| 05:11 | augustl | hmm |
| 05:11 | fmw | augustl: yes, they have their own manager classes that deal with your writers/readers (4.0 fully breaks them apart, btw, while in 3.x you could write using a reader IIRC) |
| 05:11 | augustl | 4.0 is not even mentioned on http://lucene.apache.org/ |
| 05:12 | fmw | augustl: https://twitter.com/kucrafal/status/218633823976566784 |
| 05:13 | fmw | augustl: it has been stable for the last 12 months, or so, and people have been using it in production a lot, so it is a safe bet, imho |
| 05:13 | fmw | Lucene developers are *very* conservative and don't generally break things |
| 05:13 | augustl | why not (tm) :D |
| 05:14 | augustl | fmw: do you happen to know if there are JavaDocs hosted for 4.0 anywhere? |
| 05:14 | fmw | augustl: yes, let me find them. there are also some very good background docs on the changes |
| 05:15 | fmw | augustl: https://builds.apache.org//job/Lucene-trunk/javadoc/ |
| 05:15 | augustl | yay |
| 05:15 | augustl | wut, why does it say 5.0? :) |
| 05:16 | fmw | augustl: good question. I think they've updated their trunk to 5.0 now, to make the 4.0 branch stable for release |
| 05:16 | fmw | http://blog.mikemccandless.com/ is a good resource about some of the changes in 4.0, too, btw |
| 05:16 | augustl | makes sense |
| 05:18 | augustl | Lucene is pretty darn awesome. After struggling to figure out a way to start Solr other than the start.jar in the "example" of the tarball and browsing through a zillion XML files, I thought I'd might as well use Lucene directly |
| 05:18 | augustl | turned out to be a sound decision ;) |
| 05:18 | fmw | augustl: feel free to use http://github.com/fmw/alida as a starting point for your stuff, as I wrote it as example code for a Lucene talk (and don't be afraid to ping me if you have any questions/requests for improvement, as I'm planning to build a real-world thing out of the alida project) |
| 05:19 | fmw | augustl: yes, Solr is nice if you don't have access to a JVM or need some of their specific features, but I haven't used it at all so far, despite doing quite a lot of search-related work |
| 05:21 | augustl | fmw: great :D |
| 05:26 | augustl | fmw: very off topic, but there's not much activity in #lucene.. My data will always be queried by a foreign key. Do you think I should put everything in one index, and always add the foreign key to all queries, or have a separate index per foreign key/group? |
| 05:27 | fmw | augustl: can you specify the foreign key? |
| 05:27 | augustl | fmw: I'm indeing attendants, the foreign key is an alphanumeric id, "event_id" |
| 05:28 | fmw | augustl: unless you're data is really big, just put the event_id in a field and filter your queries on that |
| 05:28 | fmw | no need to split anything |
| 05:28 | augustl | I'm thinking one large index, and shard it manually later. The number of events will grow and grow, which means a lot of files in one folder, lots of open files, etc. |
| 05:28 | augustl | fmw: yeah makes sense |
| 05:30 | fmw | augustl: Lucene has built-in IndexReaders for that, and you can also write your own |
| 05:31 | augustl | fmw: as in built-in IndexReaders for foreign key type queries? |
| 05:31 | fmw | dsabanin: thank you, that was exactly the cleaner solution I was looking for. |
| 05:31 | fmw | augustl: as in dealing with large datasets |
| 05:33 | fmw | the foreign key type thing is just something to filter on in Lucene, next to your query. There is a performance consideration, though, because Lucene 4.0 has switched to byte indexing, so its actually fast to store/filter on numbers now |
| 05:33 | augustl | fmw: ah |
| 05:33 | augustl | the semantics of a progammatic API vs query strings is reason enough to use Lucene directly imo |
| 05:33 | fmw | so if its an integer that won't take up much space and its best to store it as a numeric value |
| 05:34 | fmw | augustl: yes, even though you can use both. |
| 05:34 | augustl | the foreign keys are alphanumeric, but I suppose I'll figure something out |
| 05:34 | augustl | (ObjectID's from MongoDB) |
| 05:35 | fmw | augustl: probably not worth changing them to numeric values in that case |
| 05:42 | fmw | I'm going for a swim now, getting too hot in the afternoon sun here in Greece (I'm a northener and not used to the heat). Feel free to contact me if you have more questions about using Lucene from Clojure (https://twitter.com/#!/filipdewaard or fmw@vixu.com). |
| 07:40 | augustl | is there a function to flip a boolean? Need it for dosync/commute. |
| 07:40 | AWizzArd | augustl: you could use “not”. |
| 07:40 | augustl | oh wait I can just pass in my own function I guess |
| 07:40 | augustl | AWizzArd: ah, of course |
| 07:40 | AWizzArd | $(not true) |
| 07:40 | AWizzArd | ,(not false) |
| 07:40 | clojurebot | true |
| 07:40 | AWizzArd | ,(not true) |
| 07:40 | clojurebot | false |
| 07:41 | augustl | or just ref-set I guess |
| 07:41 | Licenser | worth reading: http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/ |
| 07:54 | wink | worth reading, yes. but it's written by a seemingly very angry person, it's not necessarily very correct |
| 08:35 | jweiss | just discovered edebug in emacs. is there any reason (beyond that no one has sat down to do it yet) that clojure couldn't have a similar debugger? |
| 08:38 | romain_p | Hi everyone, can anybody help me create the simplest possible raphaeljs example (e.g. a circle) using clojurescript (maybe starting from cljs-template)? I am just beginning with cljs and a bit bewildered... :) |
| 08:39 | gfredericks | romain_p: I'm doing cljs + raphael right now! :D |
| 08:39 | gfredericks | I'm doing it all with js interop though, so if you know how to do it in js it shouln't be hard |
| 08:39 | romain_p | gfredericks: awesome :D could you point me in the right direction? |
| 08:41 | gfredericks | romain_p: (def paper (js/Raphael ...args...))? |
| 08:41 | gfredericks | (.circle paper ...) |
| 08:42 | gfredericks | not sure what you're having trouble with |
| 08:42 | romain_p | gfredericks: ah well, it's more about setting stuff up. Where should I import the raphael lib? |
| 08:43 | gfredericks | romain_p: I just have the js file lying around |
| 08:43 | gfredericks | and a <script> for it in my html file |
| 08:44 | romain_p | ah OK, will try. I started from the cljs-template leiningen target, so I do not use a static html file, but I suppose I can require the javascript from the hiccup template |
| 08:44 | romain_p | include-js or something |
| 08:45 | gfredericks | romain_p: I don' know anything about cljs-template |
| 08:46 | romain_p | gfredericks: it is a sample noir+cljs+hiccup application, kind of a "getting started" kind of thing apparently... |
| 08:47 | gfredericks | ah ha |
| 08:52 | gfredericks | Is there no easy way in cljs to dynamically call a method? i.e., ob[s]()? |
| 08:52 | gfredericks | I just wrote a macro for it |
| 08:53 | augustl | are therre any utils for making a string of hex encoded bytes into a byte array? |
| 08:55 | jcromartie | "A LISP dialect? LISP was far and away the worst language I ever had the misfortune of having to use in school" - people keep saying this |
| 08:56 | romain_p | gfredericks: OK, that did it. Thanks for the help! |
| 09:00 | augustl | jcromartie: I like to say that Lisps are as similar to other lisps as Java and JavaScript are similar. |
| 09:01 | jcromartie | people I interview, new hires out of school, people who call themselves "Java EE guys" |
| 09:01 | augustl | jcromartie: "Lisp is a language" doesn't make sense to me, it's a bit like saying "camel case and curly brackets is a language" |
| 09:02 | jcromartie | and saying "Lisp is for AI" is like saying "Ruby is for web apps" |
| 09:02 | jcromartie | not even… "Ruby is for web apps" is at least closer to truth in a statistical sense |
| 09:03 | jcromartie | but anyway, yeah, there's an image problem there |
| 09:03 | jcromartie | I don't know what people do with Lisp in school… I never went, myself |
| 09:03 | jcromartie | BRB… going for a run |
| 09:12 | mystiiq | can anyone point out an example how to use declare function. basically some my functions want to use a shared Java object and I want that the first one who will try to use it must initiate it |
| 09:13 | gfredericks | mystiiq: would delay do what you want? or does the first one trying to use it also have to decide _how_ to initiate it? |
| 09:14 | gfredericks | ,(let [foo (delay (make-foo))] (defn get-foo [] @foo)) |
| 09:14 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 09:14 | gfredericks | mystiiq: something like that ^ |
| 09:15 | mystiiq | the first one does not have to decide how to initiate it |
| 09:15 | gfredericks | delay should work then |
| 09:27 | TimMc | amalloy_: Just juxt and parens, eh? You'd have to use encoded numerals, but it might actually be possible. |
| 09:28 | TimMc | amalloy_: Wait, no -- juxt produces vectors, which expect system integers for dereference. Not feeling it. |
| 09:28 | uvtc | What does "immutability precludes backreferences" mean? (seems to be in the context of nested data structures) |
| 09:31 | gfredericks | uvtc: backreferences I think is synonymous with self-reference or cycles |
| 09:31 | uvtc | It's mentioned in the CP chapter on zippers. |
| 09:32 | augustl | waat. What am I not getting here? `(byte 0xff)` => IllegalArgumentException Value out of range for byte: 255 |
| 09:32 | augustl | what kind of bytes are these? >< |
| 09:32 | gfredericks | uvtc: it's why you can't use normal mutable-data-structure approaches to walking a tree |
| 09:32 | gfredericks | like parent.children() and child.parent() |
| 09:33 | gfredericks | for going down and up respectively |
| 09:33 | uvtc | Hm. |
| 09:34 | uvtc | gfredericks, Ok. I was thinking I could "walk the tree" by using assoc-in... |
| 09:34 | mystiiq | in java !false is true, what's the similar syntax in clojure? |
| 09:34 | gfredericks | well that's good for single updates |
| 09:34 | gfredericks | mystiiq: (not false) |
| 09:34 | augustl | oh, bytes are signed |
| 09:34 | mystiiq | ok thanks |
| 09:35 | gfredericks | uvtc: if you want to be effiient and you have a lot of work to do at the bottom of the tree you don't want to keep walking from the root for each operation |
| 09:35 | gfredericks | uvtc: it's a lot of time and unnecessary object allocations |
| 09:35 | TimMc | ~byte |
| 09:35 | clojurebot | http://homepages.inf.ed.ac.uk/kwxm/JVM/codeByNo.html |
| 09:35 | TimMc | feh |
| 09:36 | augustl | TimMc: :D |
| 09:38 | TimMc | Although I do like that URL: "code by number" |
| 09:38 | uvtc | gfredericks, why would a data structure being immutable have anything to do with being able to figure out where a parent/child is? Seems like that's more related to the items in the d/s not being OO-style objects... |
| 09:38 | gfredericks | uvtc: figuring out the child is usually easy, but not the parent |
| 09:39 | TimMc | uvtc: Try to build a Clojure list or vector that contains a reference to itself. |
| 09:39 | TimMc | Or two that reference each other, rather. |
| 09:39 | gfredericks | if I have a tree [:ul [:li] [:li]] and call (nth tr 2) on that,, the return value has no idea that it "is in" a tree |
| 09:40 | gfredericks | it is simply [:li] and has no reference to its parent |
| 09:40 | gfredericks | so when you get to that point you can't get back up |
| 09:40 | tbaldridge | .parent() is a horrible way to transverse a tree anyways (IMO) |
| 09:41 | tbaldridge | recursive functions have always done the trick for me. |
| 09:41 | gfredericks | yeah they work for most cases |
| 09:42 | gfredericks | hell if I've ever used a zipper for anything |
| 09:42 | TimMc | tbaldridge: Unless you're doing zipper type stuff, of course. |
| 09:42 | gfredericks | TimMc: have you ever done zipper type stuff? |
| 09:42 | TimMc | It's sueful if you need to carry child information back up to parents. |
| 09:42 | TimMc | gfredericks: No, but I told someone else to use them once. :-P |
| 09:42 | gfredericks | :) |
| 09:43 | gfredericks | it's like refs. We all know what they do. |
| 09:43 | tbaldridge | TimMc: if you need to carry data up to the parent. Then start at the top, and have the function applied to the child return the data to the parent |
| 09:43 | gfredericks | and then we use proper databases instead because they are persistent |
| 09:43 | TimMc | Say you have a tree of maps, and you want to add an incrementing :id field to each map according to an in-order walk. |
| 09:43 | TimMc | That's a use-case for zippers. |
| 09:45 | uvtc | TimMc, if I try to make 2 data structures with parts that refer to parts of eachother, it fails because I Clojure gives me the value of things, not references to them. |
| 09:45 | uvtc | TimMc, but this appears to me to be because of not using any reference types ... not because of immutability... |
| 09:45 | TimMc | (Specifically, a binary tree.) |
| 09:46 | gfredericks | uvtc: no it's because of immutability |
| 09:46 | gfredericks | you do have references |
| 09:46 | TimMc | uvtc: You get references to their values. |
| 09:46 | gfredericks | in the jvm sense |
| 09:46 | TimMc | Those references are immutable in Clojure. |
| 09:46 | TimMc | Or, well, they're immutable anyway. |
| 09:46 | gfredericks | in java you could (let [a (new A), a' (new A)] (.setFoo a a') (.setFoo a' a)) |
| 09:47 | gfredericks | the only difference between that and clojure data structures is mutability |
| 09:47 | uvtc | TimMc, thanks. gfredericks : still reading your comments. |
| 09:47 | gfredericks | you can't set a vector's contents after you construct it |
| 09:47 | gfredericks | you CAN do this with lazy-seqs I believe |
| 09:48 | gfredericks | lazy-seqs have a kind of mutability |
| 09:52 | gfredericks | ,(let [x (promise), self-containing-seq (lazy-seq (cons @x ()))] (deliver x self-containing-seq) self-containing-seq) |
| 09:53 | clojurebot | ((((((((((#)))))))))) |
| 09:53 | gfredericks | o_O |
| 09:53 | gfredericks | &(let [x (promise), self-containing-seq (lazy-seq (cons @x ()))] (deliver x self-containing-seq) self-containing-seq) |
| 09:53 | lazybot | java.lang.StackOverflowError |
| 09:53 | gfredericks | that's better |
| 09:53 | uvtc | gfredericks, you wrote "the return value has no idea that it "is in" a tree ... it is simply [:li] and has no reference to its parent ... so when you get to that point you can't get back up". I see what you mean here. Thanks! |
| 09:54 | gfredericks | uvtc: awesome |
| 10:04 | scriptor | have a question that isn't really clojure-related, but still fp-related |
| 10:04 | scriptor | I'm trying to stick to the idea of data as data, and just using plain hashmaps instead of more complex objects |
| 10:05 | scriptor | however, I'd also like to be able to listen for changes to the data and re-render parts of the interface when needed |
| 10:06 | augustl | what's the canonical way of despatching a method based on the types of its arguments? Multimethods? Protocols? Something else? |
| 10:06 | scriptor | should I just create an interface through which the hashmaps are 'modified' (either in-place or by doing something assoc-style) and then these functions are responsible for updating the view? |
| 10:07 | dnolen | scriptor: I need to start keep track of how many times this question comes up :) |
| 10:08 | dnolen | scriptor: nothing exists, we need a functional answer to data binding - probably something FRP-like that isn't a hassle to use. |
| 10:08 | scriptor | dnolen: not surprised, I'm basically asking for very limited FRP :p |
| 10:09 | scriptor | hmm, I'm trying to at least move away from the idea of models in js |
| 10:10 | dnolen | cljs.core.rx sounds like a pretty compelling contrib ... |
| 10:11 | scriptor | link please? Can't find anything on google or github |
| 10:11 | dnolen | doesn't exist. |
| 10:11 | zerokarmaleft | dnolen: reactive extensions? |
| 10:12 | scriptor | ah, as in a name idea :) |
| 10:12 | dnolen | zerokarmaleft: yes |
| 10:14 | tbaldridge | I've been playing around with trying to do something rx-esque in Clojure. My work still is way too mutable for my liking though |
| 10:14 | tbaldridge | Ot' |
| 10:14 | madsy | Is there a nice article somewhere on how to setup lein-cljsbuild and clojurescript manually? The stuff on Maven is like a century old, with non-official version numbers. |
| 10:15 | tbaldridge | From my reading FRP is functional, but highly complex (at least the flapjax way), while Rx is highly un-functional, and mutable, but easier to learn/design |
| 10:15 | dnolen | tbaldridge: my sense is we need to learn from both and design something better |
| 10:16 | TimMc | dnolen: In FRP as you used it, R = relational? |
| 10:16 | TimMc | or reactive? |
| 10:16 | scriptor | TimMc: I think it's Reactive |
| 10:16 | dnolen | TimMc: no, Functional Reactive Programming |
| 10:17 | tbaldridge | dnolen: agreed. That's why I've been looking into dataflow recently, it's not quite there either, but it's simpler than the hardcore FRP stuff. |
| 10:17 | scriptor | you represent an otherwise mutable value as a behavior, which represents both the present and all future values |
| 10:17 | TimMc | OK. I'm reading Out of the Tar Pit and keep getting mixed up when I see "FRP". :-) |
| 10:17 | tbaldridge | madsy: this tut worked for me when I used it last week: https://github.com/emezeske/lein-cljsbuild |
| 10:18 | tbaldridge | madsy: i was using lein2, so I had cljsbuild to my .profile.clj but besides that it "just worked(TM)" |
| 10:19 | otfrom | CfP for 6 December Clojure eXchange if anyone fancies giving a talk in London. :-D http://bit.ly/clojurex12-cfp |
| 10:19 | madsy | tbaldridge: How does lein2 find your custom-built lein-cljsbuilt plugin? Did you just copy it to the ~/lein/plugins directory? |
| 10:20 | madsy | Or did you set up a local maven repo? |
| 10:21 | tbaldridge | madsy: I mis-typed there. You need to add {:user {:plugins [[lein-cljsbuild "0.2.2"]]}} to a file in ~/.lein/profile.clj Then just do lein deps and lein will install it. |
| 10:21 | madsy | tbaldridge: Maybe what needs to be done is supposed to be obvious from the github readme, but it's not obvious to me |
| 10:21 | tbaldridge | madsy: https://github.com/technomancy/leiningen/wiki/Upgrading |
| 10:22 | madsy | tbaldridge: So you got lein-cljsbuild prebuilt from maven? |
| 10:22 | madsy | Because, that's not what I asked about. |
| 10:23 | tbaldridge | madsy: bleh, my bad...I missed that first part. Sorry, I thought you were just trying to get it working with lein2 |
| 10:23 | madsy | No worries :) |
| 10:24 | madsy | But yes, incidentally I should get lein2 |
| 10:25 | xumingmingv | hi all, need help on this line of code: https://github.com/xumingming/storm/blob/master/src/clj/backtype/storm/thrift.clj#L19 |
| 10:26 | xumingmingv | it creates a new java object according to the classname using the *new* macro |
| 10:26 | xumingmingv | my question is: the corresponding class is not imported, why this line of code can work? |
| 10:27 | mystiiq | when a java method returns an array of strings, how can I extract first one from the array in clojure ? |
| 10:28 | xumingmingv | mystiiq: (aget arr 0) |
| 10:29 | mystiiq | xumingmingv: thanks |
| 10:30 | mduerksen | mystiiq: ##(first (long-array [1 2 3])) |
| 10:30 | lazybot | ⇒ 1 |
| 10:30 | dnolen | tbaldridge: let me know where the dataflow stuff goes, would like to check it out. |
| 10:35 | dnolen | lynaghk: your todo example looks nice, tho I agree, not really MVC (which is a good thing) |
| 10:36 | scriptor | I was dissapointed by the move article that floated around yesterday |
| 10:37 | scriptor | it's basically just MVC+events |
| 10:39 | mystiiq | how can I make java String array or convert clojure array into one |
| 10:40 | mystiiq | list is also an option |
| 10:40 | augustl | "To re-iterate: MVC is awesome, but it's designed with decades old technologies. MOVE is just a update to make better use of the new tools we have." is that content-free or what |
| 10:41 | mystiiq | lets hope to-array works |
| 10:41 | augustl | mystiiq: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/to-array |
| 10:41 | augustl | afaik |
| 10:43 | S11001001 | mystiiq: no |
| 10:43 | S11001001 | ,(instance? (map identity [1,2,3]) java.util.List) |
| 10:43 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Class> |
| 10:43 | S11001001 | right |
| 10:43 | TimMc | S11001001: You lost the argument order lottery. |
| 10:43 | S11001001 | ,(instance? java.util.List (map identity [1,2,3])) |
| 10:43 | clojurebot | true |
| 10:44 | S11001001 | the way I do |
| 10:44 | TimMc | mystiiq: Do you need a list, or any sequential coll? |
| 10:44 | TimMc | mystiiq: Also, there's no "clojure array". |
| 10:44 | S11001001 | ,(type (to-array [1,2])) |
| 10:44 | clojurebot | [Ljava.lang.Object; |
| 10:45 | mystiiq | TimMc: I need something that implements java.util.List interface or String array |
| 10:45 | lancero | what am I doing wrong here: http://pastebin.com/JRBW1ckb ? I expect that when test-promises gets called it will start delivering 5 futures into promises, then start blocking (since old isn't realized yet). Instead the function returns immediately with nothing delivered. |
| 10:45 | S11001001 | mystiiq: then all you have to deal with is the nil case |
| 10:49 | S11001001 | lancero: for isn't a looping construct |
| 10:50 | jweiss | (binding [*print-length* 50] (iterate inc (System/currentTimeMillis))) -> OOM. what am i missing? |
| 10:52 | TimMc | jweiss: The print is happening outside your binding. |
| 10:53 | S11001001 | I wish for required you to specify what monad you wanted |
| 10:53 | jcromartie | *facepalm* |
| 10:53 | locojay | hi i m using jayq and would like to do something like this in js $("td:eq(1)", this).text(); (.text ($ "td:eq(1)")) works but i need this so i don't always get the same val |
| 10:53 | jcromartie | the "LISP was far and away the worst language I ever had the misfortune of having to use in school" guy |
| 10:54 | jcromartie | I said, "well I didn't go to school, I don't know how they tortured you with it there" |
| 10:54 | jcromartie | and I get "You didn't get a degree, are you joking with me? How did you get a job?" |
| 10:54 | TimMc | haha |
| 10:55 | TimMc | "Market forces." |
| 10:56 | jweiss | TimMc: ah yes, knew it had to be something obvious |
| 10:56 | jweiss | thanks |
| 10:58 | mefisto` | jcromartie: I think people who went to school for it can more easily miss the fact that we are living in the most exciting time for computing ever :D |
| 10:59 | jcromartie | mefisto`: I just don't know how you can work in programming for any length of time and still be incredulous about non-credentialed professional programmers |
| 11:00 | jcromartie | mefisto`: I mean this guy has even written books (not great ones…) |
| 11:00 | wkelly | it is easy to be oblivious when you are self-absorbed! |
| 11:02 | lancero | S11001001: I changed for to doseq. Now test-promises returns after about 10 seconds like I expected. But everything is already realized immediately when on return. |
| 11:02 | mefisto` | jcromartie: same reason he didn't like LISP I imagine... he's stuck in some fixed idea of the way things are "supposed to be" and so is blind to seeing anything that challenges that |
| 11:03 | tbaldridge | mefisto: I agree. Our architect told me "I just don't like this FP stuff...I mean we abandoned it when we invented OOP. It's all just such a step backwards..." |
| 11:03 | gfredericks | haha |
| 11:03 | tbaldridge | then he goes and sits for a day trying to figure out what a object does with its mutable state |
| 11:03 | tbaldridge | So yeah...my face and my palm are well acquainted |
| 11:05 | mefisto` | tbaldridge: try not to blame him too much, because he's half right. OOP was invented because FP was too difficult for some people to understand, and there was unmet demand for programmers |
| 11:05 | dnolen | mefisto`: I hope you don't really think that :) |
| 11:07 | acheng | why not? mefisto`s just describing well-intentioned wrong people. |
| 11:07 | gfredericks | plausible != accurate |
| 11:08 | dnolen | acheng: "OOP was invented becausae FP was too difficult" |
| 11:08 | acheng | too difficult for some |
| 11:08 | gfredericks | also that part |
| 11:08 | dnolen | far as I know, Smalltalk OOP (which is in wide use in various perverted forms), was created as a response to Lisp's special forms. |
| 11:08 | dnolen | nothing to do w/ difficulty around FP or anything else. |
| 11:08 | acheng | oh. ok |
| 11:08 | gfredericks | what's wrong with special forms? |
| 11:09 | acheng | nothing :) |
| 11:09 | dnolen | gfredericks: nothing, but nobody at the time had a good answer why we needed them. |
| 11:09 | hyPiRion | Yeah, it's not like people say "Oh, this is too hard! Let's invent something easier" and then magically came up with OOP. |
| 11:09 | gfredericks | dnolen: as if you can have a language with no primitives? :/ |
| 11:09 | dnolen | gfredericks: so Alan Kay et al looked at messages. |
| 11:09 | tbaldridge | And SmallTalk is not very much like what the Java/C# people think it is. |
| 11:09 | hyPiRion | But OOP was a concept which was easier to understand for imperative programmers. |
| 11:10 | hyPiRion | (I suppose?) |
| 11:10 | mefisto` | dnolen: Well, only sort of. But OOP allows you to substitute a large number of easy to understand problems (tracking down where some variable is getting changed or some little bug is happening) for the smaller number of hard to understand problems (really understanding the algorithm and modeling the problem properly). So I guess I'm really talking about why OOP became popular for business programming rather than why it was invented :D |
| 11:11 | dnolen | mefisto`: hyPiRion: these arguments don't really make that much sense considering the amoutn of pushback there was too OO in the 80s, the slowness of C++ etc. |
| 11:11 | dnolen | OO wasn't taken seriously by the mainstream until the mid 90s I'd say. |
| 11:12 | wkelly | when craziness ensued with STL and java |
| 11:13 | mefisto` | yeah, I wonder if that wasn't just a function of tooling and platform maturity |
| 11:13 | tbaldridge | And even Alan Kay didn't mean for OOP to end up like Java. To quote him "Erlang looks like almost what I've been talking about since the mid-60s, I wonder how I missed it for so many years?" |
| 11:13 | scriptor | or marketing ;) |
| 11:14 | scriptor | when did java become the defacto language for cs curriculums? |
| 11:14 | scriptor | because I wonder how much of a cause it was for OOP popularity vs how much it was a reaction |
| 11:14 | mefisto` | scriptor: somewhere in the 90s is when that really started, from what I heard |
| 11:15 | acheng | scriptor: at MIT it felt like a reaction |
| 11:15 | ohpauleez | Scriptor: Yeah, later 90's it started to get picked up. Early 00's it was pretty well established - mostly because other school started doing their research in Java |
| 11:16 | scriptor | acheng: how long ago? I know they continued to use scheme until a couple years ago for sicp, but I don't know about their other courses |
| 11:16 | ohpauleez | so if you wanted to build off of it, or interop with it, you also had to use Java, and if you wanted your lab to be well established in Java, you used it as the intro language |
| 11:16 | scriptor | mefisto`: ohpauleez: ah, thanks, so it sounds pretty reaction-y |
| 11:16 | ohpauleez | At Drexel, you learned Java, Python, JavaScript, C++, and a little Common Lisp |
| 11:17 | acheng | scriptor: there were classes using java, maybe in 96-97 |
| 11:17 | ohpauleez | Scriptor: it's a reaction to the fact that some DOD and DOJ bids HAD to be in Java |
| 11:17 | jcromartie | Was the adoption to OOP really a reaction to FP? I don't think so. |
| 11:17 | jcromartie | "adoption of" |
| 11:18 | scriptor | not reaction to FP |
| 11:18 | mefisto` | I think the less prestigious schools just picked up java because the top schools started using it, but more because it was becoming the most popular enterprisey langauge |
| 11:18 | jcromartie | Nobody had heard of FP when they were picking up OOP in the industry… |
| 11:18 | scriptor | well, I was talking about adoption of java in school as a reaction to OOP and Java popularity rising |
| 11:18 | jcromartie | ah yeah |
| 11:19 | jcromartie | it reminds me of "if we evolved from monkeys, why are there still monkeys?" |
| 11:19 | scriptor | heh |
| 11:20 | borkdude | because they also evolved from monkeys we evolved from? |
| 11:20 | pipeline | afaik modern OOP came from an older OOP that was built around message passing |
| 11:20 | scriptor | we didn't evolve from monkeys ;) |
| 11:20 | acheng | the universe could have been created 2 seconds ago and we wouldn't know the difference :-P |
| 11:21 | borkdude | acheng most git repositories histories are fake too, just for messing up with people's understanding of it |
| 11:21 | acheng | adam and eve stood next to a tree... did it have rings? :-P |
| 11:22 | tbaldridge | acheng...that's actually close to the truth. See, the universe is immutable. So what we see as reality now is just a copy of the universe as it was a microsecond ago, with certain parts replaced. This sounds expensive, but the universe uses some interesting trie structures so it's all not that computationally expensive. |
| 11:22 | tbaldridge | :-P |
| 11:22 | acheng | first saw message passing in lisp with sicp |
| 11:23 | TimMc | Nah, the universe is mutable. It has some nasty race conditions, too. |
| 11:23 | jcromartie | (inc tbaldridge) |
| 11:23 | lazybot | ⇒ 1 |
| 11:23 | scriptor | tbaldridge: so you're saying that the day we verify string theory is the day FP becomes faster than C? |
| 11:23 | TimMc | There isn't even a universal clock, just local clocks that are always going out of sync. |
| 11:24 | acheng | if C code tends to be buggier, then FP is faster |
| 11:24 | borkdude | history is mutable, just study the history of writings about WW2 for example |
| 11:25 | jcromartie | I was just thinking last night: I think it's impossible to create a computer to simulate the universe in real time |
| 11:25 | jcromartie | i.e. all the particles |
| 11:25 | uvtc | TimMc, sounds like time in fast-moving threads runs slower relative to slow-moving threads. :) |
| 11:25 | jcromartie | and I don't mean that it's impossible today |
| 11:25 | jcromartie | I mean ever |
| 11:25 | mefisto` | jcromartie: only impossible if you care about it being accurate :D |
| 11:25 | borkdude | jcromartie you don't say? |
| 11:25 | scriptor | jcromartie: I think there's an smbc comic about that |
| 11:26 | jcromartie | you could simulate a smaller universe |
| 11:26 | acheng | there is a computer that does that. it's God's mind (allegedly) |
| 11:26 | borkdude | jcromartie it could ir the behavior of the universe is like a fractal, according to a repeating pattern, maybe |
| 11:27 | jcromartie | acheng: and I think some sophisticated theology could make a solid argument there |
| 11:27 | uvtc | acheng, Wait, are you thinking of the Milliard Gargantubrain at Maximegalon? |
| 11:28 | jcromartie | when you zoom in enough, things just start flitting in and out of existence, effectively "off limits" to conventional observation |
| 11:28 | jcromartie | anyway |
| 11:28 | acheng | it's how i think of free will and election :-P the author writes, the character chooses. i don't know Milliard. |
| 11:28 | jcromartie | I'd better be careful or I won't get anything done today |
| 11:28 | borkdude | http://en.wikipedia.org/wiki/G%C3%B6del's_ontological_proof |
| 11:29 | jcromartie | and of course, Gödel, Escher, Bach started all of this :) |
| 11:30 | jcromartie | fantastic book |
| 11:30 | borkdude | jcromartie I missed that part |
| 11:30 | jcromartie | good for Lispers too |
| 11:31 | jcromartie | I just mean it started me thinking about the nature of information and the universe |
| 11:32 | lynaghk` | Is there a core fn to check if something is between two other things? E.g., (between? 5 [2 9]) ;=> true |
| 11:32 | borkdude | how is the find-fn syntax in here again? ;) |
| 11:32 | lynaghk` | I can never remember the clojurebot syntax for looking up fns by arguments |
| 11:32 | borkdude | $find-fn |
| 11:32 | lynaghk` | yeah, right! |
| 11:33 | borkdude | $find-fn 5 [2 9] true |
| 11:33 | borkdude | something like that? |
| 11:33 | lynaghk` | clojurebot: help |
| 11:33 | clojurebot | http://www.khanacademy.org/ |
| 11:33 | borkdude | $findfn 5 [2 9] true |
| 11:33 | lazybot | [clojure.core/not= clojure.core/distinct?] |
| 11:33 | borkdude | hmm... |
| 11:33 | clgv | lynaghk`: how about ##(< 2 5 9) ;? |
| 11:33 | lynaghk` | $findfn [2 9] 5 true |
| 11:33 | lazybot | ⇒ true |
| 11:33 | lazybot | [clojure.core/not= clojure.core/distinct?] |
| 11:34 | lynaghk` | clgv: yeah, I was thinking that. Just thought I'd check the enormity of clojure.core first =) thanks |
| 11:34 | borkdude | lynaghk` yes, the answer is not= :P |
| 11:34 | borkdude | ,(doc <) |
| 11:34 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically increasing order, otherwise false." |
| 11:34 | clgv | lynaghk`: depending on your semantic you should maybe switch to <= ;) |
| 11:35 | borkdude | ah monotonically increasing, I didn't know that! |
| 11:35 | clgv | borkdude: pairwise could be useful as well ;) |
| 11:35 | borkdude | even about the most simple of things there's something new to learn every day |
| 11:35 | borkdude | ,(doc pairwise) |
| 11:35 | clojurebot | Cool story bro. |
| 11:36 | S11001001 | lancero: yes, all your promises will have values when you return from that |
| 11:36 | borkdude | clgv what's that |
| 11:36 | clgv | not a clojure function ;) nvm |
| 11:36 | scriptor | ,(-> 5 (< 2 9)) |
| 11:36 | clojurebot | false |
| 11:36 | borkdude | Nice, Clojurebook 50% off today (ebook): http://shop.oreilly.com/category/deals/best-of-oreilly-dotd.do |
| 11:37 | scriptor | argh |
| 11:37 | scriptor | (-> 2 (< 5 9) doesn't seem as clear |
| 11:37 | borkdude | ,(macroexpand '(-> 5 (< 2 9)) |
| 11:37 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 11:38 | scriptor | borkdude: it makes it the 2nd argument |
| 11:38 | jcromartie | borkdude: is it worth getting that book? I feel like Clojure moves too fast |
| 11:38 | borkdude | scriptor anyway, it expands to (< 5 2 9) |
| 11:38 | scriptor | so it'd be (< 5 2 9) |
| 11:38 | zoldar | Is it possible and reasonable to use different url patterns based on server name in scope of a single django project? |
| 11:38 | borkdude | jcromartie yes, get it |
| 11:39 | jcromartie | if I buy the ebook do I get updates? |
| 11:39 | S11001001 | ,(partition-all 2 1 [1,2,3,4,5]) ; clgv, pairwise |
| 11:39 | clojurebot | ((1 2) (2 3) (3 4) (4 5) (5)) |
| 11:39 | borkdude | "Ebooks from oreilly.com are DRM-free. You get free lifetime access, multiple file formats, and free updates." |
| 11:39 | zoldar | oops |
| 11:39 | jcromartie | yeah |
| 11:39 | zoldar | sorry |
| 11:39 | S11001001 | jcromartie: yes (generally for o'reilly), but not new editions |
| 11:39 | jcromartie | I just wonder if that encompasses editions |
| 11:39 | jcromartie | oh, OK right :) |
| 11:39 | jcromartie | still a good deal |
| 11:40 | foxdonut | never bought an ebook at more than 50% or 60% of the retail price |
| 11:40 | borkdude | jcromartie I like it, I have the paper version as well, but I read it from my screen most of the time anyway.. |
| 11:40 | foxdonut | or more clearly, at least 40% off, most often 50% |
| 11:40 | uvtc | lynaghk, (defn between? [x a b] (and (< x b) (> x a))) |
| 11:41 | metellus | that gets messier if you also want it to work for (between? 5 [9 2]) |
| 11:41 | TimMc | (< a x b) |
| 11:42 | uvtc | TimMc, ah, missed that. Thanks! |
| 11:42 | TimMc | The more interesting case is when you want a half-open range: (and (<= a x) (< x b)) |
| 11:42 | borkdude | ,(apply (fn between? [x a b] (< a x b)) 5 [2 9]) |
| 11:42 | clojurebot | true |
| 11:43 | borkdude | TimMc this begs for a macro...? |
| 11:44 | cemerick | borkdude: thanks for linking people up :-) |
| 11:44 | borkdude | cemerick what do you mean, linking up? ;) |
| 11:44 | scriptor | borkdude: why a macro? |
| 11:44 | lancero | S11001001: why? Using printouts I can see that the function starts blocking during the sixth element (waiting for the first element to be reliazed), then continues to deliver the rest of the elements and returns. The last 5 elements should still be sleeping when the function returns (I mean this is the behaviour that I'm trying to create). |
| 11:44 | cemerick | borkdude: RT'ing the oreilly link here |
| 11:45 | borkdude | cemerick sure! |
| 11:45 | TimMc | borkdude: A fn will do. |
| 11:45 | scriptor | right, a macro might introduce unneeded complexity |
| 11:45 | S11001001 | lancero: you delivered 5 immediately, all at once, then slept long enough for them all to finish |
| 11:46 | borkdude | TimMc what if you have a half open range, like: [-2,2[, it would be nice if you could check for that with this short notation? well, maybe too complex to be worth it, I realize |
| 11:46 | TimMc | That wouldn't even read. :-/ |
| 11:47 | borkdude | TimMc that is the mathematical notation I learned at high school |
| 11:47 | borkdude | TimMc -2 is included, 2 is excluded |
| 11:47 | scriptor | it's invalid clojure, unfortunately |
| 11:47 | borkdude | scriptor TimMc I said "like", not "exactly this notation" :P |
| 11:48 | borkdude | (is-in-range? x (range -2 2)) |
| 11:48 | borkdude | forget it :P |
| 11:49 | scriptor | could try (between? 2 [-2 2 _]) |
| 11:49 | borkdude | a math dsl would be appropriate if you use it very much |
| 11:49 | borkdude | for convenience |
| 11:50 | scriptor | and have it so that 3 arguments makes it exclusive for the max |
| 11:50 | TimMc | (map (partial inside? (range-co -2 2)) [-3 -2 1 2 3]) => [false true true false false] |
| 11:50 | TimMc | co = closed, open |
| 11:51 | borkdude | TimMc the normal range is already closed, open, but it contains only integers |
| 11:51 | TimMc | You could have a whole lib for ranges: Membership, union, etc. |
| 11:51 | borkdude | TimMc yes, maybe it already exists in incanter or smth? |
| 11:51 | borkdude | (never used incanter really) |
| 11:52 | scriptor | there's probably something like it in haskell |
| 11:53 | TimMc | borkdude: Oh, incanter is a good bet. |
| 11:53 | kremlon | wtf is clojure |
| 11:53 | borkdude | kremlon your next addiction |
| 11:53 | foxdonut | borkdude: :) |
| 11:53 | kremlon | hope so |
| 11:53 | bhenry | how can i make a in clojurescript without it being escaped and displayed in the browser? |
| 11:53 | foxdonut | next thing you know, you're reading a novel and you think "closure" has a spelling mistake. |
| 11:53 | TimMc | "I'm sorry, Bill, I just need clojure." |
| 11:54 | foxdonut | she said in response to "how about going out with me for a Java?" |
| 11:54 | jcromartie | loving the DRM-free ePub |
| 11:55 | TimMc | jcromartie: The only kind worth buying. :-) |
| 11:55 | jcromartie | kremlon: someone needs to make an introductory "WTFAQ" |
| 11:55 | foxdonut | lol |
| 11:55 | TimMc | jcromartie: Isn't clojure.org just that? |
| 11:55 | llasram | Well, any EPUB can become DRM-free with a little elbow grease... |
| 11:55 | borkdude | closure means 1) google closure, 2) a spelling mistake for clojure and 3) a function capturing its environment, in that order for me |
| 11:55 | kremlon | lol do u geise get that question alot |
| 11:55 | scriptor | is the oreilly clojure book easy to read on smaller kindle? |
| 11:55 | jcromartie | clojure.org is for people who can learn by reading man pages |
| 11:55 | TimMc | I'm pretty sure I'm not a geese. |
| 11:55 | foxdonut | jcromartie: that is just too funny. what the FAQ?! |
| 11:56 | jcromartie | scriptor: I shy away from tech books on Kindle… they never fit right, code looks awful, etc. |
| 11:56 | borkdude | jcromartie I tried clojurebook on kindle and it's doable |
| 11:56 | scriptor | jcromartie: yep, some books work alright though |
| 11:56 | scriptor | as long as the code samples are short |
| 11:56 | borkdude | jcromartie but wth man, you always want a REPL close to your book for trying it out |
| 11:56 | TimMc | bhenry: Sounds like what you want is either non-HTML-encoded output or a NBSP character. |
| 11:56 | foxdonut | scriptor: I don't know about the kindle, but my sony reader uses epub, and epub is just html+css in a zip file, so I totally hack mine to use the fonts that I want :) |
| 11:57 | bhenry | TimMc: any way for me to put an empty html tag that won't lose its shape for being empty |
| 11:57 | scriptor | foxdonut: ah, neat, my biggest issue with tech books on an e-reader is that they're never wide enough |
| 11:58 | jcromartie | borkdude: yeah, but I like the iPad because I can at least pick it up and sit on the couch if I don't need a REPL |
| 11:58 | jcromartie | and touch controls for reading |
| 11:58 | jcromartie | I hate reading on a monitor |
| 11:59 | foxdonut | scriptor: sure. some tech books don't work well. it depends. novels are best on the e-reader. I still hack the fonts though :D |
| 11:59 | scriptor | foxdonut: hah, yep, novel's are so much easier to fit to the screen |
| 12:00 | scriptor | I have 80 minutes of commute time, so I'm toying with the idea of using some of it for technical books |
| 12:00 | scriptor | in addition to novels |
| 12:00 | borkdude | I like novels on the kindle, but also non-fiction non-tech books (lots of text, no code, big pictures) |
| 12:01 | borkdude | clojure literature is better suited for small screens though, the code is usually more compact |
| 12:01 | scriptor | true |
| 12:01 | borkdude | why don't they make e-readers a bit bigger I wonder though |
| 12:01 | scriptor | don't they already do? |
| 12:01 | llasram | foxdonut: That's funny -- I do that too, re: ebook fonts. I have this pipeline using a custom-hacked version of Calibre from back when I used to contribute to it which basically auto-reformats most stuff I read |
| 12:02 | scriptor | kindle fire is an inch bigger, which isn't much I guess |
| 12:02 | borkdude | scriptor fire isn't e-ink |
| 12:02 | Wild_Cat | Kindle Fire is LCD though. It's meh. |
| 12:02 | scriptor | yea :/ |
| 12:02 | scriptor | DX is 9.7, but way too expensive |
| 12:02 | borkdude | scriptor there are some bigger models, but one company who made that is now bankrupt :( |
| 12:03 | Wild_Cat | for reading novels though, I'm totally in love with my Kindle Touch. |
| 12:04 | Wild_Cat | ...although I am sort of disappoint that the Kindle version of A Dance With Dragons doesn't come with a map of Westeros. |
| 12:05 | scriptor | is the resolution good enough to support a map like that? |
| 12:06 | Wild_Cat | scriptor: it's 600x800, landscape mode should do the trick. |
| 12:06 | zoldar | scriptor: I've got one DX under a thin cover of dust - sadly in current conditions I can't use it - do my reading mostly from phone with 4.2" inch screen - far from the eink comfort but must put up with that. |
| 12:06 | Wild_Cat | it's working okay for the map at the beginning of Greg Rucka's "Alpha" (which I'm currently reading), at the very least. |
| 12:07 | Wild_Cat | I mean, it's not ideal, but it's better than no map :p |
| 12:12 | zoldar | also, with DX it's beter to read with support for arms. It get's quite heavy on arms when holding it in air for example when lying on bed |
| 12:12 | zoldar | *gets |
| 12:14 | borkdude | for novels I'm quite happy with my kindle touch, I get the impression that I read faster than on paper |
| 12:14 | borkdude | because turning pages is effortless |
| 12:15 | borkdude | this is off topic, but novel reading can sometimes be very important for programmers to keep sane ;-) @technomancy |
| 12:15 | technomancy | FSVO sane |
| 12:18 | technomancy | I'm bummed they dropped the analog scroll wheel that's in the v1 kindle |
| 12:18 | technomancy | that's one of my favourite parts of the design |
| 12:24 | borkdude | technomancy no need when touch screen right? |
| 12:25 | technomancy | borkdude: depends on the refresh rate. the scroll wheel has a realtime indicator that lets you make selections without being tied to the e-ink screen for input feedback |
| 12:30 | dnolen | EuroClojure core.logic video is out, http://twitter.com/euroclojure/status/220185504744878081 |
| 12:40 | jcromartie | man, this guy… the last word is "As for lisp, I'm a mediocre programmer, so don't plan on using lisp.... :-/" |
| 12:45 | gfredericks | jcromartie: you're reading something? |
| 12:45 | jcromartie | no just a conversation with a recent hire |
| 12:45 | gfredericks | ah right |
| 12:46 | tbaldridge | I don't understand why someone wouldn't want to self improve, that seems so backwards. |
| 12:47 | technomancy | I find it kind of refreshing for someone to admit they're not so hot. |
| 12:47 | technomancy | being OK with staying that way, not so much though. |
| 12:47 | gfredericks | "I'm a mediocre programmer, so I intend to stay mediocre" |
| 12:48 | gfredericks | ^ non-sequitur? |
| 12:52 | gfredericks | of course if it's just a job then it's hard to fault the person |
| 12:52 | gfredericks | as a person at least; maybe not as an employee |
| 12:53 | tbaldridge | eh...I disagree though. There's an apathy I've seen in the programming world. People accept that Java is all they'll ever be able to use, so the learn java, and just deal with the crap day in and day out. |
| 12:54 | gfredericks | but if they're not doing it for the love, what does it matter? as long as they're employed. |
| 12:54 | technomancy | yeah, but maybe his passion is to write a novel in the wee hours of the night and he writes java to pay the bills. |
| 12:54 | tbaldridge | So for instance, here at work, I complained that our serializer was slow. The response I got was "eh...it uses .NET's serializer, it works...if you think you can do better than MS, try...hahaha...." |
| 12:55 | gfredericks | as long as the industry is booming you can't expect everybody to be an idealist |
| 12:55 | tbaldridge | But for me, I couldn't take that, so I rewrote it using multimethods (ported to C#) and code generation, and the new serializer is about 20x faster and produces data 1/10th the size. |
| 12:56 | zoldar | tbaldridge: what was their reaction? |
| 12:56 | tbaldridge | We use it in production right now ;-) |
| 12:57 | S11001001 | wait, tbaldridge, did someone suggest that doing better than ms would be difficult, in earnest? |
| 12:57 | foxdonut | llasram: that's very cool! (custom calibre to format your ebooks) |
| 12:57 | tbaldridge | oh yes, yes they did. |
| 12:58 | uvtc | tbaldridge, zoldar asks an interesting question though. "What was their reaction?" That is, at some places, you might get, "did you do this on company time? Were you asked to do this?" etc. |
| 12:59 | foxdonut | I'm interested in the reaction as well |
| 12:59 | uvtc | My point is, sometimes doing things one better isn't rewarded, and so that behaviour isn't selected for among sucessful employees... |
| 12:59 | zoldar | uvtc: that's what I wanted to ask, but due to my crap english I couldn't put it into words |
| 13:00 | tbaldridge | uvtc: well we ended up hitting a brick wall at one point. Loading data for a certain project was crashing .NET because the to serialize 20k records it was taking 700MB. So I developed in my spare time (on company time) and presented it as "look, now it doesn't crash, it's way faster, and we can actually send these datasets over the internet". |
| 13:00 | tbaldridge | That's about all it took to convince them. |
| 13:02 | mabes | that is probably the key point.. if the company didn't need a faster serializer then they may have still used the slower MS one due to maintenance concerns |
| 13:02 | tbaldridge | But what irks me is that no one even thought enough about the process to say "hey...maybe XML serialization isn't best here". No it was "this framework has existed for 5+ years, let's just use that and slap a ORM on to it, and barf it all up on the UI, and YAY! we're done!" |
| 13:02 | uvtc | tbaldridge, Ah, so in this case it was indeed solving a concrete problem the team was facing. |
| 13:02 | tbaldridge | uvtc: exactly |
| 13:03 | zoldar | tbaldridge: maybe that's something for a success story blog post material ? :) |
| 13:04 | tbaldridge | perhaps |
| 13:06 | zoldar | especially that it leverages the not (yet) so common platform for clojure |
| 13:06 | tbaldridge | but back to the original topic, I have to wonder sometimes if we teach people to be too apathetic, Java/C# is so complex that people don't have time to do anything but read up no the latest features of IIS, EF, Spring, etc. |
| 13:07 | tbaldridge | As I told a co-worker the other day: "I really don't care to know where IHttpHandler fits into the IIS stack vs IHttpModule..." When simplify the web server down to a few functions (like Ring does) suddenly we have more time to think about things that really matter. |
| 13:08 | tbaldridge | At least that's my idea </rant> |
| 13:09 | Jayunit100 | Wow this reduce word-count function is really slow : http://pastebin.com/raw.php?i=2X5UaTG3 … I'm not sure why though. any insights? Im using let with assoc to bind new words into a map and increment their count iteratively. |
| 13:11 | gfredericks | Jayunit100: why passing a single arg to assoc even do anything? |
| 13:11 | gfredericks | s/assoc/reduce/ |
| 13:11 | ohpauleez | Jayunit100: You also can get rid of that let and just destructure |
| 13:12 | gfredericks | &(doc reduce) |
| 13:12 | lazybot | ⇒ "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as... https://www.refheap.com/paste/3429 |
| 13:12 | Jayunit100 | ah the reduce … yeah well it needs to sum |
| 13:12 | ohpauleez | they pre clause can use `string?` |
| 13:12 | gfredericks | there is no single-arg version of reduce |
| 13:12 | uvtc | Jayunit100, what is that hash-map doing there underneath `[str_in]`? |
| 13:12 | mhanson | ,(doc constantly) |
| 13:12 | clojurebot | "([x]); Returns a function that takes any number of arguments and returns x." |
| 13:13 | Jayunit100 | the hash map is counting words |
| 13:13 | ohpauleez | uvtc: it's how you do constraints/contracts in Clojure |
| 13:13 | foxdonut | tbaldridge: what was the reaction from "haha you will never be able to do it" to "here, I did it" ? |
| 13:13 | Jayunit100 | so, it assocs a new word to the hash map every time it sees one |
| 13:13 | uvtc | ohpauleez, Oh, don't know about those yet. Thanks. :) |
| 13:13 | Jayunit100 | and (inc)s it the 2nd time, 3rd, etc.... |
| 13:14 | Jayunit100 | so if input is "a b b" the output is {"a" 1,"b" 2"{ |
| 13:14 | ohpauleez | Jayunit100: You can use group-by |
| 13:14 | gfredericks | or frequencies |
| 13:14 | gfredericks | ,(frequencies ["a" "b" "b"]) |
| 13:14 | clojurebot | {"a" 1, "b" 2} |
| 13:15 | zoldar | ,(frequencies (map str (seq "a a b"))) |
| 13:15 | clojurebot | {"a" 2, " " 2, "b" 1} |
| 13:15 | Jayunit100 | UHOH ! :) |
| 13:16 | Jayunit100 | well… i wrote the code for pedagogical purposes so I'm still curious about why it is slow. |
| 13:16 | Jayunit100 | but thanks everybody for your help. Im wondering -- is there anything truly unidiomatic in the function that i pasted ? |
| 13:17 | ohpauleez | Jayunit100: Turn the let to destructuring |
| 13:17 | ohpauleez | The pre should use string? |
| 13:17 | dnolen | Jayunit100: "slow" for what size input and compared to what? |
| 13:17 | ohpauleez | but no, using reduce to build up collections is standard |
| 13:18 | tbaldridge | foxdonut: the reaction was "heh...good job". I don't think it really sunk in that we had something really usable until the framework we use (CSLA.NET) decided to accept my patch (or the ideas behind it) and use them by default in the framework. |
| 13:18 | Jayunit100 | it must be the let, that is taking a while. |
| 13:18 | Jayunit100 | so how does reduce optimize creating a new map over and over agin ? |
| 13:18 | Jayunit100 | (i.e. how does reduce optimize assoc)? |
| 13:18 | pbostrom | Jayunit100: there is also reduce-kv |
| 13:18 | dnolen | Jayunit100: it doesn't optimize assoc |
| 13:19 | Jayunit100 | Is it a "bad" idea to do an assoc in a reduce where we expect a large number of elements in the [ ] ? |
| 13:19 | dnolen | Jayunit100: no |
| 13:19 | uvtc | pbostrom, reduce-kv? |
| 13:20 | pbostrom | http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reduce-kv |
| 13:20 | uvtc | pbostrom, Oh, whoops. Didn't see it on clojuredocs, but it's here in my repl. |
| 13:20 | uvtc | pbostrom, thanks. |
| 13:21 | pbostrom | I believe that might provide some optimization, but I'm just guessing |
| 13:22 | foxdonut | tbaldridge: wow..well done! |
| 13:23 | Jayunit100 | how does assoc implement performance under heavy insert load given the immutability constraints of clj ? |
| 13:24 | S11001001 | Jayunit100: structure sharing |
| 13:24 | gfredericks | Jayunit100: I think you use transients if you can't bear the immutability overhead |
| 13:24 | Jayunit100 | ah ok |
| 13:24 | jweiss | any slimv users know if you can do the equivalent of kill-sexp? |
| 13:26 | dnolen | Jayunit100: without explaining what kind of performance you're looking for, or without any extra information about how you are running your environment (JVM server setting etc). it's really hard to say anything meaningful in response. |
| 13:26 | dnolen | Jayunit100: are you expect it to be 2X faster? 4X faster? 10X faster? |
| 13:26 | uvtc | Jayunit100, re. your word-enrichment func; personally, I usually like using the fn form instead of the function literal #() --- so that you can give your parameters descriptive names. |
| 13:28 | nDuff | Jayunit100: ...in a lot of cases, the immutable types are fast enough -- they *don't* involve full copies. |
| 13:30 | scriptor | does it still use copy-on-write for small numbers of assoc? |
| 13:30 | dnolen | scriptor: yes |
| 13:40 | tbaldridge | cemerick: ping |
| 13:41 | lynaghk | dnolen: re: TODO, thanks. Any suggestions for cleanup before I submit it to the wider JS world? |
| 13:42 | dnolen | lynaghk: hmm not really, though I expect it to be thoroughly misunderstood |
| 13:42 | lynaghk | dnolen: heh. I'm still trying to train myself out of the OO/MVC mindset a lot of the time. |
| 13:43 | lynaghk | "This is simple. Too simple. I must be doing something terribly wrong." |
| 13:43 | brainproxy | lynaghk: what are you about to unleash on the world? |
| 13:43 | dnolen | lynaghk: it could get a lot simpler ... |
| 13:43 | dnolen | lynaghk: I'm realizing that JS MVCs are just queries+databinding, not much else. |
| 13:44 | scriptor | a lot of people won't be used to cljs's mutability primitives, so you'll see complaints about that |
| 13:44 | dnolen | lynaghk: I'm looking forward to to getting the DB functionality of core.logic working under CLJS - then you can run arbitrary queries over indexed data. |
| 13:44 | dnolen | lynaghk: instead of this linear filtering crap |
| 13:44 | lynaghk | dnolen: yeah, I'd be all about that. |
| 13:45 | lynaghk | brainproxy: Todo app written in cljs using C2's new databinding stuff: https://github.com/lynaghk/c2-demos/tree/master/todoMVC |
| 13:46 | dnolen | lynaghk: also thinking it would be cool to support using raw JSON as the data source instead of converting into CLJ data structures. |
| 13:46 | lynaghk | dnolen: You can get core.logic to work directly against an array of js objects? |
| 13:46 | brainproxy | lynaghk: sweet! |
| 13:47 | dnolen | lynaghk: core.logic can unify anything so I don't see why not. |
| 13:47 | scriptor | what does bind! do? |
| 13:47 | brainproxy | i know i've asked this before, but I want to get into the core.logic stuff, but I feel a bit lost; recommendations for getting up to speed when armed w/ general knowledge of clojure but no logic prog experience |
| 13:47 | brainproxy | ? |
| 13:48 | lynaghk | dnolen: I think that would be pretty powerful. I'm not sure how well that would work for doing actual data manipulation in CLJS though---i.e., if you want to change the underlying data. You'd need to drop to aset, no? |
| 13:48 | dnolen | brainproxy: it's an up hill battle - and then it seems so simple ... |
| 13:48 | dnolen | brainproxy: it's worth investing in a good Prolog book + The Reasoned Schemer |
| 13:48 | brainproxy | meaning links to books, ebooks, tutorials that help one to dive in, but don't require a B.A. in math |
| 13:49 | lynaghk | scriptor: there's a bit of explaination in the release announcement: https://groups.google.com/forum/?fromgroups#!topic/clojure/KCe96DbMD6k |
| 13:49 | brainproxy | dnolen: i tried looking at the minkanren dissertation, but the learning curve seemed n^n |
| 13:49 | scriptor | lynaghk: ah, nice, was just about to suggest something like that announcement |
| 13:49 | TimMc | brainproxy: Fast, then? |
| 13:49 | TimMc | :-) |
| 13:50 | Jayunit100 | dnolen: good point. well…. this whole thing came from an experiment - i wanted to see if (reduce) with (assoc) would indeed be "fast".. by fast, i mean that its O(n) time would be steady as the # of words increased. Indeed, it did. I just was having some fears that it wasn't "fast enough". But now, after benchmarking it against standard java/maps and another clojure impl, I'm pretty happy :) |
| 13:50 | dnolen | brainproxy: yeah, requires a couple of reads. The Reasoned Schemer + Prolog book. Then some head-scratching, then try dissertation again :) and only chapter 3. |
| 13:50 | dnolen | Jayunit100: well there you go :) |
| 13:50 | scriptor | lynaghk: before releasing it to the js world, just make sure to explain some of the more clojure-y bits, mutability, dereferencing, destructuring, and the templating |
| 13:51 | brainproxy | dnolen: recommendation for prolog books? |
| 13:51 | brainproxy | free, paid, out of print, whatever |
| 13:51 | lynaghk | scriptor: I've been meaning to just ping the TodoMVC guys and see what they think about including such a black sheep. |
| 13:51 | Jayunit100 | dnolen: . thanks for your help. I believe you were the one that said "tools don't mean s**t without a good community"… and the clj community is always there for me in times of despair :) |
| 13:51 | lynaghk | scriptor: but yeah, I've been thinking about this kind of stuff for a bit. I'm giving a talk at OSCON in two weeks about this compared to MVC, so I'll probably record a screencast and get everything written down. |
| 13:52 | dnolen | brainproxy: Bratko Prolog book (new edition!) or Sterling Shapiro Prolog |
| 13:52 | scriptor | lynaghk: one other recommendation is that I'd make another very simple js app and see how much code you can share between the two |
| 13:53 | scriptor | lynaghk: but I remember you mentioning that it gets rough when you factor in edge cases, still, one major complaint will be what it offers over plain js :) |
| 13:53 | lynaghk | scriptor: Not sure what you mean / what that would show. Whenever something seems useful to share between apps, I put it in a library. |
| 13:55 | dnolen | lynaghk: I think it could work fine with most JS MVC workloads, I think the whole datomic DB as value thing could work well and be efficient for many use cases. |
| 13:55 | lynaghk | dnolen: think you could find some time to write the TodoMVC data fns in core.logic? |
| 13:55 | dnolen | lynaghk: most JS MVCs require cloning anyhow ... so it possible we could do better ... |
| 13:56 | pbostrom | are there any plans to add (:require ... :refer ...) to cljs? |
| 13:56 | dnolen | lynaghk: yes, gotta wrap up this other core.logic stuff first ... but beefing up CLJS core.logic is on the list |
| 13:56 | dnolen | pbostrom: it's already there. |
| 13:57 | dnolen | pbostrom: well in master, perhaps not in a release |
| 13:57 | lynaghk | dnolen: cool. I worked through the reasoned schemer but the most advanced example was building some bit-manipulation adding circuits, and I didn't have the energy to try and work from that to something closer to my day-to-day domain. |
| 13:57 | pbostrom | ah, ok, thanks, I guess it hasn't made it through to cljsbuild (still a little unsure of the relation between versions of those 2) |
| 14:00 | scriptor | lynaghk: well, let's start with this, how *is* it better than plain (non-mvc) js? |
| 14:00 | scriptor | besides that it's in clojure :) |
| 14:03 | dnolen | scriptor: people use JS MVCs for a reason - it does control complexity in larger JS apps. |
| 14:04 | scriptor | dnolen: right, so how does using cljs also control complexity? |
| 14:04 | dnolen | scriptor: having done both - IMO, yes. |
| 14:05 | scriptor | how, exactly? The mutability primitives? |
| 14:06 | dnolen | scriptor: simpler notions of truth, sensible extensibility, namespaces, no aliasing, no pervasive mutability, useful sugar, recursive definitions, etc |
| 14:07 | brainproxy | anyone got an example of a cljs project using domina which makes heavy usage of XHR |
| 14:09 | lynaghk | scriptor: the biggest part for me is moving away from thinking of the DOM as some mutable thing that you want to hit with stuff (addClass, appendChild, ...) and starting to think of it as a plain data structure (e.g., Hiccup vectors). Write functions to transform your domain data to "view data", and then let the library handle updating the DOM for you. |
| 14:10 | scriptor | ah, so representing the DOM in the same data structures that the language uses, that's pretty big |
| 14:10 | clojurebot | make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive |
| 14:10 | dnolen | scriptor: oh, unified iteration for all types, and protocols prevent API proliferation / incompatibility also big. |
| 14:10 | lynaghk | scriptor: yeah, because you can use your actual programming language in that case. Not some janky franken-handlebar-js-html crap. |
| 14:10 | scriptor | hehe |
| 14:11 | lynaghk | scriptor: I wrote Singult to be usable from plain JS, and I'm interested to see if anyone actually tries using it out from there since that idea---treating your view as just another data structure---isn't Clojure-specific. |
| 14:11 | lynaghk | Though, like dnolen says, there's also a ton of great shit in Clojure =) |
| 14:11 | scriptor | wait, singult can be used from native js? |
| 14:12 | scriptor | holy shit, that's pretty awesome |
| 14:13 | lynaghk | scriptor: yeah, JavaScript has Arrays and Objects, so you can play the Hiccup game there too. |
| 14:13 | lynaghk | You just need a hell of a lot more commas =P |
| 14:13 | goodiebo_ | how do you write (append) to a file in clojure? |
| 14:13 | borkdude | goodiebo_ http://stackoverflow.com/questions/7756909/in-clojure-1-3-how-to-read-and-write-a-file/7757674#7757674 |
| 14:14 | goodiebo_ | ha geez, thanks! |
| 14:17 | scriptor | lynaghk: bind! seems to solve the problem of binding data to view data structures really well |
| 14:18 | lynaghk | scriptor: checkout the source. it's just using computed-observables (from the Reflex library) and merge (from Singult). |
| 14:18 | scriptor | so, when you release this more widely, I'd definitely stress that clojure's forcing you to constrain mutability to only what you must mutate means that you can easily listen for changes |
| 14:19 | lynaghk | computed-observables are pretty simple, and handy for data stuff too. |
| 14:20 | scriptor | I think knockoutjs is the only other tool that does a similar thing in js |
| 14:21 | ohpauleez | Scriptor: As a corollary, a lot of my CLJS apps deal with stream data and a specific process |
| 14:21 | ohpauleez | so something like enfocus works great for me |
| 14:22 | ohpauleez | where I want to take one piece of a the DOM (like a container) and represent all of my search results in there |
| 14:22 | ohpauleez | where my search results from from a JSONP request to a different server |
| 14:22 | scriptor | got it |
| 14:23 | dnolen | scriptor: I refuse to use anything with the word Model in it anymore when it comes to JS. |
| 14:23 | scriptor | dnolen: agreed :) |
| 14:23 | ohpauleez | but it requires me to wire up my apps differently, so I use a lot of pubsub stuff |
| 14:24 | scriptor | I sent out a long email to the dev list this morning that basically amounted to "hashmaps are better than models" |
| 14:24 | lynaghk | scriptor: yeah, knockout is where I took the computed-observable idea from. The implementation too---they did a great job of design documentation. |
| 14:24 | ohpauleez | the misunderstanding of (or perhaps overuse of) "model" and MVC is laughable |
| 14:25 | ohpauleez | and a little annoying |
| 14:26 | ohpauleez | so I'm with you guys |
| 14:44 | mhanson | Anyone else see that ebook Clojure Programming is half-off today? |
| 14:47 | borkdude | mhanson it has been noted, but can not be overemphasized |
| 14:47 | mhanson | Hah. Excellent. |
| 14:48 | tbaldridge | mhanson: is that through O'Reily? |
| 14:49 | mhanson | tbaldridge: Yep. |
| 14:49 | tbaldridge | hrm, I'm not seeing the 50% off part... |
| 14:49 | mhanson | I believe the discount code is "deal". |
| 14:50 | mhanson | If you go to the shop front page, it's under the daily deals section. |
| 14:50 | tbaldridge | ah yeah, discount code |
| 14:50 | mhanson | But yes, on the actual book page that is not reflected. |
| 14:51 | tbaldridge | cool, thanks, I think I'll pick it up |
| 14:52 | ptambala | hi |
| 14:52 | ptambala | are you talking about Clojure Programming or Programming Clojure? |
| 14:52 | foxdonut | the former |
| 14:52 | ptambala | ok, I'm currently reading Clojure Programming. |
| 14:53 | foxdonut | the latter has a 2nd edition out, btw. |
| 14:53 | ptambala | yep, I saw this |
| 14:53 | ptambala | but I don't like the swan on the cover, so I'm not really tempted to buy it :) |
| 14:54 | borkdude | =) |
| 14:54 | johndeo | I'm reading it now. It is good. |
| 14:54 | borkdude | I don't like the clojure logo, so I will stop using clojure |
| 14:55 | ptambala | ok |
| 14:55 | ptambala | I was thinking about buying a 2nd book, and I was thinking about Joy of Clojure, dunno |
| 14:55 | borkdude | ptambala http://stackoverflow.com/questions/2578837/comparing-clojure-books |
| 14:55 | ptambala | so many choices... |
| 14:55 | ptambala | oh thx |
| 14:57 | foxdonut | ptambala: JoC probably has the least overlap with CP |
| 14:58 | johndeo | Datomic looks super cool, but I'm hesitant about a cloud-only proprietary app for the DB. Should I be? Does someone have a perspective on this? |
| 14:58 | technomancy | johndeo: seems reasonable to have hesitations about that |
| 15:00 | ptambala | foxdoughnut: after reading the description JoC seems to be the right book indeed. thanks. |
| 15:01 | borkdude | ptambala can't go wrong with that one |
| 15:04 | devn | johndeo: free for open source FWIW |
| 15:06 | TimMc | *gratis |
| 15:16 | nDuff | devn: ...bah; "free-of-cost for open source" ~= useless |
| 15:16 | nDuff | almost all the OSS work I do is backing commercial projects, and selling them on a for-pay database backend, however much better it may be, when there are more battle-tested Free ones available is basically impossible. |
| 15:16 | dustingetz | whats the easiest way to make async http requests in clojure |
| 15:17 | jsabeaudry | dustingetz, jayq |
| 15:17 | dustingetz | even from the server? not in browser e.g. not using cljs |
| 15:18 | jbarrios | I am hiring for backend engineering positions, if anyone's looking. We are starting to introduce Clojure into the mix. |
| 15:18 | dustingetz | link to jobs page? |
| 15:18 | jbarrios | digging it up now. |
| 15:19 | jcromartie | dustingetz: clojure-http-client |
| 15:19 | vojd | is there any clojure service out there i can point to, stating "THIS is a full fledged clojure app" |
| 15:19 | jcromartie | er never mind |
| 15:19 | technomancy | no don't use clojure-http-client |
| 15:19 | jcromartie | how about https://github.com/neotyk/http.async.client |
| 15:20 | jcromartie | sorry :) |
| 15:20 | vojd | for those colleagues and friends saying "but meh, clojure is just a research language right?" |
| 15:20 | dustingetz | http.async.client |
| 15:20 | technomancy | vojd: clojars |
| 15:20 | technomancy | clojurebot: success stories? |
| 15:20 | clojurebot | clojure success stories is http://dev.clojure.org/display/community/Clojure+Success+Stories |
| 15:20 | technomancy | ^ if it doesn't need to be OSS |
| 15:20 | vojd | super :D thanks |
| 15:20 | dustingetz | final question, for mocking async queries, i basically want `(defn sleep-async [ms callback] …)` |
| 15:20 | jbarrios | dustingetz: here's one: https://sjobs.brassring.com/1033/ASP/TG/cim_jobdetail.asp?partnerid=25348&siteid=5039&jobid=42321 |
| 15:21 | dustingetz | not exactly sure how to go about implementing that without having my own while loop |
| 15:21 | dustingetz | i want the OS to do the polling/eventing/reactor/whatever for me |
| 15:21 | jcromartie | dustingetz: you can use Thread/sleep |
| 15:21 | dustingetz | asynchronously? |
| 15:21 | jcromartie | put it in another thread :) |
| 15:22 | dustingetz | it gets really really complicated, i want the callback to happen in my main thread |
| 15:22 | dustingetz | im exploring continuations |
| 15:22 | jcromartie | I don't think it needs to be that complicated |
| 15:22 | jbarrios | how about a future? |
| 15:22 | dustingetz | futures imply threads |
| 15:22 | jcromartie | and futures block while they wait |
| 15:23 | jcromartie | but it shouldn't be that hard to dispatch something on the main thread, right? |
| 15:23 | jcromartie | hm, yeah you'd need something like a run loop |
| 15:23 | dustingetz | i guess i can have a reactor loop on my main thread polling some cross-thread queue |
| 15:23 | dustingetz | but this isn't how things look in real life |
| 15:23 | jcromartie | no |
| 15:24 | scriptor | with clojurescript, are error line numbers mapped back to the original cljs yet? |
| 15:24 | jcromartie | you can use exceptions |
| 15:24 | jcromartie | :) |
| 15:24 | scriptor | but in the case of syntax errors and such? |
| 15:25 | jcromartie | dustingetz: this is your ticket http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html |
| 15:26 | dnolen | scriptor: nope, help welcome |
| 15:26 | scriptor | dnolen: where would I start? |
| 15:27 | dnolen | scriptor: read up on SourceMap v3, once you understand the format it's pretty clear what needs to be done. |
| 15:27 | dnolen | scriptor: VLQ64 encode/decode already in a branch, so that part is done |
| 15:28 | dnolen | scriptor: but we need to write the code that can actually decipher a source map as well as generate one. |
| 15:29 | scriptor | where is the sourcemap project located? This/ http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ |
| 15:29 | jcromartie | I love it when someone gets mad at me for not telling them something that I googled |
| 15:30 | dnolen | scriptor: that's the goto high level explanation, also links to the Google doc describing it. |
| 15:31 | dnolen | scriptor: another good reference is Mozilla's JS implementation, which also linked to. |
| 15:32 | jcromartie | hm, how the heck would I access this interface from Clojure http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html |
| 15:33 | jcromartie | ah |
| 15:33 | jcromartie | http://blog.jayfields.com/2011/01/clojure-using-java-inner-classes.html |
| 15:33 | amalloy | dnolen: i noticed that != doesn't seem to have the same "descend into lists" behavior that == does: https://gist.github.com/3042234 - is there a reason this isn't possible, or is otherwise a bad idea? (i think i'm still using != too much, but i was surprised this doesn't do what i expected) |
| 15:35 | dnolen | amalloy: what is suprising you there? |
| 15:36 | amalloy | dnolen: i thought that x would fail to unify with [1 d], because c is 1 and i said x is not [c d] |
| 15:37 | amalloy | if i'd said (== x [c d]), then a and b would be in lockstep with c and b, respectively; but using != they seem to be entirely unconnected |
| 15:37 | dnolen | amalloy: ? |
| 15:38 | amalloy | dnolen: i'll rephrase: i expected (!= x [1 d]) to mean: "x is not a two-element list whose first element is 1" |
| 15:38 | dnolen | amalloy: you say that (== x [a b]), then you unify a & c with 1, so (== x [1 b]), (!= x [1 d]) doesn't say anything - b has no value, nor d. |
| 15:38 | dnolen | amalloy: yeah that's not how disequality works. |
| 15:39 | amalloy | right. i've figured that much out, i was wondering why |
| 15:39 | dnolen | amalloy: != just means two terms should never unify, that's it. nothing more. |
| 15:40 | dnolen | amalloy: if you want your behavior you have to use firsto + != |
| 15:40 | amalloy | *nod* |
| 15:40 | amalloy | okay, thanks. i'll come back to this when i understand more about the mechanics of unification |
| 15:40 | amalloy | (or not, since most of the time when i use != it's a mistake) |
| 15:41 | dnolen | amalloy: != is very useful - it's kind of a limited form of negation. |
| 15:41 | dnolen | amalloy: it really helps with conde where you want the clauses to be non-overlapping w/o resorting to cut (conda/u) |
| 15:42 | dnolen | otherwise all clauses get tried - which may not be what you want. |
| 15:43 | amalloy | yeah. actually, do you have a moment to look at http://stackoverflow.com/questions/11256242/solving-dinesmans-multiple-dwelling-example-using-clojures-core-logic-core-mat/11280559#11280559 ? my first implementation used conda and != in not-adjacento, and then i realized that was causing problems so i went back to conde and == |
| 15:44 | amalloy | specifically (not-adjacento x y l) is supposed to say "x and y are not next to each other in the list l", but i couldn't get that to work in a purely relational way, so i backed off to "x and y are both in l, separated by a gap of at least one" |
| 15:49 | dnolen | amalloy: looking |
| 15:56 | ipostelnik | what's the difference between (next) and (rest)? |
| 15:56 | gfredericks | expressing negatives is pretty hard :( |
| 15:56 | amalloy | &((juxt rest next) [1]) |
| 15:56 | lazybot | ⇒ [() nil] |
| 15:58 | gfredericks | amalloy: x and y are from a finite domain? |
| 15:59 | gfredericks | maybe I should read the SO thing first |
| 15:59 | amalloy | gfredericks: in not-adjacento? in my first draft they were and it didn't really work; i think the current version works for any x, y, l |
| 16:01 | gfredericks | this is assuming x and y occur exactly once? |
| 16:01 | gfredericks | man I like the vector syntax there; I've never seen that done |
| 16:02 | amalloy | currently (not-adjacento 1 2 [1 1 2]) succeeds, because the first 1 is not adjacent to the 2 |
| 16:02 | amalloy | gfredericks: what vector syntax? |
| 16:02 | uvtc | ipostelnik, for one thing, compare the output of `(next [1])` and `(rest [1])`. |
| 16:02 | gfredericks | all my code is a pile of parens |
| 16:02 | gfredericks | (conde [(...) (...)]) instead of (conde ((...) (...))) |
| 16:02 | amalloy | i didn't even know parens were an option |
| 16:03 | gfredericks | and vice versa |
| 16:04 | ignacio | is anyone deloying a ring app as a WAR file? |
| 16:04 | gfredericks | I've done that before I think |
| 16:04 | gfredericks | but not currently |
| 16:04 | ignacio | I just have a question about resources in the file |
| 16:04 | gfredericks | yes? |
| 16:04 | clojurebot | yes is is |
| 16:05 | TimMc | clojurebot: forget yes |is| is |
| 16:05 | clojurebot | I forgot that yes is is |
| 16:05 | ignacio | i'm looking to preproces some of the files in resources :) |
| 16:05 | ignacio | i'm looking to preproces some of the files in resources |
| 16:05 | gfredericks | clojurebot: yes |isn't| is |
| 16:05 | clojurebot | Roger. |
| 16:05 | TimMc | What have you done?! |
| 16:05 | gfredericks | ignacio: at build-time? |
| 16:05 | ignacio | and am going to copy the code out of ring.util.response/resource-response |
| 16:05 | Raynes | TimMc: It just occurred to me that I'm an idiot. |
| 16:05 | ignacio | actually, it can be at deploy time |
| 16:05 | ignacio | either. |
| 16:05 | ignacio | but not at request time |
| 16:06 | gfredericks | ignacio: so a leiningen hook would be appropriate? |
| 16:06 | ignacio | (where i have a "servlet context" or some such) |
| 16:06 | Raynes | TimMc: You want to 'safe-require' a file. You can't do that with 'require'. You want to load the file yourself, pumping the code through a sandbox, right? |
| 16:06 | gfredericks | clojurebot: yes? |
| 16:06 | clojurebot | yes isn't is |
| 16:06 | Raynes | TimMc: You'll have to write your own thingy for that. Sorry for being so dense. |
| 16:06 | amalloy | clojurebot: forget everything, man. it's all too difficult |
| 16:06 | clojurebot | RickInGA: of course :-) *everything* is in Clojure |
| 16:06 | ignacio | well, |
| 16:06 | fenton1 | technomancy: Phil, what was the darker color theme you use for emacs again? |
| 16:07 | ignacio | @gfredericks: well, a leiningen hook wouldn't be totally appropriate, because i need access to the file contents when serving a response |
| 16:07 | TimMc | Raynes: I just want to load an entire namespace that someone hands me (as file, inputstream DB field, etc) and then safely call fns that are in that ns. |
| 16:07 | gfredericks | ignacio: pre-processed or post-processed? |
| 16:07 | ignacio | (eg: imagine that i want to minify JS and then include it directly in the body of hte returned html) |
| 16:07 | Raynes | TimMc: Right, but you can't safely call a fn loaded with require unless you know it is safe. |
| 16:07 | gfredericks | ignacio: I'm not sure why hooks aren't appropriate; in the hook, muck with your resources directory until you have it like you like it |
| 16:08 | Raynes | TimMc: You have to look at the defns first before you load them and not even let them load of they aren't safe. |
| 16:08 | amalloy | fenton1: i use tty-dark, if you want high-contrast really-dark |
| 16:08 | Raynes | clojail can't look inside of functions. |
| 16:08 | ignacio | gfredericks: then read the file using servlet-context? |
| 16:08 | ignacio | would that be the preferred way? |
| 16:08 | fenton1 | amalloy: thx, i'll try that.... |
| 16:08 | gfredericks | ignacio: I dunno, however you read resources |
| 16:08 | TimMc | Raynes: My outer code isn't going to try to use an actual :require block or anything, I'm speaking in analogy. |
| 16:08 | gfredericks | ignacio: your app shouldn't have to care if the file was there before deploy-time or not |
| 16:09 | technomancy | fenton1: I use monokai and zenburn |
| 16:09 | ignacio | right, that's what i'm looking for: it seems that ring.util.response/resource-response will do exactly what i want, but i just want to verify that there's no security issue there |
| 16:09 | TimMc | Raynes: 1) Someone submits a .clj file 2) I load it into a sandbox (which might reject it), 3) I call a fn in that sandbox and get the results back. |
| 16:10 | Raynes | TimMc: Cool. That will work fine for you. |
| 16:10 | TimMc | sweet |
| 16:10 | Raynes | TimMc: If you write a safe-require function, send me a pull request and I'll put in clojail. |
| 16:10 | foxdonut | technomancy: is it molokai or is there a different one called monokai? |
| 16:11 | fenton1 | technomancy: thank you!!! |
| 16:11 | fenton1 | foxdonut: its monokai |
| 16:11 | technomancy | foxdonut: it's this one: http://marmalade-repo.org/packages/monokai-theme |
| 16:11 | TimMc | Raynes: Could I keep the sandboxed ns around and periodically make timeout-limited calls into it? |
| 16:12 | Raynes | TimMc: Not sure I understand the question. |
| 16:12 | foxdonut | technomancy, fenton1: got it. sorry about the confusion. I didn't realize you were talking emacs. molokai is monokai port to vim :) |
| 16:13 | fenton1 | foxdonut: ah ok. |
| 16:13 | foxdonut | fenton1: definitely one of my faves. |
| 16:14 | TimMc | Raynes: The .clj file (containing one namespace, as usual) represents a user-submitted bot that will compete against others. I'd like to load it up and then call it repeatedly over time with a game-state object so that it can make moves. |
| 16:15 | Raynes | TimMc: What if two people use the same namespace? |
| 16:15 | TimMc | ...and I want a timeout on each of those calls. I'll have to set up my own timeouts for those calls, yes? |
| 16:15 | nicholasf | hi, I'm working through some clojure basics (with SICPs and 'Clojure Programming'). I have my lein repl open and am trying to define an anonymous function and pass it a number: https://gist.github.com/ada8e7fb1454afa8ee53 |
| 16:15 | nicholasf | shouldnt this work? |
| 16:15 | amalloy | &((fn [x] (+ 10 x)) 8) |
| 16:15 | lazybot | ⇒ 18 |
| 16:15 | Raynes | TimMc: The sandbox will timeout for you. |
| 16:16 | Raynes | But still, I'd be worried about namespaces. |
| 16:16 | nicholasf | amalloy: ok thanks |
| 16:16 | TimMc | Oh, hmmm. |
| 16:16 | amalloy | nicholasf: sure should work in the repl, yes |
| 16:16 | amalloy | the & is just asking the bot to eval it for us, not part of clojure syntax |
| 16:16 | nicholasf | ok it's not working in my repl, so that must be what's wrong here |
| 16:16 | uvtc | nicholasf, Are you using Leiningen to create a project and start a repl in it? |
| 16:16 | nicholasf | yeh, it's definitely my lein repl |
| 16:17 | fenton1 | foxdonut: yeah, i liked it...phil's got good taste ;) |
| 16:17 | nicholasf | amalloy uvtc I just tested it in my clj repl (homebrew repl project) and it worked |
| 16:17 | nicholasf | so I was assuming that 'lein repl' worked anywhere I typed it, like a regular repl |
| 16:17 | amalloy | nicholasf: i wonder if you've accidentally redefined the 'fn macro |
| 16:17 | amalloy | since i can't think of any other way you'd get this behavior |
| 16:17 | TimMc | def fn |
| 16:17 | nicholasf | amalloy: I think Ive just gone to any directory and used lein repl, and it hasnt found important class files in the background |
| 16:17 | TimMc | That might do it. |
| 16:18 | nicholasf | k cheers guys |
| 16:18 | amalloy | nicholasf: i don't think so. you'd get failures long before this, if something this fundamental were broken |
| 16:18 | uvtc | nicholasf, right. You need to run it from your top-level project dir. |
| 16:18 | TimMc | lein repl will work anywhere, it just might give you a random version of clojure. |
| 16:18 | amalloy | are you guys all crazy? lein repl works anywhere |
| 16:18 | foxdonut | fenton1: no doubt he does. there is also Tomorrow that you might find nice. |
| 16:18 | nicholasf | amalloy: I think lein even requires clojure for you, so if I'm opening lein in a dir without clojure, it wont be able to evaluate basic stuff |
| 16:19 | amalloy | nicholasf: humor me: if you just type (without quotes) "fn" into the broken-looking repl, what do you get? |
| 16:19 | uvtc | amalloy, Whoops. I suppose so. I didn't know you could just run `lein repl` in any old directory. |
| 16:19 | TimMc | nicholasf: Run lein repl anywhere and execute this: *clojure-version* |
| 16:19 | nicholasf | amalloy: https://gist.github.com/4616b766bb428a4d4d0b |
| 16:20 | amalloy | but i bet in that repl your ((fn [x] (+ x 10)) 8) construct works |
| 16:20 | nicholasf | user=> *clojure-version* |
| 16:20 | nicholasf | {:major 1, :minor 2, :incremental 1, :qualifier ""} |
| 16:20 | fenton1 | foxdonut: I'm on the road and having trouble loading the color theme, what is it again I need to throw into my .emacs? |
| 16:20 | nicholasf | it only works if Im doing it in a lein project directory (that I've run deps in) |
| 16:22 | uvtc | nicholasf, which version of lein are you using? Run: `lein version` |
| 16:22 | nicholasf | Leiningen 1.7.1 on Java 1.7.0_05 Java HotSpot(TM) 64-Bit Server VM |
| 16:22 | foxdonut | fenton1: sorry friend, I don't know :( I use vim |
| 16:23 | raek | nicholasf: is that paste *exactly* what you typed? |
| 16:24 | nicholasf | raek: yeh |
| 16:24 | foxdonut | fenton1: source is here if it helps: https://github.com/chriskempson/tomorrow-theme |
| 16:24 | fenton1 | foxdonut: ok, i'll keep looking...I look into tomorrow after i get *any* theme working! |
| 16:25 | Raynes | What theme? |
| 16:25 | raek | nicholasf: and if you try running `lein repl` outside a project (which is supposed to work), does the problem still occur? |
| 16:25 | Raynes | tomorrow? |
| 16:25 | Raynes | If you're using Emacs 24, just put the latest tomorrow themes somewhere and then (add-to-list 'custom-theme-load-path "/path/to/dir/with/themes") and then (load-theme 'that-theme t). For tomorrow, it'd be (load-theme 'tomorrow-night) or whatever tomorrow varient you want. |
| 16:25 | Raynes | fenton1: ^ |
| 16:25 | nicholasf | raek: that is what I'm doing in the gist. If I run lein repl in a lein project, fn won't have that problem |
| 16:26 | nicholasf | raek: yeh, I think I picked up using 'lein repl' from something written in Clojure Programming (OReilly) |
| 16:26 | raek | nicholasf: and that happens every time? |
| 16:26 | nicholasf | but it's obviously stopped working how people think it should |
| 16:26 | nicholasf | raek: each time so far, yes :) |
| 16:27 | foxdonut | we need an abbrev. for Clojure Programming (O'Reilly) |
| 16:27 | uvtc | foxdonut : CP ? |
| 16:27 | TimMc | nicholasf: At times like this I tend to blow away ~/.m2/repository |
| 16:27 | raek | yes, lein repl outsude a project is one of the most common ways to start a "just clojure" repl |
| 16:27 | TimMc | foxdonut: CPOR? |
| 16:27 | nicholasf | TimMc: hrm ok |
| 16:28 | fenton1 | Raynes: thx i'll try that. |
| 16:28 | TimMc | Maybe you have a corrupted Clojure 1.2.1 binary. |
| 16:28 | nicholasf | like I said, all of these tools are new to me, but this felt wrong |
| 16:28 | uvtc | nicholasf, I go a step further than TimMc ; `rm -fr ~/.lein` `rm -fr ~/.m2` `rm ~/bin/lein`, then download the latest lein and start over. :) |
| 16:28 | nicholasf | hang on, let me try using lein repl on my mac air (currently on another machine) |
| 16:28 | foxdonut | uvtc, TimMc: I was thinking one of those, yeah.. alongside JoC, CiA, PC |
| 16:28 | nicholasf | ok, Ive installed lein on two machines in the last week |
| 16:29 | nicholasf | they are both behaving the same way |
| 16:29 | raek | this is very, very odd |
| 16:29 | TimMc | nicholasf: Is your gist a *precise* copy of your REPL, or did you retype anything? |
| 16:30 | foxdonut | JoC, CiA, PCAP, PCPP, CPOR |
| 16:30 | nicholasf | TimMc: it's a precise copy |
| 16:30 | raek | nicholasf: is there something else that doesn't work, for instance let expressions? |
| 16:30 | nicholasf | ive programmed a bunch of other languages, I know about the importance of sharing info |
| 16:30 | nicholasf | raek: I guess let would be broken too, if fn is |
| 16:30 | TimMc | nicholasf: How about arithmetic expressions like (+ 2 3)? |
| 16:31 | nicholasf | https://gist.github.com/357cf99cdc5982fc0015 TimMc and raek |
| 16:31 | TimMc | nicholasf: 'let and 'do are no surprise |
| 16:31 | TimMc | Try (let [x 5] (+ x 4)) and (do 1 2 3) |
| 16:32 | nicholasf | https://gist.github.com/75eee8531281f8b84700 they work |
| 16:33 | nicholasf | altho that confuses me a little |
| 16:33 | nicholasf | cos if let works I would have assumed fn would too |
| 16:33 | TimMc | The compiler may handle them at different levels. |
| 16:34 | nicholasf | yeh ok, I guess special forms arent all equal |
| 16:36 | raek | this is very odd. I can't reproduce that with my lein 1.7.1 / clojure 1.2.1 repl |
| 16:36 | ppppaul | anyone here using clojurscript and couchapps? |
| 16:36 | nicholasf | raek: you're cding into a dir that doesnt have a lein project, right? |
| 16:37 | raek | nicholasf: yes |
| 16:37 | raek | nicholasf: what does `sha1sum ~/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar` return on your computer? |
| 16:37 | nicholasf | raek: that is strange |
| 16:37 | raek | we should be using the same clojure jar |
| 16:38 | nicholasf | that's not available via brew |
| 16:38 | nicholasf | andromeda:~ nicholas$ ls -ltrh ~/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar |
| 16:38 | nicholasf | -rw-r--r-- 1 nicholas staff 3.1M 28 Jun 10:34 /Users/nicholas/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar |
| 16:39 | nicholasf | but I'm using clojure-1.3.0 in my lein projects |
| 16:39 | raek | nicholasf: try replacing "sha1sum" with "openssl sha1" |
| 16:39 | nicholasf | (that's the jar it pulls down) |
| 16:39 | nicholasf | ok |
| 16:40 | raek | I get be088d20c078ce48d42afba05984f1ef7c02142b here |
| 16:40 | nicholasf | SHA1(/Users/nicholas/.m2/repository/org/clojure/clojure/1.2.1/clojure-1.2.1.jar)= be088d20c078ce48d42afba05984f1ef7c02142b |
| 16:40 | TimMc | nicholasf: When not run from a project, lein uses its own Clojure dependency for the REPL environment. In this case, 1.2.1. |
| 16:40 | nicholasf | TimMc: ok thanks |
| 16:41 | raek | nicholasf: and the same thing happens if you write a similar expression, like ((fn [y] (+ y 5)) 3) ? |
| 16:41 | brainproxy | anyone using visionmedia's superagent lib in conjunction w/ their cljs projects? |
| 16:44 | nicholasf | raek: https://gist.github.com/7f52d9573761da1e9e0e |
| 16:44 | nicholasf | that's interesting |
| 16:44 | raek | now that's expeced behavior |
| 16:44 | raek | I wonder why it doesn't like your xs... :) |
| 16:45 | nicholasf | hrm |
| 16:45 | wingy | what does the # in the first line mean: https://gist.github.com/3042912 |
| 16:45 | raek | nicholasf: is your OS set to a language that uses right-to-left directioned writing, like Arabic or Hebrew? |
| 16:45 | nicholasf | wait something is different |
| 16:45 | nicholasf | my original example (which wasnt working) now passes |
| 16:46 | TimMc | nicholasf: Try *clojure-version* in that REPL. |
| 16:46 | nicholasf | raek: nope |
| 16:46 | nicholasf | user=> *clojure-version* |
| 16:46 | nicholasf | {:major 1, :minor 2, :incremental 1, :qualifier ""} |
| 16:46 | TimMc | wingy: That's the new reader literal datatype something something syntax. |
| 16:47 | nicholasf | something bizarre is happening |
| 16:47 | raek | indeed |
| 16:47 | TimMc | I blame leap-seconds. |
| 16:47 | nicholasf | haha |
| 16:47 | raek | I blame invisible characters |
| 16:47 | nicholasf | hrmn |
| 16:47 | TimMc | indeed |
| 16:47 | amalloy | oh, that's an interesting possibility |
| 16:47 | amalloy | though i still think his original broken repl had just redefined fn accidentally |
| 16:47 | nicholasf | it must be something like that |
| 16:48 | TimMc | amalloy: But it failed on two machines. |
| 16:48 | nicholasf | the function I tested with just works on my mac air |
| 16:48 | nicholasf | no, what failed on the mac air was me writing 'fn' |
| 16:48 | TimMc | Ah! Yes, that would. |
| 16:48 | nicholasf | I thought that was an adequate test |
| 16:48 | nicholasf | so I'm sorry for wasting people's time |
| 16:48 | amalloy | &(let [fn inc] ((fn [x] (+ 1 x)) 2)) |
| 16:48 | lazybot | ⇒ 3 |
| 16:48 | amalloy | ,(let [fn inc] ((fn [x] (+ 1 x)) 2)) |
| 16:48 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:48 | amalloy | there we go. man, i need to fix that issue in clojail |
| 16:48 | raek | nicholasf: 'fn' is hardcoded into the compiler, but only at "call positsion" |
| 16:49 | amalloy | raek: no it isn't |
| 16:49 | TimMc | fn* is |
| 16:49 | raek | ah, sorry |
| 16:49 | amalloy | fn* is; fn is just a regular macro |
| 16:49 | raek | it's a macro, yeash |
| 16:49 | nicholasf | ah ok, fn is a macro using let and do, right? |
| 16:49 | TimMc | More complicated. |
| 16:49 | amalloy | well, using let and fn* |
| 16:49 | nicholasf | ok |
| 16:49 | TimMc | nicholasf: (source fn) in your repl |
| 16:50 | raek | no, it expands to fn*, which is like fn but without destructuring, IIRC |
| 16:50 | nicholasf | ha cool TimMc |
| 16:50 | nicholasf | that is *really* cool |
| 16:52 | jeremyheiler | ,(interleave [1 2 3] ['a 'b]) ; is there a nice way to have the 3 added to the end? |
| 16:52 | clojurebot | (1 a 2 b) |
| 16:53 | jeremyheiler | i mean, have the 3 be part of the lazy sequence. |
| 16:53 | TimMc | jeremyheiler: An interleave-all, in other words? |
| 16:53 | jeremyheiler | yeah |
| 16:59 | jeremyheiler | I know I can hack on the interleave implementation, but was just wondering if there's another way. |
| 17:04 | S11001001 | jeremyheiler: do you know which list is shorter? |
| 17:05 | jeremyheiler | Yes |
| 17:05 | S11001001 | what happens for [1 2 3 4] and ['a 'b]? |
| 17:06 | jeremyheiler | For my purposes, I would be ok with (1 a 2 b 3 4) but that is not an expected use case. I really only care about the second list being one element smaller. |
| 17:07 | S11001001 | ,(rest (interleave (cons nil ['a 'b]) [1 2 3 4])) |
| 17:07 | clojurebot | (1 a 2 b 3) |
| 17:10 | raek | ,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleve a b))) |
| 17:10 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: interleve in this context, compiling:(NO_SOURCE_PATH:0)> |
| 17:10 | raek | ,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleave a b))) |
| 17:10 | clojurebot | (1 a 1 b 2) |
| 17:10 | raek | ,(let [a ['a 'b] b [1 2 3]] (cons (first b) (interleave a (rest b)))) |
| 17:10 | clojurebot | (1 a 2 b 3) |
| 17:10 | raek | :) |
| 17:11 | jeremyheiler | nice, i guess that last use-case makes it that much simpler :-P |
| 17:11 | jeremyheiler | thank you both |
| 17:12 | solussd_ | is it possible to add custom json encoders for use with noir.response/json ? |
| 17:13 | TimMc | jeremyheiler: Will either list ever be of length 1? |
| 17:16 | wingy | TimMc: where can i read about it? |
| 17:16 | jeremyheiler | TimMc: Yeah, but never both at the same time. |
| 17:20 | jeremyheiler | TimMc: It seems raek and S11001001 solutions work for my current problem. but a proper interleave-all would be nice addition to core, i think. |
| 17:21 | nDuff | dnolen: Should I file a ticket against zi for that classpath issue (being unable to find clojure.plexus.compiler.impl)? |
| 17:21 | raek | (defn alternate [long short] (lazy-seq (when (seq long) (cons (first long) (alternate short (rest long)))))) |
| 17:22 | raek | jeremyheiler: ^ |
| 17:22 | S11001001 | jeremyheiler: not useful enough |
| 17:22 | nDuff | err |
| 17:22 | raek | another solution I came up with once |
| 17:22 | hugod | nDuff: if you meant me, then yes please - sorry haven't got to it yet |
| 17:22 | nDuff | indeed. |
| 17:23 | raek | for some reason that old gist 404s for me... |
| 17:24 | jeremyheiler | raek, nice, i like it |
| 17:27 | solussd_ | dakrone: you there? :) |
| 17:27 | dakrone | solussd_: yes |
| 17:29 | solussd_ | dakrone: excellent… quick cheshire question: so I'm trying to add a json encoder for org.bson.types.ObjectId, did this: (add-encoder org.bson.types.ObjectId (fn [o json-generator] (.writeString json-generator (str o)))), but calling (generate-string (org.bson.types.ObjectId.)) still throws a JsonGenerationException. Am I missing something? |
| 17:30 | dakrone | solussd_: and you're sure you're using cheshire.custom/generate-string instead of cheshire.core/generate-string? |
| 17:31 | solussd_ | dakrone: ah, I am not. :) I'm trying to add an encoder so noir.reponse/json will encode ObjectIds… looks like this wont help me then. :/ |
| 17:31 | dakrone | noir should support being able to override the json encode/decode methods with whatever you'd like |
| 17:31 | dakrone | too bad it doesn't |
| 17:32 | solussd_ | (it does work with cheshire.custom/generate-strin) |
| 17:32 | solussd_ | yes.. too bad. :/ |
| 17:32 | dakrone | maybe open an issue with the noir project and see if they have any way to work around it? |
| 17:32 | TimMc | wingy: See 2.1: https://github.com/clojure/clojure/blob/master/changes.md |
| 17:33 | solussd_ | k. thanks |
| 17:43 | hugod | nDuff: you'll need mvn 3 for zi |
| 17:56 | nDuff | hugod: ...ahh. |
| 17:57 | dnolen | amalloy: ping |
| 17:57 | amalloy | dnolen: pong |
| 17:58 | dnolen | amalloy: heh that problem was annoying enough that I added permuteo :) |
| 17:58 | amalloy | hah |
| 18:00 | dnolen | amalloy: some of those answers on Rosetta are epically convoluted |
| 18:00 | dnolen | amalloy: http://gist.github.com/3043632 |
| 18:00 | dnolen | amalloy: based on core.logic master |
| 18:00 | talios | 'lo hugod |
| 18:01 | talios | anyone using maven should be using maven 3 by now anyway. |
| 18:01 | nDuff | ...looks like Atlassian's plugin development toolchain is rather tied to Maven 2. |
| 18:01 | dnolen | amalloy: the only subtle one is not-above1o, this is a bit tricky because I'm trying to be pure, no cut. |
| 18:01 | wingy | seems that clojure 1.4 has some features added for datomic |
| 18:02 | wingy | uuid, instant and reader literals |
| 18:02 | technomancy | fact: no one outside datomic has ever cared about uuid reader literals |
| 18:03 | wingy | yeah thats why they added it in 1.4? |
| 18:05 | wingy | i mean that datomic needed uuid literals and added it to clj 1.4 |
| 18:07 | amalloy | dnolen: i haven't really tried to learn the defne and/or matching syntax that you're using, yet. certainly looks like a nice shorthand for piles of conso's |
| 18:08 | dnolen | amalloy: cleaned up the gist a bit. |
| 18:08 | dnolen | amalloy: yes conso and raw conde usage drives me insane now :) |
| 18:09 | amalloy | is there a reason you went with != for not-above1o, instead of taking the approach in my not-adjacento? it seems like if the list elements are unique, then just asserting that they're separated by at least one is equivalent to asserting that they're not next to each other with != |
| 18:11 | nDuff | hugod: Hmm. After moving to Maven 3, I'm not getting that issue -- but I'm also not getting line numbers or useful error messages on compile errors; they're all of the form file.clj:[0,0] null |
| 18:12 | dnolen | amalloy: yes that approach seems just as good, but perhaps this shows how you can use != and non-overlapping clauses to accomplish the same thing. |
| 18:13 | dnolen | amalloy: note in my not-above1o it's only possible for one clause to ever succeed. |
| 18:15 | dnolen | amalloy: same thing with aboveo, using != will be more efficient than using rembero. |
| 18:15 | amalloy | *nod* because you turned not-adjacento into two separate applications of aboveo |
| 18:15 | dnolen | amalloy: yeah |
| 18:17 | dnolen | amalloy: again your not-adjacent approach seems good in this case. items are unique and membero after a gap. |
| 18:17 | jcromartie | there is only one thing that I can think of when people discuss core.logic http://wonkette.com/assets/resources/2007/12/awesomeo.jpg |
| 18:17 | amalloy | okay. i think performance concerns are a little beyond me for now, so i'll just file that away |
| 18:18 | technomancy | jcromartie: nice! |
| 18:19 | brehaut | thats something clojurebot should learn |
| 18:19 | dnolen | amalloy: thanks for bringing it up. your run* looked solid ... reads like the puzzle :) |
| 18:19 | dnolen | brehaut: haha |
| 18:20 | brehaut | (historical evidence suggests that i am not the right person to be teaching clojurebot facts however) |
| 18:20 | amalloy | dnolen: so i'm not sure i understand the implementations of rembero and permuteo you committed (aside from me not understanding defne syntax). does your rembero remove *all* instances of x? if so, permuteo will have surprising results |
| 18:21 | amalloy | i wrote it to remove a single instance of x, so that, for example, (permuteo [1 2 2] [2 1 2]) succeeds |
| 18:22 | amalloy | but if you're removing all instances of x it seems to me that (permuteo [1 2 2] [1 2]) will also succeed |
| 18:22 | dnolen | amalloy: it doesn't not remove all occurrences |
| 18:22 | amalloy | okay. i'll just squint at the defne some more, then |
| 18:23 | dnolen | amalloy: this is what I mean by non-overlapping. either we found it & we're done - or we didn't find it (guaranteed by !=) and we keep looking. |
| 18:23 | dnolen | amalloy: this is where Prolog used to cause a lot of trouble, no disequality operator. I forget which Prolog (II ? III?) got it |
| 18:24 | amalloy | dnolen: so your rembero removes specifically the first instance of x? |
| 18:24 | dnolen | amalloy: yes |
| 18:26 | amalloy | and if you removed the != assertion it would still work, but be willing to remove any instance of x. i wrote it to remove any instance of x because i imagined that was useful for permuteo, but i suppose it actually doesn't need to be that general |
| 18:28 | dnolen | amalloy: that might be useful - hard to say w/o people sending me to fun logic puzzles on SO ;) |
| 18:28 | dnolen | amalloy: permuteo is definitely useful tho - that should have been there. |
| 18:28 | amalloy | dnolen: i'm on target though, right? != is what makes it remove exactly the first instance, and do so quickly; if you removed it it would remove any instance, more slowly? |
| 18:31 | dnolen | amalloy: yes |
| 18:31 | hugod | talios: hi! |
| 18:31 | dnolen | amalloy: if != fails if unification succeeds. |
| 18:31 | dnolen | er I mean "!= fails if unification succeeds" |
| 18:31 | amalloy | cool. glad to see permuteo and rembero added, even if i didn't write them; i feel like i've impacted core.logic now :) |
| 18:32 | dnolen | amalloy: you have! thanks! |
| 18:32 | hugod | nDuff: mm, that sounds strange - any chance of adding a minimal failing java file to the issue |
| 18:32 | wolgo | when destructuring a map to bind I see the following in a clojure book: (let [{k :unknown x :a :or {k 50}} m] -rest of the code here- |
| 18:32 | wolgo | what is :unknown doing? |
| 18:32 | wolgo | I see that the :a value gets assigned to x, that is fine |
| 18:33 | amalloy | ,(macroexpand-1 '(let [{k :unknown x :a :or {k 50}} m] foo)) |
| 18:33 | clojurebot | (let* [map__30 m map__30 (if (clojure.core/seq? map__30) (clojure.core/apply clojure.core/hash-map map__30) map__30) k ...] foo) |
| 18:33 | amalloy | &(macroexpand-1 '(let [{k :unknown x :a :or {k 50}} m] foo)) |
| 18:33 | lazybot | ⇒ (let* [map__10199 m map__10199 (if (clojure.core/seq? map__10199) (clojure.core/apply clojure.core/hash-map map__10199) map__10199) k (clojure.core/get map__10199 :unknown 50) x (clojure.core/get map__10199 :a)] foo) |
| 18:34 | amalloy | wolgo: you can see that this expands to (let [k (get m :unknown 50)])? |
| 18:34 | wolgo | let me take a tias break. I didn't try enough stuff to teach myself. Sorry |
| 18:35 | wolgo | amalloy: thanks, I do see that |
| 18:40 | wolgo | okay so :unknown is not a special argument |
| 18:40 | wolgo | I understand |
| 18:41 | wolgo | clojure is cool man |
| 18:41 | wolgo | lots of neat ideas. |
| 18:42 | locojay | hi i m new to cljs : is it a big deal to mix js and cljs (most in cljs via closure opt and some part in js like d3 charts...) |
| 18:42 | ohpauleez | locojay: You can use c2 for the charts (a d3-like library) |
| 18:43 | ohpauleez | and you can mix JS as you need |
| 18:43 | ohpauleez | there's (js* …) for that very purpose |
| 18:43 | ohpauleez | but you'll soon find out that JS offers you little once you're embedded in CLJS |
| 18:47 | locojay | yeah i ve seen c2 but i have lots of animation's ... I could reference d3 and use (js* -) as you mentioned but since the code is already their i don't think i will refactor to cljs for the time beeing. mixing parts in cljs and js seems like a good approach to me until i get more familiar with cljs |
| 18:48 | ohpauleez | locojay: talk to lynaghk - I think you can pull off all the animations you need |
| 18:49 | ohpauleez | and you should prefer CSS animations and effects when possible |
| 18:50 | locojay | ohpauleez: thanks will do (looking for thing's like brush... will send mail to userlist) |
| 18:51 | ohpauleez | np |
| 18:54 | emezeske | locojay: FYI you should probably never be using (js* ...) |
| 18:55 | emezeske | locojay: I do a ton of interop and it has never been necessary to use it |
| 19:16 | wingy | upsert = UPdate + inSERT :) |
| 19:16 | wingy | first time i heard that |
| 19:22 | emezeske | Anyone else using clojurescript 0.0-1424? I am seeing (:dne {} 42) return nil instead of 42... :( |
| 19:24 | wingy | why is datomic using a dash as in -10000002 in the id nr: {:db/id #db/id[:db.part/user -1000002], :neighborhood/name "Capitol Hill", |
| 19:26 | wingy | http://datomic.com/company/resources/transactions |
| 19:26 | Bronsa | emezeske: http://dev.clojure.org/jira/browse/CLJS-330 i think this issue refers to that problem |
| 19:26 | emezeske | Bronsa: thanks! |
| 19:27 | emezeske | Bronsa: That's a pretty major bug to slip into a release O_o |
| 19:27 | Bronsa | yeah |
| 19:28 | Bronsa | but clojurescript is still alpha i think |
| 19:28 | emezeske | alpha != super obvious regressions should go into tagged releases |
| 19:45 | melipone | I am using math.numeric-tower and when I do (ceil (/ 4 5)) I get 1N. What does the N mean? |
| 19:45 | hiredman | ,(type 1N) |
| 19:45 | clojurebot | clojure.lang.BigInt |
| 19:46 | melipone | hiredman: thanks! |
| 19:46 | sjl | anyone know what incantation I need in :repositories in my Leiningen map to get one of these suckers to work? https://repository.sonatype.org/index.html#nexus-search;quick~lanterna |
| 19:46 | melipone | Still, why is it a BigInt? |
| 19:57 | dnolen | ,(.numerator (/ 4 5)) |
| 19:57 | clojurebot | 4 |
| 19:57 | dnolen | ,(inc' (.numerator (/ 4 5))) |
| 19:57 | clojurebot | 5N |
| 19:57 | dnolen | (doc inc') |
| 19:57 | clojurebot | "([x]); Returns a number one greater than num. Supports arbitrary precision. See also: inc" |
| 19:58 | dnolen | melipone: ^ |
| 19:59 | dnolen | melipone: under the hood it uses a primitive long until it no longer can - does that address your concern? |
| 20:10 | gfredericks | ,(-> (iterate #(*' 2 %) 7) (nth 383) type) |
| 20:10 | clojurebot | clojure.lang.BigInt |
| 20:15 | gfredericks | what are "reify" and "this-as" in cljs? |
| 20:15 | gfredericks | (is there some better way to find that out than asking here?) |
| 20:15 | dnolen | ejackson's core.logic presentation is pretty nice! |
| 20:16 | dnolen | gfredericks: reify is the same as Clojure's |
| 20:16 | dnolen | gfredericks: this-as is a interop thing. |
| 20:16 | gfredericks | yeah I shoulda checked what clojure's does first :) |
| 20:16 | gfredericks | dnolen: is it like (let [foo js/this] ...)? |
| 20:17 | dnolen | gfredericks: except no promise that js/this will continue to work. |
| 20:18 | gfredericks | oh I didn't even know if it did |
| 20:18 | dnolen | gfredericks: it probably won't, I think this always becomes this$ |
| 20:18 | gfredericks | it doesn't work in himera |
| 20:18 | gfredericks | dnolen: okay cool thx |
| 20:44 | gfredericks | weird himera behavior: () => (), ()() => nil, ()()() => (), ()()()() => nil, and apparently all nil after that |
| 20:44 | Raynes | Hah |
| 20:50 | dnolen | pretty cool http://github.com/jonase/scape/commit/51d75b11b5919a1b019d4d3288b8cc28c0ee32f5 |
| 20:54 | pdk | what i learned today: |
| 20:55 | pdk | don't dispatch a bunch of agents grinding on a search tree in parallel on your local machine |
| 20:57 | sabe | evening |
| 21:01 | sabe | I'm craking my head but I can't find a solution. Perhaps someone can help? |
| 21:01 | sabe | given this: https://gist.github.com/3044453 |
| 21:01 | sabe | how can I call "f" with ["a" "b" "c"] and an initial "context"? |
| 21:03 | dnolen | (->> 0 (fn "a") ...) doesn't work? |
| 21:03 | dnolen | sabe: ^ |
| 21:04 | sabe | hm but how can I create that call from a seq? |
| 21:04 | dnolen | neat http://code.google.com/p/lanterna/ |
| 21:04 | dnolen | sabe: what do you mean? |
| 21:05 | Raynes | dnolen: Like reduce. |
| 21:06 | sabe | dnolen: given that I have ["a" "b" "c"], how do I call f 3 times passing the result of the first call to the second one and so forth |
| 21:07 | dnolen | sabe: like Raynes said, why not reduce? |
| 21:08 | sabe | lemme try |
| 21:08 | gfredericks | ,(reduce str "teehee" ["a" "b" "c"]) |
| 21:08 | clojurebot | "teeheeabc" |
| 21:08 | sjl | dnolen: sabe: the context being the second arg is going to bite you when you try to reduce |
| 21:08 | sabe | sjl: that's exactly the problem :( |
| 21:09 | sjl | otherwise (reduce f 1 ["a" "b" "c"]) would work |
| 21:09 | gfredericks | sabe: you can wrap it in an anon fn to reverse the args |
| 21:09 | sjl | unfortunately I don't think Clojure has a flip function, but it should be trivial to write http://zvon.org/other/haskell/Outputprelude/flip_f.html |
| 21:09 | sabe | sjl: :[ ] |
| 21:09 | sabe | it works :~ you guys rock |
| 21:09 | gfredericks | I'm sure useful has it |
| 21:09 | Raynes | It actually doesn't. |
| 21:10 | gfredericks | wat |
| 21:10 | Raynes | I added it once, but amalloy didn't like my version, preferring his 20 line version that he never actually added. |
| 21:10 | gfredericks | Raynes: does it have (partial partial apply)? |
| 21:11 | sabe | thanks sjl, dnolen, Raynes, and gfredericks |
| 21:11 | amalloy | gfredericks: no, though at one point i was thinking of adding that |
| 21:11 | gfredericks | ,(let [pap (partial partial apply), + (pap +)] ((comp + range) 10)) |
| 21:11 | clojurebot | 45 |
| 21:11 | amalloy | i called it ap, not pap, personally |
| 21:11 | gfredericks | amalloy: for some reason I woke up one morning with that function in my head |
| 21:12 | gfredericks | I don't know why I called it pap. should be ppa if anything. |
| 21:12 | gfredericks | oh Partial APply was it |
| 21:12 | amalloy | right |
| 21:12 | gfredericks | but I like ap too |
| 21:12 | amalloy | i just called it ap because who cares that partial is involved in the impl |
| 21:12 | amalloy | (map (ap +) (...)) |
| 21:12 | gfredericks | yeah who cares |
| 21:13 | sjl | (defn flip [f] #(apply f (reverse %&))) ? |
| 21:14 | gfredericks | (defn flop [f] #(apply f (shuffle %&))) |
| 21:15 | brehaut | gfredericks: i believe the canonical name for that operation is PHP |
| 21:17 | gfredericks | why aren't there more newbs having trouble with macros? |
| 21:19 | amalloy | isn't the most common macro-newbie problem "help, i foolishly wrote a macro" |
| 21:19 | gfredericks | yes |
| 21:20 | sabe | give me a couple days ;) |
| 21:21 | gfredericks | &clojure.tools.macro/macrolet |
| 21:21 | lazybot | java.lang.RuntimeException: Can't take value of a macro: #'clojure.tools.macro/macrolet |
| 21:21 | gfredericks | sweet we can write macros on lazybot |
| 21:23 | sabe | danger |
| 21:23 | gfredericks | &(clojure.tools.macro/macrolet [(fark [expr] (clojure.walk/postwalk #(cond (seq? %) (vec %) (vector? %) (seq %) :else %) expr))] (fark [let (foo 12 bar 15) [+ 12 [- 15 18]]])) |
| 21:23 | lazybot | ⇒ 9 |
| 21:39 | dnolen | amalloy: fwiw, I think a cKanren dinemans solution might look something like this - https://gist.github.com/3044626, which would be close to the brevity of Haskell's solution. |
| 21:40 | amalloy | dnolen: fd is some kind of...constraints-based numbers thing? |
| 21:40 | dnolen | amalloy: yep |
| 21:40 | gfredericks | just finite domains right? |
| 21:40 | dnolen | amalloy: so no permutations, should be fast |
| 21:41 | gfredericks | dnolen: (interval 1 5) takes linear space? |
| 21:42 | dnolen | gfredericks: stores lower and upper bound. might grow as constraints run of course, but as a sequence of intervals. |
| 21:42 | dnolen | gfredericks: all this stuff is done on protocols so optimizations possible - bit vectors, discrete interval encoding trees, etc |
| 21:43 | gfredericks | dnolen: oh nice; I must misunderstand the finite domain idea then |
| 21:43 | gfredericks | i.e., why not simply all integers? |
| 21:43 | dnolen | gfredericks: what do you mean? |
| 21:44 | gfredericks | dnolen: it wouldn't support (interval -infinity +infinity) for example, would it? |
| 21:45 | Shambles_ | There was a lot of discussion about OO in history that I just see now. Few people seem to understand 'how we got there'. |
| 21:46 | Shambles_ | It makes quite a lot of sense if you consider that we started out with unstructured code, so you couldn't tell what modified a particular variable, or where the code you needed to change was. |
| 21:46 | dnolen | gfredericks: protocol waiting to happen, pretty sure unbounded intervals could work. |
| 21:46 | Shambles_ | Structured programming got the code packaged in orderly procedures, but you still couldn't figure out what modified a particular variable. |
| 21:46 | gfredericks | dnolen: oh nice; I'll stop doubting then. really looking forward to arithmetic. |
| 21:47 | dnolen | gfredericks: in fact probably a requirement for the kinds of things I'd like pred dispatch do. |
| 21:47 | Shambles_ | OO bundled the variables with the code that modified them (assuming you didn't use any public variables, which, if memory serves, Simula and Smalltalk don't allow). |
| 21:48 | Shambles_ | From the imperative programming point of view, OO really was 'easier to understand', since you didn't have to read the entire program to understand how to fix a bug. |
| 21:50 | Shambles_ | I think functional programming was its own thing. It was the first (as far as I know Lisp was the first) attempt at declarative programming. I don't think it had to do with ease of anything. |
| 21:51 | kovasb | is functional programming declarative programming? |
| 21:52 | gfredericks | I can imagine an argument that HOFs allow more declarative things |
| 21:52 | brehaut | you can do declarative programming with functional programming |
| 21:53 | Shambles_ | kovasb: It's usually lumped in that category, along with everything else that isn't (blantantly) imperative, yes. Other things that are in that category are concatenative, dataflow, and logic programming languages. |
| 21:53 | dnolen | gfredericks: well read a POPL12 paper where Scala folks got it to work, can't let them show us up or anything! |
| 21:54 | gfredericks | dnolen: did you attend that? |
| 21:55 | dnolen | gfredericks: nope |
| 21:55 | Shambles_ | kovasb: Theoretically declarative languages let you worry less about control flow. They 'figure it out' for you. In practice they either aren't much help (e.g. Fortran-like and Lisp-like languages don't tend to do anything particularly 'clever' for you), or you end up fighting them every time you want to do I/O (e.g. when doing logic programming), since the order of evaluation in I/O matters. |
| 21:56 | kovasb | I guess i think of declarative as something that possible in parts of the program |
| 21:57 | kovasb | like, you have a spec for something |
| 21:57 | kovasb | eg project.clj file |
| 21:57 | kovasb | and something else interprets that, but its pretty domain specific |
| 21:58 | kovasb | basically declarative == parameterized in this POC |
| 21:58 | kovasb | POV |
| 21:58 | Shambles_ | kovasb: I think the problem is people really need to be able to use different language designs for different purposes. I/O hurts less in imperative style than anything else. GUI's probably should be built out of some weird mishmash of OO and dataflow. Functional and logic programming are probably handy where you'd want to do fancy math, including symbolic math, or proofs and planning and the like. |
| 21:59 | Shambles_ | kovasb: Of course Lisp lets you embed domain-specific languages so you can actually do that. |
| 21:59 | kovasb | yeah |
| 21:59 | kovasb | a computation for every occasion |
| 22:01 | dnolen | kovasb: I think declarative programming can be much broader than people think. People always consider putting everything into one paradigm or another. Instead if you understand what's possible in a declarative paradigm, you have a better understanding where it can be powerfully applied - i.e. a rich assertion language that you gradually annotate your program w/. |
| 22:01 | kovasb | right |
| 22:01 | dnolen | kovasb: jonasen's scape is great example, dump your code into a DB and figure out meaningful queries over it. |
| 22:02 | kovasb | i guess declarative programming is where data meets programming constructs |
| 22:02 | kovasb | dnolen: yes i agree it can be much broader |
| 22:03 | Shambles_ | It does make me a bit sad when I see people bash on OO without even understanding why it exists, which is pretty often. It really is nice not to have to wonder where to look for code that might have corrupted your variable. |
| 22:04 | dnolen | kovasb: I think part of the problem is that people consider code some holy kind thing instead of just another piece of data. In this regard Lisp still got the one-up - you don't lose that clarity. |
| 22:05 | kovasb | dnolen: another problem is they don't have nice homoiconic datastructures |
| 22:05 | amalloy | Shambles_: doesn't help much if you expose setFoo(x) methods that just do what they're told |
| 22:06 | dnolen | kovasb: that's what I mean about the clarity. You can do the same thing with many languages - but people consider that the realm of the compiler / tool writer. |
| 22:06 | kovasb | right |
| 22:06 | hugod | nDuff: your repro case works for me - Apache Maven 3.0.4 (r1232337; 2012-01-17 03:44:56-0500), Java version: 1.6.0_33 or 1.7.0_4 |
| 22:06 | Shambles_ | kovasb: Well, there's two reasons for the 'holy code' point of view too. Until fairly recently (about the 90's), there were a lot of programmers that considered self-modifying code to be great. They were rather famous for creating unmaintainable messes. The other is the drive toward better security that was hardware-based (non-executable pages). This drove programming toward very-static environments where code wasn't dat |
| 22:06 | Shambles_ | That probably got cut off. Sorry. "This drove programming toward very-static environments where code wasn't data." |
| 22:06 | kovasb | dnolen: i watched the guido pydata talk .. the whole thing was people asking for extending language syntax, and wanting macros |
| 22:07 | dnolen | kovasb: haha |
| 22:07 | kovasb | Shambles_: right |
| 22:07 | kovasb | dnolen: it was crazy. that was the the "python scientific community" has on the frontburner |
| 22:08 | Shambles_ | amalloy: It's not /as/ helpful as it could be, perhaps, but nobody is forcing you to do that with OO, and it's still better than the structured code situation, because if you need something to happen whenever that variable changes, you can at least stick it in the setFoo method and take comfort in knowing it will always occur when appropriate. |
| 22:08 | kovasb | for core language dev at least |
| 22:09 | kovasb | dnolen: btw got the cljs tagged literal support working in session. bit of a hack but |
| 22:09 | Shambles_ | I'm a Python (my preferred language anyway) programmer trying to move to Lisp. It's close enough for me to understand why people would be asking for those things in Python. There's not a lot else missing. |
| 22:10 | kovasb | Shambles_: i am not against OO, just the programs people tend to write with it |
| 22:10 | Shambles_ | I don't think they can add it without causing major headaches, and Guido is dead set against it. |
| 22:10 | dnolen | Shambles_: it not clear to me that self-modifying in the mainstream was ever popular. Do you mean in languages like C++ / C ? If so, yeah nightmare. |
| 22:11 | amalloy | dnolen: before that, i think. assembly |
| 22:11 | dnolen | amalloy: that would have been in the 50s and 60s then. |
| 22:11 | kovasb | Shambles_: yes he did a good diplomatic job of knocking them down |
| 22:11 | dnolen | and was probably better than writing all the assembly by hand. |
| 22:11 | amalloy | oh, i missed his "recently" claim. yeah, i agree that doesn't seem true |
| 22:11 | Shambles_ | kovasb: Self-modifying code was, until about the miod 90's *wildly* popular with assembly programmers. You could get away with that stuff easily in DOS. It was used to save RAM, do copy protection, and in rare cases improve speed (by removing the need for subroutines or branches). |
| 22:12 | Shambles_ | kovasb: Assembly seems to have fallen out of favor, even with game programmers, and given higher level languages were trying to avoid quite so much mess, it's not surprising it's not as doable now. |
| 22:12 | dnolen | Shambles_: do you have any evidence that it's not popular among assembly devs today? |
| 22:13 | dnolen | Shambles_: isn't the whole point of modern runtimes self-modifying code? |
| 22:13 | kovasb | somehow "self-modifying code" tends to sound more scary than it usually is |
| 22:13 | Shambles_ | dnolen: It's not as popular today due to most OS's (Windows and Linux at least) setting most pages non-executable. |
| 22:14 | kovasb | i think it's fair to say we have OO in clojure |
| 22:15 | Shambles_ | dnolen: Using data to decide what code to execute usually achieves the same ends as self-modifying code, but it's more painful, so isn't done when you don't really *need* to. It also makes it blatantly clear that that is being done from looking at the source. |
| 22:16 | dnolen | Shambles_: completely disagree with that. Data is control is great. |
| 22:16 | dnolen | Data as control. |
| 22:17 | kovasb | i agree they are very similar |
| 22:17 | kovasb | also data as control is great so long as writing the executor is easy |
| 22:18 | Shambles_ | dnolen: I didn't say anything about whether it was 'great' or not. I just said it's clearer that it's being done (no mystery code overwrites at some point in your memory map), and that it's more painful, which it is, since you have to manually specify the mapping rather than relying on what the hardware considers a particular binary sequence to 'mean'. |
| 22:19 | Shambles_ | dnolen: I also have a healthy respect for the lessons of history. 'Cute' control flow may be necessary, but I don't like to use it when I don't *need* to. There's no point in using a kaiser bomb to kill a housefly. |
| 22:19 | dnolen | Shambles_: yes, self-modifying assembly is not something I want to know anything about. |
| 22:19 | dnolen | Shambles_: no argument there. I'm not going to replace my ifs with maps. |
| 22:20 | kovasb | i definitely went through i stage in mathematica programming where i tried to do everything with replacement rules |
| 22:20 | technomancy | has anyone written ring applications that return DB-altering functions in parallel to the HTTP response map? |
| 22:20 | kovasb | but if is pretty good |
| 22:21 | technomancy | it's probably not feasible, but I'm curious if anyone's tried it |
| 22:21 | kovasb | more complex control often indicates you are doing it wrong |
| 22:22 | ohpauleez | technomancy: can you give an example? |
| 22:22 | Shambles_ | As for OO in Clojure, I guess you have it due to Java interoperability, and reference types, but mutable variables are clearly the red headed stepchildren in Clojure, and I'm finding the adjustment to extreme-minimal-mutation to be rather painful. I've been trying to get my head around zippers for that. I don't think anybody would like it if I just kept to a OO style. |
| 22:23 | technomancy | ohpauleez: {:status 201 :body "dude I made a thing for you" :db ["INSERT INTO widgets VALUES ('hello', 'world')"]} or some variant |
| 22:23 | kovasb | Shambles_: one big argument for the declarative style is that there are fewer functions to worry about. |
| 22:23 | kovasb | Shambles_: and so tends to be easier to copy code, serialize it etc |
| 22:23 | technomancy | ohpauleez: you'd probably want DB functions to work like swap! or alter functions |
| 22:23 | dnolen | Shambles_: not true, about the OO stuff & Java interop. |
| 22:24 | kovasb | Shambles_: i think the datatypes and record lend it OO status -- functions and data together |
| 22:24 | dnolen | Shambles_: Clojure distills the good OO stuff - and leaves the baggage behind. |
| 22:24 | Shambles_ | kovasb: You are kidding right? Functional programming tends to be all about having lots of itty bitty functions. In theory if they're named well (i.e. not like a mathematician would), they read a bit like a English description. If you're using Forth, they even call them "words" that are in a "dictionary", but it all reads like Yoda talking. |
| 22:24 | technomancy | ohpauleez: it probably wouldn't work without PLV8 and cljs I think |
| 22:24 | ohpauleez | technomancy: not via ring explicitly, but I have done something similar with CLJS and datomic |
| 22:24 | ohpauleez | only as a thought experiment |
| 22:24 | dnolen | Shambles_: also, local mutation is perfectly acceptable in Clojure. |
| 22:25 | kovasb | Shambles_: i mean, in my definition of declarative. Its just some piece of data. |
| 22:25 | kovasb | Shambles_: like, the datomic api is 1 function |
| 22:25 | kovasb | Shambles_: and then you pass in the declarative spec of your query |
| 22:26 | technomancy | ohpauleez: I think plv8 makes it feasible in postgres, but I imagine the build to get there could be a worlde o' pain. |
| 22:26 | Shambles_ | dnolen: Trying to figure out how to alter a simple tree, based on user response, is giving me a headache. It wouldn't if I just used vars, but I'm sure that's not the 'correct' style. I'm pretty sure what's excpected is for me to use zippers and only one var to hold the root. |
| 22:27 | ohpauleez | technomancy: Would be interesting to see how far you could get in a day though |
| 22:27 | dnolen | Shambles_: do you know the path to the thing you want to change? If so why do you need zioppers? |
| 22:27 | kovasb | Shambles_: do you have a function that outputs the modified tree? |
| 22:28 | technomancy | ohpauleez: I suck at both postgres and cljs, so I'm going to delegate that to someone else who happens to be listening to this conversation |
| 22:28 | ohpauleez | but the details are most certainly difficult - datomic has some padding that made it easier (queries are just data structures - remoting via CLJS to the server-side peer was an easy hack to tie over pieces) |
| 22:28 | kovasb | Shambles_: (swap! your-atom your-function function-arg) |
| 22:29 | technomancy | ohpauleez: I suspect queries are just data structures with cljs/plv8 too |
| 22:29 | Shambles_ | dnolen: It's a 'toy' program to try to help me understand things. It's basically a miniature expert system. It traverses a tree to answer questions. If it can't answer the question it needs to add a new node at the tip of what was a 'leaf'. |
| 22:29 | kovasb | where you have (defn your-function [original-tree function-arg] ..produce new tree..) |
| 22:29 | technomancy | but you have to do the heavy lifting yourself I guess |
| 22:30 | kovasb | Shambles_: zippers create new data structures as you are doing your insertions etc |
| 22:30 | Shambles_ | dnolen: My current thoughts are to keep passing a path as it gets built up traversing the tree, then convert that into zipper operations to modify the tree if necessary. That would keep the tree from mutating. There'd only have to be one point of mutation in the program; the variable that holds the current tree's root. |
| 22:30 | dnolen | Shambles_: is a tree a good representation? Why not tuples + indexing? |
| 22:31 | kovasb | Shambles_: if the issue is saving it at the end, there is a function to output the new modified tree. you can stuff that into a ref type |
| 22:31 | technomancy | anyway, someone who's good at postgres should implement that; kthxbai |
| 22:32 | Shambles_ | dnolen: I'm not sure what you have in mind, but yes, a tree is a good representation. There are questions, whose yes or no answers lead to more questions. |
| 22:33 | dnolen | Shambles_: so you have indexes, why do you need a tree? |
| 22:33 | Shambles_ | dnolen: I don't have a index in the sense of 1 through n. It's not look-up-able like a index in a array. |
| 22:34 | dnolen | Shambles_: don't the questions have ids? And each question can point to the next one? |
| 22:34 | Shambles_ | dnolen: In the sense that there is a pointer, I suppose. |
| 22:35 | dnolen | Shambles_: so flatten the tree, create a pointer. Less programming. |
| 22:35 | kovasb | i don't see why bother |
| 22:35 | kovasb | update-in works fine |
| 22:36 | kovasb | step 1. look up in tree using get-in |
| 22:36 | kovasb | step 2. update tree with update-in |
| 22:36 | kovasb | or assoc-in |
| 22:36 | dnolen | kovasb: it mostly does, but it really depends on the use case. nested update costs add up. |
| 22:36 | dnolen | kovasb: indexed tuple representation is cheap to update. |
| 22:36 | kovasb | it sounds like performance is not a concern in this case :) |
| 22:37 | Shambles_ | dnolen: Why would I want to flatten the tree? If something has a natural branching tree structure based on yes or no answers, cramming it into a flat data structure seems rather ugly. It also means I'll have to start manually managing what pointers were doing for me. I'll have to say "jump to question 1... uh, okay, now let's go lookup 1, alright, ask question, get answer, now I need to jump to question 89, let's look tha |
| 22:37 | dnolen | Shambles_: because now you're playing around with zipper which makes no sense to me. |
| 22:38 | dnolen | Shambles_: you have first class data structures, getting the next question is trivial. |
| 22:38 | kovasb | Shambles_: i would check out get-in, assoc-in, update-in |
| 22:38 | dnolen | (questions (:next question)) |
| 22:38 | Shambles_ | dnolen: What I want to do is mutate a tree. Mutating is demonized, so I need to find a way to do it without mutation. Zippers appear to be the promoted salve for the need to mutate a tree. |
| 22:39 | kovasb | Shambles_: use swap! in combination with the aforementioned functions |
| 22:39 | dnolen | Shambles_: your assessment would be incorrect. |
| 22:40 | dnolen | Shambles_: if you want to mutate a tree you're bringing a solution to a problem - not solving the problem. |
| 22:40 | kovasb | zippers do not mutate. they generate new datastructures |
| 22:40 | dnolen | not "actually" solving the problem. |
| 22:40 | kovasb | its just a more cumbersome way of doing the retrieval/update operatons |
| 22:40 | Shambles_ | I have no trouble imagining how to flatten this into a list. I've seen people do that in one language I've had the misfortune to use, since it had no pointer or reference type. It wasn't easy to tell what was going on when reading such code (it didn't /look/ like a tree). But with enough blood sweat and tears it could be made to work. Lists could be appended in the language so you could add new nodes that way. |
| 22:41 | Shambles_ | That was actually the only aggregate data type. There were strings, but you couldn't interact with them like arrays. Very unpleasant, especially given lists were not nestable. |
| 22:42 | dnolen | Shambles_: huh, databases work like this - even graph databases - it's not that bad. |
| 22:43 | Shambles_ | dnolen: I suppose I've gotten spoiled by 'easy' data structures. In Python if you want a tree, you make a class, and assign instances of that class type to various variables. There ya go. Easy to understand, easy to read. Everybody knows what you're up to. Anything else seems like handcuffs on. |
| 22:44 | dnolen | Shambles_: too many things to not like about Python to care about "easy" mutable graphs. |
| 22:44 | dnolen | for me |
| 22:44 | Shambles_ | I could flatten this into a list, and avoid learning how to use a zipper I guess. |
| 22:45 | kovasb | what is wrong with {:node value :children [ … ]} |
| 22:46 | dnolen | kovasb: Shambles_: I agree if this is a "toy" that works best. |
| 22:46 | kovasb | i mean, that is pretty easy to iterate over |
| 22:46 | Shambles_ | kovasb: As for zippers don't mutate, I'm aware of that. I said it's the promoted salve for /wanting/ to mutate a tree. When you say "I want to mutate" and the response is "mutation is bad", there has to be a solution "so do it this way". You end up needing to understand category theory if it's Haskell. Other languages usually have easier solutions. :P |
| 22:47 | kovasb | if i knew what computation you wanted to do, I'm sure it would be a one or two liner |
| 22:47 | dnolen | ,(update-in {:value 'foo :children []} [:children] (fn [c] (conj c {:value 'bar :children []}))) |
| 22:47 | clojurebot | {:value foo, :children [{:value bar, :children []}]} |
| 22:48 | Shambles_ | There is at no point a need to 'iterate over' the tree. It's a tree. You need to be able to crawl it based on responses. You definitely don't need/want to pass over the entire tree. The only problem is trying to figure out how to change the tree (without mutation) when it needs to be updated. |
| 22:48 | technomancy | wanting to mutate a tree for the sake of mutation doesn't sound like a very useful goal |
| 22:48 | kovasb | ,(assoc-in {:value 'foo :children []} [:children] {:value 'bar :children []}) |
| 22:48 | clojurebot | {:value foo, :children {:value bar, :children []}} |
| 22:49 | kovasb | whoops |
| 22:49 | kovasb | ,(assoc-in {:value 'foo :children []} [:children 0] {:value 'bar :children []}) |
| 22:49 | clojurebot | {:value foo, :children [{:value bar, :children []}]} |
| 22:49 | kovasb | dang |
| 22:49 | kovasb | there we go |
| 22:50 | Shambles_ | The code is a lot easier for me to understand. If this was Python I'd just use a reference to the current node to change the values. That's quite possible in Clojure too (you can apparently put reference types in data structures), but apparently not the way you're supposed to do things, so I've been trying to figure out how to drive mutation out of the program except where it *has* to exist. |
| 22:50 | dnolen | Shambles_: you can keep on talking or you can show your code at this point :) |
| 22:50 | kovasb | ,(get-in {:value 'foo, :children [{:value 'bar, :children []}]} [:children 0 :value]) |
| 22:50 | clojurebot | bar |
| 22:51 | dnolen | Shambles_: I'm sure people will / can offer up improvements to your approach. |
| 22:52 | kovasb | i guess i am not seeing where the zippers are falling down |
| 22:52 | Shambles_ | dnolen: The code doesn't exist, since, as I said, I've been trying to figure out how to update the tree, but essentially it's this Python program ported to Clojure: http://openbookproject.net/py4fun/animal/animal.py |
| 22:53 | kovasb | you use the zipper, and then.. ? how is that not working |
| 22:53 | iDesperadO | Could not transfer artifact org.mongodb:mongo-java-driver:pom:2.6.5 from/to central (http://repo1.maven.org/maven2): Checksum validation failed, no checksums available from the repository |
| 22:53 | iDesperadO | how about this error? |
| 22:54 | kovasb | sounds like a busted artifact no? |
| 22:55 | dnolen | Shambles_: for that I agree w/ kovasb, that seems trivial w/ zippers |
| 22:56 | kovasb | dnolen: one limitation i can see, is if you want to maintain tree position, but also make the new tree concurrently available |
| 22:57 | kovasb | dnolen: because you need to emerge from the zipper to create the new top level value |
| 22:57 | Shambles_ | kovasb: It's mostly me trying to understand how to do it. Currently my only guess is to pass a list, probably of symbols, that states the path taken to the node (it depends on the answers someone has given), as a argument, so if its guess is wrong, it can use that to reach and change the appropriate node. |
| 22:57 | technomancy | iDesperadO: whoever deployed the java mongodb driver screwed up pretty badly |
| 22:57 | iDesperadO | so...how to fix it? |
| 22:57 | Shambles_ | Zippers don't exist in any language I've used before, so the idea is pretty foreign. |
| 22:57 | kovasb | Shambles_: if you already have the path in-hand, why not just use update-in or assoc-in ? |
| 22:58 | iDesperadO | technomancy: I just git cloned incanter project and run `lein deps` only to find the dependencies can't be met |
| 22:58 | technomancy | iDesperadO: you can add :checksum :warn to project.clj, but that opens you up for accepting corrupted jars into your projects |
| 22:58 | kovasb | the only reason to incrementally walk the tree is if the next step in the walk is dependent on an answer you don't have yet |
| 22:58 | technomancy | iDesperadO: probably better to add :exclusions for the mongo junk |
| 22:58 | dnolen | kovasb: hmm, the cursor is purely functional tho right? you can hold on to it like any other value. |
| 22:58 | Shambles_ | kovasb: You wouldn't necessarily have the path. You just need to loop (or recur) and follow the references so long as the tree doesn't need changing. |
| 22:59 | technomancy | or just delete it out of project.clj if it's mentioned explicitly |
| 22:59 | kovasb | dnolen: yes, but if someone else changes the tree at the ref, you won't see that |
| 22:59 | dnolen | kovasb: is that relevant here? |
| 22:59 | kovasb | no idea |
| 22:59 | Shambles_ | kovasb: That's what's happening with the while loops in the Python code. When it needs to modify the tree it does it by mutating it, by using the reference to the current node. |
| 23:00 | iDesperadO | technomancy: im afraid the incanter project uses mongodb... |
| 23:00 | dnolen | kovasb: it is not relevant |
| 23:00 | technomancy | iDesperadO: really? I thought it was optional. |
| 23:00 | kovasb | Shambles_: i see. should be able to do a direct port with zippers |
| 23:01 | dnolen | kovasb: the questions are asked once you have an aswer you can then update the zipper |
| 23:01 | Shambles_ | kovasb: I would need to keep passing the path as it's traversed, right? |
| 23:01 | kovasb | right |
| 23:01 | kovasb | Shambles_: i don't think so |
| 23:01 | dnolen | Shambles_: in this case I think a zipper is more natural for a close port. |
| 23:02 | kovasb | Shambles_: i believe the path is accessible natively in the zipper |
| 23:02 | kovasb | Shambles_: when you are at a child, pretty sure that data structure keeps its path around. don't know the zipper api offhand |
| 23:03 | Shambles_ | kovasb: The tutorials I've read on zippers show a long series of down, left, right, and so on, to be able to modify something. This one looked like what I'd need to use. http://tech.puredanger.com/2010/10/22/zippers-with-records-in-clojure/ |
| 23:03 | kovasb | Shambles_: check out this talk, it has everything i know about zippers http://blip.tv/clojure/luke-vanderhart-clojure-zippers-4521622 |
| 23:04 | kovasb | Shambles_: i suggest that talk, it does simpler stuff |
| 23:05 | Shambles_ | kovasb: I'll see if I can find the "pwd" equivalent in the API. If it exists, yes, this would be easier. |
| 23:05 | kovasb | pwd? |
| 23:06 | Shambles_ | kovasb: Path to Working Directory. Unix command. |
| 23:06 | kovasb | Shambles_: that exists in zippers |
| 23:07 | kovasb | i believe its :ppath |
| 23:07 | kovasb | i mean, the zipper is a datastructure |
| 23:07 | kovasb | i suggest making one and just looking at its contents |
| 23:07 | kovasb | its actually pretty instructive of the benefits over oo |
| 23:08 | kovasb | you can just print it out and its a collection of normal clojure datastructures |
| 23:09 | kovasb | i suggest watching the last 4th of the talk where heres doing stuff at the reok |
| 23:09 | kovasb | repl |
| 23:10 | amalloy | kovasb: annoyingly, it's a collection of normal data structures...but with some hidden metadata that doesn't print unless you ask for it |
| 23:10 | kovasb | lol |
| 23:11 | technomancy | so I was listening to ejackson's core.logic talk in the car today and I'm pretty sure there was a siren in the background of the talk's audio track. |
| 23:11 | technomancy | had me kind of confused for a minute |
| 23:12 | amalloy | that was just the thought police |
| 23:12 | kovasb | i was trying to listen to that talk, but the speech pattern was too much |
| 23:13 | technomancy | his pronunciation of A in a few words didn't match my conception of the british accents I'm familiar with |
| 23:13 | technomancy | I guess there are tons of regional variations |
| 23:17 | gnarmis | Hey all, I was wondering if anyone knows where the latest snapshots of lobos are? They don't seem to be on clojars |
| 23:20 | gnarmis | Btw, currently using [lobos "1.0.0-SNAPSHOT"] |
| 23:21 | botter | Is there anything like ClojureBox for Windows for 1.5? |
| 23:21 | gnarmis | but found a closed issue which suggested there's a newer one on clojars. https://github.com/budu/lobos/issues/36 |
| 23:23 | technomancy | botter: clojurebox is old and unmaintained; recommend you not use it |
| 23:23 | botter | Yea, I'm looking for an alternative |
| 23:25 | technomancy | you'll probably have to download the parts separately |
| 23:25 | botter | :| |
| 23:26 | technomancy | orthogonal things are best kept orthogonal |
| 23:26 | technomancy | trust me, you don't want to have to upgrade your editor just because a new version of clojure came out |
| 23:27 | botter | I only want to try CLojure for a bit, so I don't want to spend too much time setting up the environment |
| 23:27 | botter | But I'll give it a shot |
| 23:28 | technomancy | if you don't already have Emacs set up, you probably shouldn't learn it at the same time you're learning Clojure |
| 23:29 | kovasb | botter: does clooj work for you? |
| 23:29 | botter | I'll try clooj, I've never head of it before |
| 23:30 | kovasb | its pretty good for a quick editing and repl solution |
| 23:30 | botter | technomancy: Setting up emacs right now. I've only used vi |
| 23:31 | technomancy | botter: strongly advise you wait on that until you know your way around clojure |
| 23:31 | technomancy | learning two things at once is a recipe for a headache |
| 23:31 | botter | Wait on what? |
| 23:31 | technomancy | wait on Emacs |
| 23:32 | iDesperadO | technomancy: how to download org.mongodb/mongo-java-driver? there are pom/jar/javadoc.jar/sources.jar to download...I have to download them all? |
| 23:32 | botter | So clooj then |
| 23:32 | kovasb | iDesperadO: you can also clone the repo and install it locally. very easy with lein install |
| 23:33 | kovasb | o wait.. that is not a clojure package |
| 23:33 | iDesperadO | http://search.maven.org/#search|ga|1|a%3A%22mongo-java-driver%22 |
| 23:33 | technomancy | iDesperadO: are you sure you need it? from what I heard it's just a convenience thing for incanter; it's not really required. |
| 23:33 | iDesperadO | O |
| 23:34 | technomancy | but you can set :checksum :warn in project.clj to turn off verification if you must =( |
| 23:34 | iDesperadO | what if i need it? I want to know how to download it manually |
| 23:35 | iDesperadO | I see lein install dependencies in ~/.m2/repository/. I guess I can do it manually |
| 23:35 | technomancy | don't do it manually |
| 23:35 | technomancy | just turn off checksum verification in project.clj |
| 23:35 | iDesperadO | O |
| 23:35 | technomancy | lesser of two evils |
| 23:35 | sjl | ,(when-let [foo false bar true] 1) |
| 23:35 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: when-let requires exactly 2 forms in binding vector in sandbox:> |
| 23:36 | sjl | :( |
| 23:36 | sjl | is there an idiomatic way to do that other than nested when-lets? |
| 23:36 | technomancy | sjl: the official story is that it's ambiguous whether the two conditions would be ANDed together or ORed. |
| 23:37 | kovasb | and-let |
| 23:37 | iDesperadO | I've already done that |
| 23:37 | kovasb | or-let |
| 23:37 | sjl | technomancy: I'd assume ANDed |
| 23:37 | xeqi | I think I remember that spawning a long mailing list thread |
| 23:37 | technomancy | not saying I agree, but that's the official position |
| 23:39 | sjl | how would or even make sense? would it short-circuit the binding like (or) and leave one unbound? |
| 23:40 | sjl | I guess it could just do them all and leave them bound to falsy stuff |
| 23:40 | sjl | wheras AND would behave the same as (and) where it short-circuits |
| 23:40 | kovasb | you let them bind to whatever the value was |
| 23:40 | kovasb | what the multi form should do is |
| 23:40 | kovasb | let you specific which variables must not be nil |
| 23:40 | sjl | kovasb: yeah, just seems weird since (or) short circuits but (when-let-or) wouldn't |
| 23:41 | kovasb | good point |
| 23:41 | michaelr525 | good morning! |
| 23:41 | sjl | whereas both (and) and (when-let-and) short circuit the same way |
| 23:42 | sjl | and there's no nice way to do the and version now, wheras you can do the or version with a single (let [...] (when (or bindings...) ...)) now |
| 23:42 | botter | clooj is what I'm looking for. thanks. |
| 23:42 | kovasb | botter: np |
| 23:43 | kovasb | something like (when-let2 [a … b …] [a b] …) |
| 23:43 | kovasb | where a b specifies that a and b must be not falsey |
| 23:43 | sjl | kovasb: eh, that's getting a bit fiddly |
| 23:44 | kovasb | seems flexible to me |
| 23:44 | kovasb | unless you want to only all or any behavior |
| 23:44 | kovasb | if you want all, might as well list them out |
| 23:45 | kovasb | or just give a symbol :all, or :any, and then have the vector case for specifying granularly |
| 23:45 | sjl | well, the when-let-or version can be done in a 3-level structure for N bindings right now |
| 23:45 | sjl | but the when-let-and version requires N levels for N bindings |
| 23:45 | sjl | so it seems that AND would be more beneficial |
| 23:46 | kovasb | i haven't had a need so i can't really tell :) |
| 23:46 | amalloy | $google github egamble let-else |
| 23:46 | lazybot | [egamble/let-else · GitHub] https://github.com/egamble/let-else |
| 23:46 | kovasb | but its pretty reasonable to have a spec that says how the logic should work |
| 23:46 | kovasb | unless there is a slam dunk case for a more specific taylored version |
| 23:46 | technomancy | amalloy: fancy-town |
| 23:47 | amalloy | eh? |
| 23:47 | technomancy | let-else |
| 23:47 | technomancy | lots of options there |
| 23:48 | amalloy | yeah. i don't like it enough to use it myself, but i helped him write it, and it seems like the road these folks are headed down |
| 23:49 | sjl | I don't need lots of crazy functionality -- I was just thinking when-let would do something useful instead of just explode |
| 23:49 | brehaut | looks like a special syntax version of the maybe monad |
| 23:50 | sjl | but it's only three levels right now so I'll just type the extra when-lets |
| 23:51 | brehaut | (that wasnt intended to sound disparaging. merely an observation) |
| 23:52 | technomancy | brehaut: "That looks like a monad. Not that there's, you know, anything wrong with that." |
| 23:52 | brehaut | haha |
| 23:54 | technomancy | sjl: what was the dependency you were having trouble with? |
| 23:55 | sjl | technomancy: Lanterna -- it's a Java lib and the version I want/need is only on Sonatype |
| 23:55 | sjl | technomancy: and I couldn't find the magic :repository incantation to get it working, so I just ended up using lein-localrepo to install the jar |
| 23:55 | technomancy | =( |
| 23:56 | sjl | meh, it's a throwaway project to relax and unwind after a day of tracking down git/python insanity -- getting it working is more important than 100% build purity |
| 23:58 | technomancy | for the record, it goes like this :repositories {"sonatype-snapshots" "https://oss.sonatype.org/content/repositories/snapshots"} |
| 23:58 | sjl | hmm, I could have sworn I tried that... |
| 23:58 | sjl | does the key matter? |
| 23:58 | sjl | (the "sonatype-snapshots") |
| 23:58 | technomancy | shouldn't |
| 23:58 | sjl | hmm |
| 23:59 | sjl | I thought I tried that, but maybe not |
| 23:59 | sjl | anyway, how would I have figured that out? I looked for a repository URL on the sonatype page for that lib, but there wasn't one |
| 23:59 | sjl | (I only vaguely know Maven, etc so it might be over my head) |