#clojure logs

2013-04-02

00:00n_bfbernier: It's a threading macro. The documentation explains it better than I could
00:00n_b,(doc ->>)
00:00clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
00:01n_bEssentially it takes each form and recursively inserts it as the last argument into the next form
00:43Raynesjhn: Psh, technomancy resolved it. You just poked it. Braggart.
00:48technomancyeh?
00:48technomancythe clojure-test-mode thing? I don't think I actually fixed anything.
00:49jhnRaynes: lolwut. Someone else PM'd me after seeing that and I just pointed him to technomancy's instructions on the repo.
00:50Raynestechnomancy, jhn: I was trying (and apparently failing) to tease jhn about a tweet he made a few minutes ago.
00:53technomancyI see
01:20john2xcan I use clojure libraries in clojurescript?
01:24scottjjohn2x: generally not unless they've had (often minor) tweaks applied to make them compatible, afaik
02:13john2xscottj: oh ok. does clojurescript have its own repo for libraries? I wanna check out the ecosystem.
02:14john2xor does it also use clojars.org?
02:23scottjjohn2x: idk, some are on clojars, here's my personal non-exhaustive list: http://jaderholm.com/paste/projects-cljs.html
02:57john2xscottj: thanks!
03:24RaynesMy internet is so fast.
03:24RaynesWhen I started writing Clojure it was on a dialup connection.
03:25rcgRaynes, that makes clojure actually sound much older than it is ;)
03:26RaynesYeah, I was just in a very rural area and uneducated about mobile broadband.
03:28rcgaye, well nonetheless fast internet is a pleasure
03:30winkextra-lazy-seq
03:50tomojno, of course it won't work to special case (bound-fn [*vars* *i* *need*] ...) !
03:50tomoj:(
04:01tomojmaybe we just need to rewrite clojurescript.test so that it doesn't use any dynamic vars..
05:06supersymclojure is such a nice vehicle as it gives me many little epiphanies ... all roads eventually would lead to a lisp anyway, if you care about your programming I guess :)
05:08supersymbut the shift in thinkin it requires coming from imperative world to functional and then what it gives back... wooa ^^
05:08supersymanyway preaching to the choir
05:09andyfingerhutand as is often the case, much of the choir is sleeping :)
05:22kalasjohnny2000...fanfares in the distance
08:08supersymandyfingerhut: yeah lots of USA people I bet :P
08:13supersymwhy is that anyway, or is it my impression, that many in the Clojure world are native Americans?
08:13supersymquestions, questions, too many to answer but internet helps :)
08:14hyPiRionsupersym: it's not your imagination
08:22supersymis there a general consensus on the matter? surely people must have spoken about this before
08:22clojurebotmin people is 5
08:23hyPiRionwell, it's true that the majority are American, but what is there to talk about, really?
08:25supersymlol
08:25supersymoh nothing I just thought there would be an underlying linguistical nature to it...of course it could also be coincidence :D
08:25supersymnever mind hehe
08:25hyPiRionCertainly I'd like to have more Norwegians using Clojure, but I'm not sure how to do that.
08:26supersymI'll be a good boy and go back top work
08:26hyPiRionMost certainly it's because Rich is living in the US himself
08:26supersymthats what I thought also
08:26hyPiRionLanguage is used by people he knows, and the people who know them uses it etc.
08:27supersymso it spreads
08:27supersymPython was made by a dutch guy
08:27supersymso they teach it at uni here because of that?
08:27supersymPerhaps...
08:27hyPiRionsupersym: Well, they have it over here too. It seems like Python is very well established in Europe
08:28hyPiRionthen again, Python is an old language compared to Clojure
08:28supersymyeah
08:28mpenetthere are quite a few clojure users in EU, it's mostly concentrated in the UK and around Germany it seems
08:28supersymand like you said, it has to spread too
08:28mpenetbut not a lot of them are often on irc, this might give you the wrong impression
08:29supersymI'd say
08:30hyPiRionmpenet: Also, since I a messed up circadian rythm, I may end up speaking with more americans simply because Europeans aren't generally awake at that time :p
08:30hyPiRion/s/I a/I have a/
08:30supersymruby probably is more popular in Japan than here
08:30mpenetsame here :p
08:39ebaxthyPiRion: With regards to getting more Norwegians using Clojure. we need success stories and people talking
08:46hyPiRionebaxt: at Java conferences, or other places? (e.g. JavaZone)
08:47ebaxthyPiRion: JavaZone, NDC, meetups etc. But more importantly we need examples to point to in order for larger enterprises to not shoot down the idea of using it
08:48hyPiRionebaxt: ah, okay
08:49ebaxthyPiRion: Just look at Scala, there are plenty of companies using it in Oslo. Conferences like flatmap is also important
08:51hyPiRionebaxt: Right, what I wonder about is whether the gap is too large (oh lord, parentheses, functional programming, immutability) to just jump from Java directly to Clojure
08:52hyPiRionScala is less frightening in that sense
08:52hyPiRionCertainly, success stories is great, but I wonder if that's enough to pull the enterprise that way
08:54ebaxthyPiRion: Sure, that's true, but the Scala community has done a good job of marketing specifically to the enterprise as well.
08:56no7hingconcerning cheshire, why does this (parse-string "{\"jsonrpc\":\"2.0\",\"result\":\"{}\",\"id\":null}}" true) result in {:jsonrpc "2.0", :result "{}", :id nil} ?
08:56no7hingaka the map stays a string?
08:56jcrossley3ebaxt: it's not just marketing. java devs *really* value strong type-safety.
08:57mpenetno7hing: it's not a string anymore, look at the keys
08:57hyPiRionjcrossley3: Well, I think that really depends on the developer. I don't think that many people think that hard about it
08:57no7hing@mpenet: i would expect :result to be {} and not "{}"
08:57mpenetoh, "result"
08:58mpenetbecause it's passed as a string in it's json form
08:58mpenet"{\"jsonrpc\":\"2.0\",\"result\":{},\"id\":null}}" would work
08:58mpenetthere is no quote on object litterals in json
08:58no7hingoh damn
08:58no7hingsorry me
09:00jcrossley3hyPiRion: i'm constantly surprised by it, too.
09:01hyPiRionebaxt: Oh, I forgot to reply. True, the Scala guys are really awesome at marketing their language. Clojure (the community, perhaps?) could be better at that.
09:01ebaxtjcrossley3: I think there are plenty of programmers working in large enterprises that would love using a more expressive language, not necessarilly strongly typed. I know of many companies using more and more Groovy for instance.
09:02jcrossley3ebaxt: i agree strongly, but it's been my experience that the ones who value the tooling that strong-typing affords them are way more vocal.
09:03ebaxtjcrossley3: That's my experience as well. Which is why I think it's important that we speak up as well ;)
09:03mpenetI doubt clojure will ever reach as much popularity as scala, its the syntax and mix oo/fp that makes it easier at the beginning and often more appealing to java devs
09:04mpenetimho
09:04lucianjcrossley3: if java devs really valued type safety, they wouldn't be using java :)
09:05jcrossley3lucian: s/type safety/tooling/ :)
09:06hyPiRionlucian: Haskell to the rescue!
09:06lucianhyPiRion: sure, that's what they'd use if they really cared :)
09:06lucianscala isn't that far off, the syntax is just crazy
09:06ebaxtmpenet: I think there is a niche market for Clojure in the enterprise, but I agree that Scala has the "advantage" of OO that makes it less scary.
09:06luciani think it's purely syntax
09:07lucianpeople hate python for similar reasons
09:10hyPiRionlucian: hm, is the enterprise hating python? I must be in this parallel universe then.
09:10lucianhyPiRion: i meant it as an initial reaction
09:10hyPiRionoh, okay
09:11mpenetsame problem with erlang, it solves some problems beautifully, but it's scary to the newcomers
09:12lucianto be fair, erlang's syntax is just stupid
09:12hyPiRionlucian: well, that's subjective, isn't it? :)
09:12lucianhyPiRion: not at all
09:13lucianit has different terminators for the same thing in different contexts!
09:13luciangood luck swapping two lines
09:13Pupniklisp flavoured erlang to the rescue!
09:13lucianelixir is particularly nice
09:14hyPiRionmpenet: Erlang has a very steep learning curve if you want to build an OTP-compliant app from the beginning
09:17hyPiRionI think Rich had it right when he came up with the simple/easy difference. People really value something which is easy at first sight, and aren't usually able to see (or value) the productivity of something on a longer time scale.
09:18mpenetabout clojure, I just encountered this issue: having to handover a clojurescript app to a js/frontend developer. I could read "omg" in his eyes when he opened the source the first time. and to be honnest this is a real issue with clojurescript at least.
09:18borkdudeis there a way to do (binding [*foo* bar] (some expr) (some other expr)) in the REPL, so I can do (some expr) and see what it returns, step by step, so not in all one binding expression?
09:18mpeneton the backend it's another story
09:19lucianmpenet: the other problem is the silly dependency on the jvm :(
09:19mpenetlucian: you mean for clojurescript?
09:19lucianyes
09:19lucianwell, for clojure too
09:19lucianbut it's a bit more forgivable there
09:20mpenetlucian: well without it, no google closure
09:20luciandon't care much about that
09:20mpenetlucian: you should, unless you want to serve mb of js files
09:20lucianat least not early in development
09:20lucianhaving to wait for the stupid jvm to spin up every single time i want to do something with lein is infuriating
09:20lucianthat's why i always give up on trying to use clojure(script)
09:21mpenetlucian: lein cljsbuild solves that pretty much
09:21lucianlanguage is nice, but the runtime is fucking useless
09:21mpenetlucian: or repl dev
09:21lucianmpenet: not really
09:21mpenetlucian: I find it fast enough in most case
09:21lucianit takes more than 2sec to start up, always
09:21lucianpython takes a few ms
09:22mpenetlucian: you just start it up once, "lein cljsbuild auto"
09:22lucianright, and it takes about 10sec to start up once
09:22lucianand several seconds to notice it has to compile things
09:22hyPiRionlucian: You may want to watch out for https://github.com/halgari/clojure-metal
09:22mpenetlucian: yeah but once a day, it's fine, eclipse probably takes longer to launch :p
09:22lucianhyPiRion: i'd be happy with self-hosted clojurescript
09:22Pupniklucian, use clojure-clr instead?
09:22lucianmpenet: that's another thing i don't use because of latency
09:23mpenetlucian: I dont use eclipse either, but this was an example, 10secs in a day is nothing
09:23lucianPupnik: is that still alive? i thought it had bitrotted
09:23lucianmpenet: it is if the alternative is 0sec
09:23hyPiRionlucian: well, when we get it up to production value, I'll certainly start to port Lein over
09:23lucianhyPiRion: that would make me very, very happy :)
09:24lucianas for a clojure vm, i think a RPython one would have a better chance of actually making it
09:24Pupniklucian, https://github.com/clojure/clojure-clr/commits/master plenty of stuff going on
09:25hyPiRionlucian: right, a restricted clojure vm?
09:25hyPiRionor, a subset of clojure?
09:25lucianhyPiRion: one built on RPython? no, it'd be a full vm, with a jit for free
09:25lucianif someone were to build such a thing
09:26lucianPupnik: that's nice. i guess mono's startup time is not as terrible
09:26hyPiRionlucian: Timothy already did some stuff on top of pypy
09:27hyPiRion(halgari or tbaldrige, or what he goes by these days)
09:27blrmhttps://github.com/halgari/clojure-py
09:28lucianthat is probably an easier path, since there already is a Python VM written in RPythonn (PyPy)
09:29lucianthere are basically two things i'd like to use clojure for: 1) replacing javascript and 2) replacing java on android
09:29lucianthe first will be easy when clojurescript is self-hosted
09:29lucianthe second, i don't know. clojure bootstrap on android still takes many seconds
09:30hyPiRionlucian: Given you do no eval/resolve/etc, and perform some tree shaking, that shouldn't be impossible if one tweak AOT compilation.
09:31hyPiRionBut that's has a long way to go, sadly.
09:31lucianhyPiRion: the latest effort i've seen is http://nightweb.net/
09:31lucianbut even on my nexus 4 it takes 5-10s to start up
09:31lucianat this point, xamarin or scala are still the only other options i consider reasonable for android dev
09:32hyPiRionheh
09:34qz_lucian: scala suffers from same startup time problems plus slow compilation :)
09:36lucianqz: the few android apps i've seen appear to start up fast enough
09:39borkdude,(apply map vector nil)
09:39clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map>
09:40borkdudeis this sane behavior?
09:42hyPiRionborkdude: yes
09:43hyPiRion,(map vector) ;; is essentially what you do
09:43clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map>
09:43borkdude(apply + [1 2 3]) == (+ 1 2 3), (apply + nil) == (+ … well, nothing to see here?) like that?
09:44hyPiRionright
09:45hyPiRion,[(apply map vector nil nil) (apply map vector [[]])]
09:45clojurebot[() ()]
09:48borkdudewhat is the reason again why you have to define clojure functions in a certain order? (not that I have problems with it, but before I get questions)
09:49asteve,(/ 3 1)
09:50clojurebot3
09:50asteve,(/ 1 3)
09:50clojurebot1/3
09:54scottjborkdude: I thought the reason was clojure compiler is single pass, but the actual reason might be more subtle.
09:57noidiborkdude, https://news.ycombinator.com/item?id=2467359
10:00borkdudenoidi thanks
10:09`fogusscottj: Clojure's compiler is not single pass
10:24devngood morning all
10:25rbxbx_devn g'morn
10:27Guest98868is there an idiomatic way to use a different kind of equality? my first thought was to rebind =, but it's not declared dynamic. but defining some protocol or other function wouldn't be used by say (some #{foo} [bar baz])
10:33sundbpanyone using expectations for testing around?
10:40gfredericksGuest64100: changing the meaning of clojure.core/= would be pretty nonstandard. Changing the meaning of the = symbol inside of some namespace or lexical scope is totally possible
10:41danielglausergfredericks: I saw a presentation that showed you could do anything with macros
10:45gfredericksdanielglauser: I think I specifically pointed out this sort of thing as an example of what you can't do with macros
10:45borkdudequestion: I guess (if … (swap! …)) is not good, since between the calculation of the conditional and the swap, some other swap might have happened. what is the common way to solve this?
10:46borkdude(swap! (if … ….)) ?
10:46danielglausergfredericks: I know, just razzing you :)
10:46gfredericksborkdude: wat?
10:47gfredericksborkdude: the conditional is based on the value of the atom?
10:47borkdudeborkdude yeah
10:47borkdudegfredericks yeah
10:47gfredericksborkdude: then you do that logic inside the swap function
10:47borkdudeexample:
10:47gfredericks(swap! a #(if (foo %) (bar %) (baz %)))
10:48borkdudegfredericks this is not good, I should have used swap! anyway: https://github.com/borkdude/tictactoe/blob/master/src/tictactoe/model.clj#L29
10:48borkdudegfredericks this is how I've done it now https://gist.github.com/borkdude/5292814
10:49borkdudegfredericks play! is near the bottom of the file now
10:52borkdudegfredericks in this case it doesn't matter much, because the session is updated within one thread, but in general
10:52borkdudegfredericks it would mean though, that a swap would always happen, either with a new value or the old value just gets stored back
10:53gfredericksI think that's fine
10:54borkdudegfredericks what, that a swap would always happen?
10:55gfredericksyeah
10:55gfredericksthough if this is all single-threaded, maybe an atom isn't what you want to be using
10:56borkdudegfredericks I'm using noir.session
10:56borkdudegfredericks and that is using an atom
10:56gfredericksoh right
10:56gfredericksnm then
10:56borkdudegfredericks what alternative would you have in mind? I used an atom before I made this a web app
10:57gfrederickshwelp if you have some "state" you could just write functions that transform it. I guess it's the state monad really.
10:57gfrederickser, burrito
10:58borkdudegfredericks the web app monad - I could do it, but I'd have to trust the user not to manipulate his data ;)
11:00borkdudegfredericks I could also use ring sessions which are more functional, but I doubt if that would make this better
11:23TimMcborkdude: That's what cryptography is for.
11:24gfrederickswell there's two "non-stateful" approaches to session middleware
11:24gfredericksone is to put all the data in the cookie which I imagine is what you're referring to
11:24TimMcMaybe you should thread the entire database state through all requests.
11:24gfredericksthe other is to have server state, but handle it all in the middleware so that the actual ring handler doesn't need to do any side-effects -- it receives the current session as part of the request map and can change it in the response map
11:26borkdudegfredericks I think I have used the latter one. but how is the first not stateful?
11:26gfrederickshaha
11:26gfredericksborkdude: not stateful from the server's perspective
11:26borkdudegfredericks I haven't used it now, but some other time
11:26borkdudegfredericks right
11:27borkdudegfredericks other way would not to use cookies but codify the state in some hidden field in the form
11:30borkdudegfredericks I think Microsoft does this in ASP.NET or smth
11:36TimMcIt's really irritating.
11:36mpenet borkdude: they call that PageState... heretics. You used to end up with 100s of KBs of pagestate per page on some apps.
11:36TimMcAs a user, that is.
11:37borkdudempenet In my memory they called it ViewState but they might have changed it
11:37mpenetright
11:37TimMcDeath to timestamps.
11:38TimMc(It really bugs me when a form submission becomes invalid just because I let the page sit open too long.)
11:38TimMcNever mind, that can actually be an issue where ever the state is kept, if it expires.
11:38geckosWhat the last dot means at (java.util.Date.)
11:38geckos?
11:39borkdudegeckos creation
11:39borkdudegeckos calling the constructor
11:39geckosborkdude: thanks
11:39nDuffgeckos: It's syntactic sugar for (new java.util.Date)
11:59squidzcemerick: i'm using youre shorleave remote libraries and currently have the problem of returning a javascript array from one of the remote functions. Do you know an easy way to do this? For example, my remote funciton returns a list of strings ("first "second) and when I call that remote clientside, I want to be able to get a javascript array ["first" "second"]
12:00geckosnDuff: I see... thanks again.. I'll stay with new aproach since I'm not an cloj guy, :-)
12:00squidzi mean ["first", "second"]
12:10tickingclojures contribution policy is like a open halway, stuffed with barbwire, in thereory you can get to the end
12:13joegalloticking: right, it'll tear the very meat from your bones, but you can get there in theory ;)
12:14nDuffNot so annoying for anyone who attends the conferences -- CAs sitting out ready to sign.
12:15joegallothe CA is just the moat, though, there's more stuff after that
12:21technomancya miniboss
12:34gfredericksI wonder what the clochure contribution policy is like
12:34technomancy(constantly :rofl)
12:34technomancyI was hoping to get some good joke pull requests for lein-xml
12:35technomancymaybe someone all "XML is too strict; can we use SGML instead?"
12:35joegallodamn, that would have been a good one
12:35joegalloi'm sorry, technomancy
12:36technomancythere's always next year
12:36Foxborontechnomancy: i am still not sure if lein-xml was a april fools or not ._.
12:37hyPiRionlein-png: Whenever you need to ensure that project.clj is syntax highlighted the same on all machines.
12:37hyPiRionproject.png
12:38gfredericksneed to make a change? photoshop has never been more user
12:38gfredericksfriendly
12:38technomancyhyPiRion: lein-piet
12:38hyPiRiontechnomancy: hah, that would actually be fancy
12:39hyPiRionIt's rather simple too, so why not
12:39hyPiRionwell, easy*
12:40technomancyhyPiRion: well, you have twelve months now =)
12:40hyPiRionFoxboron: After the survey, we found out that many people use Java or Java+Clojure with Leiningen, and since it's usually common to use XML (maven uses it, etc) we figured out that it would make sense to use xml for lein
12:40gfredericksxmleiningen
12:41hyPiRionIt's a plugin for now though, since it breaks compability.
12:41jeremyheilerI woudln't be surprised if someone successfully uses it as leverage to get Clojure into their shop. "See, we can even use the our existing pom.xml!"
12:41FoxboronhyPiRion: and the 1st of april date was not planned at all :P?
12:42technomancyjeremyheiler: I almost put a note saying explicitly that pom.xml syntax was not the goal, but I thought it might make it look too realistic.
12:44jeremyheilertechnomancy: Haha.
12:47tupi`hello
12:54tupi`i am making my fisrt steps using clojure to build small scripts using imagej/fiji anyone here is also doing digital image processing in imagej/fiji and clojure? is this a chat room i can ask Q related to this specific clojure useage?
12:55nDufftupi`: We may not know the library, but we still may be able to answer questions about problems you're having.
12:55hyPiRiontechnomancy: Well, better start today then: https://github.com/hyPiRion/ariel
12:55tupi`nDuff: thanks
12:57tupi`i have one Q to start width. please note that i am an experienced lisp/scheme programmer, but no java knowledge at all, so i suffer a lot :)
12:57technomancyhyPiRion: fun times
12:57tupi`also, fiji says they use clojure 1.3, this could be a problem i guess. here the Q:
12:57hyPiRiontupi`: You don't suffer, you're free from the chains man
12:59tupi`suppose i do (import ... '(ij Menus)) then (let [commands (keys (. Menus getCommands)) ..
12:59tupi`it works, but this does not:
12:59tupi`(let [commands (keys (.getCommands Menus)) ...
12:59tupi`
12:59tupi`and i am particularly interrested in the lisp-ish way of writting code
12:59dnolenlynaghk: http://trifacta.github.com/vega/
13:00nDufftupi`: Sounds to me like getCommands is a static method, no?
13:00nDuff(Menus/getCommands)
13:00nDuff...if that is in fact the case.
13:00tupi`checcking
13:01tupi`it says it's in static java.util.Hashtable
13:01nDuffNot its return value, the method itself.
13:01tupi`public static java.util.Hashtable getCommands()
13:01nDuffExactly. So it's the syntax I gave earlier, (Menus/getCommands)
13:02nDufftupi`: http://clojure.org/java_interop#Java Interop-(Classname/staticMethod args*)
13:03tupi`ah: this clarifies, tx
13:05lynaghkdnolen: yeah, I saw that on the twitters this morning; Jeff and I talked about it briefly at VisWeek last fall---that kind of thing is in the air
13:05lynaghkdnolen: visualization + data all the thigns, I mean =)
13:21tomojcemerick: saw your post about async testing for clojurescript.test -- given the lack of bound-fn in cljs, would we need to eliminate all dynamic vars, including the proposed *done*?
13:30tomojalternatively, people will need to manually carry those vars over any async boundary in the code under test? hoping I'm confused..
13:31steves-ercIs there a modulus relation in clojure.core.logic.fd or does anybody know how you would make one?
13:32tupi`i am very suprised and curious to read, for example, the setForeground java manual, where it says public synchronized void setForeground(Color c), where i'd expect 2 parameters. in my little test code i did try and replaced a (doto blabla (.setForeground (Color/red) by (.setForeground blabla (Color/red)) and it works [of course]. so how do i know the exact parameters i nedd to pass to write lisp-ish code?
13:33tupi`[i realize it's a java quiz but...]
13:37dnolensteves-erc: there's isn't one
13:38tupi`i mean may i assume that the doto macro always expands its code inserting the instance-expr as the first arg of all expressions ?
13:38technomancytupi`: no need to assume; try it with macroexpand-1
13:39dnolensteves-erc: http://www.swi-prolog.org/man/clpfd.html, supported by SWI so we should probably consider it.
13:39technomancy,(macroexpand-1 (doto 'my.namespace (require) (in-ns) (prn)))
13:39clojurebot#<FileNotFoundException java.io.FileNotFoundException: Could not locate my/namespace__init.class or my/namespace.clj on classpath: >
13:39tupi`technomancy: of course! tx
13:39technomancyoops
13:39technomancy,(macroexpand-1 '(doto 'my.namespace (require) (in-ns) (prn)))
13:39clojurebot(clojure.core/let [G__74 (quote my.namespace)] (require G__74) (in-ns G__74) (prn G__74) ...)
13:40saolsen_dnolen: would it be some recursive thing with *?
13:43S11001001,java.awt.Color/red
13:43clojurebot#<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)>
13:45hyPiRion,(import java.awt.Color)
13:45clojurebot#<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.awt.Color>
13:46dnolensaolsen_: no it probably be preferable to provide an optimized version of some kind. opened a ticket - http://dev.clojure.org/jira/browse/LOGIC-128
13:48saolsen_dnolen: cool
13:52cemericksquidz: use clj->js
13:53squidzcemerick: okay thanks ill give it a try
13:55cemericktomoj: I don't know. That whole topic is entirely theoretical to me at the moment, so heft that salt liberally.
14:08technomancyhas anyone experimented with a transactional require?
14:10gfrederickstechnomancy: environment as a value?
14:10gfrederickswouldn't that require being able to unload code?
14:11technomancygfredericks: not if the ns map was a ref, I think?
14:11gfredericksso we're at _least_ hoping there aren't top-level side effects
14:12technomancygfredericks: of course; you can easily break transactionality in any ref if you do something stupid
14:13technomancyI don't think defonce would be hard though
14:13technomancyoh yuck; it's all jabba code
14:13gfredericks(defmacro deftwice ...)
14:13technomancylol
14:13technomancyyeah, so mappings in Namespace.java is just an AtomicReference
14:14technomancyif I knew Java maybe that could be a seajure hack
14:15gfredericksif you're not using your own fork of clojure you're not doing real work
14:15technomancysrsly
14:16gfredericksporting the java code to scala could have been a decent project for yesterday
14:16gfredericksor groovy?
14:16nDuff*shudder*
14:16nDuffgfredericks: Scala, please. Groovy is awful.
14:17cemericktechnomancy: not for long; the happy path is straightforward. The further you stray from that, the more it's like swiss cheese.
14:17gfredericksok groovy it is.
14:17nDuffgfredericks: ...if you don't grok _how_ awful, take a look at the bytecode it generates.
14:17gfredericksnDuff: I've never even used it
14:17nDuffgfredericks: ...it's reflect-o-riffic; makes sloppily-written Clojure look like the pinnacle of efficiency.
14:18technomancycemerick: sorry, I don't follow; you're talking about side-effects at the top-level?
14:18gfredericksI also was wondering what cemerick was talking about.
14:19cemerickI was responding to technomancy's original question as to whether anyone's experiemented
14:20gfredericks"straightforward" meaning "using clojure the normal way"?
14:21cemerickgfredericks: "if you're careful"?
14:21cemerickstraightforward to replace the atomic references with refs
14:22cemerickof course, you have a serious bootstrapping problem, so you have to use clojure to load an alternatively-rooted clojure
14:22gfrederickscemerick: okay I think I totally misparsed the sentence
14:22gfredericksas "Going straight-forward is the only happy path."
14:23gfredericksdo not go left or right.
14:23cemerickotherwise, you'll only ever end up right where you began, eventually
14:23gfredericksrandom walks in >2 dimensions don't return
14:24cemerickpay me no mind, I'm trying to pick up the pieces of my life after trying vim seriously this morning
14:25Glenjamindoes one of these bots have a "tell <someone> <message>" feature?
14:26RaynesYes.
14:27Raynes$mail amalloy Hi. Now you have to read your messages.
14:27lazybotMessage saved.
14:27amalloy$timer 1 0 0 Raynes, you're a jerk
14:27lazybotTimer added.
14:28gfredericksamalloy: slingshot seems to like the &naming-convention with their &throw-context
14:28RaynesGlenjamin: So $mail person message and then that person gets a NOTICE every so often that they can run $mail to get their messages.
14:28gfredericksamalloy: is it gross for an anaphoric macro to check if &foo is used in the body and not bother to set it up otherwise?
14:28`arrdemhum... can anyone tell me why nrepl is vomiting on this deftype? https://www.refheap.com/paste/13215
14:29Glenjaminah cool, was expecting something that'll just fire a message next time it sees activity from that person, but that'll work
14:29amalloygfredericks: for sure that is bad
14:29Glenjamin$mail xeqi haven't found any other bugs, should be good to release
14:29lazybotMessage saved.
14:29amalloyyou can't tell if some other macro inside the body will expand to include &foo, for example
14:30gfredericksamalloy: and it's also bad to try to macroexpand-all the body before checking?
14:30amalloyif you want, you can bind &foo to a delay of the expensive work, and then symbol-macrolet it to forcing the delay
14:30gfredericksthat's kind of deferring the tactic to symbol-macrolet
14:30Glenjamindefinterface, haven't seen that before =/
14:31amalloydeferring the macroexpand-all?
14:31amalloyit is, but symbol-macrolet will do a much better job of it than you will
14:31`arrdemyeah it's relatively new to me as well and I've been having bad luck with it thus far
14:32gfredericksamalloy: you are a wise man of macros
14:34amalloygfredericks: i hope to one day accumulate enough reputation as a macro wise man that someone will order me a tribal shaman mask on amazon
14:39gfredericksthat is perhaps the most efficient way to make a tribal shaman mask show up at your door
14:44Glenjaminsay i have a working application, that contains a protocol. And some third parties implement that protocol. And I want to add another method to it. Is there a good way to do this without breaking existing third party code?
14:51jeremyheilerGlenjamin: Protocols are unlike Java interfaces in that not all methods need to be implemented. So technically you're fine if you only call the new method from types that have it implemented. Are you worried about calling the new method on existing extentions of the protocol?
14:52Glenjaminyep
14:53Glenjaminthe specific case is a test runner reporter for speclj, i'm adding a new type of message
14:53Glenjaminso i want to call it if it exists, but not if it doesnt
15:00gfredericksseparate protocol maybe?
15:01Glenjaminyeah, thats where i'm leaning
15:01Glenjamincan i extend the old one in some way?
15:02gfredericksnope
15:08jeremyheilerGlenjamin: I suppose you could use clojure.reflect on it.
15:12amalloyjeremyheiler: no. that is more problems than solutions (for this problem; nothing wrong with clojure.reflect in general)
15:15jeremyheileramalloy: I suppose.
15:18GlenjaminI'll just add an extra protocol for the new method specifically i think
15:18jeremyheilerGlenjamin: You could create a new protocol just for the new method. I guess the solution you use depends on if you want that your code to be that fine grained, or if you eventually expect all clients to adjust. (I am assuming just changing the version number your thing is not idea.)
15:18jeremyheilerHeh, cool.
15:19jeremyheilerno ideal*
15:19jeremyheilerugh. "not ideal"
15:19Glenjamini'm not actually sure how many third party reporters are there so it might be as easy to just break them
15:27lazybotRaynes, you're a jerk
15:28Raynes$kill
15:28lazybotKILL IT WITH FIRE!
15:28gfredericks(inc lazybot)
15:28lazybot⇒ 17
15:28Raynesgfredericks: I just remembered that I blew you off yesterday,
15:28gfredericksRaynes: laser has made me want static types
15:28Raynesgfredericks: Are you still having those issues?
15:29gfredericksI think I'll be okay now. I'm just always getting confused about when I have a node or a collection of nodes or a zipper and what I'm supposed to do in each situation
15:29gfrederickse.g., I call parse-fragment and I get a zipper I think. When I call fragment on that it turns into something else that I can't call fragment on again.
15:29gfredericksso I have to call zip to turn it back into a zipper?
15:29gfredericksI need a hoogle so I can look up the type signatures
15:30Raynesfragment should be returning a collection of zippers which you should be able to pass to another fragment.
15:30gfredericksa collection of zippers, that's the fourth type :)
15:31RaynesGive me a link to your code again and I'll try to simplify and explain it.
15:35gfredericksRaynes: https://www.refheap.com/paste/13189
15:35gfredericksmy most common error is 'Not a valid node' followed quickly by NPEs
15:38amalloygfredericks: i don't think you want to parse-fragment there: a fragment is a collection of nodes, and therefore has multiple "content"s
15:38gfrederickshow do I parse a single node?
15:38amalloyl/parse? it's what you did with page
15:39gfredericksno that's for whole documents
15:39gfrederickswill add <html> and such
15:39amalloyugh
15:39amalloywell, i don't actually know how to use laser
15:41gfredericksI got it to work by I think passing the thing from parse-fragment through the fragment function; it got harder when I wanted to prepend something.
15:41hyPiRionRaynes: I think that was a lazybot timer
15:42amalloyhe knows :P
15:42gfredericksI've gotten to the point where I can make any given thing work by twiddling the data types hard enough, but it doesn't help me avoid the next problem, because I still don't understand what the workflow ought to be (i.e., why I keep ending up with the wrong types)
15:42hyPiRion$timer 20:32:05 All hail our overlord rhickey.
15:42lazybotTimer added.
15:42Raynesgfredericks: Looking.
15:42RaynesI just typed git repl
15:42Raynesx)x
15:42Raynesx_x*
15:43hyPiRionHeh, I tend to write /chmod * +o when I want to give people op
15:43Rayneslol
15:44Raynesgfredericks: That code works fine for me broseph.
15:44Raynesgfredericks: The current version is 1.1.1. Are you using that? Seriously dude, I break shit constantly. You've got to use the current version.
15:44TimMc:-(
15:45gfredericksRaynes: I am not I am using 1.0.0. I think I got that by looking at your tags on github.
15:45Raynesgfredericks: Seriously dude, I tag shit sporadically.
15:45RaynesI'm just a bad guy in general.
15:45TimMchyPiRion: One could set a series of $timers at 1 hour intervals for decreasing amounts of time such taht they'd all fire at once.
15:46gfredericksnow I know
15:46Raynes$latest me.raynes/laser
15:46lazybot[me.raynes/laser "1.1.1"] -- https://clojars.org/me.raynes/laser
15:46Raynesgfredericks: ^ Always use that to find the current version of my libs.
15:46RaynesSeriously dude, I'm terrible at marketing.
15:46hyPiRionTimMc: that'd be like, "Imma charging my... lazybot"
15:46RaynesDon't listen to anything I say.
15:47gfredericksTimMc: I never grocked enlive any better. This might be inevitable for this kind of library.
15:47hyPiRionTimMc: oh hey
15:47Raynesgfredericks: The good news is that you have me whereas cgrand doesn't frequent this channel.
15:47RaynesI also have a nice American sense of humor.
15:48gfredericksRaynes: I am a thankful person. Have you considered protocols and records for some of this stuff?
15:48RaynesFor some of what?
15:48amalloygfredericks: why?
15:48RaynesI haven't because wtf why.
15:48amalloywell, my reaction isn't as strong as Raynes's. he's allergic to protocols
15:48hyPiRionTimMc: If lazybot still listened to clojurebot, we could've made a "quine"-like thing which did exactly what you described
15:49gfredericksamalloy: Raynes: it might make it easier to implement transformations when people like me use the wrong sort of thing in the wrong place?
15:49gfredericksand easier for me to know what kind of thing I have
15:49gfredericksas it is I'm looking at a sequence or a map but it really might be one of at least four different things
15:49Raynesgfredericks: Well, you shouldn't have to care what any of these things are.
15:50gfredericksI see.
15:50RaynesAnd your biggest problem is that you're using an old version of laser.
15:50RaynesAll of this is supposed to Just Work.
15:50gfredericksI look forward to trying the newer one.
15:50RaynesI don't add protocols and records for documentation purposes. :P
15:51gfredericksthanks for the help
15:51TimMcRaynes: I don't like the Clojure community's half-assed approach to versioning.
15:51dobladezgurus: any idiomatic way or standard function to check if a map is fully contained in another one?
15:51RaynesTimMc: I usually tag. I wrote a lein task to do it for me.
15:52TimMcdobladez: No standard function. You want key and value equality? select-keys is a first step.
15:52hyPiRionTimMc: what do you mean?
15:52TimMcdobladez: (= small (select-keys big (keys small))) *almost* does it...
15:53dobladezTimMc: both keys and values. Thanks
15:53TimMcThrow in an `and` and something from clojure.set and you're on your way.
15:53dobladezyep, propably "recur" on that and I'll be close
15:53TimMcrecur? why?
15:53Glenjaminis there an updated cheatsheet for 1.5?
15:53RaynesTimMc: Maybe I was drunk when I released that. *shrug*
15:53RaynesI feel bad now.
15:54RaynesHow do you tag old commits?
15:54hyPiRion(every? (partial find superset) (keys subset)) should work, I think
15:54dobladezTimMc: well... I need to check the whole structure, not just the top-level keys / values
15:54hyPiRionoh, urhg, then if you want more than key equality
15:55RaynesTimMc: There we go, all tagged up.
15:55TimMcRaynes: Oh, not the tagging -- this is about semver.
15:55TimMcAlthough tagging is really important too.
15:55RaynesYeah, you're not going to get me to stick to semver strictly.
15:57hyPiRionTimMc: So how would you usually do that kind of stuff?
15:57hyPiRionAre you not happy with 0.1.0-RC10-alpha1?
15:57mklappstuhlHey
15:58mklappstuhldoes it make sense to write a "short running" cli application in clojure? (thinking of JVM boot time mainly)
15:59Raynesmklappstuhl: It depends on how often you need to run it and how fast you need it to run.
15:59RaynesA Clojure CLI app can usually run in 2-3 seconds.
15:59Glenjaminthe bigger issue with clojure versioning seems to be that every lib i see depends on old versions of everything
15:59RaynesI imagine that could be lessened a bit further with some fancy JVM options.
16:00RaynesAnd if you use drip, it could be mitigated even more I expect.
16:00hyPiRionmklappstuhl: if you mean "less than 2 second short" then you shouldn't
16:00RaynesBut it really depends on your specific usecase.
16:00RayneshyPiRion: Ssssh, I have command line apps that run in 2 seconds but only ever have to be ran like once every two weeks and I'm very happy to have written in Clojure.
16:00Raynes:p
16:00mklappstuhlRaynes: hyPiRion: It'd be some simple script fetching some data from the internet
16:01Rayneshttps://github.com/Raynes/updoc
16:01Raynesmklappstuhl: ^ Example command-line app that I wrote.
16:01RaynesIf you're interested.
16:01TimMchyPiRion: Not sure what you're asking. I don't care what people do pre-v1, as long as they eventually release a v1. Once they do that, breaking changes really don't belong in anything but 1st-segment version bumps.
16:01borkdudehmz, how can 10 operations that take 1 second each be 10 seconds single threaded, but take 1 second on 4 cores? https://www.refheap.com/paste/13217
16:01mklappstuhlI also had the idea that some other runtime like JS could be used...
16:02RaynesYou could do it in clojurescript with node.js. You could also toss yourself out a 10 story window.
16:02hyPiRionTimMc: Alright, that's what I though. x.y.z where x is breaking changes, y is enhancements/additions and z is bugfixes
16:02gfredericksborkdude: those aren't exactly CPU-bound functions
16:02mklappstuhlRaynes: clojurescript no good?
16:03borkdudegfredericks oh right
16:03gfredericksborkdude: the real question is why pmap gets it all the way to 1 second rather than 2 or 3
16:03hyPiRionborkdude: because they don't run. When a thread starts sleeping, another takes over
16:04nDuffGlenjamin: Unless those specifications include version ranges, though, lein should be able to substitute in the newer/current versions without issue.
16:04borkdudehyPiRion right
16:04nDuffGlenjamin: ...ie. usually, version specifications are minimum with no maximum.
16:04technomancyRaynes: I noticed laser has no images in its readme; can you add https://lanternhollow.files.wordpress.com/2011/05/laser_gun_pew_pew_pew.jpg ?
16:04borkdudeI would try reducers, but when I want to install Java 1.7 I get some messages that Chrome won't keep working… anyone had this?
16:04Raynestechnomancy: I absolutely can.
16:04gfredericksborkdude: how long does it take for 100?
16:05Raynestechnomancy: You could send me a pull request and get in the contributor graph.
16:05RaynesIt's like winning.
16:05hyPiRionbut yeah, pmap is weird, and spawns n+2 threads, where n is the amount of threads. And some other weird stuff
16:05technomancytempted
16:05TimMcRaynes: That would be a pretty impressive window.
16:05GlenjaminnDuff: it mostly seems to work when newer libs are pulled in, but any non-back-compat changes would leave things totally broken
16:05borkdudegfredericks about 4 seconss
16:05nDuffGlenjamin: Sure. This isn't #ruby; backwards-incompatible changes to documented semantics are rare.
16:05gfrederickshuh.
16:06nDuffGlenjamin: ...thus, the thing that's an issue is code relying on on _undocumented_ semantics.
16:06borkdudegfredericks 1000 takes a lot longer though, 32 seconds
16:06TimMcWhich is pretty common.
16:06Glenjaminso basically we trust people to build libs without breaking things, and don't worry about it
16:07gfredericksborkdude: yeah at some point it would scale linearly
16:07borkdudegfredericks maybe I have to come up with a better example than Thread/sleep
16:07gfrederickshow about ((apply comp (repeat 1000000 identity)) 42)
16:08nDuffGlenjamin: Pretty much, yes.
16:09Glenjamini gotta be careful not to mock too much in my tests then
16:10amalloygfredericks: yesterday i rewrote a geni function in point-free style for april fools. i gotta say, it came out as badly as i hoped: https://www.refheap.com/paste/13185
16:11borkdudegfredericks hm, the pmap version of this take a looong time with only 10 elements
16:13borkdudegfredericks hm https://www.refheap.com/paste/13218
16:16igorwdoes lein have a fancy way of describing semver-ish version constraints? lots of other deps managers have that, and it helps a lot to promote more sane versioning
16:17Raynestechnomancy: https://github.com/Raynes/laser#laser
16:17technomancyigorw: I am suspicious as to whether it actually helps
16:17technomancymy observations have been more that it actively hurts when semver isn't applied, but not the other way around
16:17brehaut~version ranges
16:17clojurebotversion ranges are nothing but trouble: http://nelsonmorris.net/2012/07/31/do-not-use-version-ranges-in-project-clj.html
16:17technomancyRaynes: capital
16:18RaynesI broke travis-ci by force pushing 4 times in a row because I screwed up the README.
16:18RaynesAnd it won't let me restart the build.
16:18technomancyoof
16:18RaynesWhere is antares when you need him.
16:18RaynesOh, it's restarting automatically.
16:18RaynesNot bad, travis.
16:18Glenjaminheh, there really needs to be better github readme preview tooling
16:18technomancysometimes I test github's markdown via gist, but I know you might not believe in that
16:19Raynestechnomancy: Yeah, but this required that the file be in the git repo so it was a catch 22.
16:19Rayneshttps://travis-ci.org/Raynes/laser Yey green.
16:19technomancyaha
16:20GlenjaminRaynes: technomancy https://github.com/ypocat/gfms
16:20GlenjaminnDuff: do you think as the ecosystem grows, the fuzzy version matching lein does will become an issue?
16:20technomancyigorw: but lein inherits its version range support from aether, which unfortunately provides a fairly broken implementation
16:21nDuffGlenjamin: Given as lein inherits that behavior from a far larger ecosystem, I'm not so worried.
16:21Glenjaminversions in java suck too :(
16:21Glenjaminor maybe thats just from my pov
16:22technomancythe problem is it's more difficult to isolate off entire subtrees of the dependency graph with java than clojure
16:25hq1noob question, out of curiosity: using the Clojure REPL can I inspect the running system/VM like in Erlang?
16:25nDuffhq1: You certainly can inspect the running instance.
16:25nDuffhq1: "like in Erlang" requires more knowledge of Erlang than all of us have. :)
16:25igorwtechnomancy: obviously it's not a replacement for actually telling people to version properly. it amazes me that so many packages in npm is still 0.x, although it has improved a bit
16:26hyPiRionnDuff: well, with rebar you can open up a console of a running OTP program
16:26hyPiRionNot sure if that explains anything to you though.
16:26TimMc&(get-in 5 [])
16:26lazybot⇒ 5
16:26technomancyhq1: probably the main difference is in clojure you have to explicitly start a repl server; you won't get one out of the box
16:26hq1hyPiRion: you don't need rebar at all (to put it mildly it isn't the greatest software in the Erlang's ecosystem)
16:27technomancybut it's trivial to do
16:27hq1so there's nothing stopping me from testing some functions in a production system runtime?
16:28nDuffhq1: If you set up that production system to have run an nrepl server or swank, correct.
16:28technomancyhq1: definitely not. you can even do it on a web app without opening extra ports if you like: https://devcenter.heroku.com/articles/debugging-clojure
16:28hq1just got my first Clojure book, will stop asking noob questions soon ;)
16:28hq1thanks guys
16:31hq1nDuff: Erlang shell is part of the OTP, you can use remote shells which is a killer feature (connect to a remote node from a local REPL).
16:31nDuffhq1: ...whereas the Clojure equivalent is using nrepl to remote in, potentially with drawbridge to tunnel over HTTP.
16:32technomancyclojure programs don't have the same level of isolation between concurrent threads as erlang processes (which is good and bad) but can lead to some unexpected behaviour with reloads
16:32technomancyOTOH you are able to get much better performance communicating between them
16:32hq1hehe I'm biased so I won't get into this discussion :P
16:33technomancyerlang is better for things that erlang is better for; we can leave it at that. =)
16:33hq1yes please ;)
16:34jack_rabbitSo I'm working with network programming, specifically the read() method of a SocketInputStream, and think I'm probably going about this wrong. Are there nice wrappers for socket programming floating around somewhere?
16:34hq1still quite excited to finally learn a proper LISP running on JVM. hopefully it will let me to deploy stuff without even thinking of Java.
16:36hq1are there any resources you guys would recommend to learn about JVM itself?
16:37joegallolike, java generally, or the jvm specifically?
16:37amalloyjack_rabbit: aleph and lamina are one approach, or you might be able to make do with slurp, clojure.java.io/copy, and friends. but for actual non-trivial network problems, it's not unreasonable to be using sockets yourself
16:37hq1JVM specifically, I am so *not* interested in Java itself. am I a bad person?
16:38technomancys'ok
16:38Glenjamini think that makes you sane.
16:38ztellmanjack_rabbit: what are you trying to do, at a high level?
16:38jack_rabbitamalloy, I'm just not liking having to create byte buffers for my read calls.
16:38jack_rabbitztellman, At this point it's just an exercise creating a ServerSocket and reading input from the client.
16:39jack_rabbit(who is connecting through telnet)
16:39hq1still, being able to use some of the Java "goodies" like let's say SOAP support (<- mind you, the quotes) would be a good thing ;)
16:39hyPiRionhq1: You're not a bad person.
16:39hyPiRionJava isn't the worst language to work with, but well, I've seen better
16:40brehauthyPiRion: swearjure for instance
16:40amalloy(inc brehaut)
16:40lazybot⇒ 10
16:40hyPiRionbrehaut: hahah, I was for once not thinking about that
16:40ztellmanjack_rabbit: clojure.java.io will give you enough to avoid dealing with bytebuffers
16:41ztellmanbut if you end up wanting to try aleph, I can give some pointers there too
16:41hq1OK, so is there a place I can learn about JVM not being forced to read about AbstractFactoryStrategySingletons?
16:41combataircraftquestion: what is the most convenient & idiomatic way of creating a new function by editing the parameters of an existing one like: (def get-user 'request "/users/{0}.json") ?
16:41amalloyjack_rabbit: if you're starting from nothing, i recommend giving ztellman's lamina and aleph a try. there's some early conceptual hurdles, but once you get the hang of it it's a pretty neat way to write networking code
16:41technomancyhq1: this article is pretty great: http://copperthoughts.com/p/clojure-io-p1/
16:42hq1technomancy: ty, bookmark'd
16:42technomancyI/O is the most common place Java stuff sticks out
16:42jack_rabbitamalloy, ztellman Thanks I'll try out all that stuff.
16:42ztellmanamalloy: bite your tongue, everything I write is intuitive and immediately effortless to use
16:42combataircraftI need some kind of parameter templating for editing creating functions. any ideas ?
16:42hyPiRionhq1: there's not much you need to know about Java when you program in Clojure. I/O is one thing, and blocking queues are the other.
16:43amalloycombataircraft: what on earth does that question mean?
16:43hyPiRionOtherwise everything else should not have a need for Java.
16:43nDuffEh. One certainly has to know how to read javadocs.
16:43hq1hyPiRion: but I'd like to be able to call some external, hairy Java libs. Is that a problem at any point?
16:43nDuffOne has to know how java's variadic arguments work.
16:43combataircraftamalloy: what is the most convenient & idiomatic way of creating a new function by editing the parameters of an existing one like: (def get-user 'request "/users/{0}.json")
16:44nDuffOne really ought to know the Java standard library, as there's a whole lot more of it than there is standard-library for Clojure.
16:44technomancyyou need to know not to use java.util.Date
16:44hq1I can grok those I guess ;)
16:44technomancyhq1: there's no substitute for hanging out on IRC though
16:44amalloyi'll get back to you if i ever find something you've written that is immediately effortless, ztellman
16:44hyPiRionhq1: Well, if you would like to do that, then you should know some Java, yeah.
16:44ztellmanamalloy: :)
16:45gtrakany hadoop-app devs here? I'm curious if anyone's built an automated testing/deployment thing with pallet?
16:45rboydcombataircraft: do you want partial?
16:45hq1hyPiRion: I'm thinking rather of technical restrictions of Clojure if any. Got some hardcore java hackers around so I could ask them to type some stuff for me ;-)
16:46combataircraftrboyd: yes partial, but with re-arranging parameters by templating
16:46combataircraftlike this; (def get-user 'request "/users/{0}.json")
16:46hq1hyPiRion: but I'm hoping this to be fully transparent
16:47combataircraftassume we have a function called request and it takes URL as a parameter. I wanna create a new function that says "call request function by formatting this parameter"
16:47hq1hyPiRion: like, is there some Java stuff out there I *can't* call from Clojure?
16:48amalloyhq1: no, although there are some things that can be hard
16:48nDuffhq1: There's Java stuff you need to jump through hoops to call from Clojure -- ie. sometimes you need to use gen-class to build something with annotations.
16:48hyPiRionhq1: Java interop is very well designed and tightly integrated, and unless you need very high performance or need to do some really messy locking, I don't think you have to jump down to Java.
16:48nDuffhq1: ...but there's nothing you _can't_ call from Clojure, just things that are tricky.
16:48nDuffhq1: ...well, there are things you can't call from Clojure without an AOT compilation phase.
16:48rboydcombataircraft: (def get-user #(request (str "/users/" % ".json"))) ?
16:48hugodgtrak: https://github.com/pallet/pallet-hadoop if you haven't already seen it
16:48gtrakhugod: yea, I'm on it right now :-)
16:49hq1ah
16:49brehaut(def get-user (comp request (partial format "/user/%s.json")))
16:49nDuffhq1: ...unless you're dealing with 3rd-party APIs that inspect objects you pass them for annotations &c., though, those are generally fairly rare.
16:50hq1nDuff: I might deal with those, but I guess it all could be done with some kind of native Java wrappers as well, right?
16:50nDuffhq1: Yup.
16:50hq1OK, fair enough, that's perfect
16:50rboydbrehaut: slick
16:50nDuffhq1: Only time I've had to jump through hoops that large is when I'm using Clojure to build a plugin for a large Java project.
16:51combataircraftrboyd: brehaut: awesome answers, thanks!
16:51hq1nDuff: I see, thanks for clearing things up a little
16:51brehautcombataircraft: caveat that if you are bashing strings together you might have the wrong abstraction
16:52amalloyhq1: you might find https://github.com/flatland/io/tree/develop/src/flatland/io interesting, as an example of building a minimal java wrapper around an awful java api, and presenting a nice clojure api instead
16:53amalloythe java IO library is all these awful abstract classes that you have to extend and reimplement bits of; we wrote instead a concrete class that gets passed an instance of an interface and delegates to it; that interface is easy to implement from clojure
16:54hq1amalloy: splendid, thank you, will look into it
17:12Glenjaminis there a way to load-file relative to the current file?
17:12Glenjaminsomething like __FILE__ in other languages
17:17amalloyGlenjamin: don't do it, man
17:18Glenjaminamalloy: it's to make this work when using a lein checkout: (load-file "src/speclj/version.clj")
17:18Glenjamininside project.clj
17:22technomancyGlenjamin: if you need access to the version at runtime you can load pom.properties from the jar
17:23Glenjaminit's not my lib, so swapping it around seems like overreaching
17:24Glenjamini guess in general having logic in project.clj isn't a great idea though :)
17:32Glenjamini wasn't intending to commit that, just wanted it to work with the checkout
17:32Glenjaminalthough i got a weird error with interface not matching the protocol, and just used lein install
17:36tieTYTin a let, the way even params are symbols and odd params are evaluated to values is called a binding form?
17:36tieTYTlet me resay that
17:36tieTYTin a let, the way odd params are symbols and even params are evaluated to values is called a binding form?
17:38gfrederickstechnomancy: does slamhound make some attempt to solve the "what vars does this code refer to?" problem?
17:39technomancygfredericks: heh... well... "some attempt", yes
17:39technomancy"does this compile? no? let's screw with the ns form. how bout now?"
17:39gfredericksoh nice
17:39technomancybrute force search
17:39gfredericksthat's brilly
17:39technomancyhttp://technomancy.us/148
17:39gfredericksI assume brute force means you try every possible subset of the namespaces you might want to require with all possible prefixes and refer lists and etc
17:40technomancymore or less
17:47tomojtieTYT: the terminology is confusing to me
17:47tomojI think 'binding form' means the odd forms
17:48tomojbut 'binding' can mean a pair of odd and even?
17:48tomoj(I'm guessing you're 1-indexing?)
17:49amalloytomoj: tieTYT: i think it's just all poorly defined and ambiguous. "binding", "binding form", "bindings" all mean whatever you want them to mean in context
17:49tomojyeah :(
17:50gfredericks<form>
17:50tomojcore is no help for names internally iirc
17:51tomoj(let [bents (partition 2 bindings)] ...)
17:52tomojI guess that's an abbreviation for "binding entry"?
17:53tomojthen confusingly loop call it's binding entries 'bfs', binding forms?
17:53tomojcalls its..
17:55gfredericksI used the term lettings a lot in currj
17:55gfredericksthat's a good reason for nobody else to use it
18:01gfredericksthis whole using ^:private thing gets really noisy after a while :(
18:02gfredericksfor a fleeting moment I thought about writing a macro to do it and then remembered defn- exists and why I'm not using it
18:14amalloygfredericks: so don't write so many dang private functions
18:15amalloyi'd suggest making your public functions be closures around your private functions, but people always laugh at me when i do that
18:15amalloyand i don't need to introduce more pain to your life
18:15gfredericks(let [...privates...] ...def publics...)
18:16amalloygfredericks: well, that makes it hard to def a private, then a public, then a private...
18:16FoxboronSomeone should write a new book about closuers in clojure and call it "Clojure in Closure"
18:16amalloybut it is what i was recommending, yes
18:17holoFoxboron, you mean "Closure in Clojure"?
18:17Foxboronholo: No. "Clojure in Closure"
18:17amalloyyou could try something sneaky like (letfn [(private1[]) (public1*[]) (private2[]) (public2*[])] (def public1 public1*) (def public2 public2*)), but yuck
18:20Foxboronholo: it is a pun if you didn't get it ;)
18:20Foxboronbeen reading Let over Lambda for the past days and just can't come over the fact it would be an awsome name.
18:21hiredman"private" is gross
18:21hiredmanit limits reuse
18:22technomancyyou can't always design for forever-future-proof re-use
18:22hiredmanthen don't
18:23hiredmanisn't it great we have actually dependencies and you can specify a dependency and just keep using it even if upstream releases a new version with breaking changes
18:24technomancyso the idea of communicating an explicitly demarcated stable API is a waste of time?
18:24hiredmantechnomancy: sure, communicate it, but making it a pain to work with the other parts is just silly
18:25hiredmanhow about if you want something to be public you do ^:public
18:25technomancyresolving vars is not really a pain
18:25technomancyit's like two extra chars
18:25technomancyif you're a big kid and you can deal with your own breakage surely you can add two extra chars
18:25hiredmantechnomancy: sure, but once you start going "oh, I'll put my private bits in a let and close over them"
18:25technomancyhiredman: oh, yeah that's nuts
18:25hiredmanwhich, well, honestly has never stopped me
18:26hiredmanbut it is super annoying
18:27hiredmanwe have some code at work that reflectively grabs the countdownlatch closed over in the reify of a promise so we could deref with a timeout since clojure 1.2
18:27hiredmanof course now there are deref arities with a timeout
18:29hiredmanluckily the name of the closed over count down latch has never changed
18:31hiredman,(->> (class (let [x 1] (fn [] x))) .getDeclaredFields (map #(.getName %)))
18:31clojurebot("x")
18:33Lajjla,(let [i "I" worship "worship" his "his" shadow "shadow"] (str I \space worship \space his \space shadow \ space))
18:33clojurebot#<RuntimeException java.lang.RuntimeException: Unsupported character: \ space>
18:33Lajjla,(let [i "I" worship "worship" his "his" shadow "shadow"] (str I \space worship \space his \space shadow \space))
18:33clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: I in this context, compiling:(NO_SOURCE_PATH:0:0)>
18:33LajjlaOops
18:34Lajjla,(let [i "I" worship "worship" his "his" shadow "shadow"] (str i \space worship \space his \space shadow \space))
18:34clojurebot"I worship his shadow "
18:34LajjlaPerfect
18:43sandbagsCan someone tell me what version I should specify for Clojure contrib? Based on the examples I've seen I thought I should use the same version as my clojure (i.e. 1.5.1, or 1.5.0, or 1.5) but that doesn't seem to be right.
18:43sandbagsI looked at the contrib pages but it's not apparent to me from there either
18:43amalloyclojurebot: where did contrib go?
18:43clojurebotwell... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
18:43sandbags(sorry, "version" meaning what should I put in my leiningen project.clj)
18:45sandbagsamalloy: okay i'm a little confused .. from this i deduce there is no longer a single contrib jar file?
18:46RaynesThe whole contrib landscape has changed.
18:47RaynesIf you're reading the original Stuart Halloway book it's pretty extremely outdated now.
18:47sandbagssomething of an equivalent heritage it seems
18:47brehautdeintensifier intensifier noun
18:47brehauthigh five raynes
18:48Rayneso/
18:48sandbagsokay i found what i needed, apparently it got moved into clojure anyway :)
18:48sandbagsthx
18:48brehaut\o
18:52tieTYTin a let, the way the first params are symbols and second params are evaluated to values is called a binding form?
18:52amalloytieTYT: please read the scrollback from last time you asked thie question before asking it again
18:53tieTYTsorry, i didn't see that
18:53Rayneslol
18:54tieTYTseems like the answer is "nobody knows"
18:55tieTYTdoes anyone know if Rich Hickey is anti test or just anti-tdd?
18:55technomancyhe says regression tests are valuable
18:56tieTYTi see
18:56tieTYTin my limited experience, they're easier to write in clojure than java
18:57tieTYTreally hard to write regression tests when you didn't write your code for testability in mind in java
18:57tieTYTat least write it in a way that's "good"
18:57ztellmanwriting with testing in mind != tdd, though
18:58Apage43tdd == writing tests with eventually writing code in mind
18:58tieTYTright
18:59Raynestechnomancy: http://static.quickmeme.com/media/social/qm.gif
18:59dpathakjtieTYT: you may be interested in http://www.codequarterly.com/2011/rich-hickey/ . search for 'test'.
19:00tieTYTthanks
19:00tieTYTi've read this already
19:01RaynesThe good news about programming is that you don't have to do what Rich says.
19:01RaynesIf you want to TDD, you go do you some TDD.
19:01tieTYTbut Rich says...
19:01RaynesInsert comment about being told to jump off a bridge.
19:03amalloyRaynes: http://xkcd.com/1170/
19:12tomojwow, apparently you can set! even non-dynamic vars is cljs
19:14Apage43does cljs have dynamic vars?
19:14amalloytomoj: of course. it's the assignment operator, just like in clj-jvm where you can use it to set! public members of objects
19:15amalloyApage43: does cljs have vars? (no)
19:15Apage43well there we go
19:17tomojamalloy: but I would've expected the compiler to throw on setting a non-dynamic var
19:17tomojat least, directly
19:17nDufftomoj: ...but on a variant of the languages that doesn't _have_ Vars...
19:17amalloytomoj: what var?
19:17tomojvs (set! (.-foo js/cljs.user) 42)
19:17tomojthe compiler knows about vars
19:17amalloydoes it?
19:18tomojindeed
19:18tomoje.g. if you try to (binding [non-dynamic ..]) you get a warning at least
19:19tieTYTis var short for variable?
19:19Apage43what does binding do in cljs
19:19tomojit just set!'s then set!'s back after
19:20Apage43ah
19:20Apage43well that makes sense
19:20Apage43actually
19:20nDufftieTYT: In Clojure, a Var is a specific construct with specific semantics.
19:20nDufftieTYT: ...thus, it's not as general a term as a "variable".
19:20tieTYTok
19:21tieTYTI'm reading this: http://clojure.org/vars
19:21tieTYTClojure is a practical language that recognizes the occasional need to maintain a persistent reference to a changing value and provides 4 distinct mechanisms for doing so in a controlled manner - Vars ...
19:21tieTYTbut vars can only do that if theyr'e defined with ^:dynamic right?
19:21RaynesNo.
19:21tieTYTi guess the with-redefs is another way
19:21hyPiRiontieTYT: Ever tried (def foo 10) (def foo 20) ?
19:21RaynesYou can change a var at any time.
19:22RaynesNot a good example. I'm disappointed.
19:22Raynes$google alter-var-root clojure
19:22lazybot[ClojureDocs - clojure.core/alter-var-root] http://clojuredocs.org/clojure_core/1.2.0/clojure.core/alter-var-root
19:22RaynesUgh
19:22tomoj(set! + -)
19:22tomojseems nuts
19:22RaynesI wish I hadn't done that now.
19:22hyPiRiontomoj: Well, you can do that in Java too
19:22tieTYTRaynes: what hyPiRion said isn't a good example?
19:22RaynesI like alter-var-root.
19:22tomojyou can't do (set! + -) in clojure at least
19:23hyPiRionI tried to change Boolean/TRUE to false, and the whole JVM collapsed. Fun times.
19:23possibilitiesnewbie alert! what's the best way to coerce clojurescript output to be a requirejs compat module?
19:23nDufftieTYT: ...well -- it's fair if you're replacing something over a REPL. It's not something you'd ever want to have code to programatically.
19:24Apage43possibilities: how do you do it in javascript?
19:24nDuffpossibilities: I'd look at how requirejs plays with the Google Closure ecosystem, to start
19:24tieTYTthat alter-var-root is interesting
19:25possibilitiesok, nuff said, nice way of saying "don't be dumb", thank you. (:
19:25hyPiRionyou could do it through java calls too, with .bindRoot
19:26hyPiRionThough well, it's obvious that this dangerous material.
19:26nDuffpossibilities: ...well -- Google Closure has their own module / dependency system, and that's the one cljs plays well with; I honestly don't know how/whether requirejs integrates with it cleanly.
19:29corecodeoh nice, there is clj->scm
19:29corecodemaybe my dream of clj-on-microcontroller will work out?
19:29Denommushi
19:30Denommushow do I make leiningen detect my $HOME/Projects directory as the root of where I put my projects?
19:30hyPiRioncorecode: https://github.com/halgari/clojure-metal
19:30corecodehyPiRion: ooooh
19:30corecodehyPiRion: i was looking at picobit http://www.iro.umontreal.ca/~feeley/papers/StAmourFeeleyIFL09.pdf
19:30technomancyDenommus: leiningen only really works on one project at a time
19:31hyPiRioncorecode: oh dang, sweet
19:31corecodehyPiRion: the arm version compiles to 8KB VM code
19:31possibilitiesthanks peeps.
19:31technomancyDenommus: what is it exactly you're looking for?
19:31corecodehyPiRion: and i think if needed assembler/different coding could get it down to 4KB.
19:32hyPiRioncorecode: ooh, I'll find you an interesting one, sec
19:33Denommustechnomancy: I'm trying to work with clojure in Emacs, and I'm used to Common Lisp with quicklisp workflow
19:33Raynestechnomancy: What are your thoughts on el-get?
19:34technomancyRaynes: it kinda bums me out
19:34RaynesJustin made me write a refheap.el recipe and send the guy a pull request because he won't use elpa directly. :p
19:34corecodeya el-get seemed like The Solution, but now melpa/elpa/marmalade are much better
19:34technomancyRaynes: I wish the effort that went into it had gone into making package.el better, because it's still lacking a lot of features.
19:34Raynestechnomancy: The weird thing to me is that it isn't even entirely separate. You can use elpa as a method of fetching a package.
19:35RaynesMakes my skull ache.
19:35technomancyRaynes: that said, it can do some things you can't currently do with package.el. but as a library author, you should probably pretend it doesn't exist and just upload to marmalade.
19:35jack_rabbitSo... I have a future running an infinite loop with a thread monitoring it, but when I call (future-cancel the-future) on it, it doesn't seem to die, even though (future-cancelled? the-future) returns true.
19:35Raynestechnomancy: I do typically do that, but Justin is, you know, my boss more or less. :P
19:36technomancyRaynes: well, if your hands are tied... =)
19:36Raynestechnomancy: It required no modification of refheap.el. I just added a 5 line recipe thing that's like "Yo, here is a git repo. Go get it."
19:36technomancymy only objection with el-get is that it makes library authors slightly more likely to avoid doing proper packaging and the time spent writing it could have been better spent
19:37hyPiRioncorecode: http://hypirion.com/pdf/igor.pdf <-
19:37hyPiRionSorry, my server spazzed out
19:37technomancybut I'm not the boss of anyone, and package.el has horrible political contribution barriers
19:37nDuffjack_rabbit: a cancel won't do anything that a thread interrupt method won't
19:38nDuffjack_rabbit: see http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#cancel(boolean)
19:38nDuffjack_rabbit: ...note that Java's thread interrupts are, err, somewhat voluntary.
19:39nDuffjack_rabbit: see http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html for more details on that.
19:39jack_rabbitYeah, it appears that way. I'll have a look. But before I do that, I need to write this handler so it doesn't do busy waiting.
19:39Denommusguys, how do you require your projects in nrepl inside of Emacs?
19:39hyPiRionjack_rabbit: oh hahaahah
19:40jack_rabbitIs there something that blocks until the value of an atom is changed? I've looked at agents and watches, but I don't really want more than one thread executing the handler at a time.
19:40hyPiRionyou have the blocking read issue in Java
19:40technomancyDenommus: nrepl-jack-in is the most common way
19:40hyPiRionjack_rabbit: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4514257
19:40Denommustechnomancy: I understand that, but this only opens the repl. I'm asking how to load my project
19:40DenommusI mean, I have no idea how to run a project from inside emacs
19:41technomancyDenommus: usually C-c C-k
19:41hyPiRionEssentially it's a 12 year old unresolved bug report about the impossibility of killing threads on a blocking read
19:41technomancyyou can also add :repl-options {:init-ns my.init.namespace} to have things loaded on startup
19:41jack_rabbithyPiRion, I don't think that's it. This method I'm running doesn't call read anywhere.
19:41technomancybut I'm not sure whether that's checked in nrepl.el yet
19:41hyPiRionDenommus: C-c C-k and then C-k M-n (to switch namespace)
19:41hyPiRionjack_rabbit: oh, lucky you
19:41nDuffjack_rabbit: If it's all CPU and not invoking anything that waits for I/O or sleeps, then there's likely nothing checking interrupt status.
19:41nDuffjack_rabbit: Do see the last link I provided.
19:42jack_rabbitnDuff, I'm reading it now. Thanks.
19:42DenommusCompilerException java.lang.RuntimeException: Unable to resolve symbol: defproject in this context, compiling:(/home/yuri/Projetos/test-clojure/project.clj:1)
19:43jack_rabbitnDuff, So it appears I might just need to catch that exception, then.
19:43nDuffjack_rabbit: Not quite.
19:43technomancyDenommus: Leiningen isolates in-project code from code that runs in Leiningen itself
19:44nDuffjack_rabbit: The issue here is that you aren't calling anything that _throws_ that exception
19:44nDuffjack_rabbit: so setting the interrupted flag on the thread isn't actually having any effect.
19:44technomancyDenommus: so C-c C-k will only work on stuff inside src/
19:44technomancyyou should never need to evaluate project.clj yourself
19:44nDuffjack_rabbit: ...you can poll it yourself, if need be.
19:44jack_rabbithmm.
19:44corecodehyPiRion: boh, a lot to read
19:44Denommustechnomancy: so, do I have to do C-c C-k for each of my files?
19:45technomancyDenommus: typically your project will have a single entry point which will require everything that's needed
19:45corecodehyPiRion: also i'd like to use existing microcontrollers :)
19:45jack_rabbitI need to implement some sort of blocking to wait for incoming data on an atom, so I think it'll be simple to get the thread to kill itself with particular messages.
19:46nDuffThat... doesn't sound like an ideal use case for an atom.
19:46mpenetthat sounds likes a promise
19:47jack_rabbitmpenet, I'll have a look at promises.
19:50jack_rabbitOkay. Here's what I'm doing. A few futures listen on sockets for incoming data, and then conj that data to a set in an atom which is distributed amongst the futures. Another future needs to handle this incoming data. That's where I'm stuck. Right now it works except for the busy-waiting and the one future not dying.
19:51jack_rabbitI think getting rid of busy-waiting will solve the thread-not-dying problem as well.
19:54nDuffThe "atom distributed amongst the futures" part doesn't make sense to me.
19:54nDuffSounds more like a job for a queue.
19:54jack_rabbitWell it's basically a queue, yes.
19:54nDuffThere are places where using java.util.concurrency primitives rather than native Clojure ones makes sense.
19:54nDuff...indeed, rhickey has explicitly endorsed the practice
19:54jack_rabbitThe order in which they come isn't really that important.
19:56jack_rabbitThere's a starter thread that creates the set in the atom, and then waits for connections. On connection, it spawns a future with that atom, and the future conj's data to the set whenever it gets any. There's another future out there that needs to pick up that data.
19:58nDuffDo these futures eventually deliver values?
19:58mpenetcouldn't this be solved with an agent and throw away all the futures
19:59mpenetbut anyway atoms+futures are probably not what you are looking for
20:02jack_rabbitnDuff, No.
20:02Denommustechnomancy: ok, I tried to clone the compojure project from github, open core.clj and run C-c C-k
20:02Denommusthis is the result: FileNotFoundException Could not locate clout/core__init.class or clout/core.clj on classpath: clojure.lang.RT.load (RT.java:432)
20:04technomancyDenommus: you must have launched your nrepl session from the wrong project
20:05Denommustechnomancy: ok, now I understand better
20:06jack_rabbitSo I could do this with agents and watches instead it looks like.
20:10jack_rabbitNot even watches I guess. I thought multiple actions on an agent could run at the same time, but now I'm reading that's not the case.
20:19thm_proverdumb question: I have a string something that looks like "a < b, and c < d". Now, I need to encode this string in a XML-friendly manner. How do I do that?
20:19thm_proverWhat library shoudl I be using? I don't want to encode an entier list of map, I just want to encode a single string.
20:23thm_proverhttp://hpaste.org/85064
20:31ivanthm_prover: see data.xml/src/main/clojure/clojure/data/xml.clj and write an emit that doesn't (.writeStartDocument ...)
20:32thm_proverivan: actually, I found that having that little header is acceptable
20:32thm_prover:-)
20:32clojurebotNo entiendo
20:32thm_prover:- (+ 1 2)
20:32thm_prover: (+ 1 2)
20:32ivan,(+ 1 2)
20:32clojurebot3
20:32thm_prover:-)
20:32thm_proverhow did I trigger the "No entiendo" ?
20:33ivana glitch in the matrix, or perhaps a limit to spewing the same response
20:36gfredericksclojurebot occasionally assumes you're talking to him for no particular reason
20:38technomancythere's a reason
20:38technomancyit's because it's occasionally hilarious
20:39gfredericksthere's no denying that
20:40amalloyjack_rabbit: i know i recommended it already, but it really sounds like you're crying out for lamina
20:41jack_rabbitamalloy, Well if it can solve this stuff, maybe I'll give it a look.
20:41amalloyit is for doing exactly what you are trying to do
20:41corecodehyPiRion: that lisp machine is real cool
20:41ztellmanjack_rabbit: can you explain the intent of all those futures and watches?
20:41jack_rabbitThanks. I'll be checking it out right now, although I think I almost have it working with agents.
20:42amalloyztellman: do you have a highlight for lamina?
20:42ztellmanamalloy: ha, yes
20:43jack_rabbitztellman, Its a simple "chat" server as an exercise. I call a function which loops continuously creating futures that listen to a client whenever one connects. The purpose of the futures was to have each client handled concurrently.
20:44ztellmanjack_rabbit: https://github.com/ztellman/aleph#websockets
20:44`arrdemcorecode: which machine?
20:45ztellmandoing the same thing with TCP consists of changing about two lines
20:45jack_rabbitztellman, I appreciate that actually, but you obviously had to handle this stuff when you were writing that lib. I'm more interested in learning how to properly do it than doing it easily with a lib, although if I ever wanted to actually implement something like this, I'd keep aleph in mind.
20:46ztellmanjack_rabbit: fair enough, but the underlying implementation in no way resembles what you're doing with futures
20:46jack_rabbitztellman, Maybe I'll have a look at your implementation then.
20:47ztellmanokay, let me know if you have any questions :)
20:47jack_rabbitthanks!
20:49jack_rabbitztellman, Do you think you could point me to a particular source file that might be of interest to me?
20:49ztellmanjack_rabbit: there are a few
20:49ztellmanbut for some context, I use netty, not java sockets
20:49jack_rabbitokay.
20:50ztellmanwhich adds some capabilities, but does make the implementation a bit less minimal
20:50ztellmanso with that in mind:
20:50ztellmanhttps://github.com/ztellman/aleph/blob/perf/src/aleph/netty/server.clj
20:50ztellmanhttps://github.com/ztellman/aleph/blob/perf/src/aleph/tcp.clj
20:51jack_rabbitThanks. I'll be reading those.
20:51ztellmanI'm honestly not sure where to send you in lamina's source code, so try this first: https://github.com/ztellman/lamina/wiki/Channels-new
20:51ztellmanalso https://github.com/ztellman/aleph/wiki/TCP
20:53corecode`arrdem: 01:39:27 < hyPiRion> corecode: http://hypirion.com/pdf/igor.pdf <-
20:53`arrdemcheers corecode
20:54`arrdemholy shit dude thanks for sharing this
20:55`arrdemhyPiRion: where'd you dig igor up? despite all my lispm googling I never found it.
20:56`arrdemoh. he wrote it. nvm.
21:12corecodehe did?
21:12corecodeyea, absolutely impressive project
21:13corecodemaybe creating something clj-like for microcontrollers is not out of the question...
21:13`arrdemTBH that's going to be my next project
21:14`arrdemI'm working on a Pascal compiler for a class but the whole thing is over-architected with a view towards getting pointed at Clojure once the class is done.
21:16`arrdemwe'll see if it ever materializes, but I think it would be very interesting to try and build a microkernel to run & JIT a Lisp bytecode then write a usable userland atop it in lisp.
21:17`arrdem'course that's only about a decade of man hours so I'll have it on github next week XP
21:20corecodeah
21:20corecodewell, i'm talking about 32KB of flash and 4KB RAM
21:21corecode`arrdem: http://www.iro.umontreal.ca/~feeley/papers/StAmourFeeleyIFL09.pdf
21:21gfredericksRaynes: okay so let's say I have a vector of nodes
21:22gfredericksis that a normal thing to have even?
21:23`arrdemcorecode: that's really cool too. One of the things I've been pondering is using something like that instead of C to do the hardware interop. Virtual memory, clock, disk and soforth.
21:23gfredericksis :content supposed to always be a sequence of nodes or can it be a single node as well?
21:24hiredmangfredericks: sequence
21:25gfredericksman I even manage to get nrepl into some kind of infinite exception-throwing loop
21:31corecode`arrdem: yes, that is my plan.
21:31corecode`arrdem: although for a more peripheral-heavy microcontroller
21:31corecode`arrdem: less disk, more ADC, etc.
21:32corecodeusb peripheral. writing USB stacks in C is no fun.
21:36gfredericksRaynes: https://www.refheap.com/paste/13221 getting a cast exception with a single node
21:38tieTYT2i saw this as a parameter to a function, what is this called? [#^HeaderIterator headers]
21:38tieTYT2the #^
21:38gfredericksmetadata
21:39gfredericksthere's just one parameter there
21:39gfredericksthat's a typehint to say what the java type of the argument is
21:39tieTYT2ah
21:39brehautits the old notation for metadata, just ^ now
21:39tieTYT2why do you need to do that?
21:39gfredericksso it compiles to better bytecode
21:39tieTYT2so it's for performance only?
21:39gfredericksI believe so
21:40tieTYT2ah
21:40tieTYT2new topic
21:40tieTYT2is there a way to get counterclockwise to give you compilation errors?
21:40nDufftieTYT: If you're curious, see the *warn-on-reflection* flag
21:40tieTYT2i always have to load it in the repl to find errors
21:40tieTYT2nDuff: nice
21:42tieTYT2ok thanks guys
22:07amalloygfredericks: there are unusual cases where typehints affect correctness rather than just performance
22:08gfredericksthey'll at least cause class cast exceptions...are you thinking of something beyond that?
22:08brehautamalloy: java method overide selection?
22:08gfredericks,((fn [^String x] x) 12)
22:08clojurebot12
22:08amalloybrehaut: that's one of the two i know, yes
22:08brehautamalloy: whats the other one?
22:08gfredericksyou guys know way more about computers than I do
22:09mthvedt,(if (java.lang.Boolean. false) 1 0)
22:09clojurebot1
22:09brehautgfredericks: that is a sad indictment of my social life
22:09mthvedtwhyyy
22:09amalloybrehaut: imagine an interface Fooable {void foo();} and a private class FooImpl implements Fooable {...}
22:09brehautmthvedt: everything other than primative false and null are true in clojure
22:10amalloyif you get an instance of FooImpl and try to call .foo by reflection, it will complain that you don't have permission to access/use FooImpl
22:10brehauthuh interesting
22:10amalloyif you treat it as an instance of the public Fooable interface, that's allowed
22:10brehautah right, that makes sense
22:10mthvedt,(if (boolean (java.lang.Boolean false)) 1 0)
22:10clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>
22:10mthvedt: ,(if (boolean (java.lang.Boolean. false)) 1 0)
22:11amalloythe clojure compiler could do a little more work and find that out for you, probably
22:11mthvedt,(if (boolean (java.lang.Boolean false)) 1 0)
22:11clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>
22:11amalloymthvedt: don't ever use (Boolean. anything)
22:11mthvedtman i'm bad at typing
22:11mthvedt,(if (boolean (java.lang.Boolean. false)) 1 0)
22:11clojurebot0
22:11amalloybad in java, bad in clojure, bad everywhere
22:11samedhiAre we supposed to be using clojure.core.contracts or trammel?
22:11brehautcore.contracts
22:11mthvedtamalloy: i was using a library that returns Booleans
22:12amalloywrite them a nasty letter
22:12brehautಠ_ಠ
22:12amalloythey are returning bad objects to you
22:12mthvedtbecause boolean objects print as false, i spent a long time trying to debug
22:12gfredericksso clojure boxes everything except booleans?
22:12samedhiok, thanks.
22:12mthvedtunknowing i had a Boolean, not a boolean lurking in the code
22:12gfredericks,(type true)
22:12clojurebotjava.lang.Boolean
22:12gfredericks??
22:12lazybotgfredericks: What are you, crazy? Of course not!
22:13amalloygfredericks: huh? it boxes booleans, most of the time anyway
22:13gfredericksamalloy: but you were not just saying that boxed booleans are terrible?
22:13amalloyno
22:13scottjmthvedt: from docs of that constructor: "Note: It is rarely appropriate to use this constructor."
22:13gfredericksguys I'm really bad at computers
22:13amalloyconstructing new booleans is terrible
22:13scottjmthvedt: opps, scroll was messed up on my window
22:13amalloyreusing boxed booleans like ##(Boolean/FALSE) is great
22:13lazybot⇒ false
22:13gfredericksamalloy: wow, that really IS great!
22:13brehautgfredericks: type requires an object to call get class on it, so of course it boxes to a Boolean
22:14gfredericksbrehaut: yeah that part made sense; it was my perception of amalloy's point that didn't jive with anything else
22:15gfredericksthe string version of the constructor doesn't have the warning o_O
22:16gfredericks,(if (Boolean. "false") 1 0)
22:16clojurebot1
22:16`arrdemamalloy: why would you ever use Boolean/FALSE given that we have false
22:16amalloyoh, i wouldn't, not by hand. but false *us* Boolean/FALSE
22:16`arrdemsure. qualified names and whatnot. just making sure.
22:17gfredericks,(identical? false Boolean/FALSE)
22:17clojurebottrue
22:18gfredericks,(identical? (identical? true Boolean/TRUE) (Boolean/TRUE))
22:18clojurebottrue
22:21scottj,(identical? (Boolean/valueOf "false") false)
22:21clojurebottrue
22:24mthvedttwo things considered identical are logical opposites… makes sense
22:29tieTYT2can someone explain this let to me. I don't understand the or. It seems to be on the left hand side. What does it mean when you do that?
22:30gfredericks,(or 1 2 3)?
22:30clojurebot1
22:30tieTYT2oh nm, that first "param" is metadata, not a variable
22:30rationalrevoltwhen using println in a ring app and the jetty adapter - do i need to configure the logging explicitly to see the outputs?
22:30tieTYT2thanks
22:32gfredericksrationalrevolt: depends on how you're running it -- i.e., where STDOUT for the process is going
22:33rationalrevolti'm running it within nrepl
22:33rationalrevolt.el
22:33gfredericksshould just work I would think
22:33gfredericksassuming (println "foo") by itself works as well
22:34ztellmanhas anyone had issues with 'definterface' and 'hadoop jar' not playing well together?
22:34Raynesamalloy: So false *us* it?
22:34Raynes;)
22:34ztellmanreplacing it with a corresponding 'defprotocol' fixes the problem, for no reason that I can see
22:35rationalrevolthmm, println by itself works, but the same doent print to the repl when it gets called from the handler on an incomming reques
22:35amalloyztellman: what goes wrong? a bad jar is generated, no jar...?
22:35rationalrevoltztellman: could you elaboarate?
22:35amalloyif you have a jar, i'd look through it to see if the generated interface looks right
22:36ztellmanoh, right, I get something to the effect of "Type cannot be cast to IType"
22:36ztellmanwhich would typically lead me to believe that the interface is being double defined, but that doesn't appear to be the case
22:36scottjrationalrevolt: maybe buffer *nrepl-server*?
22:37rationalrevoltscottj: haha! yea, its there
22:37rationalrevoltthanks!
22:39scottjrationalrevolt: I don't recall the details and could be wrong, but maybe something like the *out* for the thread that hadnles your ring requests is different from the repl thread that has *out* going to nrepl.el, *I think*
22:40gfredericksscottj: that sounds super plausible
22:45`arrdemis there a way to get the arity of a function?
22:45gfrederickstry calling it with all possible arities
22:45gfredericksI mean no I don't think so
22:45`arrdemthat's unfortunate.
22:46`arrdemthanks.
22:46brehautsome functions in core have an :arglists meta property but thats not really universal
22:46gfredericksand that's a var
22:46brehautand presumably you could do some shenanigans with reflection
22:46brehautyeah
22:47`arrdemI was just wondering.. rolling my own internal macro system for a compiler and I'm trying to add arity checking to my macros.
22:52brehaut(map #(-> % .getParameterTypes seq count) (.getDeclaredMethods (class map))) ; `arrdem
22:52brehaut,(map #(-> % .getParameterTypes seq count) (.getDeclaredMethods (class map)))
22:52clojurebot(3 2 4 5 0)
22:53brehautyou'd probably want to modify it so that it knows about .isVarArgs too
22:53`arrdemmm... thanks brehaut
22:53`arrdem(inc brehaut)
22:53lazybot⇒ 11
22:54brehauthuh. maybe .isVarArgs is useless on clojure?
22:54brehautmap's arity-5 method is the varargs, but it doesnt get listed as such
22:55brehaut,(map (juxt #(-> % .getParameterTypes seq count) #(.isVarArgs %)) (.getDeclaredMethods (class map)))
22:55clojurebot([3 false] [2 false] [4 false] [5 false] [0 false])
22:55`arrdemah juxt.. so much better than (map vec & seqs)
22:56brehaut`arrdem: fwiw http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html
22:57brehaut,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class map))) ; `arrdem you probably only want invoke and doInvoke rather than all methods in hindsight
22:57clojurebot(["invoke" 3 false] ["invoke" 2 false] ["invoke" 4 false] ["doInvoke" 5 false] ["getRequiredArity" 0 false])
22:58brehaut`arrdem: i suspect doInvoke is for varargs?
22:59brehaut`arrdem: looking at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L83-L86 it appears only the >20 arity version of invoke has javaspace varargs
22:59amalloybrehaut: doinvoke is probably an implementation detail
23:00`arrdembrehaut: *shrug* I'll just restructure this with a wrapper macro so I can get the arity at declaration.
23:00brehautamalloy: everything about the reflection crap i experimented with above is probably an implementation detail
23:00amalloyoh, of course
23:00amalloybut varargs are IFn/applyTo, not AFn/doInvoke or whatever
23:00brehautoh ok
23:00amalloyi mean it's a *boring* implementation detail
23:01amalloyotoh i'm not sure how useful what i said is; i think it's glossing over some important stuff because i don't know what's being asked here
23:02brehautamalloy: `arrdem wants to find out arities of functions
23:02amalloyslit your throat to save time
23:02amalloyit's not a thing you can find out
23:02`arrdemlol
23:02brehauti handwaved a vague solution based on stupid reflection
23:03hiredmanif you with-meta a function anywhere
23:03hiredmanif you use a multimethod
23:03brehaut,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (partial + 1))))
23:03hiredmanetc
23:03clojurebot(["doInvoke" 1 false] ["getRequiredArity" 0 false])
23:03brehautheh
23:03`arrdem... well that makes sense...
23:03amalloyseriously though, every IFn has dozens of arities defined, most of which are implemented as (throw (ArityException.))
23:03brehautamalloy: right, but only some of those are declared on a particular instance
23:03`arrdemmmkay I'll just give up on arity checking then.
23:04`arrdemthanks amalloy, brehaut, hiredman
23:04hiredman,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (fn [x] x)))))
23:04clojurebot(["invoke" 1 false])
23:04hiredman,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (with-meta (fn [x] x) {})))))
23:04clojurebot(["meta" 0 false] ["withMeta" 1 false] ["doInvoke" 1 false] ["getRequiredArity" 0 false])
23:04amalloyoh, declared method? that might work, but hiredman is right
23:05amalloyit can't possibly work all the time
23:05brehautnot to mention its worthless in teh face of a partial frinstance
23:08`arrdemppft why do I need arity checking on functions anyway...
23:09amalloy(try (f a b c) (catch Exception "lol whatever man"))
23:09hiredman_
23:09amalloyoh yeah
23:09`arrdemoh please. this compiler is just going to ignore extra argument l3ik a bau5
23:10hiredmanin the fine tradition of javascript
23:11`arrdemI mean as long as I get em off the stack...
23:13hiredmanbe sure to allow for multivalue returns
23:13`arrdemThis edition is staticly typed Pascal, no such awesome here.
23:13`arrdemnext edition will be clojure, then we'll talk
23:16nonubyi have simple compojure/ring/jetty web app that i run with "lein ring serverheadless", all okay, the ring/jetty lab emits "2013-04-03 10:12:04.166:INFO:oejs.Server:jetty-7.6.1.v20120215Started server on port 3000" however if I use clojure.logging info emits "INFO: testing", is there a simple way to tell my higher level libraries to use the log4j format used by the base
23:58yacinany recommendations for a good xmlrpc lib for clojure?
23:59yacinnecessary-evil?