#clojure logs

2013-08-22

00:41dissipatecan someone clarify the 'keywords' section of 'clojure programming' on page 14
00:42dissipatewhy do namespaces matter for keywords? keywords are scoped to their respective maps, no?
00:44SegFaultAXdissipate: Keywords don't really have anything at all to do with maps other than they're commonly used as keys in them.
00:45dissipateSegFaultAX, but why do i care what namespace a keyword is in?
00:45dissipateSegFaultAX, doesn't it only matter what i'm looking up the keyword in?
00:45SegFaultAXdissipate: Because that namespace might be useful when passing keywords across namespaces.
00:45SegFaultAXYou can know where it has come from, for example.
00:46dissipateSegFaultAX, hmm, that seems odd to me
00:47dissipatecoming from a python background here, i've never thought of namespacing keywords in a dictionary. but perhaps i'm confused by this concept because keywords serve some greater purpose in Clojure?
00:47SegFaultAXdissipate: Unnamespaced keywords are by far the most common, but there are some interesting uses for namespaced keywords.
00:48SegFaultAXdissipate: Keywords don't have anything to do with maps.
00:48SegFaultAXKeywords are fast, atomic, interned string-like object whose primary operator is comparison (but they have some other interesting properties too)
00:50dissipateSegFaultAX, i see. i don't fully understand, but hopefully i'll figure it out by looking at later examples.
00:50SegFaultAXdissipate: Think of keywords as being like Python strings but with constant time comparison.
00:50SegFaultAXLike symbols in other languages.
00:51dissipateSegFaultAX, but things other than keywords can be keys in a map?
00:51SegFaultAXdissipate: All of clojure's built in data types can be used as keys
00:51SegFaultAXdissipate: They're all immutable
00:51SegFaultAX(Which has a similar property to being hashable in Python)
00:52SegFaultAXIf I know the data structure can never change out from under me, I know that I can use it as a key without having to worry about needing to rebuild the hash table.
00:52dissipateSegFaultAX, sounds excellent.
00:52SegFaultAXdissipate: Very excellent!
00:53technomancyI don't know if keywords-as-strings is a great comparison. I like to think of them as first-class names.
00:54SegFaultAXI only said they were string like. Which they are, even at an implementation level. (Same goes for symbols)
00:54SegFaultAXAnd in Python, there is nothing similar, so the analogy stands I guess.
00:54SegFaultAXBut generally I agree.
00:55technomancythey're string-like only insofar as their printable representation, but that's just an affordance for humans
00:55dissipateSegFaultAX, so an atom can be a key in a hash in Clojure?
00:55SegFaultAXdissipate: A keyword you mean?
00:56SegFaultAXdissipate: /All/ clojure data structures can be used as keys in hash maps.
00:56dissipateSegFaultAX, ok, but i thought that atoms were mutable through some kind of transaction?
00:56technomancyall java objects, really
00:57technomancydissipate: clojure will let you do it, but that doesn't mean you should
00:57SegFaultAXdissipate: So you do mean atoms, yea there are some complications there. Don't worry about it for now.
00:57SegFaultAX(inc technomancy)
00:57lazybot⇒ 71
00:58technomancy,(let [a1 (atom :a) a2 (atom :a)] (assoc {a1 1} a2 1))
00:58clojurebot{#<Atom@dbbb9f: :a> 1, #<Atom@1fac636: :a> 1}
00:58dissipatetechnomancy, so what happens if i say assign an integer to an atom, use the atom as a key in a hash map, then increment the integer?
00:58technomancy^^
00:58technomancythe value inside the atom isn't a factor in how it's used as a has key
00:59dissipatetechnomancy, but this is frowned upon?
00:59SegFaultAXdissipate: Yes.
01:00dissipatei can understand that
01:00dissipatemutable objects in python can be keys in dictionaries because python uses the id of the object as the key
01:00technomancyyou can't have meaningful equality between mutable objects
01:00SegFaultAXCannot*
01:00technomancyother than "are these the same location in memory?"
01:01dissipatetechnomancy, right, but you can id an object
01:01dissipateor come up with some ad hoc way of defining equality
01:01SegFaultAXdissipate: But that's lame. We'd prefer to define equality of structure, not identity.
01:01technomancydissipate: sure; that's how clojure defines = on anything mutable
01:01technomancybased on its id, not its value
01:02SegFaultAXMmhmm
01:02technomancy~equal rights for functional objects
01:02clojurebotexcusez-moi
01:02technomancy~egal
01:02clojurebotegal is http://home.pipeline.com/~hbaker1/ObjectIdentity.html
01:03technomancy^ that paper covers the logic behind equality
01:03dissipateSegFaultAX, technomancy, thanks for the info
01:03SegFaultAXdissipate: Anyway the point is that *all of clojure data structures can be used as keys in a map* but for some of them that really makes very little sense.
01:04technomancynp
01:04SegFaultAXnp
01:05dissipateSegFaultAX, i see. this whole immutability thing has me drooling. but i can tell that learning clojure is going to be quite a bit of work.
01:07SegFaultAXdissipate: Even if you don't use Clojure professionally, it's an amazing language to know and understand.
01:07SegFaultAXdissipate: It can rather dramatically change the way you analyze and reason about programming.
01:08dissipateSegFaultAX, i want to use it professionally, but i think that it's going to take me quite awhile to get to that point. :O
01:08SegFaultAXI generally think most people would benefit in learning at least 1 functional programming language if they generally work in more imperative languages and vice versa.
01:09dissipateSegFaultAX, after reading 'Out of the Tar Pit' and watching videos on the advantages of Clojure, i'm convinced it's a much better language than the 'mainstream' languages
01:10SegFaultAXdissipate: Nothing is perfect.
01:11technomancyfaint praise =)
01:11dissipateSegFaultAX, of course not, but side effects are bad and i'm excited to get rid of them as much as i can.
01:12technomancyin the #emacs channel there is literally a "faint praise" bot command that says "well, at least it's better than Java"
01:12dissipatehehe, Java...
01:12SegFaultAXdissipate: Well if you're only interested in purity, Clojure is hardly the best choice.
01:12dissipateoh how i am glad i have been able to avoid Java
01:13dissipateSegFaultAX, are you referring to Haskell?
01:13SegFaultAXdissipate: I'm referring to many languages that are far less side-effecting than Clojure. Haskell is among them.
01:13technomancyHaskell is for hippies; Coq is the path of purity.
01:13brehauttechnomancy: agda!
01:13SegFaultAXAmen.
01:14dissipateSegFaultAX, i don't want to completely eliminate side effects. i realize it is quite difficult to program purely functionally for all applications. but if the side effects are controlled say through STM, that's good enough for me.
01:15technomancySTM use is actually very rare in clojure
01:15SegFaultAXdissipate: Remember that you're running on the JVM (or js in the case of clojurescript) and it's very easy to escape Clojure's limited purity.
01:15technomancyit's more that side-effects stand out a lot more
01:15SegFaultAXIf you're using Java libraries, you're doing it all the time.
01:16SegFaultAXYup, what technomancy said.
01:17dissipateSegFaultAX, how often does that bite you?
01:18SegFaultAXdissipate: Me personally? Not often. Most of the Java libraries I interface with are specifically designed to interop with Clojure and so those side effects are hidden from me.
01:18SegFaultAXThat doesn't mean they aren't there, though. :)
01:18dissipateSegFaultAX, BTW, Haskell seems like a good language as well, but it's not homoiconic and i have heard that certain things with its atoms are quite complicated
01:19noidiit's funny, the world at large seems to see Clojure as being about the STM, but the more you program in Clojure, the less you seem to use the reference types
01:19noidiand especially the coordinated ones
01:19noidiat least that's my experience
01:19holodissipate, this may sound vain, but it's true for me. one of the things i find less time consuming in functional programming is i spend much less time naming stuff like intermediary vars ^^
01:20dissipatenoidi, well, it's good to know that noobs can fall back on STM
01:23holoi'm testing a ^:private def, and I can't get it to eval. #'myns/my-def => vector? throws: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Var
01:24holohow do you test your private vars?
01:25brehautyou dont make them private, or you varquote them
01:25SegFaultAXnoidi: My experience has been largely the same. When I have needed reference types though, they've been amazingly useful.
01:26holobrehaut, isn't what i just paste above called varquoting?
01:26brehautit is
01:28holobrehaut, it doesn't eval to an ISeq like it would if it was public. that's why i was asking how to make it eval
01:28brehautno of course not, it evals to a var
01:29holobrehaut, is there any way to make it eval to an ISeq?
01:29brehautdereference it
01:29brehaut,clojure.core/is-annotation?
01:29clojurebot#<CompilerException java.lang.IllegalStateException: var: clojure.core/is-annotation? is not public, compiling:(NO_SOURCE_PATH:0:0)>
01:29brehaut,#'clojure.core/is-annotation?
01:29clojurebot#'clojure.core/is-annotation?
01:29brehaut,@#'clojure.core/is-annotation?
01:29clojurebot#<core$is_annotation_QMARK_ clojure.core$is_annotation_QMARK_@1348b49>
01:30holooh! damm it!! i have that in another project.. heh completely forgot that
01:30holobrehaut thanks
01:32dissipateSegFaultAX, do you use java.util.regex?
01:32SegFaultAXdissipate: Sure.
01:32SegFaultAXdissipate: #"" is the Clojure literal.
01:36callendissipate: hello again.
01:37dissipatecallen, hello
01:37callendissipate: why the change?
01:38dissipatecallen, the change to clojure?
01:47seancorfield,(re-seq #"[aeiou]." "java.util.regex")
01:47clojurebot("av" "a." "ut" "il" "eg" ...)
01:47seancorfield:)
01:50rhg135Any idea how to do this https://www.refheap.com/17926 I'm trying to map a function to a certain map key at compile time
01:59noidirhg135, (1) your returning a quoted hash-map call, so the hash-map will be built at run-time, not compile-time, (2) doseq is used for side-effects and returns nil
02:00rhg135Right..
02:00rhg135So how could I?
02:01noidiwait a sec and I'll whip up an example
02:01rhg135I don't like writing macros
02:01rhg135Always problematic
02:04noidirhg135, you should first try to come up with a function that does what you want at runtime
02:04noidiand only then wrap it in a macro to move the evaluation to compile time
02:04rhg135Ok
02:04rhg135Lemme try
02:07noidirhg135, https://www.refheap.com/17927
02:09rhg135Any reasons for eval
02:09rhg135?
02:10noidiotherwise km would contain the symbol 'clojure.core/inc instead of the `inc`function
02:10noidi('inc 123)
02:10noidi,('inc 123)
02:10clojurebotnil
02:10noidiwat
02:11noidiah, symbols are functions that look themselves up in the map given as an argument, or return nil if the input is not a map
02:11noidithat's confusing as hell
02:13noiditechnically you could skip eval for m if it only has literal values
02:13rhg135K,just it kind of hurts to see eval now
02:14rhg135So ingrained lol
02:20noidirhg135, it's all eval'd sooner or later anyway :)
02:20rhg135Ik
02:21rhg135Ill use it
02:24rhg135How about instead taking a map followed by kv pairs?
02:25noidirhg135, then just change the arglists from [m km] to [m & {:as km}]
02:26rhg135I did and got null
02:28noidirhg135, ah, sorry, change the _macro's_ arglist to that
02:28rhg135I did
02:28noidithis works for me https://www.refheap.com/17929
02:29noidiif you change the function's arglist as well, you won't be able to just call it with the map that the macro receives (because it's expecting key value pairs and not a map)
02:30rhg135Ah
02:30SegFaultAXThat code is horrifying.
02:30rhg135Can you show how you called it?
02:31noidirhg135, (apply-to-map {:foo 1, :bar 2} :foo inc, :bar #(* 2 %)) ;= {:foo 2, :bar 4}
02:32noidiSegFaultAX, how would you do it?
02:32SegFaultAXnoidi: Why does it need to happen at compile time?
02:32rhg135Slow computers :(
02:33noidiSegFaultAX, I don't know: [08:29] < rhg135> Any idea how to do this https://www.refheap.com/17926 I'm trying to map a function to a certain map key at compile time
02:33SegFaultAX:(
02:33rhg135I compile it on a way faster one
02:34SegFaultAXIf your target machine is so slow it can't run a few basic functions, you need to re-evaluate your hardware ;)
02:34rhg135It's not my he, it's my target
02:34rhg135Mobile devices
02:35rhg135Not phones
02:35rhg135Slower
02:38rhg135noidi: my bad it does work
02:40rhg135SegFaultAX is right, functions are better and if its too slow too bad
02:44rhg135No, I meant I want it to produce ex (hash-map :key (f value))
02:45SegFaultAX(defmacro apply-map [m & {:as km}] `(-> ~m ~@(for [[k v] km] `(update-in [~k] ~v))))
02:47rhg135?
02:47SegFaultAXrhg135: You asked how I'd do it.
02:47rhg135I didn't
02:47SegFaultAXOh, maybe noidi did
02:47rhg135He did
02:48SegFaultAXAnyway, no eval necessary.
02:49rhg135Uh
02:49rhg135LONGER=more code
02:49rhg135More complex
02:50SegFaultAXI don't think so.
02:51SegFaultAXIt turns (apply-map M :k1 f1 :k2 f2) into (-> M (update-in [:k1] f1) (update-in [:k2] f2))
02:51rhg135But I asked the wrong q.
02:51rhg135:/
02:52SegFaultAXrhg135: Oh what was the original problem statement?
02:52SegFaultAXI thought it was something like that.
02:53rhg135No, I meant I want it to produce ex (hash-map :key (f value))
02:53SegFaultAXOh that's way less fun. :(
02:54rhg135Same args
02:54SegFaultAXnoidi: Anyway ^
02:57noidiSegFaultAX, those updates are not evaluated at compile time
03:01SegFaultAXnoidi: Then drop the outer ` if that's what you want.
03:01SegFaultAXBut Ew. ;)
03:03SegFaultAXOh well I guess that won't work. But anyway, you get the idea.
03:10rhg135I know it's unusual, that's why I am stuck
03:16ordnungswidrigmoin alle
03:39supersymgithub died?
03:40rhg135Again?
03:40RaynesIt went down like thunder this time.
03:41RaynesI can't even push.
03:42RaynesThe status page should really just have a picture of http://th01.deviantart.net/fs71/PRE/f/2010/142/b/2/Molten_Planet_by_Cushendun.png right now.
03:45supersymhehe
03:46supersymwell a canyon at least is somewhat appropriate
03:46rhg135Yup
03:47glosoliHey folks I am using httpkit with ring and compojure, any suggestions how could I server byte array from database as pdf ?
03:48supersymdoesn
03:48supersymdamn cat...
03:48supersymdoesn't clj-pdf do something in that direction too?
03:49Raynessupersym: http://www.youtube.com/watch?v=mXPeLctgvQI
03:49supersymcan't check... except google returns since github is dead :D
03:50glosolidam n github is down
03:50glosoliagain
03:50supersymRaynes: long time since I've seen that movie,...great fun tho
03:56RaynesIt returns!
07:23supersymdamn..pedestal is a tough cookie now and then
07:23supersymso many nested colls make me dizzy ><
07:35ker2xhttp://www.youtube.com/watch?v=2WLgzCkhN2g this video is super awsome
07:35ker2xyou probably saw it already, it's on clojuretv
07:39ker2xclojure is slowly coming to my workplace
07:40vijaykiranker2x: where's your workspace ?
07:40ker2xebuzzing, in france
07:41ker2xwell, the technical staff is in france
07:41vijaykirancool
07:41glosoliHmm how does one make a collection of strings that could be inserted in Postgres as varchars array
07:46Anderkentglosoli: depends on what API you're using. On the jdbc level it's `(.createArrayOf sql-connection "varchar" string-array)`, then put that into a query
07:46Anderkentwith something that abstracts higher you might have to fall back on raw string queries if there's no array api
07:47glosoliAnderkent: thanks sir, that's exactly what I needed
08:08ker2xanyone use online mind mapper ? any suggestion ?
08:17noncomhow do i make my function so that i could introduce arbitrary previously undefined symbols in its call? Like (ns) and (let) forms allow for passing and writing symbols that don't trigger the compiler's "unknown symbol" error?
08:18hyPiRionnoncom: that would require a macro, not a function
08:18noncomso it is only possible for a macro?
08:18hyPiRionyes
08:18noncomand i could pass such symbols to any macro i define?
08:19hyPiRionyes
08:19noncomok, thank you. that thing was really bugging me for some time..
08:19hyPiRionbut use macros sparsingly, and only if you have to
08:19hyPiRion(They're bug introducers)
08:20noncomyes, i try to avoid them and if i have to use them, i try them to be one-liners or something simple
08:20noncommacros are err*r-porne because of the humans not able to think well?
08:21noncomi mean, is there anything wrong with the compiler? like in scala they do not recommend extending case classes simply because compiler bugs on it and they not gonna fix it
08:22Anderkentthey're just harder to write correctly
08:22Anderkentand the compiler is not that good at telling you what exactly is wrong with your macro
08:22Anderkentalso they give you more power, which you usually don't need, and are harder to reason about
08:23noncomwell at least the compier does not bug on them.. very good! and yes, i totally understand that about reasoning and unforseeing stuff.. it could become like C #defines hell
08:23hyPiRionnoncom: well, mostly because of humans, but also because, as Anderkent said, the compiler can't give good feedback whenever you've misused one
08:24hyPiRionThe compiler can't (unfortunately) infer what you want to do and just say you need to fix X or Y.
08:26noncomduring runtime, can i get something similar to macros by forging clojure forms by assembling `(list)s of symbols?
08:26noncom(just a theoretical interest, i not gonna do that i think :)
08:27emil0ri have a small problem with the clojurescript compiler (using cljsbuild). i seemingly can't use hashmaps. the code generated is cljs.core.PersistentArrayMap.fromArray(["\uFDD0:id","\uFDD0:blah"], true) and throws an error. any obvious mistake I have made?
08:28noncomemil0r: there should be no such problem. can you post a refheap with your code?
08:28hyPiRionnoncom: eval
08:29hyPiRionbut do that on your own risk (both perf. and security wise)
08:29noncomemil0r: my best guess is that you mix js and clojurescript datastruct types. they are different afaik and there are cljs->js and js->cljs core funcs in cljs
08:30noncombut httwo seeing the code
08:30AnderkentDoes anyone understand how to interpret jvm memory usage? I have newrelic graphs showing 'used heap' at 200MB, but 'comitted heap' growing up to 600mb for no apparent reason. (it's a problem because heroku)
08:31noncomeval is like a gun. it is good to know you have it, but actualy using it is something to consider really well
08:31emil0rhttp://pastebin.com/PynsSDcr
08:31emil0rnoncom: i'm just doing an eval on {:id :blah}
08:31emil0rthat's it
08:32emil0r.fromArrays work though
08:33emil0rin so far that it gives something back :)
08:34noncomemil0r: hmmm.. never used eval in cljs for that. if you want to read a datastruct from a string i would consider utilizing the edn reader... idk if it is avail for cljs.. or try js->cljs ?
08:35emil0ri came across the problem when i tried to use crate.core/html. such as (crate.core/html [:p.woot {:id :blah} "Hey"])
08:36emil0rused cljsbuild before and never had a problem, so i'm stumped
08:36emil0rand crate
08:36noncomAnderkent: http://stackoverflow.com/questions/206847/exact-state-of-committed-memory-in-java and http://stackoverflow.com/questions/14642962/high-committed-memory-but-small-heap-size
08:37noncomthe latter one is for .net but maybe relates...
08:38noncomhttp://stackoverflow.com/questions/10357611/what-is-tomcat-memory-heap-committed
08:38Anderkentyeah, I know what it is (thanks to these links in part), what I'm looking for is someone who understands why it's so high - i'm running jvm with -Xmx320m, it really shouldnt ever need a 600mb heap
08:38noncomno real good explanatioonthough
08:40noncomAnderkent: does your app use NIO buffers or JNI?
08:40Anderkentwhatever jetty uses :D I doubt that's where the problem is. Why?
08:41noncomsometimes the underlying native resources or buffers don't get released and litter the memory. i witnessed that problem 2-o-times
08:41Anderkentright. But that would show in physical (non-jvm-managed) memory, not the committed heap.
08:41Anderkentgood thinking though :P
08:42hyPiRionyeah, that shouldn't kill the heap
08:42Anderkentit's not even that the heap is dying
08:42Anderkentit's just that it's using 700mb of physical memory while only using 200 out of 650 for the heap
08:42hyPiRionwell, then I am completely right then
08:42hyPiRion:p
08:42Anderkentand heroku doesnt like it if you eat its memory
08:43hyPiRionoh right, that's because of the JVM itself. The JVM likes to eat memory, but not free it up once it doesn't need it anymore.
08:43noncomand if you run that on your computer? same readings? can you factor out what parts of the program cause the rise?
08:43Anderkentyeah. Do you know if there's any way of telling it 'never grab more than X physical memory'?
08:43Anderkentother than trying to trick it into thinking there's only 500mb on the machine, I guess
08:43Ember--Xmx=512 or something like that
08:44Anderkentnah, that's only for the actual heap, and I already have -Xmx=320m
08:44hyPiRionEmber-: that was what he tried to do, afaik
08:44Ember-check java command line arguments
08:44Anderkentit's still committing 600mb for the heap
08:44Anderkentbut never letting it use more than 320 out of that :P
08:44Anderkentthe problem is heroku doesnt care if the OS is overcommitting and not actually using any extra physical memory
08:45Ember--XX:MaxDirectMemorySize=256M mayve?
08:45Ember-maybe
08:45noncomis there the same problem on your PC?
08:45Anderkentah! that sounds right
08:45Anderkentnoncom: hard to say, i couldnt reproduce that easily
08:45Ember-hmm, doesn't look like correct
08:46hyPiRionAnderkent: well yeah, it's not exactly overcommitting. The JVM will use that space, and no other program can
08:46noncomif direct memory adjustment helps, then you have some memory leak either in NIO or JNI
08:46Ember-yeah, that isn't the correct config
08:46AnderkenthyPiRion: if the os is overcommitting, then the jvm will think it can use that space, but no actual pages will be allocated until it tries
08:46Anderkentnoncom: I don't think it actually *uses* that memory
08:46hyPiRionhrm.
08:46Ember-that seems to affect how much memory native code ran from java can use memory
08:46Ember-and I can't write
08:47Ember-anyways, code with 'native' keyword
08:47Anderkentright
08:47Ember-how about MaxPermSize ?
08:47Anderkentthat's only for the perm gen
08:47Ember-yes
08:48Ember-I know
08:48noncommaybe heroku have their own options for the jvm screwed up?
08:48Ember-java normally gives up the memory if OS asks it do so
08:48Ember-if it is not using it that is
08:48Ember-but at heroku what you said this isn't happening
08:48hyPiRionI'd probably just ulimit it. That's the easy way.
08:48Anderkentalas, the OS will not ask it to, because it thinks it has 1.5G of space... but 1G of that is terribly slow swap
08:48Ember-wierd stuff
08:49Ember-ah, well swap :)
08:49Ember-I'm too used to having 8 or 16 gigs of mem :P
08:49AnderkenthyPiRion: ulimit -m doesnt work on ubuntu I think, and -v is not what I want
08:50AnderkentI can't use -v because jvm allocates a *lot* of virtual memory that's never actually physically accessed
08:51hyPiRionhrm, add in -Xss512k and check what happens
08:51hyPiRion(reduces stack sizes)
08:52Anderkentalready did that. But again I don't think that takes space from the heap pool
08:52Anderkentmy overhead on top of heap is ~120mb or so, which is totally fine.
08:52hyPiRionhrmm
08:52Anderkentyeah :P
08:52hyPiRionI've tried to fix that earlier, and I always struggle with it
08:53noncomlast post: https://forums.oracle.com/thread/2236644
08:54noncomall point to that being an anomaly though
08:54Anderkentthanks anyway :)_
08:55noncommaybe you could also make some use of this: http://download.java.net/jdk7/archive/b123/docs/api/java/lang/management/MemoryUsage.html
08:55AnderkentI guess this is the point where I fetch openjdk sources
08:55noncomooh.. that should be a big load
08:58fbernierHey, I hacked my first "real-world" Clojure project yesterday. If anyone have some time to give feedback on the code/style/whatever it would be nice.
08:58fbernierhttps://github.com/fbernier/taz-clj
09:00mdrogalisPretty good fbernier
09:00mdrogalisProbably don't need to type-hint so much, but good stuff.
09:01fberniermdrogalis: Thanks, I think I type-hinted only what "lein check" was complaining about though.
09:02mdrogalisI've never heard of Lein check. What's it do?
09:02ordnungswidrigfbernier: very good. I'd suggest that convert-to-image would return a lazy seq of images to avoid repeated loading and parsing of the pdy
09:02ordnungswidrig...of the pdf
09:02fberniermdrogalis: "Check syntax and warn on reflection."
09:03mdrogalisI see. Nice.
09:05ordnungswidrigfbernier: in converter.clj like that (map #(.convertToImage (.. document getDocumentCatalog getAllPages (get %))) (range (.getNumberOfPages document))
09:05fbernierordnungswidrig: For now it serves one image for one HTTP request ... so I open the file, render a single page, and close it. I'd need to keep the PDF in memory whithout really knowing if another HTTP request for this HTTP request will come any time soon.
09:06ordnungswidrigfbernier: ah, I see.
09:06fbernierbut suggestions on improving this are welcome.
09:06fbernierfor this PDF*
09:11ciphergothClojure "promises" don't have a "then" method yet, right? http://dev.clojure.org/display/design/Promises
09:12ciphergothis there a way to achieve the same thing I'm not seeing?
09:12iwohey, does anyone know an alternative strategy to with-redefs that could be used safely in an application?
09:12stuartsierraciphergoth: That's correct, promises do not currently support callbacks.
09:12stuartsierracore.async offers an alternative way to achieve that.
09:12iwoi notice that with-redefs is not thread-local, but i'm using it to dynamically re-bind a function that i need to customize
09:13iwothe fact that the rebind is global (not thread-local) makes me reticent to use it in production
09:13mpenetciphergoth: also look at lamina result-channel (probably closer to what you are looking for)
09:13ciphergothwell since I'm using alpha that seems plausible!
09:13iwobut since the var is not dynamic, i'm unsure if there's any way to customize the behaviour without with-redefs
09:14stuartsierraiwo: There isn't.
09:15ciphergothLamina channels seem pretty different from promises!
09:16mpenetresult-channels are essentialy promises
09:16mpenetnot channels
09:18ciphergothmpenet: ah OK! I found this page, bit it wasn't as helpful as I'd hoped... https://github.com/ztellman/lamina/wiki/Result-Channels
09:18mpenetyeah I know, it vanished
09:18mpenet:/
09:49zapuI'm trying to learn clojure and I'm playing with 'resolve' right now. (resolve (symbol ".toString")) doesnt work for me, I suspect member access might be somewhat special. What am I missing?
09:49klrrany recommendation of a book ? got some FP experience
09:50stuartsierrazapu: Yes, resolve only works on Vars and classes, not methods.
09:50stuartsierraJava methods are not first-class objects.
09:50zapuoh, I see
09:50zapuyeah, that would make sense. but I can pass them around wrapped in anonymous functions if I ever need to, right?
09:51Ember-in java 8 btw that is going to change, after java 8 methods are first class and can be referenced directly
09:51Ember-which is nice
09:51stuartsierrazapu: yes, to pass methods as arguments you have to wrap them in Clojure functions.
09:51hyPiRionis that a JVM change or Java change?
09:51Anderkentzapu: you can also just use memfn to pass around a method call: (map (memfn toString) objects)
09:51Ember-hyPiRion: imho jvm
09:51zaputhank you :)
09:52Ember-because it would be inefficient otherwise
09:52RiGGeRit will have to result in a jvm change, too
09:52stuartsierramemfn is slightly deprecated in favor of #(.toString %)
09:52Ember-anyway, with java 8 you write stuff like myList.filter(Something#uberMethod);
09:53Ember-you -> can <- write
09:53Ember-should help clojure's java interop too
09:53hyPiRionHm, that could speed up aot compiled code with type annotations I guess
09:53Ember-too bad they pushed the release of java 8 to 2014
09:54chrisrossiso in java 8 you can do? method = someObject.someMethod
09:54chrisrossiresult = method()
09:54chrisrossi?
09:54Ember-hmm, of *that* I'm not 100% certain
09:54klrrshould i use openJDK or oracle JVM?
09:55Ember-would have to check with current beta build
09:55Ember-anyway, method references are ok
09:55stuartsierraklrr: Not that much difference as of JDK 7.
09:55RiGGeRhttp://www.jcp.org/en/jsr/detail?id=337
09:56klrrokey, which is quickest to install on ubuntu?
09:56Ember-having to write java in this project since customer explicitly said NO for clojure :/
09:56ToxicFrogklrr: IMO, whichever's easier to install. I've been using openjdk without trouble.
09:56Ember-really missing clojure
09:56ToxicFrogklrr: openjdk, definitely.
09:56klrrokey
09:56blrmklrr: openjdk should be in the ubuntu repos
09:57hyPiRionshould actually be installed on ubuntu by default, isn't that the case?
09:57klrris the package called "openjdk", also, do i need any other packages?
09:57RiGGeRand you don't have to login to oracle to dl
09:57manuttersudo apt-get install openjdk-7-jdk
09:57manutterJust did that myself the other day
09:57Anderkentklrr: just watch out for ubuntus fucks up around openjdk. If you're gonna use ssl from java, you want to fix https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776
09:57ToxicFrog"openjdk-7-jdk" is the package you want, then just run lein and it'll grab the other stuff it needs (clojure etc) as needed.
09:58blrmhyPiRion: might just have a jre by default?
09:58hyPiRionblrm: ah
09:58klrrAnderkent: thanks for pointing out
09:58hyPiRionmight have to do `sudo update-alternatives --config java`, then
10:00klrrgot it installed now, was much easier than i expected
10:00klrrwell
10:01Anderkentyeah, having a package manager is a real boon
10:01Anderkentlooking at you osx
10:01klrrat least i got repl running
10:01Anderkentklrr: from that point onwards everything should be handled by lein for you, assuming pure jvm dependencies
10:02klrri got lein installed
10:02hyPiRionthen life is good and you got everything (except an editor, maybe)
10:02klrrhow do i make so that lein can find clojure?
10:03Anderkentklrr: lein includes clojure in its uberjar, so you shouldnt have to do anything
10:04Anderkentif you mean for your projects, you specify which version of clojure you want in project.clj, and lein automagically gives it to you
10:04ToxicFrogklrr: it should do it automatically. All you need is a JVM and a net connection.
10:04hyPiRionand downloads other clojure versions if you specify those in the dependencies
10:04Anderkent(to get a project.clj do `lein new project-name`)
10:04klrrokey
10:04klrrthen it was clojure sources i downloaded xD
10:04ToxicFrogYeah, you should never* be installing clojure by hand. Let lein handle it.
10:04klrrcoming from haskell that works differently since its distributed as a compiler
10:04ToxicFrog*rarely, and definitely not when starting out
10:05Anderkentyeah, the lein/maven ecosystem takes a bit of time to get used to, but the benefits are great
10:07klrrso how does stuff work? in haskell you basically compile stuff using the compiler, and that's it, then it ofc got cabal which is built around that, and the repl exist too. but in clojure i did not install a compiler yet, or is it what i got from lein? how do i use the compiler?
10:08hyPiRionklrr: Clojure is a Java library, so all you need is a Java version to run Clojure. Lein handles compiling for you
10:08blrmklrr: clojure is basically a library, so when you make a new project with lein, it adds the library as a dependency to the project for you.
10:09hyPiRionIf you want to create an application, you can do `lein new app my-app`, then `cd my-app`. To build into a standalone, do `lein uberjar` (runs it with `java -jar target/my-app-0.1.0-SNAPSHOT-standalone.jar`)
10:09blrmklrr: running "lein new foobar" will create a clojure project. cd into that and run lein repl, and boom
10:09hyPiRionYes, you can change the name of the standalone.
10:09klrrokey
10:09klrrthanks :)
10:10hyPiRionklrr: and if you hit any problems, we'll still be here :)
10:10stuartsierraClojure is not a platform in and of itself, it uses the Java platform. This sets it apart from languages like Haskell which are their own platforms.
10:12klrrso, theoratically clojure could use for example haskell and GHC as its platform? :D
10:13Anderkentklrr: your files are basically dynamically linked. Clojure/java packages are bundled in jars, which mvn/lein will fetch for you. Then when you request a class jvm scans the classpath (including all the jars that lein put there) for the .class or .clj file that provides it
10:13Anderkentklrr: yes, but many clojure libs do 'native' interop that's only valid with java
10:13klrrokey
10:13Anderkentthere's already cljs which is clojure on the javascript engine, and pure clojure libraries work on it(usually)
10:13klrrso most libraries are wrappers over java libs?
10:14Anderkentnot quite, but many libraries depend on libraries that depend on java, etc.
10:14blrmklrr: some are, but there are a number of pure clojure libraries too
10:14klrrokey
10:14klrrafter ive ran lein new foobar, what is the use of resources ?
10:15klrrnvm
10:15Anderkentresources are files that will be available to your code no matter where it runs. Usually you put non-code stuff that your code needs (like config files)
10:15hyPiRionklrr: it is for files you want to bundle with programs or libraries, which aren't code. I wouldn't worry too much about it for now
10:15klrrgot a bigger problem i gotta takle :P atm brb
10:16klrrokey, thanks
10:19titubearjoin #go-lang
10:19titubearhah
10:19Anderkenttraitor
10:19klrrgolang? which of them, the new limbo language or the original one?
10:20titubearmore like a traitor the other way
10:20klrrgod
10:20titubearsince it's go-nuts anyway
10:20klrr#go-lang got a dead guy in it
10:20klrr:s
10:20klrrno kidding
10:20titubearbut my work is favoring clojure and I like looking back at lisp style programming
10:21titubearrunning through the elisp tutorial was one of my early programming experiences.
10:21klrrhaskell is my first lang, tried to learn other languages before that though :)
10:23hyPiRionklrr: wow, that's very cool. You'll feel many other languages (possibly including Clojure) will be more... ancient, is perhaps the right word.
10:23Chousukeyou'll just miss fmap terribly :P
10:24Chousukeamong a couple other things in particular
10:24Anderkenthaskell was my first real language too :P
10:24noncomin clojruescript can imported ns names coincide with local var names?
10:24noncomlooking at the compiled source i think it mixes them
10:25noncom?
10:25klrrhaskell is ancient too
10:25klrr20 years or sth
10:25titubearBASIC, PERL and C for me... if it wasn't all caps, what was the point?
10:26noncomor maybe my bad
10:26noncomtitubear yeah i remember that :)
10:26noncomin school we had QBASIC
10:26noncomfrom MICROSOFT
10:26noncomrunning under MSDOS
10:27titubearnoncom: yea, well, that and logo was a good one early on
10:27blrmChousuke: have you tried the fluokitten library? I haven't used it for anything, but it looks interesting
10:27dnolennoncom: you can always shadow referred names w/ locals
10:27dnolennoncom: no different from Clojure
10:29mgaareklrr: clojure is 54 years old ;)
10:30RiGGeRthe lambda calculus is 80 ?
10:30noncomdnolen: i meant not referred names but the namespaces names themselves.. however i think that there was error in my code..
10:30noncomRiGGeR: i think that all that stuff is simply an extension to the writing.... when writing appeared?
10:30noncomyou remember they say that anient people were writing programs on walls
10:30noncoms/anient/ancient
10:31noncommostly hunting simulators
10:31RiGGeRhahahaaa, awesome way to look at it
10:31noncom:)
10:32Chousukeblrm: lacks static typing though
10:33rhg135hey i was wondering if there was a fuse api for clojure and if not a good java one to use/wrap
10:33ChousukeIn part the reason fmap is such a great thing in haskell is that it is expressive and convenient like a dynamically typed function but maintains safety.
10:33klrrmgaare: it is? i thought it was more morden than haskell
10:33klrrmodern*
10:34Chousukeklrr: just "Haskell" is not specific enough to talk about modernity
10:35ChousukeHaskell as it is implemented in GHC is very nearly bleeding edge
10:35Chousukewith some dependently typed languages going a bit further into uncharted territory.
10:35mgaareklrr: clojure is a lisp dialect, and lisp was from 1959
10:35hyPiRionChousuke: Agda mostly, or are there more?
10:36ChousukeAgda and Idris come to mind
10:36hyPiRionHm, haven't heard about Idris, thanks for that one
10:37ChousukeIt seems very interesting. Fairly new, but seemingly attempts to be practical in a way Agda doesn't.
10:37klrrmgaare: i know, but clojure is a NEW lisp right?
10:37klrrChousuke: true, there's modern extensions etc.
10:37mgaareklrr: bah, that's an implementation detail ;)
10:37mgaare(but yes, from 2007)
10:38ChousukeIt still amuses me when I see papers going "Look at this cool new thing! We implemented it in GHC"
10:39noncomrhg135: which exactly "fuse" ?
10:39noncomlots-o-software use that name..
10:39rhg135filesystem in user space
10:40noncomrhg135: a google search on "fuse filesystem java" gives good results
10:41rhg135so no recomendations?
10:41noncom(i never used that thing, so no expect for me to know that well)
10:42noncomno personal recommendation for me, but if i were you, i would look into https://code.google.com/p/javafuse/wiki/README and other references given by the search since there i see people with similar requests
10:42noncoms/for/from
10:43rhg135ok, ill look around
10:43noncomrhg135: here's something else: https://launchpad.net/jnetfs
10:44rhg135this grammar hurts my eyes
10:44rhg135dont think i trust their coding
10:45klrrhmm, vimclojure-easy says im supposed to run "lein vimclojure", but lein complains that nothing named "vimclojure" exist
10:45Anderkentklrr: I'd recommend using fireplace instead of vimclojure
10:45Anderkenthttp://clojure-doc.org/articles/tutorials/vim_fireplace.html
10:46Anderkenti don't think anyone's keeping vimclojure up to date anymore
10:46klrrnever mind got it working
10:46`cbpcant trust chinese software, no proper english in their docstrings!
10:46klrrAnderkent: the link is dead but ill google that later :)
10:46rhg135fireplace works fine
10:46Anderkentthat link works for me :O
10:46Anderkentoh well, try https://github.com/tpope/vim-fireplace
10:46rhg135let me tell you a story, it involves a korean company
10:47rhg135it ended tragically
10:49klrrwell i just want syntax highlight anyway so vimclojure will work fine :)
10:49rhg135-static
10:49rhg135or 7.4
11:07gvickersAnyone know of a better way to run functions from (ns-publics) than parsing the output and eval-ing the function? That works but it feels rather messy.
11:08Anderkentgvickers: vars are callable, so just ((get (ns-publics *ns*) 'fn-name))
11:10Anderkentgvickers: https://www.refheap.com/17942 . I assume there's a reason you use (ns-publics) and not just resolve.
11:11gvickersI have a collection of namespaces that are unknown at compile time with an expected set of functions in each. I need to check if they exist and call the functions expected in each namespace
11:12atankanowis there any performance difference between using ->> to thread a list through a series of map calls to transform data VS one map call with a compound function that does all of the transformation?
11:13rhg135i think i settled on https://github.com/EtiennePerot/fuse-jna but how do i use it in lein?
11:14gvickersAnderkent: thanks that worked a lot better than my intial solution.
11:14Anderkentatankanow: there might be, but the question is do you care? (most of the time the answer should be 'no' :P)
11:15atankanow<Anderkent> I don't care about the performance that much ... but i love the ->> macro and wanted to make sure i wasn't abusing it =)
11:17ToxicFrogatankanow: series-of-maps is probably less performant, but much more readable.
11:18Anderkentrhg135: it seems it's not a mavenized project, so you'd have to write a pom to it then push it out to clojars to use it with lein the 'right way'
11:19Anderkentah wait, it has native dependencies
11:19rhg135sigh, has nobody ever used fuse in clojure before
11:19Anderkentthen I guess you just need to download it and include it in your sources
11:20Anderkentlein isn't very good with native stuff :)
11:20rhg135that ik
11:20atankanowToxicFrog: I definitely agree about the readability ... i feel very comfortable deconstructing algorithms in a series of transformations
11:30rhg135how would i include it just add to classpath?
11:43caracal_I'm having a weird compilation error in clojurescript. Anyone willing to listen and hopefully give me some idea of how to solve it?
11:45justin_smith I'm no clojurescript expert, but I may still be able to help. What's the error?
11:46codonnellSo I've modeled a really simple app on the modern-cljs tutorial.
11:46codonnellIt's just a form with a calculation attached to the submit button.
11:47codonnellHowever, if I remove the brepl from compilation and click my submit button, I just get "page not found"
11:47codonnellThe same thing happens if brepl is included and I compile with advanced compression.
11:48codonnellI set prettyprint to true and checked out the compiled javascript file, and I cannot for the life of me find a difference between the version that works and the one that doesn't.
11:49justin_smithpart of the what the google closure compiler does is remove unneeded dependencies - could it be that it is erroneously thinking some of your generated javascript is unused?
11:50justin_smiththis is something I have watched someone address, but not done myself, sadly
11:52codonnellThat is possible. I'm going to take a second look and compare working and nonworking compiled javascript.
11:54ro_stcodonnell: also be worth inspecting the network traffic when you click submit
11:54justin_smithwe were group-programming in a workshop, I seem to recall manually adding the generated js as includes - there may be a better way to do that
11:54ro_stpage not found is a 404. what url/http verb is being attempted?
11:54codonnellI just have it on localhost for the moment.
11:54codonnellThe submit button shouldn't actually change which page I'm on. Its action should be to execute a javascript function.
11:55ro_stit's likely that it's causing your browser to redirect thanks to e.preventDefault(); not being used
11:57codonnellhmmm
11:57codonnellAny idea how I could fix that?
11:58ro_stquickest would be to stick onclick="return false;" directly on the html of the button
11:58ro_stor to not use a button inside a form
11:58ro_stunless you're trying to do form validation?
11:58codonnellNo, I'm not. I literally just started using clojurescript yesterday. I'm mimicking a technique from the modern-cljs tutorial.
11:59codonnellOf course, it works with the tutorial code. I just spent an hour futilely trying to find the difference.
12:00codonnellThanks for the tip, by the way.
12:02ro_stsure thing :-)
12:02codonnellAdding onclick="return false;" does prevent the page from redirecting, but unfortunately my function is still not attached to the form submission.
12:03ro_sthow are you binding the handler?
12:04codonnellOne sec, I'll make a pastebin.
12:04codonnellMy code is quite short.
12:06codonnellhttp://pastebin.com/VM2K6pdG
12:06ro_stwould you mind pasting the calculate fn too?
12:07codonnellSure thing.
12:08codonnellhttp://pastebin.com/bPmcnfrz
12:10ro_stcodonnell: drop a (.log js/console theForm) in just above the set!
12:10ro_stdoes it print something to the console?
12:11codonnelltheForm isn't defined up there. How about (.log js/console (by-id "draftForm"))
12:12ro_sti'm talking about inside the let form
12:12codonnelloh ok
12:12ro_stafter you have theForm bound
12:13codonnellaha!
12:13codonnellI should have thought to open up the console.
12:13ro_sti have to run, i'm afraid. happy hunting :-)
12:14codonnellAlright, well thanks for your help. :)
12:14ro_sthth :-)
12:40bkirkbridetbaldridge: ping
12:40tbaldridgebkirkbride: ack
12:41bkirkbridetbaldridge: so I took your advice to use go blocks for glue only
12:41bkirkbridetbaldridge: but I'm dealing with some synchronous systems and wanted to pick your brain on how best to interface with them
12:42tbaldridgeok, what's the issue?
12:43bkirkbridetbaldridge: The two options I see are to wrap the sync calls with async versions or make some more generic abstraction that does that on the fly using channels
12:44tbaldridgebkirkbride: my current line of thinking (there are some that disagree) is to wrap sync code in one or more (thread) blocks and then communicate using channels. (hang on for a gist...)
12:46bkirkbridetbaldridge: that's close to my thinking, but I'm creating pools with a bounded number of threads ahead of time. Here's a gist: https://gist.github.com/bkirkbri/6309498
12:46tbaldridgehttps://gist.github.com/halgari/6309500
12:46tbaldridgeyep, they're pretty much the same, your's is more generic
12:46bkirkbridetbaldridge: I decided NOT to embed a function in the thread block, as that seemed more like an actor. Instead you send a [return-channel thunk] message to the "worker"
12:47tbaldridgeand depends on how you want to divide up the work. Embedding the function may be nice when you want to limit the number of requests to something. For example, a database may need to be restricted to 4 calls in flight at a time.
12:48bkirkbridetbaldridge: Right. Sending the thunk allows worker pools to be used for more than one thing. But you probably want the bounds to be linked to the function(ality) anyhow.
12:50bkirkbridetbaldridge: Send thunks means leveraging closures more directly than sending args to a baked-in fn.
12:50bkirkbridetbaldridge: In any case, I'm glad to be on the right track. Before chatting with you the other day I was doing the sync work in the go blocks.
12:51tbaldridgebkirkbride: yeah, that's not a good idea :-)
12:52tbaldridgebkirkbride: if you want to do some research on this topic, take a look at Netflix Hystrix. I think there should be a way to use this sort of thing from core.async. https://github.com/Netflix/Hystrix/wiki
12:53bkirkbridetbaldridge: Nice. I've seen it but not considered it for use with core.async.
12:53bkirkbridetbaldridge: Another common pattern I'm trying to abstract is collection (reduction) of a bunch of work you've sent out.
12:53tbaldridgebkirkbride: basically it wraps retries/circuit breakers, etc. I haven't figured out what the interop would be like with core.async, but I think it'd be a cool research project.
12:54tbaldridgebkirkbride: like (join chan1 chan2 chan3) => [result1 result2 result3] ?
12:54bkirkbridetbaldridge: Right, I'm using my own breaker stuff right now. It's pretty easy to roll an atom-based implementation that aborts lazy seqs, etc.
12:55bkirkbridetbaldridge: Well, originally I was creating a channel for each async task sent to a pool and then alt! over those channels, check response, remove from alt! set, repeat
12:56bkirkbridetbaldridge: But now I'm leaning toward a single result channel that returns messages with the result and what work produced it.
12:57bkirkbridetbaldridge: A little more abstract than your join example. More like a channel reducer that handles errors and timeouts too.
12:57bkirkbridetbaldridge: Error channels and timeout channels that is.
13:00tbaldridgebkirkbride: yeah, I haven't done enough of that sort of thing to offer much of a suggestion. I'm still trying to figure out the best way to do that sort of thing myself.
13:01bkirkbridetbaldridge: Cool, I'll be sure to share anything that works out for me.
13:01tbaldridgebkirkbride: cool! I'd love to hear about it.
13:25schmirmy google foo fails me. how can I get the jdk/jre version I'm running on from within a clojure program?
13:25schmirs/foo/fu/
13:25ToxicFrogschmir: this isn't a clojure-specific question, so [java get jvm version] or similar is probably the query you want
13:26tbaldridge,(System/getProperty "java.vm.version")
13:26clojurebot#<SecurityException java.lang.SecurityException: denied>
13:26schmirToxicFrog: you google-fu is much better than mine..
13:26schmirthanks everyone
13:26tbaldridgewell that'd work if clojurebot wasn't so stingy
13:26rlbschmir: you're lookingf for System Properties.
13:26rlb(probably)
13:26rlbhttp://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
13:27ToxicFrog,(System/getProperty "java.version")
13:27clojurebot#<SecurityException java.lang.SecurityException: denied>
13:42dnolenbbloom: feel free to flesh out the optimizing expression semantics page when you get a chance - specifically I want to hear how the transformation pass will work. Your example from yesterday isn't enough since that just unwraps if, but we will need to unnest lets too.
13:48hiredmanif you do alpha conversion you can merge lets
13:51bbloomdnolen: link?
13:51dnolenhiredman: yes, that the kind of thing I want to see written up :)
13:52bbloomconfluence is refusing to load the nav bar for me
13:52dnolenbbloom: http://dev.clojure.org/display/design/Optimizing+Expression+Semantics
13:53bbloomdnolen: how about i add some comments & you incorporate them in to whatever format you like?
13:54bbloomseriously atlassian…. Error formatting macro: pagetree: java.lang.NullPointerException
13:54bbloomjira AND confluence are pretty much unusable
13:55bbloomdnolen: http://dev.clojure.org/pages/diffpagesbyversion.action?pageId=8192615&amp;originalVersion=3&amp;revisedVersion=14
13:55bbloomwhy should i bother contributing design notes if you're just gonna replace them wholesale?
13:56dnolenbbloom: your design note aren't design notes which I alluded to yesterday
13:56dnolenbbloom: you wrote up some high level plan with no specific goal
13:57dnolenbbloom: or an overly abstract one, now I'm asking to talk specifically how your solution can address this specific problem
13:58bbloomdnolen: *sigh* sorry man, i can't be bothered to play "guess what david nolen wants to hear". you and i both understand the problem & my proposed solution. if there are specific questions you have, i'm happy to answer them. but i'm done posting to the design wiki. it has never proven fruitful
13:59dnolenbbloom: just because you and I understand doesn't mean other people don't
13:59dnolenbbloom: nor does it mean we'll remember 2 months down the line when the proposed solution end up being more complicated then we originally though for N reasons
14:00dnolenbbloom: I'm up big changes, but I'm for thinking about how they apply to actual problems and documenting it
14:00bbloomdnolen: my proposal is an A-normal form transformation. This is *textbook compiler stuff*. I've already done a proof of concept & the only major problem i ran in to was gensyms in analysis, which i fixed
14:01dnolenbbloom: which no one knows about, nor did I follow it closely - so what?
14:02dnolenbbloom: I didn't see any benchmarks, I didn't see any source output comparisons, I just some links to Github
14:02bbloomdnolen: so i'm happy to contribute a patch & i'm happy to jump through a few hoops to do so, but if you want a design page, you're gonna have to write it. i'm happy to provide feedback
14:03bbloomdnolen: there are two separate issues: 1) future proofing the AST & API, which i've written design pages about in the past. no progress has been made 2) adding compiler passes, which has also been discussed before but is dependent on #1
14:04bbloomhttp://dev.clojure.org/display/design/Formalize+AST
14:04bbloomhttp://dev.clojure.org/display/design/AST+children
14:04bbloomi wrote some notes for you about the compiler API, you deleted those
14:04dnolenbbloom: because you keep moving too far out ahead w/ slowing down
14:05dnolenbbloom: both of your "design" note pages don't even outline *real* problems
14:06bbloomdnolen: what is the purpose of these pages? to convince you? to document our efforts for other observers? nobody ever comments on these pages
14:06bbloomnobody is paying attention to them
14:06dnolenbbloom: why should people pay to pages about problems they don't have?
14:06bbloomi'm happy to volunteer non-trivial amounts of my time, but i want my time to be productive
14:06seangrov`bbloom: I've been reading through them while trying to understand some problems with the analyzer and compiler
14:07seangrov`It hasn't been super useful though, on reflection
14:07dnolenbbloom: ^
14:07bbloomdnolen: ^
14:07bbloom:-P
14:07bhaumandnolen: bbloom: seangrov`: my next post http://rigsomelight.com/2013/08/22/channels-of-channels-dots-game-refactor.html
14:08bbloomdnolen: forgive me for being disillusioned, but afaict, you're the only person actively committing to cljs & your criteria for progress seems arbitrary and short-sighted
14:08dnolenbbloom: anyways, we have a real problem that needs actual solving with passes that isn't solved by GClosure anymore
14:08bbloomdnolen: sure, so you understand the problem, you document it if you feel that's valuable
14:08bbloomi'll contribute code, since i feel that's valuable
14:08bbloomi'm not trying to be a dick, i'm just trying to maximize the utility of my time
14:09dnolenbbloom: as am I since I'm going to have to go through your patches
14:09dnolenbbloom: which are generally the most invasive and tend to break shit
14:10bbloomdnolen: b/c you want squashed patches. in my branches, they are very fine grained commits that are quite easy to understand
14:10bbloomdnolen: as for breaking shit, yeah, *shrug* we find the issues & we fix them. i'm not super concerned w/ master being broken. i understand that you are, so i'm happy to do extra work to test & validate before applying. i've done so in the past many times & include the tests or benchmarks you ask for
14:12bbloomam i being unreasonable?
14:13dnolenbbloom: look, if you can't slow down to explain your solution to *me* and document for *others* I don't see what the point is of pursuing your solution which I'm open to doing. Otherwise I'll simply solve the problem in a local way. My time is as precious as yours.
14:14dnolenbbloom: there's no rush :)
14:15bbloomdnolen: my proposed solution is a translation to A-normal form. I can provide you with references as to why that is useful and i can answer specific questions about the impact to CLJS' compiler in particular. If you want to codify my comments in to a design page, you are free to do so
14:16seancorfieldcomment from the peanut gallery: as more people start to use CLJS, keeping releases stable - and keeping master stable - will become increasingly important
14:16bbloomseancorfield: trivial solution: unstable branch
14:16bbloomseancorfield: it's just not a problem
14:16bbloom:-P
14:16callenI think the problem is that there isn't a stable branch atm
14:16bbloomof course releases should be stable
14:16bbloomfor once, i agree w/ callen
14:17callenand unless the developers choose to split one out, it's a little unreasonable to expect people to fork and manually cut stable releases into the fork.
14:17seancorfieldwe're starting to look at AngularJS + ClojureScript so I'd want to keep master stable, just like dnolen, which means anything "big" needs to go on a branch
14:17bbloomdnolen: i can provide a proof of concept patch & you and i can work together to minimize impact
14:17seancorfieldI'm just commenting on the discussion around keeping master stable
14:18dnolenbbloom: anyways feel free to write up your thoughts whenever you like if you actually want it to move forward. I'm not planning on leading this, but I also want to know what the specific plan is for this specific optimization. IRC is not documentation of your thought process.
14:18bbloomdnolen: i provided documentation of my thought process… you didn't like it… lol
14:18dnolenbbloom: unframed to the specific problem.
14:18glosolihmm is there some decent way in VIM to find the usage of the function between the project ?
14:20dnolenbbloom: this is a better page even though it hasn't gone anywhere if you need an example http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances
14:20bbloomdnolen: my proposal addresses a number of concerns. looking back at my revision of that page, i wrote: "Eliminates (function() {})() forms that GClosure unreliably optimizes"
14:20bbloomthat's the specific problem, is it not?
14:21bbloomi'm not sure why the ceremony is required
14:21dnolenbbloom: w/o saying where such an optimization might matter - which I do over and over again.
14:22`cbpif I exclude clojure.java.jdbc from korma and use the latest instead will korma break? korma uses 0.2.3 and the latest is 0.3.0
14:22bbloomdnolen: but then you replaced *all* of my notes with an unskimmable wall of prose
14:23dnolenbbloom: I don't skimmable is meaningfully valuable for potentially significant compiler changes.
14:25bbloomdnolen: look, it's really simple: I *was* happy to type up some notes & *am still* happy to answer questions about design, notes, patches, everything. I *never was* happy to conform to some arbitrary archetype of a design document. And now, after a year of trying to jump through design hoops, I am *no longer* happy to write up notes
14:25bbloomdnolen: if that means you're just gonna do a local fix & further complicate the code generator. *shrug* fine by me i guess
14:26bbloomI feel that I've been extremely patient, but my patience has run out.
14:26dnolenbbloom: imagine I have only passing familiarity with ANF and alpha conversion for merging lets (which is true). but I have to look at the patch and push the changes through, test it, and in the future debug it.
14:26seangrov`dnolen: "This map should map each constant's original form to a unique identifier, possibly some human readable prefix like `cljs$constant$vector$` plus a short ID of some kind." => is this supposed to end up looking like #<Atom@3f86f612: {:else "cljs$constant$vector$else" :a "cljs$constant$vector$a"}> ?
14:26ker2xhumm, hey, there isn't an openCL lib for clojure hidden somewhere ? :(
14:27SegFaultAXbbloom: I missed the start of the convo, what are y'all talkin about?
14:27bbloomSegFaultAX: check the logs
14:27bbloomdnolen: i pointed you towards two references on ANF & can point you towards more. No amount of notes I could write would ever equal to the mountains of reference materials on compiler design
14:28bbloomdnolen: this page explains it very susinctly w/ working example code http://matt.might.net/articles/a-normalization/
14:28`cbpis korma no longer maintained?
14:29ker2xsomething like that https://github.com/ztellman/calx/ but not dead ?
14:29seangrov`bbloom: Maybe a blog post would be a better place to post "design docs" for you, a bit less mutable by others
14:29seangrov`That way they're there for reference, and won't be swept away in a single change
14:31bbloomseangrov`: writing blog posts or any polished prose for that matter takes *a long time*
14:32bbloomseangrov`: bullet points take minutes, discussion can take an hour, a proper quality design doc or blog post can take me a whole day
14:32bbloomseangrov`: if i've got a day to give to CLJS, i'd rather have it result in a patch
14:32seangrov`bbloom: Well, just the fact that you can point to it for reference and not have it wiped away
14:32bbloomseangrov`: there is revision control :-P
14:32seangrov`Post bullet points, but maybe rely on someone else to port them to the wiki
14:33bbloomseangrov`: i did post bullpoints… dnolen's "port" involved cmd+a, backspace
14:33bbloomdnolen: i'm sorry man. you know i want to help
14:33callen`cbp: it's maintained'ish.
14:34callen`cbp: what's wrong?
14:34dnolenbbloom: yes, yes, all this I plan to read. But just because I read it doesn't mean I'll understand immediately how you intend to use it unnest if and unnest the resulting lets. That's like me waving my hand saying "just use core.async it'll be easy to make an autocompleter"
14:34callen`cbp: I would make the point that Korma essentially "just works" and doesn't need a flurry of activity to be healthy.
14:34bbloomdnolen: if you read it, you'll discover that what ANF does *precisely* is to un-nest things like ifs in to lets
14:35dnolenbbloom: but you need to merge the lets too
14:35dnolenhiredman: thanks for the comments :)
14:35bbloomdnolen: no, you don't
14:35dnolenbbloom: you do
14:36bbloomdnolen: why do you need to merge lets? i mean you can, but why do you have to?
14:36dnolen(and true false true) -> (let [x (let ... (let ...))] (if ...)) with the transform you suggested yerterday
14:36dnolenall those lets become functions
14:37hiredmandnolen: you only hoist if the expression is non-atomic, which is open to redefinition, but I don't think booleans are non-atomic by any definition
14:37bbloomdnolen: the compiler will turn all that in to local assignments, which is the point of the ANF transform. you can merge the lets to make the intermediate form look nicer, but for a non-parallel let, that's sugar
14:38bbloomdnolen: letfn is parallel, but clojure's let could (and probably should) be defined in terms of a single binding
14:38bbloomdnolen: i've proposed this before too: a macro should UNflatten all of the lets
14:38dnolenhiredman: in the above example booleans of course can will be more complex expressions like function invokes
14:39bbloomdnolen: have you read that post yet?
14:40bbloomdnolen: most of your questions will be answered if you reflect on that post for a while
14:41bbloomdnolen: in particular, you should note the "Output language"
14:41hiredmandnolen: sure
14:41bbloomdnolen: the first argument to an 'if form is an atomic expression
14:42callen"ztellman: A reminder that there's a 50% chance of collision on a 32-bit hash with only 77k values. Don't use hashes for comparison/equality checks."
14:42ztellmanyup
14:42ztellmansource, if people care: http://en.wikipedia.org/wiki/Birthday_attack
14:43bbloomdnolen: hiredman: regarding alpha conversion - my proof of concept currently uses gensyms, but it could use de bruijn indexes instead with a very small change. we already do hacky alpha conversion in the code generator b/c js has broken lexical scoping
14:43bbloomwould be a good idea to do alpha conversion as a pass in the future, since that transformation is important for other backends
14:44bbloomalpha conversion can also leave the original symbol name as a prefix of the generated name, so that it's easier to match them up later
14:52dnolenhiredman: the problem is we always need to hoist - in order to avoid emitting complex test expression which always gets wrapped in a JS function
14:53dnolenbbloom: I'm squinting a the post, I get the high level picture but I don't see how it handles the nested let case.
14:53callenztellman: related to the Birthday Paradox?
14:54callenanybody here doing Clojure Cup?
14:54ztellmancallen: birthday problem, I think, not sure what's paradoxical about it
14:54ztellmanbut yeah
14:54callenztellman: ah yes you're right. I think it's one of those probability things that are slippery for people.
14:54hiredmandnolen: it doesn't, but combined with alpha conversion it does, because when you alpha convert, you have unique names, so you can merge the lets
14:54callenlike the Monty Hall thing.
14:54bbloomdnolen: before we discuss what you mean by "nested let case" can we first agree that clojure's let is serial, not parallel? ie, (let [x 1 y 2] z) is sugar for (let1 x 1 (let1 y 2 z))
14:55ztellmancallen: yeah, I knew about it, but still somehow glossed over it when I was writing the compare function
14:55dnolenbbloom: yep
14:55bbloomdnolen: ok so with that in mind. what is the problem with nested lets?
14:55callenztellman: you don't mind that I propagate interesting/amusing tweets to this channel do you?
14:55dnolenbbloom: (let [x (let ...)] ..) the second let is an expression context will be wrapped in function by the comipler
14:56ztellmancallen: no, why would i?
14:56bbloomdnolen: currently, yes. after an ANF transform, that would be not necessary
14:56dnolenbbloom: so what would ANF convert that into, this is what I don't see :)
14:56dnolenbbloom: and the blog post isn't making it any clearer for me
14:56callenztellman: I don't know, some people get proprietary about their missives.
14:57bbloomdnolen: if you look at the output language, you'll seee there are 3 types of "expressions" aexp, cexp, and exp
14:57bblooman aexp is totally atomic
14:57bblooma cexpr can be compound, but can't be another let
14:58bbloomthe inner let would be hoisted out, and assigned a name
14:58bbloomif that involved another inner expression, this would happen recursively
14:58bbloomsuch is the nature of the transform
14:59Bronsa(let [a (let [a 1] a)] a) => (let [a1 1 a2 a1] a2) ?
14:59bbloomas a result, if you *also* do alpha conversion (which we do), then you can remove all of those (function() { … })(); generators that check (= context :expr) in the code generator
14:59bbloomdnolen: yeah, Bronsa has it right
15:00bbloomnotice how the inner a was named to a1, then assigned that inner binding value
15:00bbloomit makes order of evaluation explicit
15:00bbloomit's also halfway to an SSA transform
15:00ker2xanyone tested G-WAN webserver ?
15:00Bronsafwiw i already do alpha conversion in CinC (but no anf) and it makes writing passes so much easier
15:01hiredmanas an aside https://github.com/hiredman/qwerty does both alpha conversion and anf, but the anf is sort of ad-hoc
15:01bbloom(inc Bronsa)
15:01lazybot⇒ 8
15:01bbloom(inc hiredman) ; you too budy
15:01lazybot⇒ 25
15:01bbloom(dec bbloom) ; for misspelling buddy
15:01lazybotYou can't adjust your own karma.
15:02bbloomwhew.
15:03dnolenbbloom: it's hard for me to confirm what's going on in Matt Might's blog pos since it doesn't work on trivial examples
15:03dnolen(normalize-program '(let ((x (let ((y 1)) y))) x)) => '(let (let ((y 1)) (let ((g1534 (x y))) (g1534))) x)
15:06bbloomdnolen: you running the racket example?
15:07dnolenbbloom: yep
15:07bbloomer which one?
15:07dnolenI just copied and pasted the the code at the bottom of the post
15:08bbloomgrumble grumble rlwrap
15:09bbloomdnolen: your arguments are invalid
15:09bbloomdnolen: a let is not an allowable top level form
15:09bbloomwrap it in (list ..)
15:09dnolenbbloom: heh, I'm not making an argument :) just fumbling along trying to understand the post
15:10bbloomdnolen: lol i didn't mean your debate argument, i meant your function arguments
15:10bbloomhaha
15:10bbloomi'm also not making an argument, i was genuinely debugging :-)
15:10bbloomheh, that's pretty funny
15:11dnolenbbloom: ok gotta switch gears, but I'll look into this, it's making sense - I'll do the dirty work of keeping the confluence page in sync and ping you again for comments.
15:11bbloomdnolen: if you look at normalize-program, you'll see that it matches empty lists, define forms, and lists
15:12seangrov`dnolen: Quick confirmation before you switch gears?
15:12dnolenseangrov`: what's up?
15:13seangrov`dnolen: "This map should map each constant's original form to a unique identifier, possibly some human readable prefix like `cljs$constant$vector$` plus a short ID of some kind." => is this supposed to end up looking like #<Atom@3f86f612: {:else "cljs$constant$vector$else" :a "cljs$constant$vector$a"}> ?
15:14dnolenseangrov`: I would probably just store an id? no strings, we should probably do the id emitter as some kind of function to keep it flexible for now
15:15seangrov`Is the id just a unique integer? Or another keyword?
15:15dnolenseangrov`: it's fine if integer for now
15:16seangrov`So #<Atom@3f86f612: {:else 1 :a 2}>, with the integers/ids being generated from a function
15:17dnolenseangrov`: something like that, could probably just be the id generator used by gensym
15:17seangrov`Ok, perfect, thanks
15:17dnolenseangrov`: also, you know there is an existing Keyword type right?
15:18seangrov`here https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L2048 right?
15:18dnolenseangrov`: yep, it needs to fleshed out into something more like this http://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L382
15:18`cbpcallen: i had some jdbc queries which depend on 0.3.0 which i wanted to copypaste but korma gets 0.2.3 or something and the queries wouldn't work so I ended translating everything in korma to jdbc and removing korma
15:19seangrov`dnolen: Yeah, I think I have that done locally, looking at the Symbol deftype and the clj-jvm Keyword implementation
15:19`cbpcallen: I could have tried to exclude jdbc from korma but that would've prolly broken it
15:20dnolenseangrov`: you should also look how we emit Symbol - we precompute all the properties at compile time.
15:21seangrov`https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L170
15:21dnolenseangrov`: yep
15:23seangrov`Ok, so do the analyzer bit to track keywords first, then finish the deftype, and then the compiler emit phase?
15:23eggheaddnolen: when you pass in 'sel' to alts! in your most recent blog post -- how does that work? I've only seen alts used on a list of chans, not on a chan and a vector of chans
15:24eggheadI see in the docs: "can be either a channel to take from or a vector of"
15:24egghead[channel-to-put-to val-to-put],
15:24eggheadbut alts! doesn't put at all but takes, doesn't it?
15:25`cbpcallen: also selmer question, the template cache only checks if 1 file has changed. So if you render "home.html" but "home.html" extends "base.html" and you change the latter, the cache won't notice the change. Should there be support for that?
15:25callen`cbp: I think you can exclude and replace deps, but just submit a pulll request man.
15:25calleneverybody has to pitch in for these things to be maintained :(
15:25t-goossensin leiningen project file how do I add a class to classpath (like: com.mysql.jdbc.Driver)
15:26callen`cbp: that's a good question, I'd brought it up before but I don't think it was addressed.
15:26dnolenegghead: sel is a chan
15:26eggheadaaaah
15:27dnolenegghead: it chan of the selector chan which has had other operations applied over it
15:27dnolenegghead: r/filter and r/map are not sequence filter/map
15:27eggheadya I was confused by the names map and filter, didn't realize they were the sort of map-chan filter-chan things from your async-tests utils
15:27eggheadcheers, thanks
15:27callen`cbp: the official policy is:
15:27callen`cbp: use dev mode if you need to disable caching.
15:28ToBeReplacedt-goossens: you need the artifact that contains the class... in your case, I think you add ["mysql-connector-java" "5.1.6"] to your :dependencies
15:28t-goossenslike that
15:28t-goossensok
15:28t-goossensthanks
15:28t-goossensfor some reason i remember something like (:import)
15:28ToBeReplacedor mysql/mysql-connector-java
15:28t-goossensbut maybe that is something else..
15:28`cbpcallen: yeah that's probably enough
15:29`cbpcallen: for my use case anyway
15:29ToBeReplacedthat's how you import the class in a clojure ns form -- that's different from telling your project it needs to use that artifact
15:29t-goossensbasically it is one namespace that needs it
15:31callen`cbp: (cache-off!)
15:33hiredman:import only lets you use a class using the shorter version of the name
15:33hiredman.win 5
15:33boblarrickGoogle keeps leading me to functions in contrib like deep-merge or dissoc-in, what is the recommended way to use that stuff now? How do I get those in my project?
15:47llasramboblarrick: Most of the utility stuff in contrib which didn't make it honestly just isn't that useful. Fortunately most of them are tiny, so you can just copy-paste them if you can't live without them
15:48llasramboblarrick: Or you can check out the non-contrib utility libraries like flatland/useful
15:49dissipatedoes anyone here use a scripting language like python to compliment clojure? or can clojure replace python/ruby/perl?
15:50callendissipate: bit of both.
15:50nDuffdissipate: in my experience, the set of projects for which each is the right tool tends to be surprisingly disjoint.
15:50dissipatecallen, bit of both? would you use clojure to whip up a recipe for the command line?
15:50nDuff...well, not entirely. There's a case I recently used Python's Trellis for which Pedestal was also very competitive.
15:51dissipatenDuff, i'm not talking about a project, i'm talking about just whipping up a script
15:51bbloomtechnomancy: nice
15:52callendissipate: depends on what it is.
15:52callenI've got a script written in Clojure running right now.
15:52callenbut it's also more complicated than a typical 1-liner.
15:53nDuffdissipate: usually, if I'm "just whipping up a script", my tool of choice is shell.
15:54boblarrickllasram: yeah i'm copy/pasting now, wondered if that was considered shady or what
15:54cemericknDuff: every time I do that, I end up writing in 40 different languages
15:54shdwprincenDuff: found shell very painfull when writing something above 2-3 lines
15:55patchworkdissipate: Clojure is not a scripting language and requires spinning up a JVM to run anything
15:55nDuffcemerick: If one knows bash well, it's rarely necessary to use awk/perl/whatnot from it.
15:55patchworkstick to bash for one off simple command line tasks
15:55cemericknDuff: I'll have to take your word for it :-)
15:56dissipatepatchwork, so it seems clojure is more suited to application development, not scripting
15:56nDuffshdwprince: people who write scripts by guess-and-test have trouble. It's a language, and has to be learned like any other to be used effectively. (Actually, needs _more_ care to use effectively, since there are so many non-obvious pitfalls).
15:56patchworknDuff: bash is awesome for stringing programs together, not so much for writing them… !
15:56patchworkI love bash for having programs as function calls
15:56ltwAnyone got any strong opinions on function naming practice when you're essentially renaming a function to swap the args around?
15:56patchworkbut I would still rather write the programs bash calls in something besides bash
15:57dissipatepatchwork, what about python?
15:57mgaareactually I think using clojure for simple scripts is very good for your health
15:57patchworkdissipate: It is like any compiled language that way
15:57nDuffpatchwork: I have a bash library that provides, in effect, higher-order-functions with lexical scoping.
15:57ToxicFrogLein repl really needs a (reload)
15:58patchworkdissipate: python is fine for simple tasks, not so much for applications (GIL)
15:58nDuffpatchwork: If you want to make an argument about where bash is and isn't the right tool, we can do that, but I'd prefer to do it at a point when we both have the time to make our arguments in full and provide counterexamples.
15:58mgaareevery time you go to run a small clojure script, get up and get a drink of water. Super helathy
15:58patchworknDuff: That sounds interesting. Link?
15:58nDuffpatchwork: unreleased.
15:58mgaareToxicFrog: see clojure.tools.namespace
15:58nDuffpatchwork: I'd *like* to release it, but property-of-employer, etc.
15:58nDuffpatchwork: big parts are inspired by the execlineb language, by the way, if you want to look at that.
15:58patchworknDuff: bummer. So much good code in private repos
15:58ltwToxicFrog: is that a complete ns reload, complete with requires, or just the ns contents?
15:59dissipatepatchwork, i'd pick python over java for a large application though. not sure if that is saying much.
15:59patchworknDuff: I don't deny you can write anything in bash, there are just less error-prone options nowadays for writing full programs
16:00dissipatemgaare, not sure if serious. :P
16:00ToxicFrogmgaare: will do
16:00patchworkdissipate: Everything is a tradeoff. You clearly prioritize developer sanity over general performance
16:01nDuffpatchwork: Depends on what you mean by "error-prone". The exception-handling story isn't so great -- I had to roll my own tools -- but if you're just referring to the pitfalls inherent in using the language badly, well, the answer is not to do it badly. :)
16:01ToxicFrogltw: I think complete with requires? Basically I want to be able to change some part of the project and reload it without needing to shut down and restart the repl (20+ seconds)
16:01mgaaredissipate: only a little bit. Although the lifestyle of programmers often leads to chronic dehydration, so it could be a good practice :D
16:01dissipatepatchwork, that i do. BTW, there are ways around the GIL, namely interprocess communication. my main beef with python is it's imperative with side effects.
16:01mgaareToxicFrog: clojure.tools.namespace will do code reloading. If you change your dependencies in project.clj, it won't pick those up though
16:01ltwthe (refresh) in mgaare's suggestions of clojure.tools.namespace seems a good fit.
16:01technomancymy rule for bash scripts: your first bug you get from weak typing counts as a warning; once you hit your second you have to throw it away
16:02patchworkdissipate: Right, running many pythons in parallel. Kind of like brute-force threading
16:02technomancyunless you actually have no choice (/me makes a sad, resigned motion towards bin/lein)
16:02ToxicFrogmgaare: that's good enough for me, thanks.
16:02benkaymgaare wine bottles fixed my hydration problem. 750 mL, 2x/day. throat size makes it super easy to drink large volumes while walking or w/e.
16:02dissipatepatchwork, and what would you recommend for a multi-threaded friendly scripting language?
16:02nDufftechnomancy: Heh. It's more the unintuitive automatic behavior (string-splitting on expansion, unescaping on read, etc) that requires effort to turn off that I see messing folks up. :)
16:02tbaldridgepatchwork: the libraries in python are super nice for that sort of thing. basically fork with a function argument.
16:03nDuff...that, and people trying to copy old, bad code that uses scalars where one should use arrays.
16:03patchworkdissipate: I don't know one : ) In that case just keep a clojure repl open, use that is your shell so to speak
16:03patchworkclojure to me hits the sweet spot of being expressive and performant
16:03patchworkthat no other language I've used can match
16:04patchworktbaldridge: Haven't used it in a couple years! Used to use it all the time ~5 years ago, but I assume things have come along since then
16:04mgaarebenkay: yeah, I think Tim Ferriss does that too
16:04benkaymgaare: now that I think about it I got the trick from him.
16:04shdwprincedissipate: maybe when you need powerfull thread system in scripting language, you doing it wrong?
16:05benkay500 mL is a great wakeup while the coffee brews
16:05ToxicFrogpatchwork: if only it didn't take so long to warm up :(
16:05patchworkToxicFrog: Just never close your repl!
16:05dissipatepatchwork, but then i have to have 2 languages in my code base. 1 language for my scripts (say python) and then clojure for my application code.
16:05ToxicFrogdissipate: lua has a nice message-passing library (Lanes) and a cluster computing library (Luapilot), but the package management situation is kind of not good.
16:05mgaarebenkay: I still haven't gotten in a good morning water habit. shame shame on me
16:06shdwprincedissipate: you want to stick one one language for all purposes?
16:06patchworkdissipate: That is why I am saying, if you keep a repl open you get around the startup time, and can use it just like a scripting language
16:06dissipateshdwprince, so you are saying i would never want to run a script that does scientific calculations?
16:06benkaymgaare: wine bottles. wine bottles errywhere :)
16:06patchworkBut also, right tool for the job and all that
16:07shdwprincedissipate: some libs for math in python writted and optimised on very low level
16:07callenshdwprince: the same libraries exist on the JVM...
16:07mgaareDidn't I read somewhere about something that lets you keep a hot jvm running to alleviate the startup time concerns for this kind of scripting?
16:07shdwprincedissipate: i say about if you really need perfomance you should'nt use scripts
16:07rlbmgaare: nailgun
16:07dissipateshdwprince, and yes, i would like to reduce complexity by not having multiple languages
16:07rlb(or similar?)
16:08patchworkshdwprince callen: Right, everyone is still using the same old fortran for matrices!
16:08mgaarerlb: yeah that sounds right.
16:08patchworkJust find blas in whatever language you are using. Done
16:08Apage43nailgun is a single JVM
16:08Apage43there's also drip
16:08Apage43https://github.com/flatland/drip
16:08dissipatepatchwork, do you use the repl as your CLI?
16:09patchworkdissipate: Increasingly yes
16:09technomancynailgun is extra-complicated for the sake of Java
16:09patchworkabstraction is great
16:09Apage43which keeps an -extra- JVM handy, with your classpath already set up
16:09shdwprincedissipate: there is many languages for very different purposes, you can't stick at one that will be very good in all
16:09mgaareoh wow, it's like double-clutch jvm
16:09stuartsierraha :)
16:10dissipateshdwprince, well, that's an epic fail
16:11stuartsierraIn case it was unclear, I was laughing at mgaare's "double-clutch jvm"
16:12hiredman,(some nil? [])
16:12clojurebotnil
16:13hyPiRion,((juxt keep some) nil? [nil])
16:13clojurebot[(true) true]
16:13mgaare;)
16:13patchworkstuartsierra: Thanks for clarifying. I thought you were laughing at everything
16:13ToxicFrogzipmap \o/
16:14stuartsierrapatchwork: Sometimes I do. It's how I stay sane. :)
16:14stuartsierraAlso, I wrote tools.namespace so that I could use a single REPL as a persistent process.
16:15stuartsierraI only restart the JVM once or twice a day now.
16:16xeqistuartsierra: whats missing to get that to 0 ?
16:17stuartsierraxeqi: Never making a mistake in my code. :)
16:17mgaareI use tools.namespace too, but PEBKAC issues cause restarts sometimes :D
16:56noncomare there any recommendations on organizing global program architecture with core.async?
16:57stuartsierranoncom: Step 1: wait until it's finished. :)
16:58noncomahaha
16:59stuartsierraMore seriously, there are good examples in docs / talks about Go.
16:59tbaldridgeI'm not sure what people are waiting for to mark it as "finished". The client API hasn't changed...well since it was first written.
17:00stuartsierraWell, I'd like a little more testing before I base my "global program architecture" on it. :)
17:00stuartsierraAnd we'll be confused about how to pronounce <!! forever.
17:01futileI wonder if it can be made into a more "pluggable" API, so that you don't have to architect your app around it, but the other way around.
17:01mgaaremaybe pronounce it "failed bank robbery"
17:02stuartsierramgaare: Not as good as "double-clutch JVM" :P
17:02futileNot that I know the first thing about its API.. I just know that when I hear that phrase, it usually indicates an API that sits under your code instead of on top of it. And I guess that's often a good thing, as clojure.core does that.
17:02tbaldridgefutile: that's kindof like asking a compiler to magically add parallelism to your code.
17:03ToxicFrogopenmp~
17:03tbaldridgeToxicFrog: even that takes code annotations most of the time
17:03ToxicFrogtbaldridge: yes, I wasn't actually serious
17:03hiredmanb
17:03mgaarestuartsierra: hm... actually "gun control" would be better. for "less bang bang"
17:03dnolentbaldridge: I think people are probably waiting for non snapshot release - is there anything blocking a 0.1.0? It would be nice to get Read/WritePort in there
17:03hyPiRionand it's not just like saying #pragma omp parallel for either, sadly
17:04stuartsierramgaare: Now that's a good one.
17:04hyPiRionWell it is, but you need to find good sizeable chunks, not throw them around everywhere
17:04tbaldridgednolen: We'd have to talk to Rich about that, but I know I handled most of the ones we discussed last Monday.
17:05tbaldridgehyPiRion: but pmap makes everything faster! It's the magic fairy dust of the Clojure world!
17:05hyPiRiontbaldridge: ha
17:05tbaldridgeI tend to call <!! "blocking take" and <! "take" or "parking take"
17:06t-goossenscan clojure.java.jdbc library give me a list of all tables in a database. I can't seem to find sometihng in the api
17:06stuartsierraI'm going to go with mgaare's "gun control"
17:06tbaldridgebut I know that doesn't really help anyone else.
17:07ToBeReplacedtbaldridge: dnolen: i'm in that camp -- i have some std blocking queue code set aside to test a port to core.async when it hits a non-snapshot
17:07stuartsierraOr maybe "angry bunny."
17:07tbaldridgestuartsierra: so what do we call >!! ? May I suggest we call it "guns for everyone" or perhaps just call it "Texas"?
17:07ToBeReplacedt-goossens: it can't; the information you want is database dependent, so you should use "query" with the right meta table
17:08mgaaretbaldridge: "Texas" sounds like a winner
17:08stuartsierratbaldridge: "Texas" is too political, "America" would work.
17:08tbaldridgenah... "Murica"
17:08mgaarehaha
17:08mgaaremaybe "NRA"
17:09hyPiRion"Now, if we do a 'Murica call here, this part will block until some other goroutine performs a gun control."
17:09hyPiRionWell, it should be the other way around really
17:09hyPiRion'Murica should run free and lose until someone performs a gun control?
17:09hyPiRion*loose
17:09stuartsierra:)
17:09tbaldridgeROFL!
17:09tbaldridge"It's the yin/yang of programming, you can't have one without the other"
17:16noncomi see...
17:17noncomfrp paradigms seem fit
17:22noncomi am doing a little gui framework on html canvas, is core.async ready for such a task? i think yes.. but what you say?
17:23noncomcurrently it is without core.async but i want to swap the architecture
17:24seangrov`Almost certainly worth an experiment
17:26dissipatea gui framework?
17:26dissipateoh hell no
17:26noncomhate framewox?
17:27dissipatenoncom, gui framework just screams OO framework to me
17:28noncomagreed, that is my mindset too.
17:28dissipatenoncom, you have a TextBox widget that you add...
17:28nDuffdissipate: eh. seesaw, f'rinstance, is downright beautiful.
17:29nDuff...whether you call it a "framework"... *shrug*.
17:29noncombut as seangrov` said i want to consider an experiment, but first asking for encouragement i guess
17:29dissipatenoncom, are your widgets going to be immutable?
17:30mgaarenoncom: we're using async quite a bit here. not for gui, but for io related things. I encourage!
17:30noncomdissipate: i am yet to decide.. i guess i will have a kind of mvc structure.
17:31tbaldridgenoncom: don't assume that OO patterns will work with core.async (e.g. MVC)
17:31tbaldridgenoncom: also, read all you can about Pedestal's UI model. It's not perfect, but it's one of the best I've seen in a long time.
17:32futileWhy is (some #{el} coll) the only core fn to test if a seq contains a given element?
17:32dissipatenoncom, immutable data structures in MVC? hmm. see that's a bit strange to me.
17:32noncomyeah, i'm not going to reimplement OO, or at least i'll try.. :).. i will read on pedestal too, thanks for the reference..
17:33futileI guess I'm wondering why there's no (contains? el coll)
17:33dissipatenoncom, that means that when you want to resize the textbox widget, you don't resize the existing one, you remove the existing one, produce a new one of the proper size and put it back in place of the old one.
17:33noncomfutile: contains? will check for index inbounds
17:33futileright
17:34noncomdissipate: good point. but actually here i come to a question: what is a textbox widget in fp? and when i try to think of it, the widget disappears in my head
17:35noncomi see functions and the flow of data
17:35noncomthat flow can be altered by other funcs
17:35noncom..
17:35dissipatenoncom, that's exactly why i said it smacks of OOP
17:35noncomi am still trying to grasp all that
17:35dissipatenoncom, in fact, there is no other use case that smacks more of OOP than GUI frameworks
17:36noncomyeah, guis are tricky :)
17:36noncomlooks like a challenge :)
17:36dnolennoncom: I'd rather see an event layer over Canvas
17:36dnolennoncom: you should also check out my blog posts on the subject
17:36justin_smithin dataflow a text box widget is a container that data flows into (from the user), that does nothing until triggered (the trigger propagating the data it has accumulated to be functionally processed)
17:37justin_smithbuckets and spouts
17:37dissipatejustin_smith, but it's immutable?
17:37justin_smithno, because the user manipulates its contents
17:38dissipatejustin_smith, there in lies the problem
17:38justin_smithbut the change of state is isolated to the contents + the triggering of functions based on them at a precise time
17:38justin_smith(rather than being entangled all through the logic as state usually is)
17:38dissipatejustin_smith, ok, so then you have side effects
17:38justin_smithyou need that for state, yes
17:38justin_smithand for UI you need state
17:39justin_smiththe key is to minimize its incidence and scope
17:39noncomdnolen: i read your posts! very inspiring and interesting! but what you say on events now? js events or you mean core.async?
17:39dissipatetheoretically you don't, but personally i would probably go insane if i had to do a GUI in pure FP
17:40justin_smithok, you need something that acts like state, and for that it just makes sense to use sensibly managed mutable state
17:41dnolennoncom: just that it would be nice to have some approach to an event layer over canvas
17:41dnolennoncom: you could use a shadow canvas
17:41noncomdissipate: i think that OOP complects textbox widgets (bear me).. there are no textbox widgets in reality.. most of the flow functions are universal archetypes, which, being decoupled from implementation are very reusable
17:41dnolennoncom: drawing operations could be surrounded in a block where you paint to that surface so it's a particular shade
17:41dnolennoncom: then when mouse event happen you can check the shadow canvas
17:42dnolennoncom: and emit an identifier
17:42dnolenso you can have sane generic event handling for canvas like you do w/ DOM
17:42dnolennoncom: far more useful than a GUI toolkit over canvas IMO
17:46noncomdnolen: oh i see
17:47noncomthat technique is widely used in games
17:47dnolennoncom: it's kind of thing you see can reinvented over and over again
17:47dnolennoncom: yep
17:47dnolennoncom: but would also just make canvas more friendly
17:47dnolennoncom: you could reuse all your HTML based logic in Canvas
17:49noncomdefinitely my interest grows more
17:51noncomi will explore all the advices and thoughts of who responded and experiment. i will share the results if i make something sane!
18:01powrtocWhat's the best method for getting a clojurescript browser repl working with emacs?
18:02glosoliI would like the same info but VIM related
18:02glosolilol
18:02dnolenpowrtoc: follow the instructions carefully that are in the repo, then do the same with lein cljsbuild
18:05glosoliHmm anyone familiar with ring ? I don't seem to get the way Session storage works in it, shouldn't session entries appear to be viewable by browser session viewer ?
18:05`cbpis there a better idiom for (->> xs (map (future..)) (doall) (map deref) (doall)) ? =P
18:06justin_smithglosoli: the browser gets a token, used to look up the actual session data in memory
18:06powrtocdnolen: so you use inferior lisp mode?
18:06dnolenpowrtoc: yep
18:06justin_smithglosoli: that is the default, at least
18:06dnolenpowrtoc: fancier things are possible with piggieback and austin but I haven't bothered
18:07glosolijustin_smith: just to be completely sure, in which memory ?
18:07powrtocdnolen: with an inferior-lisp-program set to something like "lein cljsbuild repl-listen"?
18:08dnolenpowrtoc: yep
18:08justin_smithglosoli: server
18:08mikkelghey folks! having trouble require'ing core.async:
18:08mikkelgCompilerException java.lang.RuntimeException: Unable to resolve symbol: pprint in this context, compiling:(clojure/core/async/impl/ioc_macros.clj:23)
18:09justin_smithglosoli: you can request a cookie store that is stored for client browser, but that is not the default
18:09mikkelgI don't get it, since if I clone core.async and compile the file, it works fine
18:09glosolijustin_smith: aaa thanks for taking time to explain!:) confusion is gone
18:09pbostrompowrtoc: piggieback is another option https://github.com/cemerick/piggieback
18:10powrtocpbostrom: thanks... I'm looking at it just now...
18:11powrtocon the subject of cljsbuild, is there a more up to date version that uses clojure 1.5.1 and the latest clojurescript release?
18:12dnolenpowrtoc: no just but it doesn't really matter - just specify your version of Clojure and ClojureScript
18:13powrtocdnolen: cool... that's what I've been doing
18:13dissipatenoncom, explain how a textbox resize would occur in your GUI framework
18:19Morgawribdknox: I've been playing around with light table 0.5 since I saw it's a new release, however I can't find the option to enable vim mode D:
18:20glosoliMorgawr: where is it???
18:20lazybotglosoli: Yes, 100% for sure.
18:20noncomdissipate: that is an interesting topic i'd like to discuss, but i MUST go sleep now :D it night here. next time we talk and maybe find something interesting, probably tomorrow..
18:21Morgawrglosoli: where is what?
18:21glosoli0
18:21glosoli0.5
18:21dissipateclojure programmers sleep? wow
18:21Morgawrglosoli: http://www.lighttable.com/
18:21glosoliMorgawr it isn't
18:22Morgawrglosoli: yes it is, it's version 0.5
18:22noncomahahaa, :) we hibernate
18:22glosoliMorgawr: Binary version 0.5.1..
18:22glosoliMorgawr: It's not LightTable 0.5
18:23glosoliMorgawr: Hmm I take back My words.... sorry man, must have cached links or something
18:24Morgawrglosoli: haha it's ok ;)
18:24glosoliMorgawr: I really do get only the older version on download... damn
18:28noonianlight table updates itself automatically doesn't it?
18:29glosolinoonian: not this time
18:29glosoliThis new version is awesome
18:30glosoliRainbow Parenthesis included man
18:30glosoliTHat's cool
18:32noonianawesome, I'll check out the new version then
18:33glosolinoonian: It's so damn nice and minimalistic, !!
18:33Morgawryeah the new version is awesome
18:33Morgawrjust gotta find out how to enable vim mode
18:34glosoliMorgawr: and change font lol
18:35Morgawrfont isn't that bad ;)
18:36glosoliMorgawr: Yeah, vim mode would be great though, it's somewhere hidden
18:37Morgawrlet me know if you find out how to enable it
18:37glosoliMorgawr: likewise
18:40futiledoes LightTable have structural editing yet?
18:41callenfutile: you mean paredit?
18:42callenfutile: If you do - no and it won't until the plugin functionality comes out.
18:42futilecallen: paredit is just one implementation of structural editing
18:42futileok
18:43glosoliKinda weird, CodeMirror got updated, and no way in gui to enable vim mode
18:43glosolihmm
18:48glosoliMorgawr: it is in behaviours
18:49noonianis the feature to change the skin between light, dark, and minimal gone?
18:49glosoliSeems like everything has been moved to behaviours
18:49glosoliNot sure how to get list of the ones available yet
18:50noonianI like being able to bring up the workspace with 1 keyboard shortcut as opposed to 2 or a click
18:51Morgawrglosoli: I don't know how behaviors work, I'll look it up, thanks
18:52glosoliMorgawr: neither do I xD
18:52nooniannice, can change skin (and other behaviors presumably) with the user behaviors config file
18:52glosolinoonian: yet not sure how to get available ones
18:52noonianstart typing behaviors in the command pane to access them
18:52noonianlight, dark, and minimal all seem to work, but minimal make the config file itself impossible to read
18:53glosolinoonian: can you explain more
18:53noonianit shows you 2 autocompletions of light and dark when you start typing in the string quotations
18:54glosoliI see now
18:54glosolineed to find a way to enable vim mode lol
18:54noonianI type ctrl + space bar to bring up the command pane on the right, then start typing behaviors and it will bring up 3 options, to reload behaviors, and user, workspace, and default behaviors
18:54noonianif you hit the user behaviors it has some initial code that you can edit
18:55glosolinoonian: yeah, though there should be something like "available behaviours" because Default ones does not list all of them for sure
18:55Morgawrholy crap this is amazing
18:55Morgawrthe themes and everything
18:55noonianoh cool, I hadn't checkout out the defaults, just the user ones theres way more stuff in there
18:56glosoliMorgawr: yeah lol
18:57glosoliMorgawr VI MODE!!!!
18:57glosoliworks lol
18:57Morgawr:D
18:58glosoliFonts!! man I am loving
18:59glosoliMorgawr: Nice I even got to set line height, this is good
19:37ddellacostaping cemerick
19:38`cbpztellman: ping
19:40callen`cbp: ping
19:40`cbpcallen: hihi
19:40callen`cbp: seemed like what the cool kids were doing.
19:40`cbpI just had a question about websockets in aleph :P
19:42callenddellacosta: what about you? :D
19:42ddellacostacallen: howdy
19:42callenddellacosta: hi! Have a question?
19:43ztellman`cbp: shoot
19:43ddellacostaoh, I wanted to ask cemerick about austin, specifically the use-case where you load it up in your *own* app *not* within the same repl session you have your app running from (which is the default example in the austin docs)
19:44ddellacostacallen: if you have any suggestions, I'm definitely all ears, but I figured it was relatively…niche. heh
19:44`cbpztellman: can I use ring/compojure and route a websocket?
19:44ztellman`cbp: yeah, it looks like a normal request to ring, if you wrap the handler in wrap-ring-handler at the outer context
19:45ztellmanthen you wrap the websocket handler in wrap-aleph-handler at the innermost context
19:45ztellmanthere's an example of this in the wiki
19:45`cbpok thanks a bunch
19:48callenddellacosta: asking in the open, even if you suspect only one person can answer is useful for a few reasons. It'll let people (like me) know what tools are being used, what people are interested in, and somebody willing to read the code could still help out.
19:48callenddellacosta: when I know one person can realistically answer it, I ask the question and then ping/cc afterward.
19:48callenalso some people have watches set on the name of projects they care about, although I suspect that's a minority.
19:48ddellacostacallen: fair enough…it was a tough call with this one, as I think this is a pretty esoteric thing at this point. But, point taken!
19:49ddellacostaI will take that approach.
19:49callenddellacosta: thanks for hearing me out, I know I ask things that can seem strange. :)
19:50callenddellacosta: I have a habit of researching tools I see people having a lot of trouble with. Usually either to fix them or to learn them myself.
19:50callenthat's why I use CCW and LT periodically.
19:50ddellacostacallen: no problem. It doesn't take much effort to think about how to use IRC to help the community better share ideas, which I think is the thrust of your argument.
19:50callenddellacosta: yep, you've got it exactly. :)
19:50ddellacostacallen: :-)
19:57ddellacostaclj-json vs. cheshire?
19:57ztellmancheshire's faster
19:57ddellacostaboth based on Jackson from what I can tell
19:57ddellacostaokay
19:57ztellmanand actively maintained
19:58ztellmanI thought there was a deprecation notice on clj-json
19:58ztellmanis there not?
19:58mischovThere's a clj-json?
19:58ddellacostaztellman: thanks. Yeah, I'm getting some weirdness now with clj-json, and was wondering if I should switch
19:58ddellacostaztellman: I don't see it on the git page: https://github.com/mmcgrana/clj-json
19:59ddellacostaah, but yeah, the last pushed version was from Nov. 2012: https://clojars.org/clj-json/versions/0.5.3
19:59ddellacostaalrighty then.
20:00callenddellacosta: most people use Cheshire.
20:00callenI should write a lein task that lets you compare the clojars pushing and github history of two libraries.
20:01callenand tells you which one it thinks you should use.
20:01ddellacostacallen: thanks, good to know. This is not a project I started, so I'm learning about some libs I haven't really used in the past, clj-json among them. I used cheshire on something else. We're moving most of this to edn anyways so it's moot I guess...
20:01ddellacostacallen: that would indeed be a handy lein task.
20:05malynIs Cheshire preferred over data.json? I have been using the latter...
20:05ddellacostaapropos of nothing: testing for user-agents on the server-side makes me irrationally angry.
20:06ztellmanmalyn: Cheshire is faster, and I'm not sure if other than correctness there's another dimension that can be used to compare json libraries
20:06malynztellman: Yeah, good point.
20:08hiredmanztellman: there are other features I would like a json lib to have, but as far as I can tell none of them have restartable encoding in to a fixed size buffer
20:08TimMccallen: How will it distinguish "abandoned" and "done"? By checking the issues?
20:10ddellacostaso, big diff is that data.json is pure Clojure, huh? Interesting
20:11hiredmanddellacosta: I would say the big difference is cheshire uses jackson which has had a lot of engineering time thrown at it
20:12ddellacostahiredman: right, so it would make sense that it would speed things up a bit.
20:13ztellmanalso is probably more robust to any edge cases that exist in the spec
20:13ztellmanthough that's hard to measure
20:13hiredmanthere was a talk done by an ebay engineer about comparisons they did of serialization formats in terms of speed, if I recall correctly jackson was competitive with binary formats
20:14TimMcHowever, Jackson will do some stupid things in the name of optimization, such as giving you Shorts instead of Longs when it can. :-(
20:16ztellmanTimMc: is it truncating numbers?
20:16majormajormajormhello
20:16ztellmanwhy is that stupid?
20:17hiredmanhttp://www.infoq.com/presentations/Dealing-with-Performance-Challenges-Optimized-Data-Formats
20:17TimMcztellman: It gives you the smallest possible representation of Number.
20:17ztellmandunno why that's bad
20:18ddellacostaisn't that what you want if you can do it without losing information?
20:18hiredmanyou'd prefer doubles?
20:18TimMcI don't recall the specifics, but it has caused some problems at works.
20:18TimMc*work
20:19TimMcYou know how there are all these Clojure programs that do all integer stuff with Longs?
20:19ztellmanlittle l longs
20:19ztellmanotherwise it's just Object
20:19ztellmanand is auto-coerced
20:19TimMcI guess it's not so much "stupid" as "violates the principle of least surprise".
20:21hiredmanI've seen bugs where some json libraries pedantically put a .0 at the end of all numbers, which cause other libraries to give you some kind of floating point number instead of some kind of integer, which broke equality checks, etc
20:25powrtocany idea why I'm getting same origin policy issues with my clojurescript browser repl, when accessing the page http://localhost:8080/ ?
20:26TimMchiredman: Well, that's definitely objectively worse...
20:29hiredmancomputers are basically terrible at dealing with numbers
20:30hiredmanit is sad because people say things like "computers are idiot savants, only good for dealing with numbers"
20:30hiredman"only good at" I guess
20:30AimHereBoth are perfectly grammatical
20:30hiredmanI'm pretty sure most introductions to binary arithmetic say something like that at some point
20:31callenTimMc: my to-do list? It's sorted. If something is done, it gets removed.
20:32TimMccallen: No, silly, the thing that compares libraries.
20:32AimHereIs it that the computers are bad at processing numbers or that they're bad at presenting the numbers to people? I'd say that the former is probably wrong and the latter is probably right
20:33callenTimMc: yeah, abandoned/done from unresponded to issues. It'll be comparative and explain the reasoning.
20:33callenTimMc: so it'll say, "library A has a lot of commits, so it might just be stable, but there are a couple of github issues that haven't been closed or responded to in ${X} months"
20:34callenTimMc: "Library B has fewer commits, but it's more active. Also the contributors curse frequently."
20:34callenincidentally, Raynes has a shake-n-bake library I can use for the GH integration :)
20:34TimMc"Also, the library author's username uses wAcKyCaSe so they are probably still snorting pixie sticks."
20:34callenTimMc: I snorted audibly, thank you.
20:37mischov"The library name would be a real word if you switched the ju for su. Do not trust."
20:38mischovRather.. "Do not encourage."
20:39callen"Author has '420' in their username and hasn't replaced the broken Leiningen default project test. Nuke from orbit"
20:40callen"lein-kibit reported 524 issues with the project, author may have used this project to learn Clojure"
20:51TimMc"Triple snail detected. Author is either too clever or insufficiently so."
20:52callenTimMc: @@@?
20:52TimMcyeah
20:52callenTimMc: that's like the c2 wiki, "triple-star programmer"
20:54hyPiRionIt's worse when you see (nth (iterate deref ...) n).
20:55callenhyPiRion: ...where did you see this?
20:55hyPiRionI haven't. I haven't even seen double snails yet. I'm just pointing it out
20:56TimMcYou've never used @@ in anger?
20:56brehautthat syntax looks just as shocked as is apropriate
20:58TimMcI see @@#' in tests all the time.
20:58TimMcBut tests are a different category of code, I guess.
20:59hyPiRionwhirr, I rarely put global state in vars
21:01TimMcgrep @@ -nRI --include=*.clj repos/
21:02TimMcpprint has a bunch of @@
21:02callenTimMc: I haven't used @@ in non-test code.
21:04TimMcSam Neubart wrote something interesting with a delay in an atom -- that involves an @@.
21:05callenTimMc: that sounds nifty - what for?
21:05TimMcFound it, "the Lock-less Monster": https://gist.github.com/samn/5843422
21:07callenTimMc: how apropos, I just got done writing code in Python to manage an OAuth access token lifecycle.
21:07callenof course, since it's Python, I'm fucked anyway.
21:08TimMcI don't think it's quite perfect, though.
21:08mmarczykbbloom: is there somewhere I could have a look at your ANF pass? (if I understood correctly that you have a poc)
21:09callenTimMc: even still, gives me something to think about.
21:09callenat present I'm using a global mutable variable and a timestamp expiry to manage it in Python.
21:09callenI can't say I'm entirely happy about that.
21:10TimMcI added a comment to the gist that explains what I think could go wrong.
21:10callenoh, and an accessor fn wrapper that manages cycling out and replacing expired values.
21:10ztellmancan I get the opinion of someone who's familiar with the internals of apply? bbloom, looking at you
21:11ztellmanassuming you're around
21:11callenon a quasi-related note, is bbloom's RestFn patch going to get merged?
21:11ztellmanwho knows
21:11callenthat would make some code of mine XX% faster.
21:11callenwhich would be, you know, cool.
21:12ztellmanjust noticed that in applyToHelper, we're calling RT.boundedLength: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFn.java#L154
21:12ztellmanand boundedLength doesn't check if the ISeq is Counted
21:12ztellmanso we're doing two passes through the first ~20 elements, always
21:12ztellmanI can't think of why this is necessary, but maybe I'm missing something?
21:23callenAre there any recommended Datomic schema/query libraries other than the default one?
21:24mmarczykcallen: not saying anything about "recommended" (by whom?), but https://github.com/rkneufeld/conformity is worth a look
21:25callenmmarczyk: thank you, I've been poking around for libraries to de-fang some of the prickliness of datalog for a coworker of mine who is going to be learning Clojure as they learn Datomic as well. wanted to make it a little less intimidating.
21:25callenthis is also the first Clojure project at this company >:)
21:26mmarczykoh, cool -- sounds fun
21:27callendevn: ping - need to ask you about datomic-simple.
21:29muhoohiredman: computers are good at turning electricity on and off, which makes them good at 1's and 0's. everything else, less so, depending on the software.
21:29muhooso i guess all numbers other than 1 and 0, gets to be a gray area :-)
21:32mmarczykztellman: I guess typically required arity is pretty small and so it's only 2-3 elements that are iterated over; otherwise no reason that I see fwiw, though it would have to return something like max(i + c.count(), limit + 1) in the counted case I suppose? (also, apply with extra args -- prepended to final seq -- uses cons for prepending, so not counted -- probably not a major consideration though?)
21:32mmarczykdnolen: ping
21:33ztellmanmmarczyk: agreed, but if you're applying a vector or something it's much faster and much less allocation
21:33mmarczykztellman: right, I'd expect that
21:33mmarczyk(much faster, I mean)
21:34benkaycallen where do you work?
21:34callenbenkay: the place with the really expensive rent.
21:35benkaycallen: i'm more curious about which company is dabbling in clojure
21:35benkaycompany/companies
21:35benkaycompany is/companies are (argh grammar)
21:36callenbenkay: I'm in the bay area, there are a goodly number of companies dabbling in Clojure out here.
21:47muhoocallen: brooklyn has SF beat on rent
21:47callenmuhoo: are you sure? I lived in Brooklyn a few years ago on $450 a month.
21:48callenwe had a pretty huge two bedroom big enough for four people
21:49callenztellman: way to take the air out of ibdknox's wings.
21:49ztellmancallen: I was genuinely curious, I haven't been keeping up
21:49ztellmanI use so little of what emacs can do, that's pretty much the one barrier
21:50callenztellman: last I heard, paredit happens whenever plugins do.
21:50callenie, community should implement it themselves.
21:50benkayPDX has most everywhere beat on dev salaries ;)
21:51callenbenkay: on being low?
21:51benkayyup.
21:51callenI always wondered why that was the case.
21:51benkaybecause dev salaries = f(rent)
21:51benkaywell, proportionate, but i don't know that character offhand.
21:52callenbenkay: I prefer to min-max by working in SF and living like a peasant so I can save money and escape California someday.
21:52benkaycallen: having spent a few years scraping by in NYC i've determined that (for me at least) QoL trumps most other considerations
21:53benkaynot about to sacrifice current experience of life for probabalistic future payoff
21:53callenbenkay: I have a problem finding companies that suit my personality outside of the bay area.
21:53benkaycallen: what is your personality and what kinds of companies suit it?
21:54callenbenkay: startups, companies with little/no hierarchy.
21:54callenbenkay: I'm the sort of person that would rather be kept up on what business/product priorities are and do the job of translating that to software myself.
21:55benkaycallen: well obvs you want a job at the new Salesforce plant out in the burbs then ;)
21:56callenI don't really know anything about Salesforce as a company, so I can't tell if you're being sarcastic.
21:56callenI'm very happy where I'm at right now though.
21:56benkayvery sarcastic.
21:56callenI'm in a nice little hive of anarchy. :)
21:56benkayread "plant" as "software manufacturing facility"
21:57callensaid anarchy is how I'm able to test Clojure and Datomic for a project.
21:57hiredmanabstract software factory factory
21:57benkayawesome!
21:57TimMchiredman: Would that be... a... startup incubator?
21:58callenTimMc: I think that's accurate.
21:59hiredmanI dunno, too abstract for me
21:59callenI hated incubating.
21:59callenT'was only good for the office space.
22:00benkayi've never understood the practice from the incubee's perspective.
22:00benkayi'll do my own networking, tyvm.
22:01callenbenkay: we really really needed free office space.
22:01benkayreally really equity sacrifice needed?
22:02muhoohuh, i read this lock-less-monster thing, and i'm wonder, why not memoize instead?
22:02benkaycallen: because lol move to portland and bike to each other's houses. (only sort of joking)
22:02callenmuhoo: expiry + auto-refresh?
22:02callenbenkay: we were all living in apartments together and car pooling to the incubator.
22:03callenthere were like 5 people, one of whom was an illegal immigrant, living in 2 two bedroom apartments.
22:03callenwe rotated who had to sleep on the couch.
22:03benkaycallen: holy smokes!
22:03callenI'm only just now moving out of one of those apartments to SF.
22:03benkaycallen: how much did those apartments cost?
22:05benkayeh, irrelevant I suppose.
22:05callenbenkay: $2000 apiece
22:05callenand that's in the cheapest neighborhood in mountain view.
22:05callenSF is worse.
22:05benkaydude.
22:06callenif my company ever opens a non-California office, I'm *out*.
22:06benkaywell duh you pegged your salary at those Yay Area numbers...
22:06`cbphaha thats more than i make!
22:07callenbenkay: *grins sheepishly*
22:07muhoohttp://gothamist.com/2013/08/08/skyrocketing_brooklyn_rents_close_i.php
22:08callenhttp://sfist.com/2013/03/07/map_average_rent_for_1br_in_san_fra.php
22:08benkayel oh el oh ******* el
22:08muhoosf is still marginally cheaper
22:08benkayi am renting a 3 br victorian in downtown portland for 1650
22:08callenmuhoo: only if you include all the neighborhoods nobody wants to live in.
22:08benkaywith a park across the street
22:08callenbenkay: there's only two neighborhoods (both remote) in SF with average single bedroom apartment rents lower than $1650.
22:09callenmore typical is more like $2200-3000 for a single bedroom in SF
22:09gdevcallen, if you ever move to Chicago I have a townhouse you can rent out for 1k
22:09callengdev: Chicago wouldn't be my first pick if I can finally escape Cali.
22:09TimMcMy wife had a $400 room in Somerville, about 4 miles from downtown Boston.
22:09muhooyep. a few people i know have since decamped to west oakland
22:09callenI'd probably go SEA, PDX, or AUS
22:10TimMcNow, that's pretty cheap for the area -- but $650-700 is still pretty low.
22:10gdevis AUS australia or austin?
22:10benkaySEA is a bland sea of suburbia
22:10benkaywith awful traffic.
22:12TimMcI think I'd like to see a map showing the ratio of salaries in some profession to cost of food.
22:12TimMcfood/housing
22:12muhoomy great dream is to buy some land out in coastal mendo or humboldt, put a trailer on it, and flip off the rest of the world
22:13muhooi just need one hit startup first :-)
22:14callengdev: Austin
22:14callenTimMc: well that's the problem, a lot of consumption for some people is flexible, for others it isn't. Having a family a lot.
22:16gdevcallen, really? I live in san antonio and drive up to Austin for clojure meetups, i don't see the appeal
22:16muhooyou can baseline it though. food and housing can be apples to apples for 1 person, then some relatively constant-ish factor to multiply it by per kid
22:16gfredericksaustin is the seattle of texas?
22:16callengdev: I'm sort of a gun nut. Texas appeals.
22:17muhoocallen: somalia then?
22:17TimMccallen: Soooo... not MA, then? :-P
22:18callenTimMc: I'd pick Somalia before MA.
22:18rlbgfredericks: possibly more like portland than seattle.
22:18rlbafaict
22:18muhooi hear you can buy them on the street, drive around with 50cal in the bed of your toyota pickup
22:21ToxicFrogIs there an idiomatic clojure equivalent to chaining the Maybe monad in haskell?
22:21ToxicFrogE.g. I have (->> input foo bar baz moby); any of those operations may return nil.
22:21ToxicFrogIf they do, I want the result of the entire (->>) to be nil rather than NullPointerException.
22:22arohnerToxicFrog: some->> ?
22:25ToxicFrogarohner: that is exactly what I was looking for! Thanks.
22:27holowhere is as-str?
22:28holo,(as-str :foo :bar) ; => "foobar"
22:28clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: as-str in this context, compiling:(NO_SOURCE_PATH:0:0)>
22:29benkaystr?
22:30holo,(str (name :foo) (name :bar)) ; not so compact
22:30clojurebot"foobar"
22:32brehaut,((comp (partial apply str) (partial map name) list) :foo :bar)
22:32clojurebot"foobar"
22:32`cbp(defn as-str [ks] (->> ks (map name) (apply str))) there you go
22:32brehaut(def as-str (comp (partial apply str) (partial map name) list))
22:33`cbpshowoff
22:34brehautif i was showing off, i'd have got a juxt in there ;)
22:34`cbpi was just wondering how to do that
22:34TimMcToxicFrog: clojure.incubator/-?> I think.
22:34brehautreplace the map with an apply juxt repeat
22:35ToxicFrogTimMc: already solved, I wanted some->>
22:35amalloybrehaut: extra fun: replace your map with mapcat
22:35brehautha
22:36TimMcOK, but that's new in 1.5.
22:37TimMc(Important if you're writing a lib.)
22:37TEttinger##(reductions + (repeat 20 0.1)) always nice to know that double precision sucks
22:37lazybot⇒ (0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999 1.0999999999999999 1.2 1.3 1.4000000000000001 1.5000000000000002 1.6000000000000003 1.7000000000000004 1.8000000000000005 1.9000000000000006 2.0000000000000004)
22:37TEttinger##(reductions + (repeat 20 0.1M)) works fine though, thanks clojure
22:37lazybot⇒ (0.1M 0.2M 0.3M 0.4M 0.5M 0.6M 0.7M 0.8M 0.9M 1.0M 1.1M 1.2M 1.3M 1.4M 1.5M 1.6M 1.7M 1.8M 1.9M 2.0M)
22:39holoyou are awesome.. i was just wondering where it was hehe
22:39futileoh hey holo whats new
22:40holohey futile.. same old same old
22:40futileright on, right on
22:42`cbpcopy paste code from chrome into emacs, C-c C-k, nrepl blows up and emacs goes "we cant figure out the coding system" =(
23:09gdev`cbp, I can't get it to blow up =o
23:09gdevwhat am i doing wrong?
23:10`cbpgdev: you're a) prolly not using windows and b) prolly pasting code with no non-english characters =P
23:11`cbpor c) not being delusional like me and trying to encode emacs files with utf-8
23:13gdevare you using emacs 23 or 24?
23:14`cbp24
23:14gdevwhat version of windows ?
23:14`cbp7 64-bit
23:16gdevokay, so i've tried to reproduce your environment. i have w7 laptop with emacs 24 and i'm pasting non-english chars from chrome to emacs with cc ck...wish me luck
23:16gdevwhat site are you copy-pastashing from?
23:17`cbpgdev gmail
23:17muhoowaaaay off topic, but i figured i'd ask: anyone else in the bay area seeing t-mobile data toggling on and off in an endless loop?
23:17`cbpso much effort just for some fireworks
23:19bbloommmarczyk: let me dig that up for you
23:19`cbpgdev: If emacs' coding-preference (or whatever) is set to utf-8 you should get some ugly weird \### chars instead of non-english characters when you copy paste from windows onto emacs
23:20bbloommmarczyk: https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L68-L186
23:21bbloom$mail ztellman sorry i missed you, let me know if you still need help w/ the apply stuff later
23:21lazybotMessage saved.
23:22`cbpkeyboard/locale might have to do with it too idk, maybe windows assumes everything is damn ascii or stupid latin-1
23:22`cbptl;dr: cant wait to buy a mac
23:23amacdougallNot to be that guy, but use Linux!
23:24amacdougallI'm on a Thinkpad running Xubuntu, and although there were some kinks to work out over time, it's been over a year and I'm quite satisfied.
23:24`cbpI would but I apparently suck, and can't build emacs because it segfaults randomly hehe
23:24amacdougallThat's really weird, but why do you have to build it from source?
23:25`cbpIt seemed like the only option at the time
23:25rlb`cbp: just install the emacs binary -- they're provided for windows now...
23:25amacdougallJust use a really mainstream distribution and use its package manager.
23:26rlb`cbp: http://ftp.gnu.org/gnu/emacs/windows/
23:26`cbprlb: my emacs segfaults on ubuntu not windows
23:26amacdougallrlb: I think he meant that it segfaults when he builds it on Linux, so he's using Windows. (?)
23:26rlbok, so that is strange -- which emacs emacs23 or emacs24?
23:26rlb(and have you tested without a .emacs?)
23:27rlbi.e. emacs -Q or similar
23:29`cbpI tried a lot of things for a long time, but it's been a long while and I don't remember