#clojure logs

2012-08-07

00:32Cr8what's the current best option to get started playing with clojurescript?
00:33emezeskeCr8: In my heavily-biased opinion? https://github.com/emezeske/lein-cljsbuild
00:35xeqi+1 for lein-cljsbuild
00:36Cr8hm
00:38Cr8i keep getting a blowup looking for clojure.instant when I try to use anything that does cljs
00:41Cr8hmm
00:42Cr8I seem to be getting clojure 1.3.0 even though my project.clj specifies 1.4.0
00:44xeqican you paste a `lein deps :tree` and project.clj ?
00:46jonasenemezeske: ping
00:47Cr8figured it out
00:49jonasenemezeske: about schoolseatingcharts: Is it built on canvas or svg? Do you drag'n'drop seats onto the canvas, or are their positions/directions predefined?
01:00uvtcamalloy: ping?
01:00amalloyque pasa?
01:01uvtcearlier, re. casion's question, he wanted to "remove damage at cooldown". What does that mean in english?
01:01uvtcI'm looking at your full example, but I don't see what "cooldown" is supposed to mean.
01:01amalloyoh, the phrase is nonsense. i was just guessing based on how games make sense
01:01PeregrineIt's a game term.
01:01amalloycooldown was "number of time units between attacks"
01:01clojurebotNo entiendo
01:02amalloyPeregrine: yes, the word "cooldown" is well established. what it means in his sentence/program is not
01:02uvtcBut each fighter has a "cooldown" value...
01:02uvtcLike hp, or dmg...
01:02amalloyright, they attack at different speeds
01:03uvtcBut in the example code, during each round, they each get to hit once... They fight in sync with eachother...
01:03uvtcI think...
01:03amalloyno
01:04amalloynot the code i provided, at least
01:04uvtcThe :cooldown-remaining gets updated each round, but I'm not seeing the significance of it.
01:04amalloyokay, start by dividing time up into "ticks" of whatever unit cooldown is in
01:04uvtcEach round the fighters are updated: `a` gets hit by `b`, and vice versa. The 2-item list is returned by `fight-one-round`.
01:04amalloyoh, you're right, they do fight in sync
01:04amalloyi got that wrong
01:05amalloyi need to only subtract one of their hp units, while updating both of their cooldowns, to implement what i meant to do
01:07amalloyuvtc: just updated gist with a fight-one-round that more accurately reflect what i meant
01:08amalloyand, good, now b wins my a smaller margin, which makes sense because he attacks more slowly
01:09uvtcSo, the fighters can have different "rates of attack"? Interesting.
01:09amalloythat's the most obvious guess at what he means by cooldown
01:10uvtcWill look at the code again. But `fight-one-round` still returns that vector of 2 updated fighters, so it appears to me that the fighters are still fighting in sync. Will look more closely though.
01:10amalloyit returns two fighters now, but only one of them changes hp (most of the time)
01:12ekoontzthanks to @cemerick for http://cemerick.com/2012/08/06/results-of-the-2012-state-of-clojure-survey/
01:22amalloyuvtc: you can see it more clearly if you switch (first (drop-while ...)) with (take-while ...), and give the fighters lower cooldowns (try 4 and 10 for a good example)
01:23amalloythe fast guy gets in a few punches, then the slow guy gets one, and after a few rounds they both strike at the same time when they both hit zero
01:23uvtcamalloy: I can just fine how the `fight` function works.
01:23uvtcI think.
01:23amalloyuvtc: i know, but making that change to fight makes fight-one-round easier to understand
01:24uvtc`fight` just drops rounds until it gets to one where a fighter has health < 0, then gives you the result.
01:24uvtcIn `fight-one-round`, in the `let`,
01:25uvtcI see what `ticks` is: it's just the mininum of the fighter's :cooldown-remainings. Though I don't understand why it's named "ticks".
01:25uvtcI see what `damage-dealt` is: it's just a function that takes a fighter and returns either his regular damage or else 0.
01:26amalloy"number of ticks till someone gets to attack". rather than simulating a tick at a time, i skip over the ticks when nothing is happening
01:26amalloyyou could have ticks always be 1, and it would work just fine but return more uninteresting intermediate results
01:32uvtcamalloy: I see that `tick` is a function that takes a fighter and returns an updated fighter. It either sets this fighter's :cooldown-remaining to its value of :cooldown, or else it sets it to its :cooldown-remaining minus the min ticks between the two fighters.
01:33amalloy"how long till his next attack after this one?"
01:35uvtcIs that the question, the answer of which is :cooldown-remaining?
01:35amalloyright
02:19uvtcamalloy: Thanks. Got it.
02:19uvtcamalloy: diabolical.
02:20TEttingeranyone use Seesaw here? I can't figure out why my window is incredibly wide
02:20amalloyheh, it was a straightforward a solution as i could think of
02:20TEttingerI keep setting maximum-size and it doesn't seem to notice
02:20amalloydefinitely room for improvement
02:21uvtcamalloy: would you mind if I blogged about it?
02:21amalloygo for it
02:21amalloywhy?
02:21clojurebotwhy not?
02:21amalloydie in a fire, clojurebot
02:22uvtcamalloy: Well, for one thing, because casion wanted to know how it worked. And for another, I think it's rather clever. :)
02:22TEttingerthe window is roughly 1900 pixels wide, and I can't seem to find any place I set that
02:23amalloycool. well, send me a link when you're done
02:23amalloymaybe one of these days i'll get back into blogging
02:23uvtcamalloy: Will do. It's way past my bedtime. G'night.
02:30TEttingeralso, I can't grow a section of the frame with a divider -- the left side of a split pane can shrink, but not grow. the right side is huge and consists of one widget.
02:39TEttingerfigured it out; I was calling (pack!) and it reset my widgets to use their preferred sizes
03:17ro_stso i'm trying to get domina to work. when i cljsbuild, i get "clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such var: cljs.compiler/resolve-var, compiling:(domina/macros.clj:13)"
03:18ro_stno idea how to resolve this
03:18ro_stanyone using domina successfully?
03:31jballancjust curious...what are people using for a generic Clojure REPL? (i.e. not associated with a specific project)
03:37Raynes`lein repl` works. I guess the light table playground could also be an option.
03:38edmund_lein swank and slime-connect from emacs is my default
03:38RaynesCool people use nrepl.el now.
03:38jballancah ok...just realized that `lein repl` works outside of a project if I configure my profiles.clj correctly :)
03:38gkoAre SLIME for Clojure and Common Lisp still walking on each other?
03:39ejacksonRaynes: P'TAK !
03:39RaynesYeah, but you don't have to use slime anymore.
03:39jballancyeah, I'd use nrepl.el but you'll pry vi from my cold dead hands ;-)
03:39Raynesgko: Check out nrepl.el.
03:39RaynesKeep your SLIME config safe.
03:40gkowhich nrepl.el ? technomancy, kingtim, emacsmirror, ... ?
03:43ro_stkingtim
03:45gkoro_st: OK, so this (nrepl.el) + clojure-mode is all I need for Clojure, no more SLIME from package?
03:45ro_sti've no idea. haven't jumped in yet. Raynes will know :-)
03:45ro_sti think that's the case
03:46ro_stbackup your .emacs.d and give it a spin?
03:46gko(I meant, slime-repl 20100404 from package)
03:46ro_sti still don't know, sorry
03:47gkook
04:03ro_stso, (some) will tell me if some elements appear in a collection or not. how can i check whether all elements appear in a collection?
04:03ro_stuse some and verify that the result of some's length matches the ingoing set?
04:08ro_stevery?
04:46jballancro_st: something like this:
04:46jballanc,(empty? (reduce (fn [l c] (disj l c)) (set (map char (range 97 123))) "the quick brown fox jumps over the lazy dog"))
04:46clojurebottrue
04:47jballanc,(empty? (reduce (fn [l c] (disj l c)) (set (map char (range 97 123))) "does not use the whole alphabet"))
04:47clojurebotfalse
04:47ro_stthanks jballanc
04:49jballancyou can loop/recur with the empty check inside if you expect your set to be much smaller than the collection you're checking
04:49ro_stit turns out that the logic for determing inclusion differs from item to item, so my approach has to be a little different
04:50ro_stdetermining*
04:52clgv,(->> "does not use the whole alphabet" (map char) set (= (->> (range 97 123) (map char) set)))
04:52clojurebotfalse
04:53clgv,(letfn [(char-set [c] (->> c (map char) set))] (= (char-set "does not use the whole alphabet") (char-set (range 97 123))))
04:54clojurebotfalse
04:54clgv,(letfn [(char-set [c] (->> c (map char) set))] (= (char-set "the quick brown fox jumps over the lazy dog") (char-set (range 97 123))))
04:54clojurebotfalse
04:55clgv,(use 'clojure.set)
04:55clojurebotnil
04:55clgv,(letfn [(char-set [c] (->> c (map char) set))] (difference (char-set (range 97 123)) (char-set "the quick brown fox jumps over the lazy dog")))
04:55clojurebot#{}
04:56clgvah the \space ^^
05:04clojure-newcomerhey guys, is there a library for helping out with versioned REST API's with compojure ?
05:05clojure-newcomerdispatching to functions based on the version ?
05:06augustlclojure-newcomer: I don't know anything about your API, but it sounds like you might want two completely separate handlers for that
05:06augustlsince paths might be different etc
05:07augustland then just wrap each handler in middlewares that dispatches on version
05:07clojure-newcomeraugustl: ok, have you seen this kind of thing done ? or done it yourself ?
05:07augustlwell not sure what you mean with dispatching on version
05:07clojure-newcomeraugustl: so if the accept header specifies 1.0.0 relevant functions would be called for outputting the result xml in the correct format
05:08augustldon't think compojure can route on headers, it only routes on method and path afaik
05:08augustlit's a HTTP library, not a REST library :)
05:08clojure-newcomerah, so in theory the function my route definition calls could take care of dispatching ?
05:09clojure-newcomermaybe I could use multimethods :-)
05:09augustlclojure-newcomer: probably not to hard to make something like (rest-map (GET "/foo") {"1.0.0" my-handler "1.0.1" my-handler "1.1.0" other-handler})
05:10augustlclojure-newcomer: that sounds more sensible yeah
05:10augustlso, (GET "/foo" (version-dispatch {.... }))
05:10clojure-newcomeraugustl: so the handlers are part of the middleware paradigm ?
05:10augustlwhich returns a handler that chooses which function to call based on whatever
05:10clojure-newcomeraugustl: yeah right.. your latest looks like the kind of thing I had in mind
05:11clojure-newcomeraugustl: just a little sure about terminology and handlers...
05:11clojure-newcomergot any pointers ?
05:11augustlthe GET and POST functions (or macros? not sure) end up returning a plain ring handler
05:11augustlso wrapping and extending is trivial
05:23clgvaugustl: writing a ring middleware for rewriting paths to version-specific paths could work
05:34kralnamaste
06:02muhoolein2 won't instal on an embedded platform, because it doesn't have the root certificates and apparently lein2 grabs parts of itself via https
06:03muhooi'm not a jvm expert by any means. is there any trick to maybe making lein2 NOT use https?
06:04Fossican't you fix the real problem?
06:05Fossiis space really that limited that you want to "disable" ssl?
06:07muhooi have nfi where the jvm gets its certificates from
06:08muhooif you could point me to some clear documentation on that, i'd be happy to fix the real problem. i haven't found any
06:16nkkarthikI have a very small app, I have expose a simple REST api for it... which library should I use?
06:18vijaykirannkkarthik: http://mmcgrana.github.com/2010/08/clojure-rest-api.html
06:19nkkarthikvijaykiran: cool... I will look at it... thank you
06:38muhoothere's also the wakeful library, and bishop
06:56meenalHi,i see clojure.contrib is not in use, where did clojure.contrib.properties go? it is replaced by which package?
06:58clgv~contrib
06:58clojurebotMonolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
06:58clgvmeenal: seems "clojure.java.data" might be the answer
07:03meenalhanks clojurebot and clgv, but clojure.java.data seems to be supporting only beans right now, not properties.
07:03meenal*thanks
07:04meenali am looking at reading properties file, getting data from it as a map, in a clojure way
07:05clgvoh ok. java interop should help you there, e.g. ##(keys (System/getProperties))
07:05clgv,(keys (System/getProperties))
07:05clojurebot#<SecurityException java.lang.SecurityException: denied>
07:05nkkarthikmuhoo: thank you... I will look at them too
07:06clgvRaynes: ping. lazybot is down
07:06Raynesclgv: The whole sever is down.
07:07RaynesOr, well, was.
07:07clgvRaynes: ah ok. dont know which server it is on anyway ;)
07:07RaynesI think it lost network connectivity for a moment.
07:07RaynesThe server of milk and honey.
07:07RaynesAnyways, it's coming back up.
07:08clgvRaynes: you earned it right now ;)
07:09meenalclgv: thanks. i was trying to avoid java interop as much as i can
07:09meenalbut i guess for properties, i will have to use it
07:09clgvmeenal: java interop works pretty well - you should not try to avoid it artificially
07:10clgvmeenal: if you use property access often, you can write one or two clojure functions encapsulating the java interop
07:10eduardis it possible to combine -> and 'map'?
07:11clgveduard: with ->> yes
07:11eduardwhat if I need -> first and then to use map on result? is there is juxt-like function?
07:11meenalclgv: okay
07:11clgveduard: e.g. that would work (-> 10 range (->> (map inc)))
07:12clgv&(-> 10 range (->> (map inc)))
07:12lazybot⇒ (1 2 3 4 5 6 7 8 9 10)
07:12eduardclgv, thanks
07:36meenalclgv:i see (keys (System/getProperties)) helps in getting system information, how do i use to read a properties file and get the values of a key?
07:37meenalhttp://stackoverflow.com/questions/7777882/loading-configuration-file-in-clojure-as-data-structure
07:37meenalhow about the above method?
07:43clgvmeenal: looks good. you do not necessarily need the (into {} prop) since the map-interface is sufficient for a lot of things
07:45meenalclgv: thanks :)
07:45clgvmeenal: take the accepted one from Dave Ray - mayb without that for-expression if you dont need that
07:46meenalokay
07:47meenali will work it out in my project and see
07:47meenalthank u
07:53meenalclgv: i have another question
07:54meenali populate a stringbuffer in my code, so that the output of the buffer is <v11:ID id="93"/>
07:54meenalfor inputting the number "93" in double quotes i had to escape the double quotes
07:55meenalbut when i convert it to a string, i get <v11:ID id=\"93\"/>
07:56meenali want the buffer output <v11:ID id="93"> after string conversion too
07:56clgvmeenal: use println to see the actual string output
07:57clgvthe repl will print the escape backslashes
07:57meenali use println for displaying both buffer and string
07:58meenalbuffer print is just wat i want, but after converting it to string, it prints with escape backslash
07:59clgvwhat is your code? what does the input look like? use a paste website
07:59muhoolein2 running (slowly) on a beagleboard: https://www.refheap.com/paste/4091
07:59meenali am sorry, i havent used a paste website. can u give me a url?
07:59clgvwhat meant is ##(let [s "<v11:ID id=\"93\"/>"] (println s) s)
07:59lazybot⇒ <v11:ID id="93"/> "<v11:ID id=\"93\"/>"
08:00muhoomeenal: http://refheap.com
08:00clgv~paste
08:00clojurebotpaste is gist.github.com
08:00clgvone of these ^^
08:00clgvrefheap is fine
08:00muhoowhy clojurebot no love refheap?
08:01clgv~paste
08:01clojurebotpaste is not gist.github.com
08:01meenalk..trying refheap
08:04firesofmayIs there any ios testing library in clojure?
08:04meenalhttps://www.refheap.com/paste/4092
08:10clgvmeenal: prints just fine overhere
08:10meenalwierd
08:11clgv(println buffer) => #<StringBuffer <v11:ID id="93"/>> AND (println (.toString buffer)) => <v11:ID id="93"/>
08:11meenallet me see wats wrong.. thank u
08:13clgvmeenal: notice the difference here: ##(let [s "<v11:ID id=\"93\"/>"] (println s) s)
08:13lazybot⇒ <v11:ID id="93"/> "<v11:ID id=\"93\"/>"
08:15meenalok.. println just prints fine, while what gets returned is with escape slah
08:16meenal*Slash
08:16clgvmeenal: only if you let the repl print the data
08:16clgvmeenal: i thinlk the repl uses pr
08:17clgv,(do (println "<v11:ID id=\"93\"/>") (pr "<v11:ID id=\"93\"/>"))
08:17clojurebot<v11:ID id="93"/>
08:17clojurebot"<v11:ID id=\"93\"/>"
08:18meenaloh ok..
08:18meenalcan i change the way it prints?
08:18clgvmeenal: why would you want that?
08:18meenaljust want to knw if its possible
08:18clgvjust use print/println if you really want to output something
08:19meenalclgv: sure, thank u
08:26muhoonrepl, clj, and cljs http://bace.s3.amazonaws.com/cljs-and-clj.png
08:27ro_stmuhoo: oooooh
08:28ro_sti can haz configs, pleez? :-)
09:01zaargywhen people say clojure is good for concurrency does that mean a specific kind of concurrency? [C[C
09:01zaargyif you just simply want to do lots of things at once but every 'thing' is quite isolated that's relatively easy in any language right?
09:02antares_zaargy: clojure has at least 5 concurrency features, all built with shared (but NOT mutable in the tranditional sense) state
09:02antares_*in mind
09:02antares_plus everything java.util.concurrent has to offer
09:02zaargysure, i udnerstand that
09:02zaargybut when you don't need shared state
09:03ohpauleezzaargy: If you have isolated processes, sure - but what happens when you need cooperative concurrency? Clojure's is complete in that it offers you all forms of concurrency and a way to get from one form to another. It takes a specific stance on *time* which no other language does
09:03antares_when you don't have to share anything, it does make things easier in several languages
09:03zaargysure, i definitely see that
09:04antares_then just use a message passing library of some kind
09:04zaargythe point is when i use have isolated things going on, i might decide to use a langauge i'm already familar with to do that, so it's trade-off
09:04zaargyi definitely see clojure has distinct advantages as soon as you talk about shared state
09:05ohpauleezzaargy: If you have isolated tasks, then you're focused on macro level concurrency anyway, which is much more of an architectural concern than a programming language
09:05ohpauleezprogramming language concern
09:06ohpauleezzaargy: So you'd be spinning up threads or forking things off to other processes
09:06antares_zaargy: it depends on what you are familiar with, if the problem inherently requries no shared state, erlang or scala with akka are excellent options
09:06antares_but clojure or java probably can do well, too
09:07ohpauleezClojure has thread pools configured out of the box and the calling semantics for something like a future are simpler in clojure than in other languages (many due to deref/@)
09:07zaargyyeah
09:08ohpauleezbut just one person's opinion :)
09:08ohpauleezzaargy: There's also underlying language constructs built on top of Fork/Join, so you get that for free
09:09ohpauleezin short: Agents, Futures, Promises, Fork/Join, and Atoms all when you need them, all with sane notions of time (where it makes sense), and all with sane use patterns
09:15ro_stohpauleez: :-)
09:15ro_stpubsub is compiling and working
09:15ohpauleezYES!
09:15ro_st*happiness*
09:15ohpauleezro_st: Enjoy!
09:15ro_stquestion. do i need to create multiple simple busses?
09:15ro_stor can i jam all my topics into a single bus?
09:16ohpauleezJam all of them on one
09:16ro_stwicked
09:16ro_stso it's (subscribe topic fn), (publish topic), essentially
09:16ohpauleezIn the first version of the bus, the bus was a singleton object, but I changed that to make it more functional
09:16ro_stwith the bus injected so that it's not some ambient value somewhere
09:17ro_stall to the good :-) nice for switching busses to see how the app's behaviour changes, as well
09:17ohpauleezro_st: That's the correct calling semantic, but more often than not, you'll just do:
09:17ohpauleez(subscribe bus some-fn another-fn)
09:17ohpauleezand leave it at that
09:17ro_stneed to publishize as well though, right?
09:18ohpauleezwhen some-fn is called in your code, it will publish its result to the bus automatically. All subscribing funcs will automatically be called
09:18ohpauleeznope, the bus handles it all
09:18ohpauleezohh yes
09:18ro_stso why is publishize there, then? :-)
09:18ohpauleezyou need to publishize the function
09:19ro_styeah
09:19ohpauleez(that design decision is to allow you to call the function WITHOUT it going to the bus automatically)
09:19ro_stthe fun bit for me is that all my model code is in .clj files and cljsbuild's crossovers are copying em over. so my pubsub will be a layer in cljs 'on top' of the model
09:20ro_stthis'll be fun to refactor
09:20ro_stright now all my ui is in one mammoth update-ui fn :-)
09:21clgvlein-outdated seems broken. it throws a "status 404" exception when connecting to "repo1-maven.org"
09:31ro_stohpauleez: what about atoms and publishize?
09:32ro_stcan you opt out of the bus when updating a publishized atom?
09:32ohpauleezro_st: Not currently, but that should probably be changed
09:33ohpauleezwell, hang on, I have to look at the code
09:37ohpauleeznope, you can't opt-out one-off
09:37ro_stnot a problem
09:37ro_stwas just curious
09:38ro_stgoing to start with fn based topics first
09:38ohpauleezcool, let me know if you hit a snag
09:38ro_stoh, i will -grin-
09:38ohpauleez:)
09:38ro_stps, it'd rock to have a pubsub impl working in jvm clj
09:39ro_stmeans can wire and test pubsub defs with midje :-)
09:39ohpauleezI've been thinking the same thing
09:39ohpauleezI'll make a deal with you
09:40ohpauleezif you tell me a report on what works and what doesn't work with the general protocol and approach
09:40ohpauleezI'll make a clj bus
09:40ro_stoh, happily
09:40ro_stgiven that you used protocols to begin with, plugging in a clj bus shouldn't be all that tough, right?
09:41ohpauleezexactly
09:41ro_sthttps://github.com/Yuppiechef/simple-rabbit/
09:41ohpauleezBut the feedback is important for the FRP work we're considering for contrib
09:41ro_strabbitmq with clojure
09:42ro_st#justsaying
09:42ro_stFRP?
09:42ohpauleezFunctional Reactive Programming
09:42ro_stoh yes
09:42ro_stonce my spike solution with pubsub is working, i'm going to start using phantomjs to write tests for it
09:43ohpauleezro_st: Full FRP thread is here: https://groups.google.com/forum/?fromgroups#!topic/clojure-dev/LzVu4dIvOrg
09:43ro_stone small thing i noticed is that the bus isn't always the first arg. in publishize it's second, in subscribe, it's first
09:44ohpauleezoh weird, I thought I made it the first for everything
09:44ro_stwhich means -> threading a bus isn't possible
09:44ohpauleezohhh you don't pass the bus to publishize
09:45ohpauleezoh, yes you do
09:45ro_st-grin-
09:45ohpauleezhahaha
09:45ohpauleezI need to look at my own code
09:45pandeiroro_st: check out my casperjs wrapper if you want to write your tests in clojure: https://github.com/pandeiro/ghost
09:46ro_stpandeiro: you rock!!
09:46ro_stdidn't know about casperjs
09:46ro_stthis looks fantastic
09:46ohpauleezSo I originally did that so you could visually see when you were using the Bus protocols and the Publish protocols, but I'm for changing it if it becomes a headache for you
09:47ro_stpandeiro: so this is for functional, integration, acceptance testing? what do you use for unit testing in cljs?
09:48pandeiroro_st: actually i am not using it for testing, but for scraping ajaxy pages like gtranslate
09:48ro_stoh right
09:48pandeirobut i think there's good potential for all that
09:48pandeirohonestly i am new to casperjs too but i was trying to implement a lot of it myself in phantom and luckily someone pointed me to it
09:48ro_stohpauleez: so, are you saying that the arg order matters, or that the bus isn't actually a necessary arg?
09:49ohpauleezno it's needed - so one thing can participate with multiple buses and you can track which buses it's publishing to
09:50ro_stohpauleez: i see you ^:export the publishized fn. is this required?
09:50ohpauleezro_st: Nope, just for use at the JS console
09:50ro_stohpauleez: ok, so bus could move to the first arg, then
09:50ro_stdoesn't have to, i'm just verifying that it's possible :-)
09:51ohpauleezyeah, but it doesn't do you any good for threading - you most likely def the result of the publicized fn
09:51ro_styes
09:51ohpauleezyou just want it to be consistent
09:52ro_sti think the consistency is good, ya
09:52ohpauleezfor sure
09:54ro_stso in my model .clj i'm setting up a (defn some-model-changed []) for pubsub to hook onto, and then from elsewhere in my .clj model i'll call (some-model-changed)
09:58ro_stah crap. so, there's no way to put a publishized fn into the .clj code for it to call
09:58ro_stwithout horrible state mutation stuff
09:58ohpauleezro_st: Yeah, you write the function (say - model-updated), then publishize it (def model-updated-pub (publishize model-updated)) then at the top level, wire up the subscribers
09:59ohpauleezthen in your code you just write (model-updated-pub 1 2 3 4)
09:59ro_styup. i have that set up.
09:59ohpauleezand the reactions auto happen
09:59ro_stexcept, the call to -pub has to happen from my .clj
10:00ohpauleezserver side? or just for crossovers
10:00ro_stboth, although server side probably won't actually want to publish to subscribers. as long as it compiles and doesn't break :-)
10:01ro_sti'm going to move the calls to pubsub stuff off to its own .cljs and stub it out in .clj
10:01ohpauleezyeah, from server side, what I do is pull it a level back to the client side and my it call a remote fn
10:02ohpauleezro_st: Yeah, that's the only work around right now. I didn't design with crossovers in mind
10:06foxdonuthttps://www.google.com/doodles/hurdles-2012
10:06foxdonut12.2s
10:08stainI got 16s
10:10ro_stohpauleez: it's working :-)
10:12ro_stlike so
10:12ro_sthttps://www.refheap.com/paste/4094
10:17ohpauleezro_st: Awesome to see. I think as you move forward you'll drop the *-topic name - since publishize is like memoize - it's still a function, you should treat it like one
10:18ohpauleezmostly for readability
10:18ohpauleezbut this is awesome - I'm excited to hear how it goes for you
10:18ro_stits possible. i'm using the earmuffs to make it clear where pubsub is happening
10:19ro_stsubscribe quickly became (defn subscribe [topic & fs] (doseq [f fs] (pubsub/subscribe bus topic f)))
10:20ohpauleezro_st: Same for me, you'll see that is being considered for the current protocol (commented out)
10:21ro_stcan you publishize an empty topic?
10:21ro_stie, just get a generic topic for the bus?
10:21ro_st(pubsub/publishize bus)
10:21ohpauleezyou want to see everything coming through the bus?
10:21ro_stanother good reason to put bus first. if f isn't passed, assume an no-op fn
10:22ohpauleezyou'd pass identity as the fn
10:22ro_stno, just making a topic that doesn't have any args
10:22ro_stgotcha
10:22ohpauleezro_st: You might also want something like subscribe->, which chains subscriptions
10:23ohpauleezso you can express full workflows
10:23mdeboardIs there anything about this macro, particularly lines 79-81 that are written improperly? I get an error message when I run it, but when I replace `~@body' with the actual code I'd otherwise be passing it, it runs fine
10:23mdeboardhttps://github.com/mattdeboard/clj-itext/blob/pdfwriter/src/clj-itext/core.clj#L62
10:23ro_stone triggers two, and two triggers three?, therefore, one triggers two and three?
10:24ohpauleezone->two, two->three, three->four, etc
10:24ro_stgotcha
10:24ro_sti have pretty simple pubsub requirements at the moment; one to one and one to many
10:24ohpauleezwhich is also being considered for the protocol (because I use it a lot)
10:24ohpauleezahh cool
10:25ro_stbut that's how i've planned it. i could very well need a chain
10:25ro_stidentity isn't working
10:26ro_stoh, wait, it's not working on the clj side
10:26ro_stisn't there a no-op function already?
10:26ro_stwith zero args
10:27ohpauleezwhat would that do in the bus? I can't picture the use-case
10:28ro_sthttps://www.refheap.com/paste/4097
10:29ro_stln 23 i have (fn [])
10:29ro_stwhen you want a blank topic that doesn't actually need a fn with args
10:29ohpauleezohhh
10:29ro_stthis works in cljs but in clj when i use identity in this manner it shouts at me :-)
10:30ohpauleezyou can just use strings or keywords
10:30ohpauleezwhen you want the topic to actually be a topic
10:31ohpauleezso if you want a broadcast topic (which I think you're going for)
10:31ro_stbut that'd cause mutlple calls to (topic) to return the same topic due to using the same source literal data
10:31ohpauleezjust use :broadcast or something to that affect
10:32mdeboardare you guys making a game
10:32ohpauleezro_st: this line doesn't make sense (def model-changed-topic (pubsub/topic))
10:32ro_stthink of topic here like a factory. no args, give me a fresh topic which i'll store at a name to subscribe to. arg, make a topic out of the arg.
10:32ohpauleezno
10:33ohpauleezit's a decorator
10:33bryanlis it a normal behavior of the lein midje lazytest to run my tests twice?
10:33ro_stright, publishize is. but i'm putting it into a factory, so that i can call it with no args to get a new fresh topic :-)
10:33ohpauleezmdeboard: He's battling through a library of mine that hasn't been released yet :)
10:34ro_sti'm trying to avoid having to create a no-op function in the model, basically
10:34mdeboardI see
10:34ro_stbecause the model will invoke the publishized version of that fn, and never the fn directly (in this case)
10:35ro_stit's not a biggy. i can live with no-op fns
10:36ohpauleezro_st: The return on a publishized-fn is the input to the subscribers
10:37ohpauleezso a no-op is going to blast nils through the bus
10:37ro_stok, so it has to be something real
10:37ohpauleezyeah
10:37ro_stcool. i can dig
10:37ohpauleezat most: #(identity 5)
10:38ohpauleezor something to that effect
10:38metelluswould comment work?
10:38metellus,(doc comment)
10:38clojurebot"([& body]); Ignores body, yields nil"
10:39ohpauleezmetellus: nah, still blast nils through the bus
10:39ohpauleezyou want a real return
10:39metellusoh ok
10:39ohpauleezif you want to signal as a topic, you can use strings, ints, or keywords
10:40ro_stah so i could do (pubsub/topic :model-changed)
10:41ohpauleeztotally
10:41ohpauleezI do it all the time
10:41ohpauleezwhen you want to broadcast something, that's the way to do it
10:42ro_stmoney for nothing, and your chicks for free?
10:43bryanli'm looking for an idiomatic method for taking the first two items off a list. kind of like first/rest, but i want the first-2
10:43achengro_st: maybe get a blister on your thumb
10:43pjstadig(take 2 ...)
10:43ohpauleezbryanl: ^
10:44achengro_st: (maybe i should say these are quotes from something, lest people think i'm sketchy)
10:44ro_st-grin-
10:49acagle_ /flush
10:53bryanlohpauleez thanks
10:53ohpauleeznp, thank pjstadig :)
10:54pjstadigohpauleez: from one paul to another...thank you
10:54ohpauleezhaha
11:08ro_stohpauleez: so, if i use (pubsub/publishize :topic-name bus), that should work?
11:09mdeboardpublischeisse
11:09ro_sti'm getting an exception: throw cljs.core.missing_protocol.call(null, "IPublishable.publishize", t);
11:09ro_stt is "﷐'current-cog-changed"
11:09ro_stmdeboard: sorry for the noise :-)
11:10mdeboardlol, just giggling about "publishize"
11:10ohpauleezro_st: You don't have to publishize the kw, you can just do raw publishes with it
11:10ro_stohhh
11:10ro_stfancy
11:11ro_stso then what's the api for publishing? because publishize returns a fn that i can call
11:12ro_st*reads source*
11:13ohpauleezro_st: In short, publishize takes callable or IWatchable things and auto-publishes for you, as a decorator
11:13ohpauleezotherwise you can broadcast on the bus, like a normal bus, using ints, strings, keywords
11:13ro_stok. just to get on with it, i'm going to use no-op fns
11:13ro_stso that my exposure to the api from .clj is limited
11:14ro_stbecause i'll definitely have both 'empty' publications and ones with data
11:14ohpauleez(publish bus :data-changed {:a 1})
11:14ohpauleezor (publish bus :data-changed nil)
11:26ro_strocking. works beautifully
11:27ohpauleezro_st: Glad to hear it!
11:28ro_stit's rough for now (i re-render entire chunks of the ui), but now the groundwork is laid to update the dom with laser focus
11:28ohpauleezawesome
11:28ro_stthe fun one is going to be inserting elements into the middle of a html node and removing them; basically responding to add/remove events
11:32pablo_Hi. I'm trying to find where "to-byte-array" went in Clojure 1.4 (it used to be in clojure.contrib.io). I've been searching for some time but didn't find it...
11:33ro_st~contrib
11:33clojurebotMonolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
11:33pandeiroclojure.java.io ?
11:34pablo_I didn't find it in clojure.java.io
11:36gfredericksis there any easy way to use jline programmatically?
11:37FrozenlockIs there, by any chance, a forum library for clojure? With compojure or noir?
11:40pandeiropablo_: sorry, dunno.
11:40pablo_pandeiro: no problem, thanks
11:41pablo_pandeiro: It looks like it just got ditched. It's a bit annoying, but I can copy-paste the code from contrib...
11:42scriptorFrozenlock: like a phpBB or something like that for clojure?
11:45pepijndevosis there a vimclojure cheat sheet? I put a lot of effort in getting this thing to run, but I keep forgetting all the useful commands it has.
11:45Frozenlockscriptor: yes
11:47FrozenlockI have a website on Noir and would like to add a forum without using another webserver
11:47ro_sti doubt an opensource clojure impl of a forum exists, yet
11:48ro_sttoo boring a thing to be building with clojure :-)
11:54si14hello, guys. what's a decent way to write parser in clojure now?
11:54arrdemsi14: while the original is out of date, I love fnparse
11:54si14looks like there are a bunch of PEG and Parsec-inspired parser generators, but all of them look ead
11:55si14*dead
11:55si14arrdem: is it alive?
11:55arrdemare you kidding me? the original has been dead for two years but there's an updated package
11:56ohpauleezsi14: Can a parser be dead? once you write a parser, there's nothing really left to do - there's no innovation or features to add, polish, etc
11:56si14https://github.com/search?langOverride=&amp;q=fnparse&amp;repo=&amp;start_value=1&amp;type=Repositories looks like the most recent one is 9 month old and without watchers
11:56Frozenlockro_st: yeah I guess... thanks :)
11:56si14ohpauleez: fixing bugs, adding combinators/examples/docs, squeezing performance
11:57arrdemyeah I agree with ohpauleez here. I though about adding some features to FNParse for a while, and then I realized I could achieve everything I wanted with some tack-on macros that were project specific.
11:58si14ok, then what fork is best to use?
11:58ohpauleezthat's often what I find too arrdem. I either need some lightweight parser or just use antlr from clj
11:58arrdemorg.clojars.doo/fnparse "2.2.8" is what I used in my last parser project
12:01arrdemohpauleez: how well does antlr work for you? I looked at it for a while but it didn't have the grammars I wanted packaged so I built em in fnparse
12:01ohpauleezarrdem: Pretty well if you just need some AST from a grammar they provide or one you can adapt
12:01ohpauleezI started with fnparse for a JS-like language
12:02ohpauleezgot pretty far
12:02si14arrdem, ohpauleez, anyway, tkanks :)
12:02si14*thanks
12:02ohpauleezswitched to ANTLR and in a week had the same thing, just need some extra work to push it into Clojure data
12:05ohpauleezsi14: np
12:06arrdemohpauleez: ooh.... they have my base language too.... thanks I may have to transition
12:06casiondoes anyone know of a 'functional programming' tutorial written in clojure?
12:06casioneverything I find is in haskell
12:07ohpauleezcasion: Neal Ford's Thinking Functionally pieces?
12:07ohpauleezthat are Java, Groovy, and Clojure
12:07casionohpauleez: let me look
12:08ohpauleezcasion: I think Functional Programming for Java Developers + Neal Ford's Thinking Functional + one of the intro Clojure books should be nice
12:08ohpauleezmaybe 7 languages to round it all out
12:08casionI don't know any java at all
12:08casionor any oop languages for that matter
12:09ohpauleezcasion: First language? if not, where are you coming from?
12:09casionohpauleez: been working in c/asm for about 14 years
12:09casionand only c/asm, mostly embedded
12:10casionpretty closed off from the rest of the world until I decided to change that recently
12:11ohpauleezcasion: It's going to be a bit of a brain bend, but shouldn't be too bad. I'd suggest just working through one of the intro Clojure books
12:11casioni have both the emerick and halloway books
12:11ohpauleezAlso, the Caves of Clojure is a nice piece
12:12ohpauleezthose are great books
12:12casionemericks book is way, way over my head
12:12trptcolin,(doc promise)
12:12clojurebot"([]); Alpha - subject to change. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block, unless the variant of deref with timeout is used. All subsequent derefs will return the same delivered value without blocking. See also - realized?."
12:12ohpauleezcasion: Try Seven Languages in seven weeks and also read through http://stevelosh.com/blog/2012/07/caves-of-clojure-01/
12:12casionit analogizes everything to languages Im not even remotely familiar with
12:12ohpauleezmaybe those will help
12:13trptcolin,(doc deliver)
12:13clojurebot"([promise val]); Alpha - subject to change. Delivers the supplied value to the promise, releasing any pending derefs. A subsequent call to deliver on a promise will throw an exception."
12:13casionok ohpauleez
12:13trptcolin,(let [p (promise)] (deliver p "hi") (deliver p "lolwut?") @p)
12:13clojurebot"hi"
12:13casionI feel like I understand most of clojure, but how to approach things functionally is not making sense (yet?)
12:13trptcolin^^ just a wrong docstring, or are there situations in which multiple delivers actually throws?
12:14arrdemcasion: TBH most of the clojure code I write is imperative
12:14clgvtrptcolin: yes when you deliver to the same promise more than once
12:14trptcolinclgv: see the example i pasted above?
12:14casionarrdem: any examples?
12:14arrdemit's just getting used to using (map) and (reduce) and other applicative functions where appropriate
12:15clgv trptcolin: oh. that was changed in 1.3
12:16ohpauleezcasion: It definitely takes time. Watch Rich's talk: http://blip.tv/clojure/hammock-driven-development-4475586
12:16ohpauleezthe trick is building up to the solution using smaller pieces
12:16casionah, I've watched a few of hickey's talks
12:16casionnot seen this one
12:17casionthank you for the info so far :)
12:17ohpauleeztotally welcome
12:17foodoocasion: Thinking in a functional way is also a matter of practise. Maybe you should check out 4clojure.com
12:17ohpauleezcasion: ^ also a great suggestion
12:17trptcolinclgv: gotcha, thanks. just wasn't sure if it was intentional. we'll open a ticket
12:17casionfoodoo: ah
12:17casioni have the clojure koans as well, been going through those once a day
12:18casionI'll add this to my daily routine as well
12:18casionI think in large part the concept of immutability just breaks my mind
12:19casionat least as a 'rule' rather than an option
12:19foodoocasion: sure, if you worked with assembler before then you have a totally different view on the machine
12:19casionyeah
12:20foodooso you should consider functional programming as a safeguard. It will restrict you in your ways of solving things, but it will also provide you with the possibility to make some assumptions which are guaranteed to be true
12:21foodooand you should also understand that there is no 'true' definition of functional programming. About every programming language approaches it differently, if at all. (The same applies to OOP)
12:22casionyes, I get that
12:22casionif for no other reason than asking questions in #haskell ;)
12:28otfromheading off to skills matter in a bit for this: http://skillsmatter.com/event/home/london-clojurians-user-group
12:28otfromstill spaces if anyone is in London and fancies coming
12:29casionthese caves of clojure posts are fantastic
12:35ohpauleezcasion: Glad to hear!
12:45achengmaybe a wiki somewhere should list the current-best clojure caves for things like functional programming, concurrency, etc
12:46antares_Clojure folks, don't forget to cast your vote in this "JVM priorities" survey: http://www.infoq.com/research/priorities-java-jvm
13:31gerunddevAh core.logic... just when I think I've got you I find something else I don't understand!
13:31gerunddevhttps://gist.github.com/3287562
13:31gerunddevI really thought the first constraint would mean no results whether or not view and search are present.
13:32gerunddevBut in unit tests if I pass in nil for design but a value for view I get ["_design" nil "_view" "view"]
13:35amalloy!= is a tricky animal, gerunddev. i don't really get it either, and my general approach is to stay away from it
13:35gerunddevamalloy: Have you found another trick to avoid nulls?
13:36amalloydon't pass nils to begin with. core.logic doesn't create nils for you in most of its core primitives. for example, emptyo rather than scheme's nullo
13:36gerunddevBTW I updated my gist to have code, unit test and results: https://gist.github.com/3287562
13:37gerunddevOk so I could check for nulls before passing into my logic code I guess
13:37gerunddev*nils
13:37amalloyie, i haven't avoided nils because i haven't encountered one yet
13:39gerunddevI am destructuring keys and trying to interpret the next step based on a bunch of rules.
13:39gerunddevIf a key wasn't passed in the symbol will be nil...
13:39gerunddevI'd like to say oh you passed :a and :b, but not :c and so I'll go down this path...
13:43gerunddevamalloy: Ok I figured out a solution. Introduce a new lvar, put the constraints on that... Solution added to the gist: https://gist.github.com/3287562
13:44amalloythat doesn't make sense to me. i suggest asking dnolen` what's up
13:45gerunddevdnolen`: Does this make sense to you? https://gist.github.com/3287562
13:45milindaanyone know way to store zip archive as a blob via sqlkorma?
13:45gerunddevdnolen`: Looks like I had to add an extra lvar to constrain against nil...
13:52amalloyfwiw, gerunddev, i doubt nil is relevant; have you tried the same thing replacing nil with, say, 5? it's probably != that's acting oddly, not nil
13:59eggsbyHmm, I'm giving a short 5 minute talk on clojure at work to try to get other teams to start using it... what sort of stuff should I try to fit in there... hello world doesn't seem like a good example of it's power, but I'm afraid stuff like macros/lazy-seqs would probably be too advanced...
13:59technomancywow, the original jdk6 EOL date was last month
14:00duck11231is there an up to date ants demo? That was pretty cool originally
14:00naegeggsby: I have a link for you and I think Clojure Programming has a section on that - checking both...
14:00amalloyeggsby: demoing some math stuff is pretty easy and somewhat awe-inspiring
14:00technomancyit got pushed back to november though
14:00technomancymaybe we can have a deprecation party at the conj =)
14:00amalloyeg, finding the sum of the squares of the first hundred odd fibonacci numbers
14:00scriptoreggsby: what kind of stuff do you work on at work?
14:01gerunddevamalloy: Ok now the original code is working fine... maybe I'm just letting nrepl get in weird states over time...
14:01hiredmantechnomancy: last I heard clojure's minimum jre is still 1.5
14:01amalloygerunddev: no, i was able to repro your original problem with copy/paste into a fresh repl
14:01naegeggsby: yeah, Clojure Programming has: Chapter 19. Introducing Clojure into Your Workplace which might help you and also this link: http://www.andrewhjon.es/142343729
14:01amalloylast time i did that, eggsby, i got the clojure program right on the first try, and made two or three subtle errors in my C version
14:02eggsbythanks guys!
14:02otfrom@ryangreenhall is giving a great shout out to the friendliness and thoughtfulness of this channel. Thanks everyone for being a great and welcoming place.
14:02otfrom(I'm at the London Clojurians skills matter talk btw)
14:02casionamalloy: thanks again for writing that code last night, I'm slowly figuring out the concept of it
14:02gerunddeveggsby: Another suggestion, maybe use light table? I used it to show a coworker.
14:02eggsbyscriptor: I work at an affiliate advertising company, so it's mostly tracking events and asking questions about those events
14:03amalloycasion: uvtc apparently plans to write a blog post about it
14:03amalloymake sure you look at the updated version; i was managing cooldown a bit wrong
14:03casionamalloy: about the 'problem' i presented?
14:03amalloyand my solution to it, yes
14:03casionamalloy: yes, I was going to ask about that
14:03gerunddevamalloy: Oh no, that's scarry that my tests are passing now. Well meeting time, then I guess I'll get back to it. Thanks for the help!
14:04naegotfrom: I can only confirm that, after being around for a few days
14:05naegnot all channels are like that...
14:05otfromnaeg: agreed. Just thought I'd pass on the love from the talk.
14:06dnolengerunddev: sorry didn't see your earlier question until now.
14:07gerunddevdnolen: I hope the gist is clear, it seems that != isn't acting the way I expected
14:08naegotfrom: sounds like an interesting talk...is it? probably useful for eggsby too
14:08dnolengerunddev: it's the first test that's giving you the weird result right?
14:09gerunddevdnolen: Yes
14:09dnolengerunddev: oh right.
14:09dnolengerunddev: core.logic expressions are not regular clojure statements
14:09amalloyoh, he needs an (all ...)
14:09dnolengerunddev: uri-path is not correct, you need a fresh around that or all.
14:09gerunddevSo adding the fresh in the solution was the fix?
14:10amalloynow i feel silly for not noticing that myself
14:10dnolengerunddev: all just macroexpands to (fresh [] ... goals ...)
14:10dnolengerunddev: so no ... that extra var is not necessary.
14:10dnolengerunddev: it's the conjunctive aspect of fresh that fixed your problem.
14:11gerunddevYeah, that's funny. I didn't need x, but fresh was the real fix. Ok, so when do I need an all or fresh?
14:11dnolengerunddev: all is idiomatic since you don't need to declare any vars.
14:12amalloygerunddev: anytime you want to make multiple logic statements you need to wrap them up in *some* core.logic container
14:12dnolenyep
14:12amalloyusually they're already inside a fresh or whatever, so that you don't have to do anything. but at the top level of a regular defn...
14:12gerunddevOk so start everything with a fresh or all (if no vars are needed). Got it!
14:12dnolengerunddev: I made that mistake recently too, it's easy to forget.
14:14dnolengerunddev: perhaps an argument for defg sugar that does that for you ...
14:14gerunddevGreat thanks for the help! I'm loving core.logic for problems, just need to keep understanding it better
14:14amalloydefg, for goal? does that exist already, or are you proposing it?
14:15dnolenamalloy: doesn't exist ... perhaps worth considering if the sugar should be comprehensive.
14:16dnolenamalloy: I made a similar mistake w/ let.
14:16amalloyi've done it too
14:17amalloybut i'm not sure defg is a good solution. it will train me to look at (defg f [x y] (== x 1) (== y 2)) and say "oh, that's fine". then the pattern-recognizer in my brain will not notice the difference in (defn f [x y] (== x 1) (== y 2))
14:18dnolenamalloy: yeah, I somewhat agree. it's an surprise that's probably best for people to actually understand.
14:18dnolenamalloy: it's just annoying because it won't fail, you'll just get strange results.
14:19dnolenwon't "always" fail I mean.
14:19amalloyright
14:21amalloywhat would be ideal is if you could somehow hook into the macroexpander/compiler, and complain if the form "above" a logic statement is (do ...)
14:22amalloybut i don't think there's any way to do that currently
14:22amalloy(nor am i proposing there should be, really)
14:28acagle_ /flush
14:32achengit seems if something takes 3 screens to print out at the repl in emacs, the repl gets very slow. ... and stays slow even for later expressions like (inc 3)
14:32casionacheng: I've noticed this as well
14:33technomancywrapping extremely long lines is pretty slow in emacs, especially with screen splits
14:33technomancyC-c M-o clears output in slime IIRC
14:33achengcasion: i'm on windows. i was wondering if it was just my machine. i can even hear something like a cpu fan spin up
14:33casionI'm in os x, and it happens to me
14:33technomancyusually takes more than 3 screens to cause a slowdown though
14:33achengooh, thanks technomancy!
14:34achengthat improves things
14:35duck11231never try to print a whole bunch of xml at the clojure repl. It causes no end of trouble
14:35technomancyit's usually fine if you have newlines
14:37achengif i have a zipper from an xml string and it has :tag :attr and :content... how do i get the content for something with :tag foo ? (xml-> foo :content) ?
14:37amalloybut technomancy, isn't that wasting like three bytes for every xml tag? i really want to use xml for my super-compact format
14:38achengduck11231: the reason i'm printing xml to the repl is that i'm trying to figure out zippers
14:38hiredmantechnomancy: if you use prn the newlines will all get escaped, so you are boned
14:39duck11231acheng: right, I was just noting that every time I've tried to print out xml to slime I've ended up regretting it
14:39technomancyhiredman: yeah, that sucks =\
14:40duck11231That's why I tend to prefer using the logging lib and running my server from a terminal, that way if I want to dump anything, I can just hit F12 to pull down my terminal
14:44piranhastill no replies to my question about protocols in clojure mailing list... :( I wonder if I should escalate that somehow - it looks like a bug to me.
14:45achengnakkaya.com/2009/12/07/zipping-xml-with-clojure/ has an example... the paintings zipper has something with tag :img that has :content nil... how would i verify that it is nil using clojure code? ... or let's imagine that it has content "foo"... how would i verify that?
14:45llasrampiranha: What was the subject line for your post?
14:45piranhallasram: ClojureScript & protocols
14:48llasramOh, Clojure*Script*. Sorry, I haven't used yet
14:48piranhanp :)
14:48_fogus_Has anyone experimented with SCXML and Clojure?
14:49piranhaI'm just wondering if 2-day lag is ok for this mailing list or does this mean that message probably won't be replied ever...
14:50technomancythe mailing list really isn't what it used to be =\
14:50clojurebotlist* doesn't actually make a `list?`
14:51llasramThanks, clojurebot!
14:51pepijndevoswhere is lazybot?
14:51llasrampiranha: Yeah, hard to say. Usually people jump on pretty quickly if they can help.
14:51duck11231piranha: just like any ML, sometimes good posts slip through without any response
14:52piranhayeah, I see... I'll wait until tomorrow's morning and probably will reply to myself. I guess I can't just create a ticket in an issue tracker, haha :-)
14:52llasramMaybe someone here has some ideas? FWIW, nothing leaps out of me about your code, but like I said, don't know what quirks ClojureScript has
14:53_fogus_technomancy: The ML seems the same as always... except for a different Ken
14:53duck11231if you can find a way to make a reproducible test case, you'll discover your error and have no need for the test case (at least that's how it usually works)
14:54llasrampiranha: Well, there is one thing I can think of: re/evaluation order. If the protocol is loaded, the record defined, then the protocol re-loaded, the record can end up implementing the earlier version of the protocol, which is no longer what the protocol vars reference. (Or at least that's what can happen in JVM Clojure -- no idea if it also plagues ClojureScript)
14:54acheng(ah, i think "text" is the answer to my question... the return value of (xml-> paintings :tag-name text) seems to match any edits i make)
14:55piranhallasram: hm, is order of importing is somehow wrong in my code?
14:55m0smithpiranha: where is your code? I just worked through getting protcols to work in clojurescript
14:56piranham0smith: oh, 1 second
14:56piranham0smith: https://github.com/piranha/cj-locations/blob/master/src/google.cljs
14:56piranhahere is a file which imports protocol and implements it
14:56piranhaprotocol is, naturally, in file 'map.cljs'
14:56llasrampiranha: Oh, no. I'm talking about something that can happen in the REPL. If this happens with a fresh environment, loading things in normal order, then the issue I mentioned is not the problem
14:56piranhaah, I see...
14:57piranhallasram: well, here it looks like defrecord has no idea how to generated method names based on protocol or something like that
14:57piranhaI don't know really :)
14:57piranham0smith: so does this look wrong? :-)
14:58m0smithpiranha: I did two things differently in https://github.com/m0smith/crossfire/blob/master/src/crossfire/miss.clj
14:59piranhahmhmmh
14:59piranhaI tried with extend-type
14:59m0smithFirst, I used extend-type
14:59piranhabut I'll try once again :)
15:00m0smithSecond I used :require :as on the protocol and referenced it that way
15:00piranham0smith: I see... I'll try, give me few minutes :)
15:00m0smithlines 9 and 16
15:00m0smithk
15:01piranhabtw, when I did :require [locations.map :as lmap] in my core.cljs, I couldn't refer to them as lmap
15:01pandeiroi created an indexed seq with entries like [0 "foo"] [1 "bar"] ... and say i want to return a sub-sequence of just items 300 through 350
15:01pandeiroi thought i could use (select-keys indexed-seq (vec (range 300 350)))
15:01pandeirobut i that would work if it were a vector i suppose
15:02m0smithpandeiro: (take 50 (drop 300 ( your-seq)) ?
15:02piranham0smith: :require :as helps!
15:02piranhaoh yeah
15:03piranha%)
15:03technomancypandeiro: interestingly select-keys accepts a vector, but it returns a map
15:03piranhaI should reply to my email just in case
15:04amalloyit couldn't really work well otherwise, right, technomancy?
15:04m0smithpiranha: glad it helps. I had some help on this channel the othernight getting it right.
15:05piranha:)
15:06pandeirotechnomancy: yeah i noticed that, b/c it uses (find...) under the covers, which works on vectors
15:06pandeirom0smith: that works too
15:06technomancyamalloy: right, not reliably across a non-contiguous key range
15:06amalloytechnomancy: even a contiguous key-range
15:07amalloy(-> (select-keys x [k]) (get k)) should return the same as (get x k), for all k, i think
15:09technomancyhrm; arguable
15:09technomancywell... yeah, probably
15:10piranham0smith: do you by any chance know then why is this https://github.com/piranha/cj-locations/blob/master/src/core.cljs#L18 compiled as lmap.Map instead of locations.map.Map? :)
15:11piranhaor maybe someone else knows... it works normally in some places it seems though
15:12m0smithpiranha: It is in both the :use and the :require and the one in :require is missing the [ ] around it. You can 2 things being required but only one vector
15:12piranhaoops
15:12piranhai'm dumb apparently
15:12piranham0smith: thanks :)
15:12m0smithwhen I first started I was missing the : on :use and it mostly worked
15:13piranha:-)
15:13piranhaanother question: does anybody here use some analogue of promises/futures?
15:13piranhato abstract at least somehow from js endless callbacks
15:13m0smithpiranha: I have been banging my head on that same question.
15:13piranha:-)
15:14piranham0smith: I found an article by Brian McKenna, plus this piece of code: https://github.com/netguy204/MOVE/blob/master/src/move/macros.clj#L29
15:14m0smithjavascript is not threaded, except for WebWorkers and AJAX as far as I can tell
15:14piranhaajax is not threaded at all
15:14piranhait's just asynchronous
15:15piranhaweb workers are threads but I don't know anyone who uses them
15:15m0smithpiranha: I saw that article as well
15:15piranhait's a bit like some monad, this doasync
15:16piranhaI would love to have some abstraction but I still am not used to clojure that much to see what can be done
15:16piranhaand what's the best way :\
15:16piranhaI would love to have someone more experienced do that part for me :D
15:16m0smithpiranha: I was going to look into WebWorkers to see if it can be done
15:16piranham0smith: well, I guess it can, but it won't help you much I think
15:16m0smithI am still thinking about it but you can watch the crossfire project
15:17piranhaeverything is callbacks
15:17ibdknoxthere's a long discussion about this on the dev list
15:17piranhaibdknox: oh, interesting. Is there any outcome?
15:17ibdknoxpeople are working on it :)
15:17piranham0smith: crossfire is a game, right?
15:18piranhaibdknox: hehe :) is there any work in progress or something just to poke something at least? :)
15:18m0smithpiranha: yes, a Battelship-ish game. I am using it mostly as a way to investigate some ideas related to other projects
15:18piranhaibdknox: can you maybe tell me a name of thread with discussions? I couldn't find anything...
15:18ibdknoxpiranha: https://groups.google.com/d/topic/clojure-dev/LzVu4dIvOrg/discussion
15:18piranhathanks
15:18achengdoes lein search work for you right now? i get a 404... is a repository down?
15:19piranhabtw, is there any site which can show you clojure libraries available on clojars?
15:19piranhaand if not, why? :))
15:20antares_piranha: there is a couple, and a new one in the works, that list prominent libraries
15:20uvtcpiranha: I'm glad you asked...
15:20antares_there is interest in getting a better browsing UI into clojars.org eventually
15:20uvtcpiranha: The Dining Car is new, and lists a few: http://www.unexpected-vortices.com/clojure/dining-car.html
15:20antares_piranha: some projects have their own sites, e.g. http://clojurewerkz.org
15:21piranhayep, I've seen clojurewerkz
15:21uvtccasion: ping
15:21casionsup
15:21piranhauvtc: dining car looks like something curated by hand, right?
15:21casionI heard you were writing a blog post about the code amalloy did?
15:21xeqiacheng: the index on central changed, and lein needs to update... theres an issue for it
15:21piranhaantares_: is clojars.org open source?
15:21xeqipiranha: https://github.com/ato/clojars-web
15:21uvtcYou were asking about amalloy's example last night. I wrote up a blog post explaining the code. Have a look: http://www.unexpected-vortices.com/blog/2012/clojure-battlebots.html
15:22achengxeqi: thanks!
15:22casionuvtc: awesome
15:22uvtc:D
15:22casionis that the updated code?
15:22antares_piranha: https://github.com/ato/clojars-web/
15:23uvtcpiranha: Yes, hand-curated --- hopefully by the community though. I don't know many libraries.
15:23piranhaI guess I have to update my laptop if I want to continue my endeavor with clojure...
15:24piranhauvtc: well, this solves part of the problem - list of quality/mature libraries.
15:24uvtccasion: Yes, it's amalloy's latest.
15:25casionuvtc: reading it now
15:34casionuvtc: so at the conceptual level, it's just finding the 'next attacker', subtracting that distance from the cooldown of both fighters, dealing damage, thn returning a list of the 2 fighters new state
15:34casionis that correct?
15:35scriptorcasion: I've only looked at it briefly, but that's what fight-one-round seems to do
15:35uvtcWell, you only subtract it from the other fighter's cooldown-remaining. The one who did the attacking gets its cooldown-remaining reset to max.
15:36casionuvtc: ahhhh that makes more sense
15:36scriptorfind the next cooldown, do damage, move clock forward by that cooldown (ie. set cooldowns to new points)
15:37casionalright, this explanation was incredibly useful
15:37uvtcYay! {big smile}
15:38casionthe idea of returning a list of an updated state completely eluded me
15:38casionand the lazy evaluation I didnt catch either, I was stuck on why the code didnt just blow up haha
15:39uvtcYou can use recursion, and pass state along as args into the recursive function, but amalloy's method here skipped that and just used iterate + the `fight-one-round` function.
15:39casionwell, my next task then, is to write this differently on my own
15:40uvtc(That is, he let `iterate` do that recursion for you.)
15:40casionit seems like you could do this without tick
15:41casionand simply subtract the min from both fighter's cooldowns
15:41casionthat sets the min result to 0, and decrements the other to the new state
15:42pandeirohow can i match a paren in java regex?
15:42ibdknox\(
15:43pandeirohuh
15:43pandeirohow can i return what's inside parens?
15:43jodarois that the answer or a new emoticon?
15:44jodarounhappy cylon
15:44TimMcpandeiro: \(([^)]*)\) ?
15:45TimMcpandeiro: Unless you want nested parens, in which case you'll need to add a stack and a loop (making it a context-free parser).
15:45m0smithI love the quote from the Joy of Clojure: If you think you have a problem you can solve with regular expressions, now you have two problems
15:45TimMcm0smith: It's an old quote.
15:45TimMcjwz, maybe?
15:45pandeiroyeah that's a classic
15:45pandeiroTimMc: ibdknox: thanks
15:45amalloyyeah, jwz is usually credited with it. dunno if he was first
15:46m0smithTimMC: All old things are new again. We are talking about LISP and all of a sudden 50 years of computer thought become more relavant
15:46TimMcIt's probably an appropriation of an older adage.
15:46pandeiroTimMc: not sure why the second closing paren goes inside the square brackets
15:46pandeirowait, is that a typo? there are three closing parens
15:46TimMcpandeiro: It doesn't; [^)] means "anything but a closing paren".
15:47TimMc[^\)] if that offends your sensibilities.
15:47pandeiroah got it
15:47pandeiromakes it clearer with the escape i think
15:48TimMcOne of the rare cases in regexes. :-)
15:48amalloy:( to adding \ arbitrarily because you aren't comfortable with how [] works
15:48amalloyit's like putting ) on its own line - makes you comfortable for a while, but ultimately hinders understanding
15:50pandeiroamalloy: good point, i am definitely not comfortable with how [] works
15:50langmartinso I have a program that's been running in production for a few months and a some of my recent patches make it fire the garbage collector every few seconds on Linux (not on mac)
15:50TimMcamalloy: What it really means is that one's editor is insufficient. :-P
15:50langmartinIf there isn't an easy answer to this it's probably one I'll have to trace for
15:51langmartinproviding the jvm command line option to stop explicit gc "fixes" the issue
15:51langmartinthe interesting part is that it's a boring set of patches, with no new dependencies
15:51TimMc$ grep 'System/gc' . --include='*.clj'
15:51langmartinI did use System/getenv for the virst time
15:52amalloy$ find -name '*.clj' | xargs grep System/gc ## more flexible
15:52langmartinTimMc: tried that, no match
15:53TimMcOh, and throw an -nR in there, or use amalloy's suggestion. -.-
15:53amalloylangmartin: does the behavior go back if you revert the patches? could be unrelated
15:53TimMclangmartin: Is it just producing more garbage?
15:54langmartinthe behavior does go back if I revert the patches
15:55langmartinTimMc: that's a good question, of course. the command line switch -XX:+DisableExplicitGC is what makes the vm stop spiking cpy
15:55langmartincpu, that is
15:55langmartinwhich shouldn't stop anything but explicit collection
15:56langmartinI was hoping there was some known thing in clojure (1.3) about the return value of System/getenv or something easy
15:56hiredmanlangmartin: how are you running the app?
15:56langmartinhiredman: from an lein uberjar
15:57hiredmanhuh
15:57langmartinjava -XX:+DisableExplicitGC -cp platform-standalone.jar platform.core -v -d
15:58langmartinif there isn't a known issue I can trace it down, I'll just have to do it after a few unrelated things done
15:58hiredmanlangmartin: so by "it's a boring set of patches" you mean there are no direct calls to System/gc in the patches? have you looked for indirect calls?
15:58langmartinhiredman: correct. It's mostly moving names around in maps
15:58langmartinthere are no explicit calls to System/gc in my code at all
15:58TimMcAt this point I'd try attaching a debugger and breakpointing System/gc.
15:59TimMcAre there other ways of invoking GC?
16:00hiredmanlangmartin: yeah, but if your code calls X and X calls System/gc
16:00langmartinsure
16:00langmartinI went looking at gc as a culprit because it was spiking the cpu while my code was idle
16:00langmartinwaiting for incoming network connections
16:01m0smithlangmartin: I have seen this behavior in Java programs from both XML parsing and CORBA message passing. It has also occured with Spring when the context gets initialed a bunch of times
16:01langmartinwherever System/gc is getting called, I don't think it's in anything that's started by a call in my program
16:02langmartinm0smith: I'm not intentionally doing any of that, there must be an xml parser in log4j somewhere, though
16:33casionif I have a vector of maps, how do I get the a new vector of maps where :key is x
16:34casionand all associated keys in those maps intact
16:34amalloyfirst, clarify what "where :key is x" means
16:35casionsay I want to find all maps in a vector with :key 10
16:36amalloytry ##(doc filter)
16:36lazybot⇒ "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."
16:36nDuffcasion: Do you really need a vector, or just a sequence?
16:36technomancyor filterv if you like
16:38RaynesHe is such a square []/
16:38amalloynobody(1) ever really needs a vector
16:38amalloy(1) except people who already know this and don't ask the question
16:38casionnDuff: I have no idea
16:39technomancyI wonder how often mapv/filterv are abused simply to avoid doall
16:39S11001001I don't need a vector
16:39technomancyalso: is that an abuse?
16:39technomancyI think so
16:40S11001001technomancy: depends if you need a vector; it'd still cons less to keep the doall result
16:40technomancyI'd argue that using mapv communicates to the reader that a vector is specifically needed
16:40S11001001better than vec?
16:41technomancyso if you use it to replace doall it could cause confusion about the intent of the code
16:41amalloyS11001001: you think so? conj! probably doesn't allocate that much, does it?
16:41S11001001amalloy: oh, right, I forgot that you could implement mapv without plain map and into
16:43pandeiroi have '(2007 :a :b :a :b :a :b 2008 :a :b :a :b) and i want '((2007 (:a :b :a :b :a :b)) (2008 (:a :b :a :b))) - which hofs will do best here?
16:44amalloypartition-by?
16:45casionamalloy: so does something like (filter #(zero? (:key %)) coll) seem reasonable?
16:45amalloysure
16:46casionok thank you
16:46amalloypersonally i prefer (filter (comp zero? :key) coll)
16:47pandeiroamalloy: sure got that, and then once i have ((2007) (:a :b :a :b)), partition 2 ... etc? is there no easier way?
16:48casionamalloy: ah ok, I wasn't familiar with comp
16:59muhoohehehe, nrepl and pprint are not happy. it can get into an endless loop printing unlmited recursion levels
16:59muhooand yes, i have (alter-var-root *print-level* (constantly 15))
16:59muhoopprint seems to ignore that when using nrepl
17:11dakrone,(doc *print-level*)
17:11clojurebot"; *print-level* controls how many levels deep the printer will print nested objects. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum level to print. Each argument to print is at level 0; if an argument is a collection, its items are at level 1; and so on. If an object is a collection and is at a level greater than or equal to th...
17:11dakronemuhoo: you are setting *print-level* to a function instead of a value
17:12dakrone,(binding [*print-level* 2] (println {:a {:b {:c {:d 1}}}}))
17:12clojurebot{:a {:b #}}
17:12amalloydakrone: no he isn't
17:12amalloybut in using alter-var-root instead of binding, he's probably not impacting the thread-local binding that his repl already has
17:12dakroneamalloy: you are correct, I was thinking binding, not alter-var-root
17:14dakroneif you're interested in setting it globally, why not just use (set! *print-level* 15)
17:20technomancyman... tempted to use deliver as a 1-arg funcall here
17:20technomancy(-> (cemerick.drawbridge/ring-handler) (basic/wrap-basic-authentication authenticated?) (deliver req))
17:20amalloytechnomancy: just define your own funcall in a utils lib somewhere
17:21amalloyor use useful.utils/invoke
17:21technomancythis is a lein-template, so that's not really appropriate
17:21amalloyneither is using deliver as a stand-in for funcall, man
17:22technomancyI know; just sharing my internal struggles and temptations.
17:23technomancyhttp://p.hagelb.org/sample-web.clj.html <- not a big fan of the way conditionals fit into the -> wrapping pattern
17:24technomancy(if (= "/repl" (:uri req)) ...) and (if (env/env :dev) ...)
17:26muhoodakrone: IllegalStateException Can't change/establish root binding of: *print-level* with set clojure.lang.Var.set (Var.java:233)
17:27muhootechnomancy: awesome, drawbridge wrapped in friend for auth!
17:27hiredmantechnomancy: you know, you could use define some routes
17:27hiredmanjust
17:27technomancymuhoo: friend is overkill here
17:27technomancyhiredman: oh yeah, that would be a lot nicer for the repl bit
17:27dakronemuhoo: interesting, it works at the repl, perhaps a clojure version difference?
17:27technomancyhiredman: still sucks for wrap-stacktrace though
17:28muhoodakrone: i'm on 1.4, using nrepl
17:29dakronemuhoo: same: http://p.draines.com/1344374866770fec31fe4.txt
17:29raekmuhoo: the ordinary clojure repl is executed inside a clojure.main/with-bindings
17:29hiredmantechnomancy: higher order wrapping
17:30hiredman(-> (wrap-cond trace/wrap-stacktrace env :dev) ...)
17:30technomancyhiredman: starting to look conduity =)
17:34muhooraek: is there any way to get underneath that and change those bindings?
17:34llasramHuh. Why does the docstring for `deliver` say "A subsequent call to deliver on a promise will throw an exception," when that is not in fact true?
17:35llasramSubsequent attempts actually just return `nil`, which IMHO seems more sane anyway
17:35muhoollasram: jira
17:36raekmuhoo: if you are in the dynamic scope of a 'with-bindings' or 'binding', then you can just use 'set!'
17:36amalloyllasram: the impl changed in 1.3; the docstring, predictably, did not
17:36llasramamalloy: Ah, that makes sense
17:36hiredman:(
17:36muhooraek: theoretically, however, set! throws an exception in the repl, strrangely.
17:36hiredmanthat is horrible
17:36llasrammuhoo: Man, time to go home. I thought "good idea," and opened my work Jira instance
17:36hiredmanit should throw
17:37muhoollasram: hahaha
17:37amalloyhiredman: i like the nil behavior
17:37muhoollasram: beer-thirty
17:39raekmuhoo: in which repl?
17:39muhooraek: nrepl
17:39raeksounds like nrepl is missing something, then...
17:49akhudekIt is possible to use the SVN version of the closure library with clojurescript?
17:49trptcolindeliver docstring patch is now in jira, fwiw - http://dev.clojure.org/jira/browse/CLJ-1038
18:04m0smithibdknox: is crate ready for people to try?
18:09naegbtw, this is the talk otfrom was talking about: http://skillsmatter.com/podcast/home/reviving-uswitchs-back-office-with-clojure
18:46hologood day everyone
18:49mdeboardhi
19:02holoin noir, how do i switch between development and production mode?
19:08xeqiholo: `lein run :prod` I think
19:08holooh, i see, that is what is passed to -main. makes sense, thanks xeqi, again
19:10amalloylein with-profile :prod run?
19:16holoamalloy, thanks
19:36mabes_in slime debug can you see the locals values at the time of an exception if you use the local clearing option in clojure 1.4?
19:40FrozenlockI'm ready to try clojurescript! :D Any recommendations on stuff to read on how to get started?
19:41xeqibeyond lein-cljsbuild ?
19:41LuminousMonkeyI'm just trying ClojureScript myself, so I would be interested.
19:42Frozenlockxeqi: I was reading it at this very moment! Guess I'm on the right path :P
19:42LuminousMonkeylein-cljsbuild is great, but the only example I can find is Twitterbuzz.
19:42FrozenlockBut yes, if you have other suggestions I would take them.
19:44xeqihave you seen http://www.chris-granger.com/2012/02/20/overtone-and-clojurescript/ ?
19:44LuminousMonkeyOh, nice.
19:45Frozenlockibdknox is everywhere :P
19:47xeqias far as libraries go, ibdknow has some and ohpauleez made some at https://github.com/shoreleave
19:48xeqi*ibdknox
19:50LuminousMonkeyThanks xeqi
19:51FrozenlockThanks indeed
19:54m0smithxeqi: I can't find any examples of how to use shoreleave
20:07FrozenlockI'm just blown away by the overtone-and-clojurescript example. It looks so.... simple.
20:07technomancyare there any existing nice HTML error pages for compojure?
20:07technomancy(not stacktrace middleware; thinking of something prod-appropriate)
20:08FrozenlockIsn't the stacktrace only in dev mode?
20:08gfredericks"We feel pawful."
20:08technomancyFrozenlock: it's wherever you decide to apply the middleware =)
20:09technomancycompojure doesn't have a notion of "dev mode"
20:11xeqitechnomancy: wouldn't you want those to look like the rest of the site?
20:11weavejestertechnomancy: I haven't seen any prod error pages, but there must be some nice ones out there that are just HTML
20:12technomancyxeqi: yeah, but I'm creating a lein-template project, so a generic starter would be fine
20:12technomancyI guess there's no reason to look for something compojure-specific
20:15weavejesterWith there's a compojure template for Lein I've been working on.
20:16weavejesterAt the moment it just sets up a basic route and some tests
20:23technomancyI'm working on a heroku one that adds in environ and drawbridge
20:23gfrederickshow about a white page with a rectangle in the middle around some red text that reads "We're sorry, but something went wrong."
20:23gfredericksand maybe a questionable claim about having been notified about the issue
20:24hiredmanand a uuencoding of the stacktrace
20:26hiredmanmay we all be so lucky
21:15amalloyhiredman: why uuencode rather than base64?
21:27gfredericksamalloy: then I wouldn't have learned anything
21:31hiredmanamalloy: no reason