#clojure logs

2013-01-21

00:05TimMcAnyone want to help me redesign my high-level circuit simulator? (Sequential circuit, functions as combinatorial logic blocks, registers.) I have a working version, but it's a little limited in design and I think it could be nicer. https://github.com/timmc/feedback
00:06tomojkind of something like this https://www.refheap.com/paste/9bd8650fb60801977f3eec825
00:06tomojneeds to support conj though, hmm
00:11muhoowhoahbot: http://refheap.com please
00:11muhoowhoahbot: wait, no i meant WuHoUnited
00:12muhooTimMc: industrial-sounding at first, then very circuit-bendy
00:14TimMctomoj: What does it mean for an infinite sequence to be reversible?
00:14muhooreversible infinity... start at the end and work backwards... um, wait...
00:15TimMcI can't think of a meaningful invariant that is defined on infinite seqs.
00:15tomojhmm
00:15tomoj(= cycle (rseq (rseq cycle))) obviously
00:16tomojoh, my impl has (= (first cycle) (first (rseq cycle)))
00:16tomojwhich does seem weird
00:18TimMcEven then, I still don't think Reversible is appropriate.
00:21TimMctomoj: Anyway, what's the use-case?
00:22tomojring buffer
00:24tomojreal use case is reusing dom nodes for a list
00:33tomojI guess it's like a deque
00:34tomojto move right, you pop-left and conj-right, to move left, you pop-right and conj-left
00:36TimMctomoj: So you really want a completely filled, fixed-size ring that you can navigate left and right in?
00:37TimMc(first (left 3 ring))
00:39tomojI dunno, that's what I thought I wanted
00:39TimMc(->> ring (left 3) (set "hi!"))
00:40TimMcReversible would make sense if you made the seq finite.
00:40tomojnow that I think about it more the real use case seems more complicated, so maybe it's moot
00:42tomojhow about: (= (reverse (drop-last coll)) (rest (reverse coll)))
00:42warzwent ahead and reformatted to ubuntu, heh.
00:45tomoj.. uh, where drop-last is the identity on cycles
00:46tomojwell that's a semantic equality anyway, obviously not going to call reverse on a cycle
00:46TimMc(defn reversible? [coll] (if (empty? coll) (empty? (rseq coll)) (and (= (first coll) (last (rseq coll))) (reversible (rest coll)))))
00:47TimMc*reversible?
00:47clerksySo, If I am attempting to use the case macro, but the test constants are static fields from a java class, what would be the best way to handle that?
00:47TimMcor (= (nth coll x) (nth (rseq coll) (- (count coll) x 1)))
00:48tomojare there things which fail those that pass my test?
00:48clerksyOhh, I should be using (cond), huh?
00:48TimMcclerksy: Yeah, I don't know if case can handle Java static fields as compile-time literals.
00:49TimMc&(let [x Long/MAX_VALUE] (case x Long/MAX_VALUE :can :can't))
00:50lazybot⇒ :can't
00:50TimMctomoj: reverse will fail on a cycle
00:51tomojwell, yeah
00:51tomojI mean the semantics of reverse
00:51TimMc(oh, you said that)
00:51tomojsemantic `(reverse (drop-last cycle))` would be implemented by (rseq cycle)
00:52tomojbut anyway your functions assume finitude
00:52TimMcIt's true.
00:52tomojuh, finiteness
00:53TimMcfinity?
00:53clojurebotis too infinity +1!
00:53TimMc...
00:54muhooso says.... godel? or was it cantor?
00:54TimMctomoj: You can't ask for last on an infinite sequence, so you can't ask for first on the reverse of one.
00:55muhoocantor http://en.wikipedia.org/wiki/Transfinite_number
00:55tomojhmm, yes, these aren't sequences
00:55TimMcGiven a general rseq, (defn last [x] (first (rseq x)))
00:56tomojthey have a rest and an unrest
00:56TimMcunrest :-P
00:57TimMcIs Cycle going to implement Counted?
00:57tomojheh
00:58TimMc(counted? cyc) ;;= true / (count (seq cyc)) ;; infinite...
00:58tomojwell it has to be an int
00:59tomojso no
01:01tomojif they have a first, rest, and unrest, then they have a first and rest, so the can be ISeq. Reversible does seem possibly strange
01:05n_bHow do you seq a BufferedReader by char rather than line?
01:05n_bDo I have to go down to using the java.io stuff?
01:08TimMcn_b: How are you currently getting a seq from a BufferedReader?
01:08n_bline-seq, but given my input it's not very convenient
01:10TimMc(defn char-seq [br] (let [c (read br)] (when-not (= c -1) (cons c (lazy-seq (char-seq br))))))
01:10TimMcShould work?
01:11TimMcOh, change that to (cons (char c) ...)
01:11TimMcCribbed from the line-seq implementation.
01:12tomoj(take-while pos? (repeatedly #(.read br))) ?
01:12TimMcooh
01:12n_booh
01:13TimMcReplace pos? with (complement neg?), though.
01:13TimMcOtherwise you'll start dropping NULs.
01:13tomojoh yeah
01:13tomoj#(not= % -1) is probably good
01:14yunfanhi, can lein repl hook those use fail error, and install that library ?
01:16TimMc&(let [br (java.io.StringReader. "foo")] (->> (repeatedly #(.read br)) (take-while #(not= % -1)) (map char)))
01:16lazybot⇒ (\f \o \o)
01:17TimMcyunfan: That would be an interesting modification. You'd need pomegranate (or similar) to add stuff to the classpath, and some other hook with a database of namespaces -> Maven coordinates...
01:19TimMcI'm not sure how you'd go about detecting #'use failures, though.
01:19yunfanTimMc: because i am reading someone's handbook on clojure, which the code sample use many library that i dont have
01:21TimMc(Heading to bed.)
01:22n_bTimMc: Thanks for the hel
01:22n_b(conj p *1)
01:23n_bsame to you tomoj
01:37johnmn3_trying to convert a piece of java here: while(true){if((line=br.readLine())==null)continue; post(line);}
01:37johnmn3_I don't think I can do it with a clojure while
01:37tagrudevmorning
01:37johnmn3_can I just take-while on a br?
01:38johnmn3_morning tagrudev
01:38johnmn3_or is there a best highlevel function to consume the buffered reader?
01:40tomojshould `continue` be `break`?
01:41johnmn3_tomoj... that's what I'm seeing... continue.. this while happens to be within an inner class which is also running a while(while) true... not sure if that's why a continue is used
01:41johnmn3_I'm not familiar with it.
01:42johnmn3_sorry, it is an inner class which calls another inner class, both of which have while(true)
01:42johnmn3_and this second, sub while(true) has the continue
01:42johnmn3_nakkaya mentions using a line-seq on a buffered reader
02:03TheBusbyjohnmn3_: isn't that filter?
02:05johnmn3_I suppose filtering on nil would consume the sequence for me.
02:09TheBusby(->> br line-seq (filter identity))
02:14johnmn3_well, because I had to call post, I went with (->> br line-seq (map #(post %) ))
02:19xumingmingvI want to add a hook for `lein repl`
02:19TheBusbyjhowarth__: remember map is lazy
02:19TheBusbywhoops, sorry
02:20xumingmingvThe doc: https://github.com/technomancy/leiningen/blob/stable/doc/PLUGINS.md says I needs to add a namespace lein-repl/plugin.clj
02:20TheBusbyjohnmn3_: remember that map is lazy
02:20TheBusbyalso you removed the filter...
02:21johnmn3_won't it just stop mapping once it hits nil?
02:21TheBusbyah, I see your point
02:22johnmn3_I'm hoping the seq will be consumed
02:22TheBusbydoall?
02:22johnmn3_I guess I'll throw a doall in front of it... sometimes I don't need to though
02:23TheBusbyI think the chunksize for some sequences is ~32? So if it's less than that likely not, but otherwise...
02:23TheBusbyyour java was an endless loop, so not sure how to handle that here
02:25johnmn3_I'm putting it in a function and I'll be calling repeatedly on that function in a thread
02:26johnmn3_hoping that will work
02:37johnmn3_if a library I'm using has a (def foo (atom nil)) in it and I require that namespace in two separate namespaces of mine, do each of my namespaces have unique atoms? or do they share the same one?
02:43amalloythe same
02:45johnmn3_they're "thread local" right? But the loading of my namespaces will all take place in the same thread, so they'll share the same atoms?
02:58semisighthey does anyone here have any experience with clojure and sql?
02:58amalloythere is no thread locality involved
02:59semisightI'm having a really weird problem with it
02:59semisighthere's my code: https://gist.github.com/4584333
02:59semisightI can't insert multiple records using clojure's builtin map?
03:00amalloy~map
03:00clojurebotmap is slightly retarded
03:00amalloyhm
03:00amalloymore importantly it is LAZY
03:01semisightwat
03:01semisightthat completely makes sense
03:02semisightthank you so much!
03:03semisightso would the best strategy be to wrap the map in a dorun call?
03:06amalloymeh
03:06amalloythat's fine, though i'd personally use doseq. but it looks like insert-records already does exactly what you want?
03:07semisightthe problem with the batch insert is that I really need an upsert
03:08semisightI am guaranteed that there will be multiple rows of data with the same primary key
04:14WraithanSo is there something I could do so my template files are lazy loaded? https://github.com/wraithan/leech-tracker/blob/master/src/leech_tracker/handler.clj
04:16WraithanSo, my problem is I have to bounce my server to see changes to my templates, which makes working on them terribly inconvenient
04:19ro_styou'd have to touch handler.clj as well, and ensure ring reloads files with wrap-reload
04:19ro_stthen handler'd reload the html files when it reloads
04:20WraithanSure, that is a terrible solution though, I know I could touch a clojure file to make it reload as well
04:20ro_stotherwise handler must load them every time they're used
04:21WraithanI come from other languages and expect it to load the file from disk each time it executes
04:21ro_stcongratulations :-)
04:22ro_sttwo option's i've presented are the shortest-path solutions on offer to you
04:22WraithanI don't want to come off as combative, but you didn't.
04:23ro_stapologies. it appears that you want it to do something magical. my point is, there is no magic :-)
04:23WraithanYou offered one solution (touching handler.clj) and then you mentioned exactly what I am looking for without an sort of solution, just a restatement of what I want.
04:23ro_stif you want it to load after initial compilation (as it does now) you need to write code to produce that effect
04:24brainproxyWraithan: have you looked into the reload middleware for ring?
04:24WraithanWhat would code that loads it from the file system each time look like?
04:24Wraithanbrainproxy: it already reloads on clj files changing if that is what you mean?
04:24brainproxyw/ the lein-ring plugin you can get the effect pretty easily with an option set in project.clj, but I'm not sure it's exactly what you want
04:25ro_stthe issue is that they're html files. if they were clj files, it'd just work
04:25brainproxyWraithan: ring reload middleware checks whether certain files have changed since the last request came in
04:25brainproxyand if so, the file and dependent namespaces are reloaded
04:26brainproxylein-ring also exposes an auto-refresh? option, so changes on disk will trigger a browser refresh
04:26brainproxywhich then kicks off the namespace reload
04:26ro_styes. but this mechanic only works for .clj files. you have to touch the relevant .cljs, or, move your loading logic into a function that gets called on each request, rather than once during compilation (as (def) forms)
04:26brainproxyah I see
04:26ro_sts/cljs/clj
04:27WraithanI just don't see why it loads at compilation time rather than at execution time
04:27brainproxywell auto-refresh? w/ lein-ring watches other things too
04:27ro_stWraithan: (def …) is evaluated once
04:27brainproxye.g. I change a file in resources/public/stylesheets/...
04:27brainproxya .css file
04:27brainproxythen the browser will refresh
04:27Wraithanro_st: so it automatically memoizes?
04:27ro_stbrainproxy: interesting. i've not experienced this behaviour
04:28ro_stoh, that's the browser. we're talking about updating stuff in memory on the server side
04:29ro_stWraithan: yes. if you put (render-file "…") into your (GET "/" [] ?) directly, you should see that it updates properly
04:29ro_stor
04:29ro_st(defn get-index [] (render-file …)) and (GET "/" [] (get-index))
04:29WraithanI see
04:30brainproxyi see, didn't realize the redner file issue
04:30brainproxybasically, the old stuff is stuck in memory
04:31Wraithanro_st: thanks, that fixed it
04:32ro_stexcellent
04:33WraithanAlso, now I understand the difference
04:33ro_stof course, in production, you'd want some sort of only-load-if-actually-necessary mechanic to prevent excessive disk usage
04:33WraithanThat supposes a high load
04:33Wraithanthis should be super low load (10-20 requests a day)
04:33ro_stindeed
04:34ro_sti see you're in portland! are you attending ClojureWest?
04:34WraithanUnlikely
04:34WraithanActually definitely not
04:34WraithanIt is during PyCon
04:34ro_stah
04:35WraithanJust playing with clojure in my spare time
04:35WraithanI am a python hacker for Mozilla
04:35ro_stnice
04:36WraithanAlso hard to justify 350 for a hobby side language
04:39ro_sttrue :-)
04:46muhoo350?
04:46muhoooh right, cljwest fee
05:44piranhaI've changed drip wiki a bit: https://github.com/flatland/drip/wiki/Clojure/_compare/8733641e714006f8da8ab1cb081f7a0bf6d6e23d...f953a9221f8b6f3f772b3a05903aa70746a58bad
05:44piranhaI hope I actually fixed it and wrote what was intended from the start :)
05:51borkdudeis it possible to have a two-line title in org-mode?
05:52borkdudenot really important though
06:08ucbborkdude: not afaik; if you find otherwise please let me know though :)
06:11borkdudeI'm trying to go from latex to org-mode, so far I like it
06:16ucbborkdude: check out todo items, archiving and calendars (and tables!); your mind will be blown!
06:48borkdudeah, org-mode and jekyll looks like an exciting combination
07:38rasputnikhave a simple Ring REST service packaged via uberjar, and need to supply it with some config (DB urls, etc). Is there an idiomatic way to parse config files etc.?
07:39rasputnike.g want to run it as "java -jar restything.war config.json" or similar
07:41borkdudeanyone happen to know this one? http://stackoverflow.com/questions/14438582/org-mode-highlighting-using-minted-for-latex-and-htmlize-for-html
07:57augustlhow do I load a schema from a .sql file with clojure.java.jdbc?
08:00augustlit works fine if I just have one CREATE TABLE and pass it to do-commands, but I get syntax error when I have multiple
08:00augustlthe file works fine when being executed with "mysql" itself
08:01borkdudeis it possible to create a listing with a reference/label in org-mode?
08:01augustlalso wondering why 0.2.4 isn't out yet, 0.2.3 seems quite old and there are lots of improvements in 0.2.4
08:06borkdudeah got it: <<code-reference>>
08:07borkdudeI wonder why this has a different notation, but it works
08:12augustlisn't there a way to make the threading macro pass the previous value as a argument I specify, instead of the first argument?
08:12augustlthe use case is to end the threading with a (remove predicate insert-prev-value-here)
08:13scottjpiranha: were you able to see a speedup in lein? which commands?
08:14piranhascottj: lein cljsbuild once <target> was 18 seconds vs 5 seconds
08:14piranhawhen I just had -drip it was always 18 seconds
08:15ucbaugustl: you also have ->> which places the value as the last arg.
08:15ucbaugustl: afaik those are the two only options
08:16scottjpiranha: ahh, I was running lein not lein2 :) thanks for the edit!
08:16piranhanp :)
08:17augustlucb: I see
08:22augustlfigured out how to load a sql schema - split the sql file on #";" and run them as individual commands ;)
08:46dignatiHey clojurists! Would someone mind to check out this function and tell me if it is idiomatic/good code? I read a lot of CL code recently and think I got confused with functional/non-functional code. https://gist.github.com/4585871
08:50ucbdignati: why do you define an anonymous fn only to call it immediately?
08:51dignatiThe function recurs to it. I needed more function params to keep track of my state
08:52xeqiloop
08:52ucbthat'd be the one
08:52ChongLihmm, nested js obj property access is really ugly in cljs
08:52ChongLiis there no macro for this?
08:53dignatixeqi: of course I can loop over it but I looked for a recursive solution
08:54ChongLidignati: function params to keep track of your state? just use a map
08:56ucbdignati: I think he meant the loop/recur construct; you can have recursion with loop
08:56xeqidignati: loop just sets bindings and creates a recur point. its the same effect as immediately calling the anon fn
08:56dignatiChongLi: Ah, now I know what "params to keep track of state" reminded me of. I have no idea how to do it in this but might have to take a look
08:57ChongLidignati: a map is an extremely useful data structure
08:57ChongLiit stores keys and their associated values
08:58dignatiucb: xeqi: Okay I check this out. Thanks!
08:58dignatiChongLi: Oh I thought you meant #'map
08:59ChongLimore like this: {:key value :key2 3} etc.
08:59dignatiOkay thanks for your help, I'm going to rewrite it with loop
08:59ChongLimaps in clojure can be nested as well
09:00dignatiChongLi: Got that ;)
09:00ChongLiyou can put a very big tree of program state entirely within one map
09:02xeqi$findfn [1 2 3 4 5] [3 4] true
09:02lazybot[clojure.set/superset? clojure.core/not= clojure.core/distinct? clojure.core/every?]
09:02xeqi$findfn [1 2 3 4 5] [3 4] [3 4]
09:02lazybot[clojure.set/select clojure.set/intersection clojure.core/max-key clojure.core/cond clojure.core/dosync clojure.core/sync clojure.core/char-escape-string clojure.core/*data-readers* clojure.core/filterv clojure.core/default-data-readers clojure.core/filter cloju... https://www.refheap.com/paste/8832
09:02aroemersChongLi: I am still pondering whether a big state map is a good idea. I think for one it is good for "trampolining" functions, but still.. the entire state passing around..
09:03aroemersIt feels wrong somehow.
09:03aroemersAny opinions on this?
09:06ChongLiaroemers: what do you mean the entire state passing around?
09:06ChongLiall that passes around is a reference
09:07ChongLiyou don't pass the entire thing to every function, that would force every function to traverse the state to get what it needs
09:08aroemersSure, but it may complicate undestanding simple functions that have this reference. It starts with all this state available. Less state in a function is desirable.
09:08ChongLiit's not really state
09:08ChongLisince it's not mutable
09:08ChongLiit's just a value
09:08ChongLia simple function would operate on a simple value
09:09aroemersHmm, assuming you know up-front what part of the state the function needs (and what the nested function calls need)
09:11aroemersFor instance, in a parses I've written, I have to pass the entire state to a simple function, because that simple may call another function that needs most of the state. Thus, more state is available in the simple function than necessary.
09:11aroemers*parser
09:12aroemersAh well, still in doubt whether this is a bad thing.
09:12ChongLiwell, you can pass the state around, stick it in an atom or go the monad route
09:13ChongLimonads have been used in parsers in the past
09:14aroemersTrue, if you put it like that, passing the state around is actually a good choice. :)
09:32borkdudehmm, I'm having this in a .org file: src_clojure{[1 2 "a" "b"]}
09:32borkdudebut it doesn't translate well to latex
09:37aroemersborkdude: Using the 'listings' package might help you out.
09:37borkdudearoemers I'm using minted
09:37aroemersAh, don't know that one
09:38borkdudearoemers It has better highlighting for clojure
09:41aroemersClojure highlighting is listing takes some work indeed, but it is doable. I'll check minted the next time though
09:42aroemers*in
09:47borkdude=[1 2 "a" "b"]= in org-mode becomes [1 2 äb"] in latex…
09:49borkdudemaybe it's just better to not inline code
10:14xumingmingvneed a little help here
10:14xumingmingv,(= (quote a) (quote a nil))
10:14xumingmingv&(= (quote a) (quote a nil))
10:14lazybot⇒ true
10:14clojurebottrue
10:14xumingmingvwhy (quote a) == (quote a nil) ?
10:17algernonxumingmingv: because quote quotes a form, "a nil" is two forms, not one
10:17xumingmingvso the `nil` here is just ignored?
10:17algernonyes
10:17algernon&(quote a b)
10:17lazybot⇒ a
10:17xumingmingvohh, thanks
10:31borkdudecan you have TODO items in org-mode which aren't headings
10:31borkdudeheadlines
10:32borkdudeI just want to add some TODO remarks to my text, without it being a section, and exclude it on export
10:33qzhow do i pass java methods as predicate to filter? say i want to call .isFile, wrap it in anonymous function #(.isFile %) ?
10:33aroemersqz: Yes, that's how I do it anyway.
10:34qzaroemers: i see, thanks
10:40tmciverHas anyone else had a problem with nrepl where loading a file (C-c C-l) stops working apparently after a previous attempt at loading a file failed with an exception?
10:41tmciverI'm using 0.1.5. I should probably try out 0.1.6.
10:41NeedMoreDesuHow do I add jar to the project? I wish it would be somewhere in project dir.
10:43augustlare there any general tips for calling macros inside macros? Trying to call "binding" within a macro, getting "Can't embed object in code, maybe print-dup not defined:" all of a sudden
10:45jweissi think i might have asked this before, but is it possible to alias a namespace without requiring it? i don't want to load it, i just want to refer to namespaced keywords
10:45jweissi mean in the ns form. i am aware of alias fn
10:46aroemersNeedMoreDesu: install the library in your local repository, it's the best option. It is intentional that you cannot add a jar to the project easily.
10:53augustlcan preconditions alter the arguments? For example, I want a precondition that validates that something is a date, and to do that I need to create a date object. Would be nice if I could just pass on that date object so I don't have to create a new one
10:55nDuff...why would you need to create a Date to validate whether something _is_ a date?
10:55nDuffDo you mean validate that something can be used as an argument to one of Date's constructors?
10:56NeedMoreDesuaroemers: thanks. I think I'm getting how does it work now.
10:56augustlnDuff: it was probably not a good example. But in some cases, you want to parse something and check if the parse result was A OK, and use that parsed object.
10:57nDuffSounds like a precondition just isn't the right construct.
10:58nDuffMove the parsing into your function, and then it's moot. Could make a macro or HOF that automates it for you, of course.
10:59augustlyeah it's in the function now
10:59augustlit's called preconditions, not pre-operations, after all :)
11:37gfredericksis it normal that `lein run` takes a few minutes to return if I use a future? i.e., a few minutes past the last future finishing
11:37gfredericksI assume `shutdown-agents` is related to this...
11:37gfredericksjust curious about the long delay
11:40nDuffgfredericks: ...right -- if you shut down the pools yourself, you should be able to avoid that delay.
11:42gfredericksAnybody know why the delay is necessary?
11:42craigbrogfredericks:
11:43craigbrogfredericks: a few minutes islonger than I have experienced, but I have seen such delays. I explicitely System/exit
11:43gfredericksit may be shorter, I'm timing it now
11:43craigbroI had a -main method that called some code that use pcalls and it added tens of seconds or more to calling that module, unless I did System/exit
11:44craigbrogfredericks: I didn't investigate why, I just did that because as a unix dork I was like, "err, waiting on children, exit will round em up."
11:45gfredericksafter timing once with and without, it is strikingly close to exactly one minute
11:46clgvgfredericks: do you use shutdown-agents?
11:46gfredericksclgv: it finishes 60 seconds sooner with shutdown-agents
11:46gfredericksthis is tricky because I'll need to make sure that I have no more things to run
11:46craigbrohttp://clojuredocs.org/clojure_core/clojure.core/future
11:46craigbroexplains it 8)
11:47gfrederickscraigbro: oh nice, thanks
11:48craigbroone would expect dereferencing the future should kill it's thread eh?
11:50craigbrothe jira bug is illuminating
11:50nDuffcraigbro: I wouldn't tend to expect that. Starting and shutting down threads is expensive.
11:52gfredericksis it odd that there's no mechanism to register a deliverance callback with a promise?
11:52nDuffHmm. That _could_ be useful.
11:52nDuffSeems like something you could do yourself
11:52nDuff...not hard to wrap something but still keep it implementing IDeref
11:52gfrederickswithout holding up a thread on a deref?
11:53clgvgfredericks: put a deref of that promise in a future ;)
11:53gfredericksclgv: I'm naively assuming that's unideal to keep a thread occupied in that
11:53clgvgfredericks: huh? it does not do anything actively
11:54gfredericksclgv: sure. I don't know about the impl details. E.g., is there a fixed-size thread pool that we're hogging a thread from?
11:55clgvgfredericks: futures use an unbounded threadpool
11:55gfredericksthen do I have to worry about doing this hundreds of times?
11:58craigbroyah, I didn't realize futures use a pool
11:59craigbroI had a problem with futures accumulating (ring file upload handler) it would blow up under load testing
12:00craigbroso I assumed that each future was it's own thread
12:25technomancygfredericks: lein used to shut down the thread pool, but it had some weird effects on programs that relied on the fact that the thread pool was keeping the JVM running
12:27gfrederickstechnomancy: oh that's reasonable; I wouldn't expect lein to monkey with this. Would have broken my code I'm pretty sure.
12:29technomancyit wouldn't be a problem if Clojure actually exposed the thread pool and allowed you to restart it, but it's all hard-coded and yucky
12:31Morgawrhello... I started using clojure a few days ago and I decided to give leinigen a try... I created a new project and I can add functions and stuff to my core.clj file
12:31Morgawrhowever I want to have multiple files .clj
12:31Morgawrif I give them all the same namespace, I can't still find the functions loaded in the repl
12:31Morgawrhow do I make lein recognize multiple different .clj files in my src folder?
12:32nDuffMorgawr: First -- your files should each have their own namespace.
12:32nDuffMorgawr: ...the namespace names need to correlate to the filenames.
12:32SchaeferMorgawr - Each file should be in its own namespace. Also, the file name should match* the namespace. Are you familiar with java packages and class files?
12:32nDuffMorgawr: once that's done, you should be able to require or use them.
12:33Schaefer*match - as you're learning, stay away from special characters in namespaces like the dash "-"
12:33MorgawrSchaefer and nDuff ah okay... I get it, so I have this file called mytest.clj in my src/tests/ directory
12:33MorgawrI do (require 'tests.mytest) (I have the right namespace in the file)
12:33Morgawrand it still can't find the function I declared
12:34nDuffMorgawr: so, require doesn't automatically bring references into the current namespace.
12:34nDuffMorgawr: so, how are you trying to use it? If it's tests.mytest/myfunction, that should work.
12:34Morgawroh.. okay, using that it worked :)
12:34nDuffMorgawr: ...likewise, if you want a shorter name, you can (require '[tests.mytest :as mytest]), and then it's just mytest/myfunction.
12:34Morgawrthanks, I was getting a bit confused by this :)
12:34technomancyMorgawr: might want to read `lein help tutorial`; it offers some pointers there
12:35Schaeferi'm having trouble with lein's injections and CCW. should i expect ":injections [(prn (into {} (System/getProperties)))" to print out the system properties with i start a CCW repl session?
12:35technomancySchaefer: it'll put it to stdout; where that goes is CCW's business
12:35Morgawrtechnomancy: I read the tutorial, I was really confused because I couldn't find any reference to this specific case of having multiple files.. but yeah, might have been me
12:36Morgawrtrying to do project euler stuff, having a namespace for each problem :)
12:36technomancyMorgawr: oh, it has a link to the 8th light article instead
12:36bozhidartechnomancy: sorry to bother you, but I was wondering if you'll be able to spare some time to review the dozen of PRs for clojure-mode and give it some love :-)
12:37muhooit's starting to get annoying that nrepl-eval-last-expression keeps trying to eval in the user namespace, not the namespace of the file
12:37muhoonrepl-set-ns does not fix it
12:38muhoobut evaling the ns declaration in the file does.
12:38Schaefertechnomany: i don't think the injections is getting evaluated at all. i have changed my project def to include ":injections [(use 'clojure.pprint)]" but when i try (pprint "test") on the repl, i get an unable to resolve symbol error
12:39muhoonDuff: i thought it was here, actually. #python has the "NO LOL" rule
12:39bozhidartechnomancy: In particular https://github.com/technomancy/clojure-mode/pull/128 fixes a small error I made when I converted clojure-mode to a derived mode and people living on the edge are getting a byte-compilation warning
12:39Morgawris there a way to force lein to re-load a file? because I am editing a file and I am still in the repl
12:39gfredericksman returning from inside a ruby block has got to be the ultimate example of an impure "function"
12:39bozhidarmuhoo: just use `C-c C-k`
12:40muhooMorgawr: (require 'foo :reload) ?
12:40Morgawrmuhoo: thanks!
12:40bozhidarmuhoo: we're having some problems deciding on the behaviour of nrepl-eval-last-expression
12:40muhoobozhidar: great, thanks, that worked
12:40tomojb
12:47muhoook next... is there some way to force stencil to refresh its core.cache?
12:48muhooah got it invalidate-cache-entry
12:54muhoohmm, i could swear i've seen a lein plugin somewhere that watches moustache templates and invalidates the cache entry if they get updated on disk
12:55Morgawrokay.. got another question for lein and repl.. I have a "(def mylist (range 1 20))" (just something, doesn't matter what it is), if I require the correct namespace inside my lein repl, why can't I do (mynamespace/mylist)? it says undefined reference
12:58Morgawroh nevermind =_= I'm an idiot I was using the wrong namespace name sorry
13:14tmcivertechnomancy (or anyone else): how do I tell emacs to load the nrepl elisp I cloned from github rather than the version I had installed through package.el?
13:17bpr(load-file "/path/to/nrepl.el")
13:17hyPiRiontmciver: M-x package-list-packages, remove the nrepl you got there first
13:18tmciverbpr: Yeah, I can try that. I was hoping that it would load automatically as the current version of nrepl does.
13:18hyPiRiontmciver: Put it in your emacs.d/init.el file
13:19tmciverhyPiRion: I don't have that file. I wonder how nrepl gets loaded now.
13:23bprtmciver: you can create it
13:23technomancytmciver: if you're not planning on updating your git checkout often, M-x package-install-file is an easy way to do it
13:24technomancymuhoo: don't get me started on the namespacing problems of nrepl.el; it's completely bonkers
13:24technomancymuhoo: here's a workaround: (add-hook 'clojure-mode-hook (defun nrepl-fix-buffer-ns () (when (clojure-find-ns) (setq nrepl-buffer-ns (clojure-find-ns)))))
13:24jonasenDo I have to do something special when starting an nREPL server (programmatically) to redirect *out* to the response map? https://www.refheap.com/paste/8838
13:24tmcivertechnomancy: ah, that sounds like the solution I was looking for.
13:25tmcivertechnomancy: do I have to re-run package-install-file each time I update it?
13:26technomancytmciver: yeah, better to use load if you're updating frequently
13:26tmciverk
13:26beffbernardIs there such a thing as a reusable promise?
13:27nDuffbeffbernard: What do you mean by that? You can re-deref them and get the same result more than once after they've done their work.
13:28beffbernardnDuff: I want to be able to set it more than once..
13:28beffbernardnDuff: my use case to hold a socket in that promise
13:28beffbernardand the socket can and does change
13:29nDuffbeffbernard: I'm not sure that promises are the right abstraction for that, then.
13:29tomoj'set a promise more than once' = 'break a promise'
13:29beffbernardI guess the semantics I want is to block if the resource is nil
13:29nDuffbeffbernard: almost sounds more like you want an agent than a promise to me.
13:29beffbernardand have the convenience of deref
13:29nDuffbeffbernard: ...if I'm understanding your use case correctly.
13:36beffbernardnDuff: doesn't quite fit my use case I think
13:37yedihow can i find the most recent version numbers for cljs
13:42hyPiRionOh lord, my hair's on fire. I'm sad I can't use Leiningen for c projects.
13:52muhoohmm, what's the difference between :injections and :init in lein?
13:52technomancymuhoo: :injections is composable; :init is kind of leftover from 1.x
13:52muhoocool, thanks
13:54gfredericksis there any straightforward way to check if something is a promise?
13:54gfredericksprobably good enough for me to use (instance? clojure.lang.IPending ...), but it's weird there doesn't seem to be anything else
13:56muhoobeffbernard: there was some stuff in lamina that looked like it could be used for that purpose
13:58TimMcgfredericks: When would you want to know that it's one type of IPending versus another?
13:58bprbeffbernard: maybe this is what you want: http://clj-me.cgrand.net/2010/04/02/pipe-dreams-are-not-necessarily-made-of-promises/
13:58TimMcOh, do you also want to check for futures as well?
13:58gfredericksTimMc: IPending is fine for me; there might not be an actual use case
13:59gfredericksassuming that IPending is what it sounds like at least
13:59gfredericksunfortunately it has no docstring :)
13:59gfredericksheck, I'm not even sure it's not just an implementation detail
14:00technomancywhen in doubt, it's an implementation detail
14:00gfrederickstechnomancy: okay then. How do I tell if something is a promise? :)
14:01gfredericks,(instance? (type (promise)) (promise))
14:01clojurebottrue
14:01gfredericksI guess that's bound to work
14:01technomancyI dunno; TBH you'd never really get anywhere in Clojure without relying on implementation details
14:02gfrederickswhether or not something is an implementation detail is an implementation detail
14:02technomancy...!
14:02muhoometa
14:03technomancyyeah actually even the "keys and vals are guaranteed to use consistent ordering on the same instance" is somewhat apocryphal
14:03gfredericks"Legends of Clojure: implementation details you can count on"
14:04technomancyheh
14:04technomancyI smell a conj talk?
14:04gfrederickshaha
14:04gfrederickstechnomancy: this talk will feature live documentation coding
14:05technomancygfredericks: for extra living dangerously points: live attempts at using Jira
14:05gfredericksit's not an implementation detail if you can trick stuarthalloway into merging in your docstring patch
14:05muhooclojure seems not nearly as implentation-detail-heavy as, say, android, which has a huge layer of folklore built on top of its otherwise good documentation
14:06hyPiRionHave anyone here programmed in C++? Then you'll know implementation details.
14:06muhoogood point
14:09muhoooh gawd, i just realized that after a decade of dealing with autotools. unix itself is pretty much one big implementation detail.
14:09muhooapt-get hides all that, but it's there.
14:10technomancyI've started to notice these weird parallels between the monthly "everyone hates jira" threads on the clojure mailing list and the monthly "everyone hates bzr" threads on emacs-devel.
14:13aaelonya strange thing just started happening in lein-swank. I compile my ns, which returns nil, but then it is as if it didn't load in any of the require and import statements. For example, I'm importing java.io.BufferedWriter but it reports "Unable to resolve classname: BufferedWriter" If I do a lein repl outside of emacs, and run the same ns statement and run the functions, everything is fine. [lein-swank "1.4.5"] is in my
14:13aaelony~/.lein/profiles.clj under :user then under :plugins. Any ideas?
14:13clojurebotGabh mo leithscéal?
14:15mmitchellanyone using nrepl and auto-complete in emacs? I keep getting this error when connecting: clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: complete.core, compiling:(NO_SOURCE_PATH:1)
14:16hyPiRionmmitchell: I do
14:17hyPiRionnot sure if this helps, but I have https://github.com/hyPiRion/emacs.d/blob/master/hypirion-clj.el#L21-29 for setting up ac
14:18muhoocan :init-ns be used elsewhere except in :repl-options?
14:19amalloytechnomancy: phases of the moon, perhaps?
14:19muhooi don't want to define :repl-options in the project and have it clobber what's in profiles.clj
14:20muhookeep getting burned by non-recursive merges in lein
14:22mmitchellhyPiRion: thanks! unfortunately i'm still getting that error hmm
14:23mmitchelli don't even know where to get "complete.core" ?
14:23muhoooh cool. it merges them. yay lein pprint
14:25gfredericksso future is guaranteed to inherit dynamic var values right? No ambiguity there?
14:25muhoommitchell: https://github.com/ninjudd/clojure-complete ?
14:25gfrederickss/ambiguity/edge-cases/
14:29muhoohmm, nrepl doesn't seem to honor :init-ns
14:29muhooalways get user
14:30muhoothrashy thrashy bang bang
14:30technomancy:init-ns might be specific to reply
14:31technomancycemerick might know if there's a way to set that stuff on the server side
14:32muhoowait, i'm totally confused now. sample.project.clj says that :injections gets evaled on every form, but then it implies elsewhere it gets evaled on every repl
14:33muhoo"Forms to prepend to every form that is evaluated inside your project."
14:33technomancyoh, that should be "every eval-in-project invocation" instead
14:33amalloymuhoo: from lein's point of view, the repl is one form
14:33amalloy(in-the-project (run-a-repl))
14:33muhooah, cool. confusing way to put it tho
14:33technomancywhat amalloy said, but that's an implementation detail that the docs shouldn't assume
14:35muhoomaybe i should take a step back. here's what i'm trying to do:
14:35muhoo1) set the namespace for every new repl to go into (hmm. maybe :injections might work for that)
14:35muhoo2) set some code to run on every repl invocation
14:36technomancy1) would need to be handled by nrepl; I'm not sure how it's done
14:36muhoo3) have some form to evaluate in-project whenever the project loads, not on every repl, i.e. (myns.server/-main)
14:36technomancyif 2 means on every `lein repl` invocation then :injections inside the :repl profile should do it
14:37technomancyand 3 should work as :injections in the base project map
14:37muhoook, so two different injections, get evaled at different times?
14:37muhoodepending on where they are in the map?
14:38muhooby 2) i mean every time i connect to the repl over :repl-port
14:38muhoovia nrepl
14:38gfredericksso I'm about to write some code that manages running async jobs (via future), particularly giving functionality to wait for all jobs directly or indirectly started from this thread to be done
14:39gfredericksam I reimplementing something that already exists in clojure/jvm?
14:39gfrederickswas just going to wrap future with code that registers the job and notes when it's done, and use a dynamic var to track what thread it originated in
14:39technomancymuhoo: oh, ok that's different then for 2
14:39technomancythat would be an nrepl question rather than leiningen; unfortunately I'm not familiar
14:40muhoofair enough, thanks
14:40jeremyheilergfredericks, there is java.util.concurrent.CyclicBarrier
14:41technomancymuhoo: I agree that we should document though
14:41technomancyjust haven't figured it out yet
14:41muhootechnomancy: the bummer is though, i thought i was told never to shadow the :repl profile in the project.clj
14:41muhoobecause it clobbers it
14:41muhoobut i'll try base project map, that may do it
14:41technomancymuhoo: yeah, I think hyPiRion fixed that
14:42muhoooh cool
14:42technomancybecause you're right that it's confusing
14:43amalloy(doto (f x) (-> (->> (g y)) (h z))) ;; i love arrows and doto, but i really can't bear to put this in my program
14:44hyPiRionmuhoo: https://github.com/technomancy/leiningen/issues/520
14:44muhootechnomancy: sorry, i've got more dumb :injections questions
14:44muhoowhy would :injections be exploding with "Unable to resolve symbol: do" ?
14:45technomancymuhoo: that's strange... is it being syntax-quoted?
14:45muhooi'm trying :injections (do (require 'myns.server) (myns.server/-main))
14:45muhooah i see, it wants a vector
14:46technomancyoh, yeah you need that in order to combine injections from multiple profiles
14:46gfredericksjeremyheiler: that sounds like an interesting google, thanks
14:46technomancymuhoo: we should probably put a warning on non-vectors there; feel free to open an issue
14:47Schaeferhi. i'm having trouble using cemerick's piggieback + clojurescript with CCW. i get "Can't change/establish root binding of: *cljs-repl-options* with set" .
14:48amalloymake sure it's as helpful as the error message for (defn foo (vector bar baz)), technomancy
14:48technomancyamalloy: necessarily
14:48amalloyfor the lazy: "Parameter declaration vector should be a vector"
14:49muhoowell in my case, "RTFM" would have been a sufficiently useful error message
14:50technomancyit's not as clear as it should be
14:50muhooah, yay, it works. all is bliss.
14:51technomancyjust need to stalk cemerick to get those nrepl tips from him
14:52Schaeferthanks. do you happen to know if CCW using lein to start the repl? i can't figure out if it honors :repl-options in the project definition
14:54Schaeferah... i bet i know the problem: the current release of CCW fails on some dependency. i thought i had a workaround but possibly not
14:57gfredericksthat unified update model is quite slick.
15:00craigbroccw?
15:00clojurebotccw is http://github.com/laurentpetit/ccw
15:01amalloy(inc clojurebot)
15:01lazybot⇒ 15
15:01craigbroah, eclipse
15:02amalloygfredericks: yeah, it's great. it's also the only time i can call a single function with seven or eight arguments and not feel filthy
15:02mmitchellmuhoo: hey thanks, i'll check that out
15:02frozenlockAny advice on how to handle states in cljs? (Libraries or best practice) I've just begun to deal with them and I'm pretty sure I'm digging myself in a hole :/
15:03mmitchellmuhoo: do you know how i use that?
15:03gfredericksamalloy: yeah that's what sparked the thought :)
15:03mmitchellmuhoo: the clojure-complete lib w/emacs and auto-complete?
15:03amalloygfredericks: the only thing i don't like is that if i write something like (apply swap! x vary-meta update-in :logs concat) i lose track of the fact that i'm applying by the time i get to concat
15:03gfredericksit kind of makes me want a (map coll func & args)
15:04muhoommitchell: i thought it was already included from nrepl/reply/etc already
15:04therealadamwhat is the go-to http client for clojure?
15:04gfredericksclj-http
15:04mmitchellmuhoo: oh i see
15:05muhoommitchell: last i checked, if you have nrepl and lein installed and working, autocomplete just works
15:05therealadamgfredericks: thanks!
15:05muhoowhich isn't to say i have either, so i'm still M-/ 'ing by habit
15:05amalloystates like: california, a state machine, or mutable state throughout your application?
15:06therealadamgfredericks: is https://github.com/mmcgrana/clj-http still the canonical repo?
15:06therealadamderp, n/m
15:06mmitchellmuhoo: ok good to know. I'll remove a bunch of my emacs config and see what happens
15:07gfrederickscurious if anybody thinks this is terrible or knows an easier way: https://www.refheap.com/paste/8840
15:07borkdudeDoes anyone using org-mode to write the answer to this one? http://stackoverflow.com/questions/14446157/writing-a-document-in-org-mode-is-it-possible-to-refer-to-a-code-fragment
15:08amalloygfredericks: line 14 is crying out for fnil
15:08gfredericksI've never once thought to use fnil
15:08gfredericksyou have to admit though that fnil technically creates a set that might not get used :P
15:08frozenlockamalloy: If your question was for me, it's mutable states.
15:08gfredericksbut yeah it's a lot more readable
15:08amalloyand `wait` has a race condition that leads to deadlock
15:09amalloyi recommend using useful.state/wait-until, which doesn's
15:11amalloygfredericks: (let [conj (fnil conj #{})] (defn run-job ...)) ;; now the set is only made once, you whiner
15:13gfredericksamalloy: oh I misunderstood how to use fnil there then
15:13amalloywell, i wasn't suggesting you actually do that. but if creating a set that might not get used bothers you, you can do this instead
15:13gfredericksI imagined a #{job-id} getting created but you're right
15:13gfredericksamalloy: amn't figuring out what the race condition is
15:14amalloyhmmmm, there might not actually be one because the keys in the map are thread ids
15:15amalloybut i think there is. line 27 runs, sees there's still a job waiting. so it creates a promise, then gets interrupted. some other thread finishes the last job, and updates the atom. now the first thread adds a watcher and blocks on it, but nobody ever updates the job list again
15:16gfredericksah right
15:16gfredericksso another check before line 34 would do it?
15:17amalloygfredericks: yes. that's basically what i do at https://github.com/flatland/useful/blob/develop/src/flatland/useful/state.clj#L54
15:17gfredericksI was reading that
15:17owengalenjonescan anyone explain why ( or point me in the direction of explanations why ) recur in this situation hangs the repl: http://d.pr/n/fOGk
15:17amalloyowengalenjones: recur points at your lambda, not at tree?
15:18owengalenjonesamalloy: is there a way to have it escape the scope?
15:18amalloyno
15:18owengalenjonesso in this situation you would always have to specify the parent fn
15:18TimMcgfredericks: So run-job fires off a job, and wait "joins" on all the jobs?
15:18amalloyrecur doesn't consume stack space; there is no way to write what you want without stack space (ignoring CPS)
15:19amalloythus, you can't use recur
15:19owengalenjonesok thanks
15:22TimMcgfredericks: It would be nice if this code were commented with descriptions of e.g. what the atom is supposed to contain, what invariants you expect to hold...
15:23gfredericksTimMc: yes and yes
15:23gfrederickswell
15:23gfrederickswait joins on all jobs that originated from the current thread
15:23TimMcMmm, I see.
15:24gfrederickscome to think of it I don't actually have a use case for ignoring things from other threads
15:24gfredericksbut just in case I even do... :)
15:24gfrederickss/even/ever/
15:26TimMcIs the following correct? #'jobs is an atom containing maps of thread IDs to sets of IDs of jobs that may or may not have started yet, but definitely have not finished.
15:26Sgeo#'jobs is (var jobs) which is a var
15:27TimMcYes, it's a var of an atom of a map of...
15:27TimMcI don't know why she swallowed the fly... I guess she'll die!
15:28amalloyTimMc: i think it's just as accurate to say the jobs have definitely started as to say they have definitely not finished. the process is like: (1) add to set; (2) run job; (3) remove from set. so there's space on either side of (2)
15:29nDuffDamn -- using Clojure gets me spoiled on having its features available.
15:32TimMcgfredericks, amalloy: I *think* that if the when-not empty? is moved to just be around the deref, then it's all good.
15:32TimMcHowever, I'm not entirely sure what the thread safety of watchers is.
15:33amalloyTimMc: sure. as i note in the comments of useful/wait-until, which i linked to, the first deref is only a performance optimization
15:34TimMcHaha, you're using the promise itself as the watch-key? Pretty non-obvious.
15:36amalloyTimMc: what else would you use?
15:36TimMcA gensym, as gfredericks did.
15:36amalloyfeh
15:36TimMcI don't see anythign wrong with using the promise, I just would have made that choice more explicit.
15:37TimMcI also don't like the idea that the promise is escaping that scope.
15:37TimMcSeems dangerous.
15:38amalloyyour first objection seems reasonable enough, but i don't understand what you mean by escaping that scope
15:39TimMcIt's ending up in a watcher.
15:39TimMcWho watches the watchers?
15:40amalloyit has to end up in the watcher, or else the watcher couldn't deliver to it?
15:40amalloyyou're objecting to it being a key in the map as somehow more dangerous than being closed over by a funciton that's a value in that same map?
15:41TimMcIn gfredericks' version, the watcher holds a closure over the local scope, but someone outside that scope can't actually touch the promise.
15:41amalloyokay, fair enough
15:42TimMcI can't build a solid case for how that might make a program go pear-shaped, but I have this general sense that something might try to str-ify the promise somehow.
15:42TimMc(I don't worry that somthing would deliver to it.)
15:43muhoowow, that's just bizarre. lein trampline :repl works on machine 1, but on machine 2, it gives a bizarre jboss error that 8080 is already in use, and doesn't actually start the nrepl listen port
15:43amalloyi'm not really worried about that. not least because, in order to get a list of all watchers on a ref, you have to use undocumented interop methods
15:43muhoosame profiles.clj, same version of lein. different versions of java though
15:46Sgeoo.O fogus is now into Racket
15:46Sgeo....What's the name of that effect where you learn a word and now everyone is using it?
15:46TimMcBaader-Meinhoff?
15:46SgeoI feel like I play with a programming language and then a little while later I see others playing with it
15:46SgeoTimMc, I think so
15:47TimMcBaader-Meinhof
15:50winkSgeo: but, most importantly: did you use Racket... before it was cool? :P
15:51SgeoI wish there was a language with Racket as the language and something Smalltalk-like as the environment
15:51SgeoI like Racket for the language (mostly) and Smalltalk for the IDE
15:53winkas I've never written any for-money production code in all those languages I find so cool.. I still can't say whether I find them practical or just nice :(
15:53gfrederickshas anybody seen korma apply a transform function to a whole result set rather than one row at a time?
15:54dnolenwink: plenty of people have put Clojure code into for-money production
15:54winkdnolen: that's not at all what I was hinting at :P
15:54AimHereDon't you find Clojure cool?
15:55winkdnolen: for example I see no way in hell to even try to write any clojure code without quitting my day job
15:55winkmuch less anything like CL or Racket
15:55dnolenwink: sorry I missed some backlog context
15:55dnolen"sorry if" I mean
15:56winkdnolen: didn't say much before :P it was just about using/hearing about Racket
15:57dnolenwink: I see, doesn't Naughty Dog use Racket for all their game scripting (I get your point about the day job)
15:58winkdnolen: yeah, think so
15:59winkmaybe I need a "just get shit done" job instead of a "write maintainable code" one :P
16:00CrawfordComeauxI'm trying to debug https://github.com/nathanmarz/storm-deploy, but I've never used clojure before (though slightly familiar with lisps). I'm reading that I can drop a repl in where the exception's coming up, but I'm not sure how to do that
16:01gfredericksamalloy: TimMc: thx for comments
16:03winkCrawfordComeaux: least specific way would be to $ lein repl and start your boilerplate code by hand
16:03CrawfordComeauxwink: not even sure what the boilerplate code would be...any other things I could try?
16:06winkCrawfordComeaux: https://github.com/nathanmarz/storm-deploy/blob/master/src/clj/backtype/storm/provision.clj is zthe enty point
16:07winkafaict ;)
16:07CrawfordComeauxso load up the repl & c/p lines from the source?
16:08amalloyCrawfordComeaux: nobody can help with "X doesn't work", for any X. at least a description of what's going wrong is necessary, and ideally a stacktrace and/or what you're doing that causes a problem
16:08CrawfordComeauxamalloy: this was an attempt to get a stack trace
16:08CrawfordComeauxbut the bug's already been id'd....
16:08CrawfordComeauxit's me :P
16:09CrawfordComeauxwrong argument when executing a command
16:16seangroveHrm, really struggling here - it seems like clojurescript is affecting the javascript runtime globals
16:17seangroveWithout my script, rapportive loads fine and does its thing. As soon as my script is injected into the page, rapportive falls apart - even if it's a delayed injection
16:20TimMctechnomancy: Where did "locative1" come from as an example password?
16:21dnolenseangrove: sounds like a bad bug, we try to avoid messing with native prototypes (there are a couple of remaining cases), but I'm not aware of any global clobbering.
16:22dnolenseangrove: would be helpful if you could isolate.
16:22seangrovednolen: Really struggling to isolate it. Will continue to try
16:22dnolenseangrove: the one place where much with native prototypes is String, we add an apply method.
16:22dnolen"where we muck"
16:23devnls
16:23lazybotboot etc lost+found mnt opt proc root sbin srv swap sys tmp usr var
16:23arrdemrm -r /
16:23Bronsai laughed pretty hard
16:24seangroveHrm, wonder if that could be it. Rapportive calls .apply on objects for type-checking to see if they're objects, functions, strings, etc.
16:24dnolenseangrove: yes that propably is, but checking JS types that way sounds awful :P
16:24amalloymuahaha. lazybot strikes again
16:25arrdem,({:foo :bar} :foo)
16:25clojurebot:bar
16:25dnolenseangrove: there is an open ticket for the String issue
16:25seangroveYeah, looks like it's going to mistakenly think that strings are objects... not sure if that's the root cause or not though
16:25seangrovednolen: Yeah, awful, but I have to find a way to be compatible with it, which is a bummer
16:26dnolenseangrove: http://dev.clojure.org/jira/browse/CLJS-381
16:26seangroveAny other changes to prototypes like that?
16:26dnolenseangrove: nope
16:26seangrovedefinitely useful for knowing where to look next
16:27dnolenseangrove: it's there to support keyword invokes. The ticket outlines the temporary solution. Real keywrods & symbols is the proper fix.
16:27seangrovehrm, is there someway I can hijack that extremely early on, e.g. (set! (.-apply js/String) nil), to test out if that's the cause
16:28dnolenseangrove: I don't see why not, you can probably do that before you load rapportive
16:28seangroveAlright, let me give it a try...
16:30gfredericksunderscore had a type-check that got broken by cljs, but they took a patch to allow for it
16:30gfredericks(wrt the string prototype)
16:33dnolengfredericks: that was nice of them
16:33gfredericksit was nice of them.
16:33gfredericksI think there was some alternate argument for why it was a good idea as well
16:33gfredericksbut I was only interested in cljs compat
16:34dnolengfredericks: checking for apply is a horrible idea in general yes
16:35gfredericksin case anybody is curious: https://github.com/documentcloud/underscore/commit/2206092e25f66f3a0dbb05c24509a7831b1863fe
16:36dnolengfredericks: oh yeah, checking for call is a terrible idea too
16:36dnolengfredericks: nice patch!
16:38arrdemcan I (:require :only :as)?
16:38gfrederickss/:only/:refer/, yes
16:39gfredericksarrdem: my favorite is (:require [jayq.core :refer [$] :as $])
16:40seangroveRapportive has: _.isFunction = function(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); }
16:40dnolenseangrove: I looked a bit closer at what would be involved in a quick fix - I don't see one.
16:41dnolenseangrove: yes that's completely broken
16:41seangroveuhg
16:41dnolenseangrove: should (typeof obj == "function")
16:41dnolenshould be
16:41dnolenseangrove: not much we can do CLJS side
16:42dnolenseangrove: well .. actually we can, but somebody needs to do the Symbol & Keyword work.
16:42seangrovednolen: Other than not touching String ;)
16:42dnolennot a particularly small project
16:42dnolenseangrove: no can do w/o breaking every CLJS project.
16:42seangroveYeah, let me see if this is the root cause first though
16:43arrdemgfredericks: isn't that eqivalent to (:use [ ... :only [$]])?
16:43dnolenseangrove: but really you should also file a bug w/ them.
16:43gfredericksarrdem: probably; :use is quasi-deprecated to :require
16:43gfredericksdnolen: switching symbol/keyword to a deftype breaks old projects?
16:43dnolenseangrove: or overwrite _.isFunction if you can.
16:44gfredericksI guess it means changing how IFn works too?
16:44dnolengfredericks: no it wouldn't break old projects
16:44seangrovednolen: It's inside of an anonymous function
16:44dnolengfredericks: sorry to confuse - I just meant we can't just stop monkeypatching String. If we're going to fix it we need real Keywords & Symbols
16:44seangroveInterop between apps in js is unbelievably bad
16:45gfredericksdnolen: oh gotcha
16:45dnolenseangrove: seriously that implementation of _.isFunction makes no sense.
16:46dnolenseangrove: the whole thing should be replaced w/ typeof check
16:46seangrovednolen: Yeah, but it is what it is. I'll email them and ask about their reasoning, but they're crazy slow to get back, so I always try to find a way to do it without going through them
16:46technomancyTimMc: the username in that example is Milgrim from https://en.wikipedia.org/wiki/Spook_Country, a book partly about locative art
16:47technomancywho works for Blue Ant and https://en.wikipedia.org/wiki/Hubertus_Bigend
16:48dnolenhttp://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js?r=2#536
16:48dnolenseangrove: I guess it's a bit more complicated. JS sucks.
16:48technomancy"he wears a suit in the color International Klein Blue which he likes because it is a color that cannot be represented on most computer monitors."
16:49seangrovednolen: Yeah, I've come to rely on goog.isObject/Function/String/etc.
16:50daviddparkIn a leiningen project, is it necessary to add some dependency for java libraries? I am getting "Unable to resolve classname: Properties" error when I attempt to run a repl with code: (ns myproj.core (:import (java.util Properties)))
16:52amalloydaviddpark: no, anything in the java core is already on the classpath
16:52amalloyprobably you're running your repl in the user namespace, and so the myproj.core namespace clause doesn't matter
16:53dnolenseangrove: it boggles the mind how there can be so much variance in typeof behavior across JS implementations
16:53dnolenbut perhaps it's not well defined in the spec ...
16:55seangrovednolen: Yeah, it reminds me of this post, which is pretty upsetting http://www.futurealoof.com/posts/balance.html
16:55gfredericksI was about to start hacking on keywords/symbols until I remembered the concern about memory leaks
16:55seangrove"There is a balance to be found between correctness and accessibility and node.js seems to be finding it. Living with JavaScript, and all its faults, seems to have built an understanding in the community that nothing will ever be perfect. By embracing the warts of the language and of various operating systems node.js lives in a harsh reality"
16:55gfredericksI don't remember if there was an alternative approach to interning everything
16:56daviddparkamalloy: I am attempting to interact with system properties, and so need to import java.util.Properties in my leiningen project. The import statement is in the ns declaration since it is in myproj/core.clj
16:56brehautgfredericks: i *think* that keyword interning now uses weak refs to avoid a space leak
16:56gfredericksbrehaut: yes this is wrt cljs where I don't expect weak refs exist
16:56brehautgfredericks: ah. my bad.
16:57gfrederickswould punting on interning work, just having a separate copy like how it works now with strings? As long as hash and eq are defined correctly it'll still work?
16:58gfredericksI would think you could even intern the ones in the source code if that gives any advantages
16:58therealadamI'm trying to wrap my head around ->; it seems like (-> 1 inc #(inc %)) should give me 2 but it bonks trying to cast a symbol
16:59seangroveYeah, appending: delete String.prototype.apply to the compiled cljs brings rapportive back to life
16:59therealadamwhat's my misunderstanding?
16:59amalloy,'(-> 1 inc #(inc %))
16:59seangroveWow that was a long and crazy snipe hunt
16:59brehautgfredericks: i think weakmaps are coming as part of 'Harmony', and mozilla might have an imp?
16:59clojurebot(-> 1 inc (fn* [p1__27#] (inc p1__27#)))
16:59brehautgfredericks: aha https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/WeakMap
16:59dnolenseangrove: good to know, I've been wanting to remove that wart from CLJS for a long time - but haven't had time for that particular mid-sized project.
17:00amalloy&(clojure.walk/macroexpand-all '(-> 1 inc #(inc %)))
17:00lazybot⇒ (fn* (inc 1) [p1__26306#] (inc p1__26306#))
17:00seangrovednolen: Well, you have a lot on your plate
17:00seangroveWould love to see source maps too
17:00amalloytherealadam: make sense?
17:00seangroveI think that ticket is probably above my skill level for now though, or I'd go after it
17:00dnolenseangrove: I'm suprised that fixed it, don't you need to replace .call too?
17:00therealadamamalloy: no :( I looked at the macroexpanded version earlier and don't see an obvious problem
17:01dnolenseangrove: oh right, their _.isFunction checks call & apply
17:01amalloy(fn (inc 1) [x] (inc x)) doesn't look at all wrong to you?
17:01therealadamthe arglist is out of place?
17:01amalloythere's an (inc 1) in a totally nonsense place
17:02therealadamahh
17:02amalloyi think you're imagining that -> is function composition
17:02amalloybut it's not; it's a macro that rewrites your forms at the source-code level
17:02therealadamahhh
17:02amalloybecause of which, putting a lambda in generally results in nonsense
17:02seangrovednolen: There's another call that checks for .call, so deleting that causing Rapportive to be fully healthy again
17:02seangroveObviously kills my app though
17:03bbloomdnolen: i'll be in town next week, we should get together and try to get the keywords/symbols stuff working. i have an old branch we can use as a guide, but i'd appreciate your expertise in optimizing it
17:03seangroveI think we'll just have to cancel rapportive compatibility with this new release, I don't see much else we can do
17:04therealadamamalloy: so `comp` is for replacing f(g(x)) and `->` is for replacing a(b(c())) ?
17:04amalloy-> is best for functions that take multiple arguments
17:05amalloy(-> x (conj 10) (disj 20))
18:46bbloomdnolen: well haskell relies on it's type system to eliminate all the thunks, so i don't see why it wouldn't be possible to make it perform comparably on something like v8
18:47bbloomi dunno what (if any) runtime optimizations modern haskell implementations do
18:51dnolenbbloom: yes I don't see why it couldn't be done, but I would like to see it :) Fay is going down that path but as far as I can tell doesn't do much thunk elimination yet.
18:53bbloomdnolen: the more i experiment with factjor, the more i believe that the haskell approach to isolating side effects (monadic style) is a neat trick but an evolutionary dead end
18:53bbloomdnolen: it makes much more sense to me to figure out how to compose strict and impure programs and use functional abstractions to generate those programs for evaluation
18:54bbloomthere are types of stateful operations that have properties that are similar to pure functions.... idempotent operations, for example
18:55dnolenbbloom: that maybe, don't have any opinions yet - just started really digging into Haskell a few days ago. It's fun.
18:56ibdknoxthe stunted repl made me sad
18:56dnolenibdknox: heh yes, a lot of file reloading
18:57bbloomagreed, the file reloading is a necessity because 'def is really a side effect
18:57dnolenit's also funny that people complain about Clojure errors, Haskell type errors are pretty cryptic for a beginner as well.
18:57ibdknoxdnolen: few people will ever make it to haskell :p
18:57bbloomdnolen: i think that the ppl complaining about clojure errors are mostly people coming from ruby/javascript/java/python
18:57ibdknoxin terms of the language funnel
18:57technomancyocaml compilation errors are pretty good except for the fact that they're translated from french
18:57dnolentechnomancy: ha!
18:58bbloomtechnomancy: lol
18:58ohpauleezhahaha
18:59ibdknoxohpauleez: does your cljs impl of pprint exist somewhere?
18:59dnolenohpauleez: yeah, what's story w/ that ;)
19:00bbloomibdknox: i just grepped my fipp project for '\(\.' and got no hits... soo it should be trivial to run on cljs
19:00bbloom:-)
19:01ohpauleezdnolen: ibdknox: I was just walking through it with brenton ashworth a couple weeks ago
19:01ohpauleezI would go with bbloom's fipp if it fits the bill
19:01ibdknoxbbloom: oh? I thought I looked at it when you mentioned and there were some classy things in there
19:01ibdknoxif not
19:01ibdknox /win
19:02ohpauleezmy port was only for the absolutely necessary parts to make the cl-format work
19:02bbloomibdknox: do you need code-dispatch too? or just simple-dispatch (edn)?
19:02ohpauleezI went back and started porting the rest
19:02ibdknoxbbloom: edn is sufficient for now
19:02ohpauleezbut it's essentially like porting CL to Clojure
19:02ibdknoxohpauleez: lol yeah, not so much fun
19:03ohpauleezyeah, so I was re-writing parts of it - fipp is pretty close to what I was coming up with
19:03ohpauleezI kept some of the CL stuff
19:03bbloomibdknox: the only "classy" things in there are in edn.clj which refers to the types from clojure.lang
19:03bbloomyou can probably just rename clj to cljs and then rename those 5 or 6 class entries and it would work
19:03bbloomshould take 5 minutes & if it takes any longer, let me know & i can tweak it
19:03ohpauleezI'd be more than happy to give people the cl-format piece, but it's probably not what most people want
19:04ibdknoxbbloom: awesome. I'll let you know
19:04ohpauleezibdknox: Yeah, not fun at all haha
19:04technomancypretty sure cl-format only got into clojure because pprint needed it
19:04technomancylike clojure.walk
19:04bbloomi'm probably not going to do code-dispatch until i decide on some way to do something stylesheet-like
19:04ibdknoxI <3 clojure.walk
19:04bbloomi want it to be trivial for people to supply indentation rules and the like for their libraries
19:05ibdknoxbbloom: that's also something I would be really interested in at some point :)
19:05ibdknoxanyone going to ICSE?
19:05bbloomibdknox: i'll get to it eventually, it's very low priority now. all i needed was the damn pretty printer to be much much faster for some local diff tests that i'm doing :-)
19:06ibdknoxI actually think that'd be useful at the community level
19:06technomancyISTR clojure.walk has been disowned by its author?
19:06ibdknoxit's one thing I thought they did very nicely for Go
19:06bbloomi also want to pretty print other stuff, like CSS or whatever
19:06technomancynot that it's bad from a user perspective; just the implementation
19:07bbloomand i'd also like colored output and other niceties
19:07ohpauleeztechnomancy: Yeah, those libs are pretty terrible, even for CL-style code
19:07bbloombut all that stuff is queued up behind real work ;-)
19:07ibdknoxlein format would be nice :)
19:08ibdknoxdamn priorities ;)
19:08bbloomibdknox: yeah it would :-)
19:08technomancybbloom: wait, does yours work in a comment-preserving fashion?
19:08technomancyI thought only sjacket did that?
19:09bbloomtechnomancy: i don't have a parser of any kind
19:09bbloomtechnomancy: that's another reason i haven't done code-dispatch
19:09ibdknoxtechnomancy: it probably wouldn't be too hard to add comment preservation to blind
19:10bbloomi want to be able to re-use the formatting rules for data-structures->pretty-printed as well as string-or-file->ast->pretty-printed
19:11bbloomi need some time to think about how to do stylesheets. it needs to 1) be data 2) be easy to create new styles 3) compose cleanly 4) perform well during printing
19:14bbloomibdknox: what are your pretty printing needs for LT?
19:14ibdknoxCLJS results right now :)
19:15bbloomibdknox: ie repl results?
19:15ohpauleezibdknox: Strict edn?
19:15pbostromdoes anyone run lein on an amazon ec2 micro instance? it seems like it takes up to 10-15 minutes to start up, but ec2 small instances run fine, I'm wondering if there's something I need to tweak, I've tried a few -Xmx and -Xms opts in vain
19:15ibdknoxohpauleez: it may contain non-printable things that could be [object object] or whatnot, but yeah more or less
19:15ibdknoxbbloom: more or less, yes
19:16bbloomibdknox: so i assume you need controls like depth, item limits, etc ? fipp doesnt do that yet
19:18ibdknoxbbloom: at some point those things would be nice, but there are other ways for me to deal with that in the mean time :)
19:18ibdknoxmeantime*
19:19bbloomibdknox: heh, mental image of an angry clock
19:19ibdknoxhaha
19:20bbloomibdknox: both of those things should be relatively easy to add, but again, i was waiting until i thought about stylesheets b/c i want those things to be stylable
19:20bbloomibdknox: ie argument lists are vectors, but they should never be elided if you set the list print limit to 6 or whatever
19:20ibdknoxmakes sense
19:21bbloomibdknox: we probably have a lot of stuff in common... i think it's possible that I'm gonna be building the Blend to complement your Visual Studio, heh
19:22bbloomlots of *needs* in common, in terms of components, that is
19:22ibdknoxyeah probably :)
19:23seangrovebbloom: What're you building?
19:24cheezeyall right guys
19:24cheezeyoops wrong channel
19:37seangrovebbloom: Well, I suppose I'll see it when I see it then :)
19:40bbloominterestingly, angular does a fair amount metaprogramming to achieve optimal performance. There are places where they call Function(...) with a string of code
19:55seangrovebbloom: Are you using angular from cljs?
19:56bbloomseangrove: no, i'm just studying it
19:56bbloomi've used it from coffeescript
19:57seangroveYeah, I've heard good things about it, but haven't thought much about how it would fit in the cljs world
19:58seangroveI hate debugging javascript in firefox, it's such a bad experience: http://dl.dropbox.com/u/412963/Screenshots/a-.png
20:01SegFaultAXseangrove: In fairness, javascript can be painful to debug in general. :)
20:01seangroveSegFaultAX: True, and this is with the caveat that I've sworn off IE as a target at all for now
20:02seangroveSo I suppose it gets worse
20:02SegFaultAXI find the browser that gives me the most trouble is usually opera.
20:03SegFaultAXI think it's because they are more "standards-nazis" than the other vendors.
20:03SegFaultAXAlthough I definitely don't do a lot of javascript development day-to-day, so that could just be my suckiness.
20:05bbloomcallbacks are the real source of hard to track bugs
20:06kovasI'm getting into angular these days
20:06kovasmy theory re: cljs is
20:06kovasthat its all about defining the directives, rather than the controllers
20:07kovasdefining the directives using js is a pretty shitty experience
20:07kovasbut we can do a lot better
20:11bbloomkovas: you gonna be at clojure/west ? we can talk about what "better" looks like
20:11kovasbbloom: yup will be there
20:11kovasbbloom: my immediate concept of better is: macros
20:12kovasbbloom: that eliminate the 100 ways to shoot yourself in the foot
20:12bbloomheh
20:12kovasbbloom: have you seen the angular videos
20:12kovas?
20:12bbloomi'm thinking bigger :-)
20:12bbloomno, which videos?
20:12kovasbbloom: its basically one example of a gotcha after another
20:12bbloomkovas: link?
20:12kovasone sec
20:13kovashttp://www.youtube.com/watch?v=WqmeI5fZcho&amp;list=UUbn1OgGei-DV7aSRo_HaAiw
20:13kovashttp://www.youtube.com/watch?v=iB7hfvqyZpg
20:13kovasi mean, i give them a ton of credit for understanding the problems
20:13bbloomkovas: sheesh, long videos :-P but definitely a topic i'm interesting in, so i'll probably get around to watching them at some point
20:13kovasbut making JS do the things they want is a feat
20:13kovasyeah
20:14kovasbbloom: in terms of doing better, they are an enumeration of the flaws
20:14kovasbigger is better
20:14kovasbut its hard to see the bigger picture when bogged down in all the incidental complexity
20:15bbloomkovas: in your opinion, what are the primary sources of incidental complexity?
20:15bbloomat the directive level, that is
20:16kovasbbloom: the way scope is set up is kindof a mess
20:16kovasbbloom: since they can't introduce a higher level language construct
20:16SegFaultAXSo is Backbone.js dead?
20:16SegFaultAX(And did Angular kill it?)
20:16bbloomSegFaultAX: it's not dead, it's just a simpler tool for smaller problems
20:17bbloomSegFaultAX: backbone is great for a few rich components on top of a REST API
20:17bbloomSegFaultAX: but it always has been woefully inadequate for large apps
20:17taliosbrehaut: nice blog post :) one thought tho - an HttpRequest and DatabaseRecord are still types, mostly modelled as maps with extras, so you can still do static typing there - maybe not CustomerRecord tho
20:18kovasbeing able to define your own tags always seemed like the missing thing to me
20:18bbloomkovas: i agree that the scopes are complex. i think it's mainly an attempt to preserve the javascript mutable getter/setter experience for working with models
20:18bbloomkovas: which is more pleasant than the model.get('prop') approach
20:19kovasbbloom: i think conceptually they are doing the right thing, its just the expression of the concept that is a disaster
20:19bbloomkovas: i wouldn't call it a disaster
20:19kovaswatch the videos :)
20:19bbloomi will :-)
20:19brehauttalios: thanks. the bit i glossed over is that if your code is marshalling from HttpRequest to DatabaseRecord with only a tiny bit of logic in the middle (ie from roughly two different Universal types), theres boiler plate you gain is traded off against everything else
20:19bbloomkovas: my goal is to have the "scope hierarchy" be a single immutable data structure and that it's accessed via update-in or assoc-in etc
20:19kovasI'm gonna watch them again and take notes. theres about 10-15 wacky things
20:20bbloomso you bind to paths
20:20bbloomi think it will enable pretty fast dirty checking too, since we have fast equality for our data structures
20:20taliosbrehaut: true, but if you're mapping directly from request->database query, are you not also walking into a Ruby On Rails style security f**k up? ( potentially )
20:20kovasbbloom: that would be pretty cool. i spent a lot of time last summer trying to do something similar but couldn't figure it out
20:21bbloomkovas: it's a really hard problem, but i have some cool stuff actually working
20:21kovasbbloom: awesome
20:21bbloomkovas: i feel like i wouldn't have been able to pull it off if i didn't have the very particular (and very unlikely) collection of past professional experiences :-P
20:22kovasbbloom: is it the times that make the man, or the man that makes the times
20:22brehauttalios: i dont disagree that there is potential for bugs. i would however be leary of any system that pushes all security concerns to the type system
20:23kovasbbloom: my pov is that if you can crack the directives, you can then program them to fit with clojure datastructures
20:23kovasbbloom: rather than the other way around
20:24kovasbbloom: also if you have a nice high-level directive language, thats interesting to everyone doing angular dev
20:24bbloomkovas: well, my though is that there are really multiple classes of directives
20:24brehauttalios: tbh, i think the bigger issue with not having static types is that systemic changes over the long term can be harder
20:24taliosbrehaut: depending on how you model it, if you did (let [db-record (map request db-func)] ...) you can still type shift/validate/sanitize there, or it could just return a modified/restructured map
20:24bbloomkovas: there are those that work with the dom and then there are higher level ones that operate in the domain of applications
20:24bblooms/though/thought/
20:25brehauttalios: oh absolutely, not validating and sanatizing the data would be mental
20:25kovaswhat would be an example of the latter?
20:25bbloomkovas: i expect that a macroexpand-like behavior for templates/views/whatever can be leveraged to mean that writing "directives" is often really simple, unless you need to directly interface with the dom
20:25taliosbrehaut: true, the counter to that is you get fast-fail of API breakages - if/when you break APIs. if you silently change a map structure, you leaving that to the hope that someone else also has tests covering it, not only you having tests
20:25bbloomkovas: examples of non dom interacting directives?
20:25kovasyeah
20:25bbloombasically anything that doesn't need to, itself, bind event handlers
20:26brehauttalios: thats exactly what im saying.
20:26bbloomyou need some higher level concepts that are missing from angular currently
20:26kovasbut if they bind data, they are also interacting with the dom right
20:26bbloomkovas: not directly
20:26bbloomconsider, Triggers in WPF for example:
20:26taliosbrehaut: nah, I 1/2 read your line :)
20:26bbloomkovas: http://wpftutorial.net/Triggers.html
20:27taliosbrehaut: lack of typing is good to starting up, getting going, but on the long term I'm not so sure.
20:27bbloomkovas: that sort of stuff can be expressed *abstractly* and different backends can be provided
20:27taliosbrehaut: overheard a conversation here yesterday about naming, and about clojures re-match functions etc. etc. if you're prepending function names with type information, you may as well have types :)
20:27kovasok, i think i understand
20:28bbloomtalios: those name prefixes also help in reading and understanding
20:28taliostrue
20:28bbloomtalios: types aren't necessarily apparent at the call site
20:28bbloomnames, generally, are
20:29kovasbbloom: by abstractly, you mean as a protocol, as a element tag, or as something else?
20:29bbloomkovas: something else
20:29bbloomkovas: i'm separating directives into two concepts: properties and passes
20:29kovasbbloom: a pass is some metaprogramming transform?
20:29bbloomkovas: pretty much
20:30kovascool
20:30bbloomkovas: the premise is that you have a schema that defines facts about properties. how to validate them, how to compose them, how they are inherited via hierarchy or via templating, etc
20:30kovasyeah, the interaction between directives seems like one of the under defined aspects of angular
20:30bbloomkovas: then you define passes, which effectively macro expand properties until you get properties in terms of the target platform
20:31kovasinteresting
20:31bbloomand once you have that data structure in the fully expanded form, you need a runtime to operate on it
20:31bbloomand that runtime is what does the real event binding
20:31kovasright
20:31bbloomand each pass captures its inputs and outputs, such that expansion can be resumed at any point in the transformation
20:32bbloomso that you can efficiently re-expand only the bits that have chnaged
20:32kovasat runtime?
20:32bbloomyup
20:32kovasthats great
20:32bbloomi'm excited about it :-)
20:32bbloomit's A LOT OF WORK to get it all designed right
20:32kovassymbolic programming FTW
20:32bbloombeen working on it for months
20:32bbloomi've got about 2,000 lines of production quality code haha
20:32bbloomgetting all the abstractions right is really difficult
20:32kovasno doubt
20:33kovasgithub that baby :)
20:33bbloomkovas: you worked at wolfram for a while, right?
20:33kovasbbloom: yup
20:33bbloomi'll open source it eventually :-)
20:34bbloomkovas: symbolic everything, huh? haha
20:34kovassymbolic all the things
20:34bbloomyeah, i'm becoming a big believer in that
20:34kovasrecursive substitution is powerful
20:34bbloomi'm not really sold on rewrite systems though, although they make a ton of sense for algebraic systems
20:35kovasrewrite systems will never perform like function calls
20:35bbloomyeah, it's recursive substitution, but not generalized pattern matching & rewrites
20:35kovasbut i truly believe its a higher level paradigm
20:35bbloomeach "pass" has a special set of behavior for substitution and for delegating to the next pass
20:35kovasinteresting
20:36kovasi've been thinking a lot about how to do that in clojure
20:36bbloomafter i write a whole bunch of passes, i'll see what i can do about a more generalized rewrite mechanism for making it easier to create passes
20:36kovasis that something that happens in your concatenate language, or in this unpublished library?
20:36bbloomi've only got 6 or so passes right now and they are pretty different
20:36bbloomunpublished
20:36kovasthats interesting stuff
20:37kovasseems relevant for the cljs compiler as well
20:37bbloomthe concatenative library is being used in the platform-specific runtime layer, not in the expansion/substitution system
20:37kovasi see
20:37kovasis it all about core.walk?
20:37bbloomyeah, i think the approach is generally applicable: in theory the tree being expanded could be something like an AST. if you can capture the inputs you could incrementally recompile
20:38bbloombut i'm focused on user interfaces for v1
20:38kovasby capturing the inputs, you mean caching them and associating with the output?
20:38bbloomyes
20:38bbloomwhich is what i need to do for performant data binding
20:38kovasso this is like recursive substitution & dynamic recomputation
20:38bbloomprecisely what it is
20:39bbloomi assume mathematica does all that internally :-)
20:39kovasmathematica takes the easy way out
20:39kovasyou tell it what the recompilation points are explicitely
20:39bbloomre-expand/substitute from the root?
20:39kovaswith Dynamic[]
20:39bbloomah, i see
20:40kovasits powerful, but still a hack
20:40kovasit only applies to rendered content, rather than to general expressions
20:40bbloomthe goal is: model <-> view-model <-> view <-> platform
20:40bbloomwhere view-model == angular scopes basically
20:40bbloomand model is optional for really simple systems
20:40kovasright
20:40bbloomand the <-> arrows express two way communication
20:41bbloomand it's intentionally linear
20:41kovaslinear?
20:41bbloomie platform doesn't talk to view-model
20:41bbloomit talks through view
20:41bbloomit's a bidirectional pipeline, but it's a pipeline, not a cyclic system
20:41kovaswhat is the platform in the case of the browser
20:42kovasis it the dom?
20:42bbloomyes
20:43kovasnice. well I'm glad this is getting solved without me doing the work :)
20:43bbloomhaha
20:43bbloomit's complex stuff, but it's fun
20:44bbloommy hope is that i can build a pretty bitching UI toolkit with this, but you're right, this could be even more broadly applicable
20:44kovasthe symbolic substitution is definitely a general tool
20:45kovasi won't be totally happy with clojure until we have that
20:45kovasbut UI is the immediate need
20:45kovasI'm dying here
20:45bbloomkovas: ha! yeah, my stuff would hopefully be very useful for session
20:45bbloomi think that UI is an immediate need in general
20:45bbloomit's sorta like an unsolved problem
20:45kovasi just started rewriting session in angular
20:45bbloomit's just *fucking hard*
20:46kovasyup
20:46bbloomthat's a bummer, but understandable
20:46kovasthats the bottleneck right now
20:46bbloomhmm, are you NYC based too?
20:46kovasi think its just gonna take a weekend. (famous last words)
20:46kovasfor another week or so
20:46kovasthen i move to bay area
20:46kovaswhere are you?
20:47bbloomheh, aw, we'll just miss each other. i'm moving to NYC next week :-)
20:47kovasI'm gone on the 1st
20:47kovassame deal?
20:48bbloomnah, like 29th ha, but i'll be pretty busy the first few days
20:48kovasno doubt
20:50kovasbbloom: are you gonna release this b4 clojure west?
20:50bbloomkovas: unlikely, but i'll probably have something to demo there
20:51kovasbbloom: ok, i will continue my rewrite then ;)
20:51bbloomhaha
20:51bbloomkovas: please keep some notes & share them with me, i'm curious how it goes
20:53akhudekbbloom: that sounds very interesting. Looking forward to learning more!
20:54kovaswiill do
20:55bbloomakhudek: i'll be sure to make lots of noise about it when it's ready to show off :-)
20:56kovasbbloom: i suggest doing that prior to the conf
20:56ibdknoxbbloom: we should talk again
20:56kovasbbloom: lets other announcements suck up the oxygen
20:56kovaslest
20:56ibdknoxbbloom: because I'm thinking even bigger I believe ;)
20:57bbloomibdknox: free free to talk here or msg me
20:58bbloomkovas: i don't expect to have anything to announce or release until some time after the conference
20:59bbloomibdknox: what's "bigger"? :-)
20:59ibdknoxa different programming paradigm :)
20:59gdevwhat's going on?
20:59bbloomibdknox: heh, i'm not quite there yet. one step at a time :-P
21:00AtKaaZwhere are the logs? cause sounds interesting
21:00akhudekbbloom: any similarity to http://goo.gl/lIOWF
21:00bbloomhttp://clojure-log.n01se.net/
21:00akhudek?
21:00kovasI'm pretty convinced symbol rewriting is the simplest programming paradigm possible
21:00AtKaaZthanks;)
21:00kovasand pretty ideal for working with on e.g. an ipad
21:01bbloomakhudek: i'll take a peek at that paper, give me a sec
21:01ibdknoxkovas: example?
21:01ibdknoxwhat I've been thinking (and prototyping) is also ideal for an ipad
21:02akhudekdifferent application, but some of your descriptions above sounded similar to basic technique
21:02kovasibdknox: i'm thinking about a simplified version of the mathematica language
21:02bbloomibdknox: i figure that declarative UIs in edn is a reasonable starting point & that the implementation is totally secondary to getting the abstractions right
21:02bbloomibdknox: if you magically come up with another programming paradigm that lets me get the same behavior and perf with less code, i'll be happy to evaluate it :-)
21:03kovasibdknox: something like scratch, but far more powerful
21:03bbloomakhudek: i don't really have time to dig into this paper now. is there something in particular you thought paralleled what i'm talking about?
21:04kovasibdknox: if the UI is represented symbolically, then you can see the substitutions in code simultaneously with their visual interpretation
21:04gdevsounds like light table
21:04bbloomkovas: and you can provide single-step debugging of the expansion process :-)
21:04ibdknoxkovas: yep, I'm making that work
21:04bbloomexpansion -> substitution
21:04kovasibdknox: aww yeah
21:04bbloomi guess it can *shrink* not just expand, but 90% of the time it expands haha
21:05akhudekthe basic idea there is to compile a query by a sort of step-wise graph expansion. You stop expanding when you've mapped the input concepts to the target concepts.
21:05akhudekthat's a gross simplification, but sounded a lot like what you were describing with passes
21:05bbloomheh, that's an interesting parallel to a thought discussed in IRC a week ago or so: reducers don't always reduce, sometimes they expand: ie mapcat
21:05bbloomand similarly, macroexpand doesn't always expand
21:06bbloom,(macroexpand '(-> 1))
21:06clojurebot1
21:06bbloom:-)
21:06bbloomsubstituters and macrosubstitute doesn't really have the same ring to them
21:07kovasyeah I've been struggling with good names for that as well
21:07bbloomakhudek: yeah, that's what i'm describing, but that's similar to any symbolic program... in particular: compilers
21:07kovasthe words are hopelessly overloaded
21:08bbloomnames are fucking hard
21:08bbloomthat's why haskell people just give up and pick some symbols
21:08bbloomheh
21:08akhudekbbloom: yes, though the devil is always in the details. :-) Proving that you've genuinely achieved a correct mapping under your constraints is the hard part.
21:09brehautyup, its one of the two hard problems, along with cache invalidation and off by one errors
21:09akhudeknevermind the graph search problem itself
21:10bbloomakhudek: luckily, there is no *correct* mapping in UIs
21:10ibdknoxkovas: this is a relatively new endeavor, but I was hoping to maybe demo something at the liveprogramming workshop: http://liveprogramming.github.com/2013/
21:10bbloomakhudek: consistency is more important
21:10bbloomakhudek: as long as the expansion process is clear, understandable, consistent, and produces testable output, then the developer can tweak until they get a UX they like
21:11bbloomakhudek: unlike queries, which are being optimized, there is no consistent output
21:11kovasibdknox: cool. I'm gonna hit that up
21:11bbloomibdknox: can you give a couple sentence overview?
21:13akhudekInteresting. Still looking forward to seeing what you've cooked up. :-)
21:14ibdknoxbbloom: your program as a datastructure ;) Basically what would a truly declarative approach to building *real* software look like? And more interestingly, what does that allow you to do with tools?
21:14bbloomibdknox: very cool. it's definitely something i have extreme interest in
21:14kovasif you program is declarative, that makes it a lot more trivial to share
21:14craigbrovan roy? haridi?
21:14ibdknoxthe demo I was thinking of for ICSE is building todoMVC
21:15ibdknoxon a touch screen :)
21:15craigbroam I correct to think you mean something other than declartive programming?
21:15bbloomibdknox: HA! I have a (mostly) working todoMVC
21:15bbloomit seems we are playing in the same sandbox :-)
21:15bbloommy thought is that declarative programming for real software is strictly harder than declarative UI, and real tools need real UI
21:16bbloomin the chicken and egg cycle, one of us has chosen the chicken and the other has chosen the egg, ha
21:16bbloomi also have a pong game :-)
21:16ibdknoxI agree, though I think there's an underlying solution that actually addresses both
21:16bbloomibdknox: i think that underlying solution is symbolic expansion
21:16kovasdeclarative UI quickly devolves into declarative programs
21:16kovasyou need to save the state somewhere, first of all
21:17ibdknoxkovas: yeah, that's what I ran into
21:17kovasibdknox: i gave up until datomic free came out
21:17bbloomkovas: nah, you can isolate that into "commands" where the declarative bit is only what named command (1) to execute on what path in the state data structure (2), with what arguments (3)
21:17ibdknoxbbloom: any reading you can suggest on symbolic expansion?
21:17bbloomibdknox: install mathematica :-P
21:17kovas+1
21:18ibdknoxwhy don't we use mathematica for everything?
21:18bbloomb/c it is largely backwards compatable with v1
21:19bbloomlooong before persistent data structures were common place :-)
21:19ibdknoxbut you think they've solved the underlying problem?
21:19kovas_its slow and proprietary
21:19bbloomno, i think that mathematica is the best known example of symbol substitution
21:19bbloomand hence mathematica is worth studying
21:19craigbrocommercial example...
21:19kovas_and doesn't have the abstractions that go down to the platform
21:19ibdknoxgot it
21:20craigbromatlab
21:20bbloomthis topic is extremely interesting to me, but sadly, i gotta run
21:20kovas_ibdknox: if you implement Manipulate, that will be considered a heroic act
21:21kovas_later!
21:21bbloomManipulate is super cool
21:21bbloomkovas_: & ibdknox: we should all definitely get together and talk about this the next time i'm in the bay area
21:21kovas_would love to
21:21ibdknoxsure thing
21:22ibdknoxkovas_: as in turning values into sliders and such? That's manipulate?
21:22craigbropresent/
21:22craigbroaccept
21:22kovas_ibdknox: theres maybe 3 aspects
21:22craigbroseperates presentation types from data types
21:22kovas_ibdknox: first is auto-generating an interface that is relevant to the parameters being manipulated
21:22craigbrois in effect a declarative layer sitting on top of a procedural layer for UI
21:23kovas_ibdknox: second is rendering values as UI without any intermediate nonsense
21:23craigbroCLIM was totally baroque tho
21:23kovas_ibdknox: third is the dynamic recomputation
21:23ibdknoxgot it
21:23ibdknoxwell
21:24ibdknoxfrom watching these couple videos and from what you guys are saying, that sounds like what I intended to be able to do
21:24ibdknoxlol
21:24ibdknoxI prototyped an engine for this stuff this weekend, just really simple stuff
21:25ibdknoxworking on what primitive notions you need to build the vast majority of programs
21:25kovas_sweet
21:25kovas_what are the primitives?
21:27ibdknoxI've been thinking of it as a system that has two things in it
21:28ibdknoxyou need to define the "things" in your program - objects
21:28ibdknoxand then you need to define the relationships between them
21:29ibdknoxthe things in your program are sinks for IO basically
21:29kovas_this is for all programs, or mainly UI-driven ones?
21:29kovas_ok
21:29ibdknoxI've been primarily thinking about the entire web stack, which encompasses both UI and non-UI things
21:30ibdknoxI was focusing on figuring out the types of relationships that exist, because I think there are very very few
21:30kovas_are the relationships constraints, or rules for evolution
21:31ibdknoxmore akin to constraints I think
21:31ibdknoxthough again, this is a first pass
21:31kovas_how do you make it run?
21:32ibdknoxfeed the datastructure into the (run ...) function, of course ;)
21:32kovas_right :)
21:32ibdknoxevery program has to have some entry point, something that kicks it off
21:32craigbroreally?
21:32kovas_but in terms of turning constraints into updates i mean
21:32craigbrocould just start a listener
21:32ibdknoxcraigbro: then the thing that kicks it off is that listener firing
21:33ibdknoxbind your listener in run
21:33ibdknoxand wait
21:33craigbrothe litener need not be part of the program
21:33akhudekthis sounds exactly like the project I've been part of for the last two years at UW, complete with IO black boxes. It's not an easy problem to solve, especially update.
21:33ibdknoxkovas_: delayed binding of listeners
21:33craigbroif my program is a combination of a data structue, some more declaration of how to dispaly aspects of it etc..
21:34ibdknoxcraigbro: I'm not sure I understand what you mean by the listener need not be part of the program. Can you give a concrete example?
21:34craigbroan html page
21:35ibdknoxan html page runs
21:35ibdknoxon load
21:35craigbrothe browser runs it
21:35craigbrothe onload in this case is a procedure description
21:36kovas_ibdknox: so what are the identified relationships so far?
21:36ibdknoxpush, associate, and update
21:36craigbrobut, this semantic distinction is, an aside
21:37craigbroanother example would be a NetLogo program
21:37kovas_is delete a special case of update?
21:37craigbroit's a blob of code, and a description of a UI
21:37craigbrono code is run until a user clicks on a button that calls something
21:37ibdknoxkovas_: update can send messages
21:38kovas_ibdknox: how is it different from _just_ sending messages?
21:38craigbrothis distition of what is inside and outside the program is important when you want the program to run in lots of different contexts
21:39craigbrothe same netlogo model can be run interactively, or run in the "lab" which will run in N times where N is the number of combinations of different parameters you tell the lab to run it with
21:39ibdknoxkovas_: what are you referring to with "it"
21:40kovas_ibdknox: update
21:42ibdknoxkovas_: it depends on how you define the end points, but fundamentally it's a form of message passing
21:43ibdknoxkovas_: update is a triggered push
21:43ibdknoxa push relationship keeps all dependents in sync automatically
21:44ibdknoxcraigbro: that's just a property of the runner though, right?
21:44kovas_ibdknox: i see. and assoc?
21:45kovas_ibdknox: does that change the topology or something?
21:45ibdknoxkovas_: you need a way to say that this thing has a copy of something
21:45ibdknoxkovas_: each todo needs its own copy of a representation that is bound correctly and such
21:45kovas_right
21:46kovas_so assoc is for inserting identities, push is for inserting values. is that the idea?
21:46ibdknoxyep
21:46kovas_nice
21:47ibdknoxvery early still, but with just those, you can get surprisingly far
21:47kovas_is update a pure function?
21:47ibdknoxall pure functions
21:48craigbroibdknox: Dclarative UIs are all about where you draw the distinction between the program, and the container, or "runner"
21:48kovas_so the contract is update produces new state that you can perceive and hang out to (rather than arbitrary side effects)
21:48craigbroibdknox: HTML is a perfect example of a declarative UI, which can do all kinds of things, even without js
21:48ibdknoxkovas_: I think that's how it's going to play out
21:49kovas_sounds pretty clean
21:49craigbroibdknox: but I'm not so sure the point I'm making is germane to your experiment, or in any way a "revelation" in regards to it
21:50ibdknoxcraigbro: haha :) My thought is that I don't want to think about the container if I don't have to
21:50craigbroibdknox: where cootainer is your mishmash of procedural/functional jQuery and clojurescript to make the pixels on the screen?
21:50ibdknoxthe completely ridiculous demo I want to do is to by changing one of the directives in my todoMVC it goes from a completely local (just an HTML page) program to spinning up a server and running remotely serving that and communicating changes back
21:52kovas_hmm
21:52kovas_that would be impressive
21:52ibdknoxI agree - now to make it work :)
21:52kovas_but its hard to know what conclusion to draw from that in terms of general capabilities
21:53kovas_or is the point really the easy transition between client and server
21:53ibdknoxno, more that it's able to figure that out
21:53ibdknoxwhat do you think would show the more general capabilities?
21:53kovas_by directive you mean like html tag?
21:54ibdknoxI have a collection of todos, I change a piece of metadata on it from :local to :remote
21:54kovas_i see
21:54kovas_ok, that would be pretty sweet
21:55ibdknoxbasically that transition would cause a near complete rewrite in the normal case
21:55kovas_right
21:55ibdknoxbecause no matter how hard you try you must take architectural dependencies
21:55ibdknoxbut if you stop saying "how" and start saying "what" it doesn't matter
21:55ibdknoxthe architecture is decided JIT
21:56kovas_right
21:57kovas_interesting compilation problem
21:57craigbroCLIM again 8^)
21:57kovas_do you have to analyze it at the source code level?
21:58craigbro(present my-todo-lisp 'todo-presentation-type +swing+)
21:58ibdknoxhaha
21:59craigbro(present my-todo-lisp 'todo-presentation-type (merge +htmlserver+ {:base-url "/todo" :authhandler (reify...))
21:59ibdknoxkovas_: I haven't thought too far down how that level of transformation will work yet :)
21:59craigbroto handle events you have input and output streams that read/write presentation records
22:00ibdknoxbut you have complete information, I believe it's possible
22:00kovas_ibdknox: i imagined it as tagged literals rather than metadata. then its easy to bind the interpretation. but TLs not great for code-like things.
22:00craigbroi have a lightweight presentation system we use for our web apps, that renders to just a hiccup view
22:01craigbrometadata is a pain in the ass
22:01craigbroespecially if you do symbolic operations on your data
22:02kovas_what kind of operations?
22:02craigbroeq?
22:02clojurebot@ splices in a seq and foo# is a symbol, not a seq
22:02craigbrohehe
22:03kovas_because it ignores metadata?
22:03craigbrofor example, i tagged some symbol names for one data type with metadata
22:03craigbroI always have to go back to the original symbol object to get the metadata
22:05kovas_i see.
22:05kovas_you want them to be more like vars then
22:05clojurebotyour idea of vars, symbols, and scoping is wackadoodle
22:05craigbroit gets to be a pain when you are doing thigns like spitting stuff out to a file
22:05craigbroand reading it back in
22:06kovas_because every instance of the symbol is a distinct entity
22:06craigbroyou want them to be more like vars then
22:06craigbroerr
22:06craigbrotrying to trigger clojurebot there
22:06craigbroeq?
22:06clojurebotAnyone can hack! http://images.wikia.com/pixar/images/0/0d/Http_alliedow-files-wordpress-com_2011-01_anyone-can-cook-445x355.png
22:06kovas_I agree its a shame you can't directly attach stuff to symbols as identities
22:07kovas_that would make things more symbolic for sure
22:07craigbrosymbol properties!
22:07craigbrocommon lisp again
22:07craigbrolord save us all
22:07kovas_i mean, its easy enough to do it yourself
22:08kovas_without some programmatic meaning to the properties, its not that useful
22:08kovas_but if its integrated with macros, then it is very useful
22:09craigbroprogrammating meaning to the properties?
22:09craigbroprogrammatic..
22:10kovas_yes, like mathematica attributes
22:10craigbronot familiar
22:10kovas_its trivial to make symbols thread over lists by setting the attribute Listable
22:10arrdem,\f
22:10clojurebot\f
22:11kovas_http://reference.wolfram.com/mathematica/tutorial/Attributes.html
22:11kovas_unfortunately in mathematica attributes are not extensible by the user
22:11kovas_but they cover many of the cases we use macros for
22:11kovas_in a much easier to use way
22:12kovas_"Sometimes, however, you need to specify general properties of functions, without necessarily giving explicit values."
22:12kovas_actually this is also relevant to ibdknox 's project
22:13kovas_so what id like to figure out is how to have the concept of Attributes be made extensible
22:13kovas_by attached metadata on the symbol, combined with some kind of macro protocol
22:14craigbrogetting to be one too many transformation layers for my tastes
22:14kovas_its more of a natural completion of the abstractions we have now
22:14kovas_why can't macros have protocols?
22:14kovas_that would make them a lot more interoperable
22:15kovas_and symbols could specify what their own macro expansion should be
22:15kovas_under a given macro
22:15kovas_as it is, its pretty broken from the "program against abstractions" pov
22:16kovas_if you want (foo [a b c]) -> [(foo a) (foo b) (foo b)]
22:16kovas_its silly to not have an abstraction you can apply to the symbol foo to get that behavior
22:17craigbrowrite the function that way
22:17kovas_craigbro: so layers of transformation is good for CLIM, but not for general programming ;)
22:18craigbrodon't hide it in a property...
22:18kovas_its more declarative as a property
22:18kovas_"what, not how"
22:19kovas_you can set the attribute in the function definition, so its not off somewhere else
22:20craigbromap is as much what as how
22:21craigbroso this is not decl. vs anything else
22:21craigbrosyntactic mutability
22:23craigbrocan't you not alrady do this with tagged literals?
22:23kovas_i wish
22:23craigbrosure you could
22:23kovas_i don't think so
22:24craigbrofor listable
22:24craigbroyour data reader fn would be given foo
22:24kovas_i don't think TLs capture scope the way you want
22:25kovas_i should play with that again, but theres some tricky issues
22:25kovas_i mean, you can do it with a macro right
22:26kovas_at least thats what we end up doing
22:26kovas_but that isn't extensible.
22:26kovas_the macro can't know, for each symbol, which positions should be listable
22:26craigbroseems to me you could do it in the fn itself
22:27craigbroa macro (listable-body...
22:27kovas_yes, but then that information is lost to the symbol level
22:28kovas_its just "this happens to be the behavior of the function, buts that a black box"
22:29kovas_it wouldn't be so bad if you could have multiple function forms with the same arity
22:29kovas_if you have a 1-arity function, you have to have a conditional first before you figure out if you map, or if you do the base case
22:29craigbroyou could us your own defn
22:29craigbrosince you're just talking about fns...
22:30craigbrowe don't have symbol macro expansion anyways
22:30kovas_i think we should
22:30craigbrosure, I do to actually
22:30craigbroyour defn would be a fine way to experiment with this
22:31kovas_yes thats a good point
22:31craigbroi do macros like that all the time
22:31kovas_you mean like custom defns?
22:31craigbroa macro that defines a fn as the vlaue of the symbol, but also sets up alot of bookkeeping
22:32craigbroand metadata
22:33craigbroI prefer a global ref to a map
22:33craigbrokeys on the symbol
22:33craigbrokeyed...
22:33craigbroinstead of metadata
22:33kovas_yeah that solves your other problems
22:33kovas_i gotta run
22:33kovas_ttyl!
22:34craigbrolatah
22:54yediwow clojurescript up and running is a super quick read
22:56ChongLiyedi: yeah, it is
22:57ChongLiI hope they update it at some point when the tooling becomes more developed
22:58ChongLisetting up a browser repl in particular is a tricky process
23:21TimMcibdknox: The difference between local and remote is more than just an implementation detail. You suddenly have to deal with network outages where before there was a simple function call.
23:22bbloomTimMc: agreed, i think that a more likely first step is something akin to the "himera model" that fogus talks about here: http://blog.fogus.me/2012/03/27/compiling-clojure-to-javascript-pt-3-the-himera-model/
23:23bbloomthat's what i'm going for: in that model<->viewmodel<->view<->platform chain, i want to be able to pick and choose where i draw the line on what parts of the pipeline go on which endpoint
23:25bbloomie a mobile app may choose to run everything but the platform rendering on the server
23:25bblooma desktop app may run everything on a single node
23:25bblooma web app may run only the underlying model on the server
23:26yediwhats the decision process for making a library a core lib?
23:27technomancyyedi: it basically doesn't happen any more
23:27ibdknoxTimMc: I'm not sure I understand the distinction you're drawing. There are well defined strategies for dealing with the network, I would just employ one of those?
23:28yediso a core.matrix might be out of the question?
23:28bbloomibdknox: i think the point he's making is that sometimes there are genuine *what* questions, not just *how* questions, to be answered about the behavior of an app in the face of latency
23:28cjfriszSo...is there documentation for Domina anywhere?
23:28TimMcibdknox: What I mean is, suddenly there are parts of your program that have to know about non-local execution.
23:28cjfriszOr is it all documentation by example?
23:29technomancyyedi: you mean a contrib?
23:29ibdknoxbbloom: TimMc: can you give an example?
23:29bbloomibdknox: like when you post a comment on facebook, it's rendered optimistically, but if the request times out, then the input form shows back up. however, there are options you wouldn't want to render optimistically, for example a sale of stock
23:30technomancyTimMc: are you referring to rich's "why Clojure isn't like Erlang" post?
23:30TimMcWell, it does depend on where you draw the app/framework boundary, but at a certain point you want to have business logic involved in error handling.
23:30TimMctechnomancy: No, but that sounds like interesting reading. :-)
23:31bbloomibdknox: when you introduce a partition, you introduce latency and failure. when you introduce latency and failure, you need to make decisions about trade offs and behavior
23:31ibdknoxbbloom: that's a good one. I'll have to think about it
23:32carktechnomancy: is that post on the mailing list ?
23:32technomancyTimMc, cark: http://bc.tech.coop/blog/081201.html
23:32TimMcthx
23:32carkthanks !
23:32technomancysearch down to "I chose not to use the Erlang-style actor model for same-process state management in Clojure for several reasons:"
23:32yeditechnomancy: nvm, was getting the two confused
23:33TimMchttps://groups.google.com/group/clojure/browse_thread/thread/2a2b24ffef5d1631/2ad59d1c4bb165ff#2ad59d1c4bb165ff
23:35bbloomtechnomancy: that's a good read
23:35technomancyyedi: I don't know what the process is, but I know it involves not completely hating Jira and trying to figure out how to get Hudson working with Maven and Sonatype OSS... so... yeah.
23:36TimMcI'll read that tomorrow.
23:36TimMcIt looks interesting, but so does my bed.
23:37amalloyif your bed looks interesting, probably time to clean up, mate
23:38bbloomcraigbro: thanks for mentioning CLIM, i hadn't seen it before. i'll study it
23:39TimMcamalloy: The fact that it contains my spouse probably factors in here somewhere. :-)
23:40craigbrobbloom: lots to pick from the cold cold corpse of common lisp
23:41craigbroTimMc: shush, you don't want to remind people of CORBA with all this talk of the difference btween local and remote
23:45arrdemdo we have a -> that short-circuits on `nil`?
23:45craigbronot that I know of, but sounds innaresting
23:45craigbrohmmm
23:45arrdemit could be a 1.5.0 feature, but I know I've heard of it.
23:45craigbrocan't you just do
23:46craigbrooops never mind
23:46craigbrothere are a bunch of threading macros added in 1.5.0 right?
23:47craigbrohttps://github.com/clojure/clojure/blob/master/changes.md
23:47craigbrosome->
23:47bbloomcraigbro: yeah, in particular cond-> is awesome
23:47craigbrothere ya go
23:47craigbroI had a hard time warming up to threading macros
23:47bbloomi <3 them :-)
23:48bbloomi really enjoy thinking in steps
23:48craigbro(as-> I dig
23:48bbloomit makes it really easy to test some more complex multi-step algorithms
23:48craigbroand could totally use
23:48craigbrothat clj-http wrapper I wrote uses them alot
23:48arrdem(some->) is what I want..
23:48arrdemmmkay.
23:48craigbrothe idea is you thread a map that represents a browser session
23:49craigbroarrdem: if you look around I bet you can find implementations you can load into 1.4.0
23:49craigbrothru a bunch of calls that requests urls, save cookies or params, fill in forms, etc...
23:50bbloomhmmm no as->>
23:50bbloom?
23:50frozenlockcljs: I have a js function with a callback. However the function I want to pass in the callback is inside a remote-callback (fetch) and is asynchronous. Is there a way to remain into the callback until the fetch is completed?
23:50bbloomfrozenlock: you mean block?
23:50TheBusbyanyone else following the drama in the clojurescript contribution thread on the ML?
23:51nopromptquick question about namespace naming conventions: is it ideal to use singular or plural names? i.e., if i have a ns that contains types should it be (ns foo.types) or (ns foo.type)
23:51frozenlockbbloom: I think... "By the nature of JavaScript letrem is an asynchronous block"-Fetch library
23:52bbloomnoprompt: http://programmers.stackexchange.com/a/75929
23:52frozenlockI could set an atom, then wait until the atom is changed... but it seems.. yuck
23:52nopromptbbloom: thanks :)
23:53cjfriszSorry for asking twice, but got no answer...
23:53cjfriszIs there domina documentation anywhere?
23:53frozenlockcjfrisz: besides the github readme?
23:54nopromptso just to make sure i'm understanding this, in this case i'm looking for (ns foo.type) since it only contains records?
23:55cjfriszfrozenlock: yes, besides that
23:55cjfriszAnd I already looked through ClojureScript One
23:56technomancyTheBusby: it appears with fairly predictable regularity
23:56cjfriszMaybe I'm just having trouble coming at it from not having done much JavaScript
23:56technomancyit's getting to be more predictable than the "hey guys what if we did clojure but with whitespace instead of parens" posts
23:56cjfriszNot good enough at guessing the translation from JS to CLJS+domina
23:56arrdemtechnomancy: oh gods you get those?
23:57technomancyarrdem: used to be every 6 months
23:57TheBusbytechnomancy: don't imagine it'll be going away either. :(
23:57technomancybut it's been a while
23:57frozenlockcjfrisz: I don't think there's anything else. But there's an API section in the source code which is quite straightforward https://github.com/levand/domina/blob/master/src/cljs/domina.cljs#L108
23:57technomancyTheBusby: not till every last potential contributor's hope is crushed
23:57TheBusbyhaha, we'll see
23:57arrdemI guess if you use Python-style four space indentation... but I'm thoroughly revolted.
23:58TheBusbyI was curious if you can submit patches to core members and have them take care of it?
23:58technomancyarrdem: "you know, for newbies" http://www.dwheeler.com/readable/sweet-expressions.html
23:58technomancyTheBusby: maybe if you submit them along with a bribe
23:59TheBusbytechnomancy: a nice scotch maybe? or Sake?
23:59cjfriszfrozenlock: thanks
23:59technomancyTheBusby: try it and let me know if it works =)
23:59arrdemI mean... it's a solid syntax proposal... but for the part where you count whitespaces.