2013-04-02
| 00:00 | n_b | fbernier: It's a threading macro. The documentation explains it better than I could |
| 00:00 | n_b | ,(doc ->>) |
| 00:00 | clojurebot | "([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:01 | n_b | Essentially it takes each form and recursively inserts it as the last argument into the next form |
| 00:43 | Raynes | jhn: Psh, technomancy resolved it. You just poked it. Braggart. |
| 00:48 | technomancy | eh? |
| 00:48 | technomancy | the clojure-test-mode thing? I don't think I actually fixed anything. |
| 00:49 | jhn | Raynes: lolwut. Someone else PM'd me after seeing that and I just pointed him to technomancy's instructions on the repo. |
| 00:50 | Raynes | technomancy, jhn: I was trying (and apparently failing) to tease jhn about a tweet he made a few minutes ago. |
| 00:53 | technomancy | I see |
| 01:20 | john2x | can I use clojure libraries in clojurescript? |
| 01:24 | scottj | john2x: generally not unless they've had (often minor) tweaks applied to make them compatible, afaik |
| 02:13 | john2x | scottj: oh ok. does clojurescript have its own repo for libraries? I wanna check out the ecosystem. |
| 02:14 | john2x | or does it also use clojars.org? |
| 02:23 | scottj | john2x: idk, some are on clojars, here's my personal non-exhaustive list: http://jaderholm.com/paste/projects-cljs.html |
| 02:57 | john2x | scottj: thanks! |
| 03:24 | Raynes | My internet is so fast. |
| 03:24 | Raynes | When I started writing Clojure it was on a dialup connection. |
| 03:25 | rcg | Raynes, that makes clojure actually sound much older than it is ;) |
| 03:26 | Raynes | Yeah, I was just in a very rural area and uneducated about mobile broadband. |
| 03:28 | rcg | aye, well nonetheless fast internet is a pleasure |
| 03:30 | wink | extra-lazy-seq |
| 03:50 | tomoj | no, of course it won't work to special case (bound-fn [*vars* *i* *need*] ...) ! |
| 03:50 | tomoj | :( |
| 04:01 | tomoj | maybe we just need to rewrite clojurescript.test so that it doesn't use any dynamic vars.. |
| 05:06 | supersym | clojure 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:08 | supersym | but the shift in thinkin it requires coming from imperative world to functional and then what it gives back... wooa ^^ |
| 05:08 | supersym | anyway preaching to the choir |
| 05:09 | andyfingerhut | and as is often the case, much of the choir is sleeping :) |
| 05:22 | kalasjohnny2000 | ...fanfares in the distance |
| 08:08 | supersym | andyfingerhut: yeah lots of USA people I bet :P |
| 08:13 | supersym | why is that anyway, or is it my impression, that many in the Clojure world are native Americans? |
| 08:13 | supersym | questions, questions, too many to answer but internet helps :) |
| 08:14 | hyPiRion | supersym: it's not your imagination |
| 08:22 | supersym | is there a general consensus on the matter? surely people must have spoken about this before |
| 08:22 | clojurebot | min people is 5 |
| 08:23 | hyPiRion | well, it's true that the majority are American, but what is there to talk about, really? |
| 08:25 | supersym | lol |
| 08:25 | supersym | oh nothing I just thought there would be an underlying linguistical nature to it...of course it could also be coincidence :D |
| 08:25 | supersym | never mind hehe |
| 08:25 | hyPiRion | Certainly I'd like to have more Norwegians using Clojure, but I'm not sure how to do that. |
| 08:26 | supersym | I'll be a good boy and go back top work |
| 08:26 | hyPiRion | Most certainly it's because Rich is living in the US himself |
| 08:26 | supersym | thats what I thought also |
| 08:26 | hyPiRion | Language is used by people he knows, and the people who know them uses it etc. |
| 08:27 | supersym | so it spreads |
| 08:27 | supersym | Python was made by a dutch guy |
| 08:27 | supersym | so they teach it at uni here because of that? |
| 08:27 | supersym | Perhaps... |
| 08:27 | hyPiRion | supersym: Well, they have it over here too. It seems like Python is very well established in Europe |
| 08:28 | hyPiRion | then again, Python is an old language compared to Clojure |
| 08:28 | supersym | yeah |
| 08:28 | mpenet | there are quite a few clojure users in EU, it's mostly concentrated in the UK and around Germany it seems |
| 08:28 | supersym | and like you said, it has to spread too |
| 08:28 | mpenet | but not a lot of them are often on irc, this might give you the wrong impression |
| 08:29 | supersym | I'd say |
| 08:30 | hyPiRion | mpenet: 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:30 | hyPiRion | /s/I a/I have a/ |
| 08:30 | supersym | ruby probably is more popular in Japan than here |
| 08:30 | mpenet | same here :p |
| 08:39 | ebaxt | hyPiRion: With regards to getting more Norwegians using Clojure. we need success stories and people talking |
| 08:46 | hyPiRion | ebaxt: at Java conferences, or other places? (e.g. JavaZone) |
| 08:47 | ebaxt | hyPiRion: 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:48 | hyPiRion | ebaxt: ah, okay |
| 08:49 | ebaxt | hyPiRion: Just look at Scala, there are plenty of companies using it in Oslo. Conferences like flatmap is also important |
| 08:51 | hyPiRion | ebaxt: 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:52 | hyPiRion | Scala is less frightening in that sense |
| 08:52 | hyPiRion | Certainly, success stories is great, but I wonder if that's enough to pull the enterprise that way |
| 08:54 | ebaxt | hyPiRion: Sure, that's true, but the Scala community has done a good job of marketing specifically to the enterprise as well. |
| 08:56 | no7hing | concerning cheshire, why does this (parse-string "{\"jsonrpc\":\"2.0\",\"result\":\"{}\",\"id\":null}}" true) result in {:jsonrpc "2.0", :result "{}", :id nil} ? |
| 08:56 | no7hing | aka the map stays a string? |
| 08:56 | jcrossley3 | ebaxt: it's not just marketing. java devs *really* value strong type-safety. |
| 08:57 | mpenet | no7hing: it's not a string anymore, look at the keys |
| 08:57 | hyPiRion | jcrossley3: Well, I think that really depends on the developer. I don't think that many people think that hard about it |
| 08:57 | no7hing | @mpenet: i would expect :result to be {} and not "{}" |
| 08:57 | mpenet | oh, "result" |
| 08:58 | mpenet | because it's passed as a string in it's json form |
| 08:58 | mpenet | "{\"jsonrpc\":\"2.0\",\"result\":{},\"id\":null}}" would work |
| 08:58 | mpenet | there is no quote on object litterals in json |
| 08:58 | no7hing | oh damn |
| 08:58 | no7hing | sorry me |
| 09:00 | jcrossley3 | hyPiRion: i'm constantly surprised by it, too. |
| 09:01 | hyPiRion | ebaxt: 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:01 | ebaxt | jcrossley3: 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:02 | jcrossley3 | ebaxt: 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:03 | ebaxt | jcrossley3: That's my experience as well. Which is why I think it's important that we speak up as well ;) |
| 09:03 | mpenet | I 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:04 | mpenet | imho |
| 09:04 | lucian | jcrossley3: if java devs really valued type safety, they wouldn't be using java :) |
| 09:05 | jcrossley3 | lucian: s/type safety/tooling/ :) |
| 09:06 | hyPiRion | lucian: Haskell to the rescue! |
| 09:06 | lucian | hyPiRion: sure, that's what they'd use if they really cared :) |
| 09:06 | lucian | scala isn't that far off, the syntax is just crazy |
| 09:06 | ebaxt | mpenet: 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:06 | lucian | i think it's purely syntax |
| 09:07 | lucian | people hate python for similar reasons |
| 09:10 | hyPiRion | lucian: hm, is the enterprise hating python? I must be in this parallel universe then. |
| 09:10 | lucian | hyPiRion: i meant it as an initial reaction |
| 09:10 | hyPiRion | oh, okay |
| 09:11 | mpenet | same problem with erlang, it solves some problems beautifully, but it's scary to the newcomers |
| 09:12 | lucian | to be fair, erlang's syntax is just stupid |
| 09:12 | hyPiRion | lucian: well, that's subjective, isn't it? :) |
| 09:12 | lucian | hyPiRion: not at all |
| 09:13 | lucian | it has different terminators for the same thing in different contexts! |
| 09:13 | lucian | good luck swapping two lines |
| 09:13 | Pupnik | lisp flavoured erlang to the rescue! |
| 09:13 | lucian | elixir is particularly nice |
| 09:14 | hyPiRion | mpenet: Erlang has a very steep learning curve if you want to build an OTP-compliant app from the beginning |
| 09:17 | hyPiRion | I 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:18 | mpenet | about 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:18 | borkdude | is 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:18 | mpenet | on the backend it's another story |
| 09:19 | lucian | mpenet: the other problem is the silly dependency on the jvm :( |
| 09:19 | mpenet | lucian: you mean for clojurescript? |
| 09:19 | lucian | yes |
| 09:19 | lucian | well, for clojure too |
| 09:19 | lucian | but it's a bit more forgivable there |
| 09:20 | mpenet | lucian: well without it, no google closure |
| 09:20 | lucian | don't care much about that |
| 09:20 | mpenet | lucian: you should, unless you want to serve mb of js files |
| 09:20 | lucian | at least not early in development |
| 09:20 | lucian | having to wait for the stupid jvm to spin up every single time i want to do something with lein is infuriating |
| 09:20 | lucian | that's why i always give up on trying to use clojure(script) |
| 09:21 | mpenet | lucian: lein cljsbuild solves that pretty much |
| 09:21 | lucian | language is nice, but the runtime is fucking useless |
| 09:21 | mpenet | lucian: or repl dev |
| 09:21 | lucian | mpenet: not really |
| 09:21 | mpenet | lucian: I find it fast enough in most case |
| 09:21 | lucian | it takes more than 2sec to start up, always |
| 09:21 | lucian | python takes a few ms |
| 09:22 | mpenet | lucian: you just start it up once, "lein cljsbuild auto" |
| 09:22 | lucian | right, and it takes about 10sec to start up once |
| 09:22 | lucian | and several seconds to notice it has to compile things |
| 09:22 | hyPiRion | lucian: You may want to watch out for https://github.com/halgari/clojure-metal |
| 09:22 | mpenet | lucian: yeah but once a day, it's fine, eclipse probably takes longer to launch :p |
| 09:22 | lucian | hyPiRion: i'd be happy with self-hosted clojurescript |
| 09:22 | Pupnik | lucian, use clojure-clr instead? |
| 09:22 | lucian | mpenet: that's another thing i don't use because of latency |
| 09:23 | mpenet | lucian: I dont use eclipse either, but this was an example, 10secs in a day is nothing |
| 09:23 | lucian | Pupnik: is that still alive? i thought it had bitrotted |
| 09:23 | lucian | mpenet: it is if the alternative is 0sec |
| 09:23 | hyPiRion | lucian: well, when we get it up to production value, I'll certainly start to port Lein over |
| 09:23 | lucian | hyPiRion: that would make me very, very happy :) |
| 09:24 | lucian | as for a clojure vm, i think a RPython one would have a better chance of actually making it |
| 09:24 | Pupnik | lucian, https://github.com/clojure/clojure-clr/commits/master plenty of stuff going on |
| 09:25 | hyPiRion | lucian: right, a restricted clojure vm? |
| 09:25 | hyPiRion | or, a subset of clojure? |
| 09:25 | lucian | hyPiRion: one built on RPython? no, it'd be a full vm, with a jit for free |
| 09:25 | lucian | if someone were to build such a thing |
| 09:26 | lucian | Pupnik: that's nice. i guess mono's startup time is not as terrible |
| 09:26 | hyPiRion | lucian: Timothy already did some stuff on top of pypy |
| 09:27 | hyPiRion | (halgari or tbaldrige, or what he goes by these days) |
| 09:27 | blrm | https://github.com/halgari/clojure-py |
| 09:28 | lucian | that is probably an easier path, since there already is a Python VM written in RPythonn (PyPy) |
| 09:29 | lucian | there are basically two things i'd like to use clojure for: 1) replacing javascript and 2) replacing java on android |
| 09:29 | lucian | the first will be easy when clojurescript is self-hosted |
| 09:29 | lucian | the second, i don't know. clojure bootstrap on android still takes many seconds |
| 09:30 | hyPiRion | lucian: Given you do no eval/resolve/etc, and perform some tree shaking, that shouldn't be impossible if one tweak AOT compilation. |
| 09:31 | hyPiRion | But that's has a long way to go, sadly. |
| 09:31 | lucian | hyPiRion: the latest effort i've seen is http://nightweb.net/ |
| 09:31 | lucian | but even on my nexus 4 it takes 5-10s to start up |
| 09:31 | lucian | at this point, xamarin or scala are still the only other options i consider reasonable for android dev |
| 09:32 | hyPiRion | heh |
| 09:34 | qz_ | lucian: scala suffers from same startup time problems plus slow compilation :) |
| 09:36 | lucian | qz: the few android apps i've seen appear to start up fast enough |
| 09:39 | borkdude | ,(apply map vector nil) |
| 09:39 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map> |
| 09:40 | borkdude | is this sane behavior? |
| 09:42 | hyPiRion | borkdude: yes |
| 09:43 | hyPiRion | ,(map vector) ;; is essentially what you do |
| 09:43 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map> |
| 09:43 | borkdude | (apply + [1 2 3]) == (+ 1 2 3), (apply + nil) == (+ … well, nothing to see here?) like that? |
| 09:44 | hyPiRion | right |
| 09:45 | hyPiRion | ,[(apply map vector nil nil) (apply map vector [[]])] |
| 09:45 | clojurebot | [() ()] |
| 09:48 | borkdude | what 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:49 | asteve | ,(/ 3 1) |
| 09:50 | clojurebot | 3 |
| 09:50 | asteve | ,(/ 1 3) |
| 09:50 | clojurebot | 1/3 |
| 09:54 | scottj | borkdude: I thought the reason was clojure compiler is single pass, but the actual reason might be more subtle. |
| 09:57 | noidi | borkdude, https://news.ycombinator.com/item?id=2467359 |
| 10:00 | borkdude | noidi thanks |
| 10:09 | `fogus | scottj: Clojure's compiler is not single pass |
| 10:24 | devn | good morning all |
| 10:25 | rbxbx_ | devn g'morn |
| 10:27 | Guest98868 | is 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:33 | sundbp | anyone using expectations for testing around? |
| 10:40 | gfredericks | Guest64100: 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:41 | danielglauser | gfredericks: I saw a presentation that showed you could do anything with macros |
| 10:45 | gfredericks | danielglauser: I think I specifically pointed out this sort of thing as an example of what you can't do with macros |
| 10:45 | borkdude | question: 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:46 | borkdude | (swap! (if … ….)) ? |
| 10:46 | danielglauser | gfredericks: I know, just razzing you :) |
| 10:46 | gfredericks | borkdude: wat? |
| 10:47 | gfredericks | borkdude: the conditional is based on the value of the atom? |
| 10:47 | borkdude | borkdude yeah |
| 10:47 | borkdude | gfredericks yeah |
| 10:47 | gfredericks | borkdude: then you do that logic inside the swap function |
| 10:47 | borkdude | example: |
| 10:47 | gfredericks | (swap! a #(if (foo %) (bar %) (baz %))) |
| 10:48 | borkdude | gfredericks this is not good, I should have used swap! anyway: https://github.com/borkdude/tictactoe/blob/master/src/tictactoe/model.clj#L29 |
| 10:48 | borkdude | gfredericks this is how I've done it now https://gist.github.com/borkdude/5292814 |
| 10:49 | borkdude | gfredericks play! is near the bottom of the file now |
| 10:52 | borkdude | gfredericks in this case it doesn't matter much, because the session is updated within one thread, but in general |
| 10:52 | borkdude | gfredericks it would mean though, that a swap would always happen, either with a new value or the old value just gets stored back |
| 10:53 | gfredericks | I think that's fine |
| 10:54 | borkdude | gfredericks what, that a swap would always happen? |
| 10:55 | gfredericks | yeah |
| 10:55 | gfredericks | though if this is all single-threaded, maybe an atom isn't what you want to be using |
| 10:56 | borkdude | gfredericks I'm using noir.session |
| 10:56 | borkdude | gfredericks and that is using an atom |
| 10:56 | gfredericks | oh right |
| 10:56 | gfredericks | nm then |
| 10:56 | borkdude | gfredericks what alternative would you have in mind? I used an atom before I made this a web app |
| 10:57 | gfredericks | hwelp if you have some "state" you could just write functions that transform it. I guess it's the state monad really. |
| 10:57 | gfredericks | er, burrito |
| 10:58 | borkdude | gfredericks the web app monad - I could do it, but I'd have to trust the user not to manipulate his data ;) |
| 11:00 | borkdude | gfredericks I could also use ring sessions which are more functional, but I doubt if that would make this better |
| 11:23 | TimMc | borkdude: That's what cryptography is for. |
| 11:24 | gfredericks | well there's two "non-stateful" approaches to session middleware |
| 11:24 | gfredericks | one is to put all the data in the cookie which I imagine is what you're referring to |
| 11:24 | TimMc | Maybe you should thread the entire database state through all requests. |
| 11:24 | gfredericks | the 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:26 | borkdude | gfredericks I think I have used the latter one. but how is the first not stateful? |
| 11:26 | gfredericks | haha |
| 11:26 | gfredericks | borkdude: not stateful from the server's perspective |
| 11:26 | borkdude | gfredericks I haven't used it now, but some other time |
| 11:26 | borkdude | gfredericks right |
| 11:27 | borkdude | gfredericks other way would not to use cookies but codify the state in some hidden field in the form |
| 11:30 | borkdude | gfredericks I think Microsoft does this in ASP.NET or smth |
| 11:36 | TimMc | It's really irritating. |
| 11:36 | mpenet | borkdude: they call that PageState... heretics. You used to end up with 100s of KBs of pagestate per page on some apps. |
| 11:36 | TimMc | As a user, that is. |
| 11:37 | borkdude | mpenet In my memory they called it ViewState but they might have changed it |
| 11:37 | mpenet | right |
| 11:37 | TimMc | Death to timestamps. |
| 11:38 | TimMc | (It really bugs me when a form submission becomes invalid just because I let the page sit open too long.) |
| 11:38 | TimMc | Never mind, that can actually be an issue where ever the state is kept, if it expires. |
| 11:38 | geckos | What the last dot means at (java.util.Date.) |
| 11:38 | geckos | ? |
| 11:39 | borkdude | geckos creation |
| 11:39 | borkdude | geckos calling the constructor |
| 11:39 | geckos | borkdude: thanks |
| 11:39 | nDuff | geckos: It's syntactic sugar for (new java.util.Date) |
| 11:59 | squidz | cemerick: 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:00 | geckos | nDuff: I see... thanks again.. I'll stay with new aproach since I'm not an cloj guy, :-) |
| 12:00 | squidz | i mean ["first", "second"] |
| 12:10 | ticking | clojures contribution policy is like a open halway, stuffed with barbwire, in thereory you can get to the end |
| 12:13 | joegallo | ticking: right, it'll tear the very meat from your bones, but you can get there in theory ;) |
| 12:14 | nDuff | Not so annoying for anyone who attends the conferences -- CAs sitting out ready to sign. |
| 12:15 | joegallo | the CA is just the moat, though, there's more stuff after that |
| 12:21 | technomancy | a miniboss |
| 12:34 | gfredericks | I wonder what the clochure contribution policy is like |
| 12:34 | technomancy | (constantly :rofl) |
| 12:34 | technomancy | I was hoping to get some good joke pull requests for lein-xml |
| 12:35 | technomancy | maybe someone all "XML is too strict; can we use SGML instead?" |
| 12:35 | joegallo | damn, that would have been a good one |
| 12:35 | joegallo | i'm sorry, technomancy |
| 12:36 | technomancy | there's always next year |
| 12:36 | Foxboron | technomancy: i am still not sure if lein-xml was a april fools or not ._. |
| 12:37 | hyPiRion | lein-png: Whenever you need to ensure that project.clj is syntax highlighted the same on all machines. |
| 12:37 | hyPiRion | project.png |
| 12:38 | gfredericks | need to make a change? photoshop has never been more user |
| 12:38 | gfredericks | friendly |
| 12:38 | technomancy | hyPiRion: lein-piet |
| 12:38 | hyPiRion | technomancy: hah, that would actually be fancy |
| 12:39 | hyPiRion | It's rather simple too, so why not |
| 12:39 | hyPiRion | well, easy* |
| 12:40 | technomancy | hyPiRion: well, you have twelve months now =) |
| 12:40 | hyPiRion | Foxboron: 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:40 | gfredericks | xmleiningen |
| 12:41 | hyPiRion | It's a plugin for now though, since it breaks compability. |
| 12:41 | jeremyheiler | I 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:41 | Foxboron | hyPiRion: and the 1st of april date was not planned at all :P? |
| 12:42 | technomancy | jeremyheiler: 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:44 | jeremyheiler | technomancy: Haha. |
| 12:47 | tupi` | hello |
| 12:54 | tupi` | 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:55 | nDuff | tupi`: We may not know the library, but we still may be able to answer questions about problems you're having. |
| 12:55 | hyPiRion | technomancy: Well, better start today then: https://github.com/hyPiRion/ariel |
| 12:55 | tupi` | nDuff: thanks |
| 12:57 | tupi` | 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:57 | technomancy | hyPiRion: fun times |
| 12:57 | tupi` | also, fiji says they use clojure 1.3, this could be a problem i guess. here the Q: |
| 12:57 | hyPiRion | tupi`: You don't suffer, you're free from the chains man |
| 12:59 | tupi` | suppose i do (import ... '(ij Menus)) then (let [commands (keys (. Menus getCommands)) .. |
| 12:59 | tupi` | it works, but this does not: |
| 12:59 | tupi` | (let [commands (keys (.getCommands Menus)) ... |
| 12:59 | tupi` | |
| 12:59 | tupi` | and i am particularly interrested in the lisp-ish way of writting code |
| 12:59 | dnolen | lynaghk: http://trifacta.github.com/vega/ |
| 13:00 | nDuff | tupi`: Sounds to me like getCommands is a static method, no? |
| 13:00 | nDuff | (Menus/getCommands) |
| 13:00 | nDuff | ...if that is in fact the case. |
| 13:00 | tupi` | checcking |
| 13:01 | tupi` | it says it's in static java.util.Hashtable |
| 13:01 | nDuff | Not its return value, the method itself. |
| 13:01 | tupi` | public static java.util.Hashtable getCommands() |
| 13:01 | nDuff | Exactly. So it's the syntax I gave earlier, (Menus/getCommands) |
| 13:02 | nDuff | tupi`: http://clojure.org/java_interop#Java Interop-(Classname/staticMethod args*) |
| 13:03 | tupi` | ah: this clarifies, tx |
| 13:05 | lynaghk | dnolen: 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:05 | lynaghk | dnolen: visualization + data all the thigns, I mean =) |
| 13:21 | tomoj | cemerick: 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:30 | tomoj | alternatively, people will need to manually carry those vars over any async boundary in the code under test? hoping I'm confused.. |
| 13:31 | steves-erc | Is there a modulus relation in clojure.core.logic.fd or does anybody know how you would make one? |
| 13:32 | tupi` | 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:33 | tupi` | [i realize it's a java quiz but...] |
| 13:37 | dnolen | steves-erc: there's isn't one |
| 13:38 | tupi` | 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:38 | technomancy | tupi`: no need to assume; try it with macroexpand-1 |
| 13:39 | dnolen | steves-erc: http://www.swi-prolog.org/man/clpfd.html, supported by SWI so we should probably consider it. |
| 13:39 | technomancy | ,(macroexpand-1 (doto 'my.namespace (require) (in-ns) (prn))) |
| 13:39 | clojurebot | #<FileNotFoundException java.io.FileNotFoundException: Could not locate my/namespace__init.class or my/namespace.clj on classpath: > |
| 13:39 | tupi` | technomancy: of course! tx |
| 13:39 | technomancy | oops |
| 13:39 | technomancy | ,(macroexpand-1 '(doto 'my.namespace (require) (in-ns) (prn))) |
| 13:39 | clojurebot | (clojure.core/let [G__74 (quote my.namespace)] (require G__74) (in-ns G__74) (prn G__74) ...) |
| 13:40 | saolsen_ | dnolen: would it be some recursive thing with *? |
| 13:43 | S11001001 | ,java.awt.Color/red |
| 13:43 | clojurebot | #<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:45 | hyPiRion | ,(import java.awt.Color) |
| 13:45 | clojurebot | #<NoClassDefFoundError java.lang.NoClassDefFoundError: Could not initialize class java.awt.Color> |
| 13:46 | dnolen | saolsen_: 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:48 | saolsen_ | dnolen: cool |
| 13:52 | cemerick | squidz: use clj->js |
| 13:53 | squidz | cemerick: okay thanks ill give it a try |
| 13:55 | cemerick | tomoj: I don't know. That whole topic is entirely theoretical to me at the moment, so heft that salt liberally. |
| 14:08 | technomancy | has anyone experimented with a transactional require? |
| 14:10 | gfredericks | technomancy: environment as a value? |
| 14:10 | gfredericks | wouldn't that require being able to unload code? |
| 14:11 | technomancy | gfredericks: not if the ns map was a ref, I think? |
| 14:11 | gfredericks | so we're at _least_ hoping there aren't top-level side effects |
| 14:12 | technomancy | gfredericks: of course; you can easily break transactionality in any ref if you do something stupid |
| 14:13 | technomancy | I don't think defonce would be hard though |
| 14:13 | technomancy | oh yuck; it's all jabba code |
| 14:13 | gfredericks | (defmacro deftwice ...) |
| 14:13 | technomancy | lol |
| 14:13 | technomancy | yeah, so mappings in Namespace.java is just an AtomicReference |
| 14:14 | technomancy | if I knew Java maybe that could be a seajure hack |
| 14:15 | gfredericks | if you're not using your own fork of clojure you're not doing real work |
| 14:15 | technomancy | srsly |
| 14:16 | gfredericks | porting the java code to scala could have been a decent project for yesterday |
| 14:16 | gfredericks | or groovy? |
| 14:16 | nDuff | *shudder* |
| 14:16 | nDuff | gfredericks: Scala, please. Groovy is awful. |
| 14:17 | cemerick | technomancy: not for long; the happy path is straightforward. The further you stray from that, the more it's like swiss cheese. |
| 14:17 | gfredericks | ok groovy it is. |
| 14:17 | nDuff | gfredericks: ...if you don't grok _how_ awful, take a look at the bytecode it generates. |
| 14:17 | gfredericks | nDuff: I've never even used it |
| 14:17 | nDuff | gfredericks: ...it's reflect-o-riffic; makes sloppily-written Clojure look like the pinnacle of efficiency. |
| 14:18 | technomancy | cemerick: sorry, I don't follow; you're talking about side-effects at the top-level? |
| 14:18 | gfredericks | I also was wondering what cemerick was talking about. |
| 14:19 | cemerick | I was responding to technomancy's original question as to whether anyone's experiemented |
| 14:20 | gfredericks | "straightforward" meaning "using clojure the normal way"? |
| 14:21 | cemerick | gfredericks: "if you're careful"? |
| 14:21 | cemerick | straightforward to replace the atomic references with refs |
| 14:22 | cemerick | of course, you have a serious bootstrapping problem, so you have to use clojure to load an alternatively-rooted clojure |
| 14:22 | gfredericks | cemerick: okay I think I totally misparsed the sentence |
| 14:22 | gfredericks | as "Going straight-forward is the only happy path." |
| 14:23 | gfredericks | do not go left or right. |
| 14:23 | cemerick | otherwise, you'll only ever end up right where you began, eventually |
| 14:23 | gfredericks | random walks in >2 dimensions don't return |
| 14:24 | cemerick | pay me no mind, I'm trying to pick up the pieces of my life after trying vim seriously this morning |
| 14:25 | Glenjamin | does one of these bots have a "tell <someone> <message>" feature? |
| 14:26 | Raynes | Yes. |
| 14:27 | Raynes | $mail amalloy Hi. Now you have to read your messages. |
| 14:27 | lazybot | Message saved. |
| 14:27 | amalloy | $timer 1 0 0 Raynes, you're a jerk |
| 14:27 | lazybot | Timer added. |
| 14:28 | gfredericks | amalloy: slingshot seems to like the &naming-convention with their &throw-context |
| 14:28 | Raynes | Glenjamin: So $mail person message and then that person gets a NOTICE every so often that they can run $mail to get their messages. |
| 14:28 | gfredericks | amalloy: 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 | `arrdem | hum... can anyone tell me why nrepl is vomiting on this deftype? https://www.refheap.com/paste/13215 |
| 14:29 | Glenjamin | ah cool, was expecting something that'll just fire a message next time it sees activity from that person, but that'll work |
| 14:29 | amalloy | gfredericks: for sure that is bad |
| 14:29 | Glenjamin | $mail xeqi haven't found any other bugs, should be good to release |
| 14:29 | lazybot | Message saved. |
| 14:29 | amalloy | you can't tell if some other macro inside the body will expand to include &foo, for example |
| 14:30 | gfredericks | amalloy: and it's also bad to try to macroexpand-all the body before checking? |
| 14:30 | amalloy | if you want, you can bind &foo to a delay of the expensive work, and then symbol-macrolet it to forcing the delay |
| 14:30 | gfredericks | that's kind of deferring the tactic to symbol-macrolet |
| 14:30 | Glenjamin | definterface, haven't seen that before =/ |
| 14:31 | amalloy | deferring the macroexpand-all? |
| 14:31 | amalloy | it is, but symbol-macrolet will do a much better job of it than you will |
| 14:31 | `arrdem | yeah it's relatively new to me as well and I've been having bad luck with it thus far |
| 14:32 | gfredericks | amalloy: you are a wise man of macros |
| 14:34 | amalloy | gfredericks: 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:39 | gfredericks | that is perhaps the most efficient way to make a tribal shaman mask show up at your door |
| 14:44 | Glenjamin | say 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:51 | jeremyheiler | Glenjamin: 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:52 | Glenjamin | yep |
| 14:53 | Glenjamin | the specific case is a test runner reporter for speclj, i'm adding a new type of message |
| 14:53 | Glenjamin | so i want to call it if it exists, but not if it doesnt |
| 15:00 | gfredericks | separate protocol maybe? |
| 15:01 | Glenjamin | yeah, thats where i'm leaning |
| 15:01 | Glenjamin | can i extend the old one in some way? |
| 15:02 | gfredericks | nope |
| 15:08 | jeremyheiler | Glenjamin: I suppose you could use clojure.reflect on it. |
| 15:12 | amalloy | jeremyheiler: no. that is more problems than solutions (for this problem; nothing wrong with clojure.reflect in general) |
| 15:15 | jeremyheiler | amalloy: I suppose. |
| 15:18 | Glenjamin | I'll just add an extra protocol for the new method specifically i think |
| 15:18 | jeremyheiler | Glenjamin: 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:18 | jeremyheiler | Heh, cool. |
| 15:19 | jeremyheiler | no ideal* |
| 15:19 | jeremyheiler | ugh. "not ideal" |
| 15:19 | Glenjamin | i'm not actually sure how many third party reporters are there so it might be as easy to just break them |
| 15:27 | lazybot | Raynes, you're a jerk |
| 15:28 | Raynes | $kill |
| 15:28 | lazybot | KILL IT WITH FIRE! |
| 15:28 | gfredericks | (inc lazybot) |
| 15:28 | lazybot | ⇒ 17 |
| 15:28 | Raynes | gfredericks: I just remembered that I blew you off yesterday, |
| 15:28 | gfredericks | Raynes: laser has made me want static types |
| 15:28 | Raynes | gfredericks: Are you still having those issues? |
| 15:29 | gfredericks | I 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:29 | gfredericks | e.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:29 | gfredericks | so I have to call zip to turn it back into a zipper? |
| 15:29 | gfredericks | I need a hoogle so I can look up the type signatures |
| 15:30 | Raynes | fragment should be returning a collection of zippers which you should be able to pass to another fragment. |
| 15:30 | gfredericks | a collection of zippers, that's the fourth type :) |
| 15:31 | Raynes | Give me a link to your code again and I'll try to simplify and explain it. |
| 15:35 | gfredericks | Raynes: https://www.refheap.com/paste/13189 |
| 15:35 | gfredericks | my most common error is 'Not a valid node' followed quickly by NPEs |
| 15:38 | amalloy | gfredericks: i don't think you want to parse-fragment there: a fragment is a collection of nodes, and therefore has multiple "content"s |
| 15:38 | gfredericks | how do I parse a single node? |
| 15:38 | amalloy | l/parse? it's what you did with page |
| 15:39 | gfredericks | no that's for whole documents |
| 15:39 | gfredericks | will add <html> and such |
| 15:39 | amalloy | ugh |
| 15:39 | amalloy | well, i don't actually know how to use laser |
| 15:41 | gfredericks | I 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:41 | hyPiRion | Raynes: I think that was a lazybot timer |
| 15:42 | amalloy | he knows :P |
| 15:42 | gfredericks | I'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:42 | hyPiRion | $timer 20:32:05 All hail our overlord rhickey. |
| 15:42 | lazybot | Timer added. |
| 15:42 | Raynes | gfredericks: Looking. |
| 15:42 | Raynes | I just typed git repl |
| 15:42 | Raynes | x)x |
| 15:42 | Raynes | x_x* |
| 15:43 | hyPiRion | Heh, I tend to write /chmod * +o when I want to give people op |
| 15:43 | Raynes | lol |
| 15:44 | Raynes | gfredericks: That code works fine for me broseph. |
| 15:44 | Raynes | gfredericks: 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:44 | TimMc | :-( |
| 15:45 | gfredericks | Raynes: I am not I am using 1.0.0. I think I got that by looking at your tags on github. |
| 15:45 | Raynes | gfredericks: Seriously dude, I tag shit sporadically. |
| 15:45 | Raynes | I'm just a bad guy in general. |
| 15:45 | TimMc | hyPiRion: 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:46 | gfredericks | now I know |
| 15:46 | Raynes | $latest me.raynes/laser |
| 15:46 | lazybot | [me.raynes/laser "1.1.1"] -- https://clojars.org/me.raynes/laser |
| 15:46 | Raynes | gfredericks: ^ Always use that to find the current version of my libs. |
| 15:46 | Raynes | Seriously dude, I'm terrible at marketing. |
| 15:46 | hyPiRion | TimMc: that'd be like, "Imma charging my... lazybot" |
| 15:46 | Raynes | Don't listen to anything I say. |
| 15:47 | gfredericks | TimMc: I never grocked enlive any better. This might be inevitable for this kind of library. |
| 15:47 | hyPiRion | TimMc: oh hey |
| 15:47 | Raynes | gfredericks: The good news is that you have me whereas cgrand doesn't frequent this channel. |
| 15:47 | Raynes | I also have a nice American sense of humor. |
| 15:48 | gfredericks | Raynes: I am a thankful person. Have you considered protocols and records for some of this stuff? |
| 15:48 | Raynes | For some of what? |
| 15:48 | amalloy | gfredericks: why? |
| 15:48 | Raynes | I haven't because wtf why. |
| 15:48 | amalloy | well, my reaction isn't as strong as Raynes's. he's allergic to protocols |
| 15:48 | hyPiRion | TimMc: If lazybot still listened to clojurebot, we could've made a "quine"-like thing which did exactly what you described |
| 15:49 | gfredericks | amalloy: Raynes: it might make it easier to implement transformations when people like me use the wrong sort of thing in the wrong place? |
| 15:49 | gfredericks | and easier for me to know what kind of thing I have |
| 15:49 | gfredericks | as it is I'm looking at a sequence or a map but it really might be one of at least four different things |
| 15:49 | Raynes | gfredericks: Well, you shouldn't have to care what any of these things are. |
| 15:50 | gfredericks | I see. |
| 15:50 | Raynes | And your biggest problem is that you're using an old version of laser. |
| 15:50 | Raynes | All of this is supposed to Just Work. |
| 15:50 | gfredericks | I look forward to trying the newer one. |
| 15:50 | Raynes | I don't add protocols and records for documentation purposes. :P |
| 15:51 | gfredericks | thanks for the help |
| 15:51 | TimMc | Raynes: I don't like the Clojure community's half-assed approach to versioning. |
| 15:51 | dobladez | gurus: any idiomatic way or standard function to check if a map is fully contained in another one? |
| 15:51 | Raynes | TimMc: I usually tag. I wrote a lein task to do it for me. |
| 15:52 | TimMc | dobladez: No standard function. You want key and value equality? select-keys is a first step. |
| 15:52 | hyPiRion | TimMc: what do you mean? |
| 15:52 | TimMc | dobladez: (= small (select-keys big (keys small))) *almost* does it... |
| 15:53 | dobladez | TimMc: both keys and values. Thanks |
| 15:53 | TimMc | Throw in an `and` and something from clojure.set and you're on your way. |
| 15:53 | dobladez | yep, propably "recur" on that and I'll be close |
| 15:53 | TimMc | recur? why? |
| 15:53 | Glenjamin | is there an updated cheatsheet for 1.5? |
| 15:53 | Raynes | TimMc: Maybe I was drunk when I released that. *shrug* |
| 15:53 | Raynes | I feel bad now. |
| 15:54 | Raynes | How do you tag old commits? |
| 15:54 | hyPiRion | (every? (partial find superset) (keys subset)) should work, I think |
| 15:54 | dobladez | TimMc: well... I need to check the whole structure, not just the top-level keys / values |
| 15:54 | hyPiRion | oh, urhg, then if you want more than key equality |
| 15:55 | Raynes | TimMc: There we go, all tagged up. |
| 15:55 | TimMc | Raynes: Oh, not the tagging -- this is about semver. |
| 15:55 | TimMc | Although tagging is really important too. |
| 15:55 | Raynes | Yeah, you're not going to get me to stick to semver strictly. |
| 15:57 | hyPiRion | TimMc: So how would you usually do that kind of stuff? |
| 15:57 | hyPiRion | Are you not happy with 0.1.0-RC10-alpha1? |
| 15:57 | mklappstuhl | Hey |
| 15:58 | mklappstuhl | does it make sense to write a "short running" cli application in clojure? (thinking of JVM boot time mainly) |
| 15:59 | Raynes | mklappstuhl: It depends on how often you need to run it and how fast you need it to run. |
| 15:59 | Raynes | A Clojure CLI app can usually run in 2-3 seconds. |
| 15:59 | Glenjamin | the bigger issue with clojure versioning seems to be that every lib i see depends on old versions of everything |
| 15:59 | Raynes | I imagine that could be lessened a bit further with some fancy JVM options. |
| 16:00 | Raynes | And if you use drip, it could be mitigated even more I expect. |
| 16:00 | hyPiRion | mklappstuhl: if you mean "less than 2 second short" then you shouldn't |
| 16:00 | Raynes | But it really depends on your specific usecase. |
| 16:00 | Raynes | hyPiRion: 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:00 | Raynes | :p |
| 16:00 | mklappstuhl | Raynes: hyPiRion: It'd be some simple script fetching some data from the internet |
| 16:01 | Raynes | https://github.com/Raynes/updoc |
| 16:01 | Raynes | mklappstuhl: ^ Example command-line app that I wrote. |
| 16:01 | Raynes | If you're interested. |
| 16:01 | TimMc | hyPiRion: 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:01 | borkdude | hmz, 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:01 | mklappstuhl | I also had the idea that some other runtime like JS could be used... |
| 16:02 | Raynes | You could do it in clojurescript with node.js. You could also toss yourself out a 10 story window. |
| 16:02 | hyPiRion | TimMc: Alright, that's what I though. x.y.z where x is breaking changes, y is enhancements/additions and z is bugfixes |
| 16:02 | gfredericks | borkdude: those aren't exactly CPU-bound functions |
| 16:02 | mklappstuhl | Raynes: clojurescript no good? |
| 16:03 | borkdude | gfredericks oh right |
| 16:03 | gfredericks | borkdude: the real question is why pmap gets it all the way to 1 second rather than 2 or 3 |
| 16:03 | hyPiRion | borkdude: because they don't run. When a thread starts sleeping, another takes over |
| 16:04 | nDuff | Glenjamin: Unless those specifications include version ranges, though, lein should be able to substitute in the newer/current versions without issue. |
| 16:04 | borkdude | hyPiRion right |
| 16:04 | nDuff | Glenjamin: ...ie. usually, version specifications are minimum with no maximum. |
| 16:04 | technomancy | Raynes: 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:04 | borkdude | I 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:04 | Raynes | technomancy: I absolutely can. |
| 16:04 | gfredericks | borkdude: how long does it take for 100? |
| 16:05 | Raynes | technomancy: You could send me a pull request and get in the contributor graph. |
| 16:05 | Raynes | It's like winning. |
| 16:05 | hyPiRion | but yeah, pmap is weird, and spawns n+2 threads, where n is the amount of threads. And some other weird stuff |
| 16:05 | technomancy | tempted |
| 16:05 | TimMc | Raynes: That would be a pretty impressive window. |
| 16:05 | Glenjamin | nDuff: it mostly seems to work when newer libs are pulled in, but any non-back-compat changes would leave things totally broken |
| 16:05 | borkdude | gfredericks about 4 seconss |
| 16:05 | nDuff | Glenjamin: Sure. This isn't #ruby; backwards-incompatible changes to documented semantics are rare. |
| 16:05 | gfredericks | huh. |
| 16:06 | nDuff | Glenjamin: ...thus, the thing that's an issue is code relying on on _undocumented_ semantics. |
| 16:06 | borkdude | gfredericks 1000 takes a lot longer though, 32 seconds |
| 16:06 | TimMc | Which is pretty common. |
| 16:06 | Glenjamin | so basically we trust people to build libs without breaking things, and don't worry about it |
| 16:07 | gfredericks | borkdude: yeah at some point it would scale linearly |
| 16:07 | borkdude | gfredericks maybe I have to come up with a better example than Thread/sleep |
| 16:07 | gfredericks | how about ((apply comp (repeat 1000000 identity)) 42) |
| 16:08 | nDuff | Glenjamin: Pretty much, yes. |
| 16:09 | Glenjamin | i gotta be careful not to mock too much in my tests then |
| 16:10 | amalloy | gfredericks: 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:11 | borkdude | gfredericks hm, the pmap version of this take a looong time with only 10 elements |
| 16:13 | borkdude | gfredericks hm https://www.refheap.com/paste/13218 |
| 16:16 | igorw | does 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:17 | Raynes | technomancy: https://github.com/Raynes/laser#laser |
| 16:17 | technomancy | igorw: I am suspicious as to whether it actually helps |
| 16:17 | technomancy | my observations have been more that it actively hurts when semver isn't applied, but not the other way around |
| 16:17 | brehaut | ~version ranges |
| 16:17 | clojurebot | version ranges are nothing but trouble: http://nelsonmorris.net/2012/07/31/do-not-use-version-ranges-in-project-clj.html |
| 16:17 | technomancy | Raynes: capital |
| 16:18 | Raynes | I broke travis-ci by force pushing 4 times in a row because I screwed up the README. |
| 16:18 | Raynes | And it won't let me restart the build. |
| 16:18 | technomancy | oof |
| 16:18 | Raynes | Where is antares when you need him. |
| 16:18 | Raynes | Oh, it's restarting automatically. |
| 16:18 | Raynes | Not bad, travis. |
| 16:18 | Glenjamin | heh, there really needs to be better github readme preview tooling |
| 16:18 | technomancy | sometimes I test github's markdown via gist, but I know you might not believe in that |
| 16:19 | Raynes | technomancy: Yeah, but this required that the file be in the git repo so it was a catch 22. |
| 16:19 | Raynes | https://travis-ci.org/Raynes/laser Yey green. |
| 16:19 | technomancy | aha |
| 16:20 | Glenjamin | Raynes: technomancy https://github.com/ypocat/gfms |
| 16:20 | Glenjamin | nDuff: do you think as the ecosystem grows, the fuzzy version matching lein does will become an issue? |
| 16:20 | technomancy | igorw: but lein inherits its version range support from aether, which unfortunately provides a fairly broken implementation |
| 16:21 | nDuff | Glenjamin: Given as lein inherits that behavior from a far larger ecosystem, I'm not so worried. |
| 16:21 | Glenjamin | versions in java suck too :( |
| 16:21 | Glenjamin | or maybe thats just from my pov |
| 16:22 | technomancy | the problem is it's more difficult to isolate off entire subtrees of the dependency graph with java than clojure |
| 16:25 | hq1 | noob question, out of curiosity: using the Clojure REPL can I inspect the running system/VM like in Erlang? |
| 16:25 | nDuff | hq1: You certainly can inspect the running instance. |
| 16:25 | nDuff | hq1: "like in Erlang" requires more knowledge of Erlang than all of us have. :) |
| 16:25 | igorw | technomancy: 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:26 | hyPiRion | nDuff: well, with rebar you can open up a console of a running OTP program |
| 16:26 | hyPiRion | Not sure if that explains anything to you though. |
| 16:26 | TimMc | &(get-in 5 []) |
| 16:26 | lazybot | ⇒ 5 |
| 16:26 | technomancy | hq1: 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:26 | hq1 | hyPiRion: you don't need rebar at all (to put it mildly it isn't the greatest software in the Erlang's ecosystem) |
| 16:27 | technomancy | but it's trivial to do |
| 16:27 | hq1 | so there's nothing stopping me from testing some functions in a production system runtime? |
| 16:28 | nDuff | hq1: If you set up that production system to have run an nrepl server or swank, correct. |
| 16:28 | technomancy | hq1: 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:28 | hq1 | just got my first Clojure book, will stop asking noob questions soon ;) |
| 16:28 | hq1 | thanks guys |
| 16:31 | hq1 | nDuff: 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:31 | nDuff | hq1: ...whereas the Clojure equivalent is using nrepl to remote in, potentially with drawbridge to tunnel over HTTP. |
| 16:32 | technomancy | clojure 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:32 | technomancy | OTOH you are able to get much better performance communicating between them |
| 16:32 | hq1 | hehe I'm biased so I won't get into this discussion :P |
| 16:33 | technomancy | erlang is better for things that erlang is better for; we can leave it at that. =) |
| 16:33 | hq1 | yes please ;) |
| 16:34 | jack_rabbit | So 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:34 | hq1 | still 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:36 | hq1 | are there any resources you guys would recommend to learn about JVM itself? |
| 16:37 | joegallo | like, java generally, or the jvm specifically? |
| 16:37 | amalloy | jack_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:37 | hq1 | JVM specifically, I am so *not* interested in Java itself. am I a bad person? |
| 16:38 | technomancy | s'ok |
| 16:38 | Glenjamin | i think that makes you sane. |
| 16:38 | ztellman | jack_rabbit: what are you trying to do, at a high level? |
| 16:38 | jack_rabbit | amalloy, I'm just not liking having to create byte buffers for my read calls. |
| 16:38 | jack_rabbit | ztellman, At this point it's just an exercise creating a ServerSocket and reading input from the client. |
| 16:39 | jack_rabbit | (who is connecting through telnet) |
| 16:39 | hq1 | still, 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:39 | hyPiRion | hq1: You're not a bad person. |
| 16:39 | hyPiRion | Java isn't the worst language to work with, but well, I've seen better |
| 16:40 | brehaut | hyPiRion: swearjure for instance |
| 16:40 | amalloy | (inc brehaut) |
| 16:40 | lazybot | ⇒ 10 |
| 16:40 | hyPiRion | brehaut: hahah, I was for once not thinking about that |
| 16:40 | ztellman | jack_rabbit: clojure.java.io will give you enough to avoid dealing with bytebuffers |
| 16:41 | ztellman | but if you end up wanting to try aleph, I can give some pointers there too |
| 16:41 | hq1 | OK, so is there a place I can learn about JVM not being forced to read about AbstractFactoryStrategySingletons? |
| 16:41 | combataircraft | question: 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:41 | amalloy | jack_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:41 | technomancy | hq1: this article is pretty great: http://copperthoughts.com/p/clojure-io-p1/ |
| 16:42 | hq1 | technomancy: ty, bookmark'd |
| 16:42 | technomancy | I/O is the most common place Java stuff sticks out |
| 16:42 | jack_rabbit | amalloy, ztellman Thanks I'll try out all that stuff. |
| 16:42 | ztellman | amalloy: bite your tongue, everything I write is intuitive and immediately effortless to use |
| 16:42 | combataircraft | I need some kind of parameter templating for editing creating functions. any ideas ? |
| 16:42 | hyPiRion | hq1: 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:43 | amalloy | combataircraft: what on earth does that question mean? |
| 16:43 | hyPiRion | Otherwise everything else should not have a need for Java. |
| 16:43 | nDuff | Eh. One certainly has to know how to read javadocs. |
| 16:43 | hq1 | hyPiRion: but I'd like to be able to call some external, hairy Java libs. Is that a problem at any point? |
| 16:43 | nDuff | One has to know how java's variadic arguments work. |
| 16:43 | combataircraft | amalloy: 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:44 | nDuff | One 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:44 | technomancy | you need to know not to use java.util.Date |
| 16:44 | hq1 | I can grok those I guess ;) |
| 16:44 | technomancy | hq1: there's no substitute for hanging out on IRC though |
| 16:44 | amalloy | i'll get back to you if i ever find something you've written that is immediately effortless, ztellman |
| 16:44 | hyPiRion | hq1: Well, if you would like to do that, then you should know some Java, yeah. |
| 16:44 | ztellman | amalloy: :) |
| 16:45 | gtrak | any hadoop-app devs here? I'm curious if anyone's built an automated testing/deployment thing with pallet? |
| 16:45 | rboyd | combataircraft: do you want partial? |
| 16:45 | hq1 | hyPiRion: 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:46 | combataircraft | rboyd: yes partial, but with re-arranging parameters by templating |
| 16:46 | combataircraft | like this; (def get-user 'request "/users/{0}.json") |
| 16:46 | hq1 | hyPiRion: but I'm hoping this to be fully transparent |
| 16:47 | combataircraft | assume 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:47 | hq1 | hyPiRion: like, is there some Java stuff out there I *can't* call from Clojure? |
| 16:48 | amalloy | hq1: no, although there are some things that can be hard |
| 16:48 | nDuff | hq1: 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:48 | hyPiRion | hq1: 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:48 | nDuff | hq1: ...but there's nothing you _can't_ call from Clojure, just things that are tricky. |
| 16:48 | nDuff | hq1: ...well, there are things you can't call from Clojure without an AOT compilation phase. |
| 16:48 | rboyd | combataircraft: (def get-user #(request (str "/users/" % ".json"))) ? |
| 16:48 | hugod | gtrak: https://github.com/pallet/pallet-hadoop if you haven't already seen it |
| 16:48 | gtrak | hugod: yea, I'm on it right now :-) |
| 16:49 | hq1 | ah |
| 16:49 | brehaut | (def get-user (comp request (partial format "/user/%s.json"))) |
| 16:49 | nDuff | hq1: ...unless you're dealing with 3rd-party APIs that inspect objects you pass them for annotations &c., though, those are generally fairly rare. |
| 16:50 | hq1 | nDuff: I might deal with those, but I guess it all could be done with some kind of native Java wrappers as well, right? |
| 16:50 | nDuff | hq1: Yup. |
| 16:50 | hq1 | OK, fair enough, that's perfect |
| 16:50 | rboyd | brehaut: slick |
| 16:50 | nDuff | hq1: 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:51 | combataircraft | rboyd: brehaut: awesome answers, thanks! |
| 16:51 | hq1 | nDuff: I see, thanks for clearing things up a little |
| 16:51 | brehaut | combataircraft: caveat that if you are bashing strings together you might have the wrong abstraction |
| 16:52 | amalloy | hq1: 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:53 | amalloy | the 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:54 | hq1 | amalloy: splendid, thank you, will look into it |
| 17:12 | Glenjamin | is there a way to load-file relative to the current file? |
| 17:12 | Glenjamin | something like __FILE__ in other languages |
| 17:17 | amalloy | Glenjamin: don't do it, man |
| 17:18 | Glenjamin | amalloy: it's to make this work when using a lein checkout: (load-file "src/speclj/version.clj") |
| 17:18 | Glenjamin | inside project.clj |
| 17:22 | technomancy | Glenjamin: if you need access to the version at runtime you can load pom.properties from the jar |
| 17:23 | Glenjamin | it's not my lib, so swapping it around seems like overreaching |
| 17:24 | Glenjamin | i guess in general having logic in project.clj isn't a great idea though :) |
| 17:32 | Glenjamin | i wasn't intending to commit that, just wanted it to work with the checkout |
| 17:32 | Glenjamin | although i got a weird error with interface not matching the protocol, and just used lein install |
| 17:36 | tieTYT | in a let, the way even params are symbols and odd params are evaluated to values is called a binding form? |
| 17:36 | tieTYT | let me resay that |
| 17:36 | tieTYT | in a let, the way odd params are symbols and even params are evaluated to values is called a binding form? |
| 17:38 | gfredericks | technomancy: does slamhound make some attempt to solve the "what vars does this code refer to?" problem? |
| 17:39 | technomancy | gfredericks: heh... well... "some attempt", yes |
| 17:39 | technomancy | "does this compile? no? let's screw with the ns form. how bout now?" |
| 17:39 | gfredericks | oh nice |
| 17:39 | technomancy | brute force search |
| 17:39 | gfredericks | that's brilly |
| 17:39 | technomancy | http://technomancy.us/148 |
| 17:39 | gfredericks | I 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:40 | technomancy | more or less |
| 17:47 | tomoj | tieTYT: the terminology is confusing to me |
| 17:47 | tomoj | I think 'binding form' means the odd forms |
| 17:48 | tomoj | but 'binding' can mean a pair of odd and even? |
| 17:48 | tomoj | (I'm guessing you're 1-indexing?) |
| 17:49 | amalloy | tomoj: 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:49 | tomoj | yeah :( |
| 17:50 | gfredericks | <form> |
| 17:50 | tomoj | core is no help for names internally iirc |
| 17:51 | tomoj | (let [bents (partition 2 bindings)] ...) |
| 17:52 | tomoj | I guess that's an abbreviation for "binding entry"? |
| 17:53 | tomoj | then confusingly loop call it's binding entries 'bfs', binding forms? |
| 17:53 | tomoj | calls its.. |
| 17:55 | gfredericks | I used the term lettings a lot in currj |
| 17:55 | gfredericks | that's a good reason for nobody else to use it |
| 18:01 | gfredericks | this whole using ^:private thing gets really noisy after a while :( |
| 18:02 | gfredericks | for 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:14 | amalloy | gfredericks: so don't write so many dang private functions |
| 18:15 | amalloy | i'd suggest making your public functions be closures around your private functions, but people always laugh at me when i do that |
| 18:15 | amalloy | and i don't need to introduce more pain to your life |
| 18:15 | gfredericks | (let [...privates...] ...def publics...) |
| 18:16 | amalloy | gfredericks: well, that makes it hard to def a private, then a public, then a private... |
| 18:16 | Foxboron | Someone should write a new book about closuers in clojure and call it "Clojure in Closure" |
| 18:16 | amalloy | but it is what i was recommending, yes |
| 18:17 | holo | Foxboron, you mean "Closure in Clojure"? |
| 18:17 | Foxboron | holo: No. "Clojure in Closure" |
| 18:17 | amalloy | you could try something sneaky like (letfn [(private1[]) (public1*[]) (private2[]) (public2*[])] (def public1 public1*) (def public2 public2*)), but yuck |
| 18:20 | Foxboron | holo: it is a pun if you didn't get it ;) |
| 18:20 | Foxboron | been reading Let over Lambda for the past days and just can't come over the fact it would be an awsome name. |
| 18:21 | hiredman | "private" is gross |
| 18:21 | hiredman | it limits reuse |
| 18:22 | technomancy | you can't always design for forever-future-proof re-use |
| 18:22 | hiredman | then don't |
| 18:23 | hiredman | isn'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:24 | technomancy | so the idea of communicating an explicitly demarcated stable API is a waste of time? |
| 18:24 | hiredman | technomancy: sure, communicate it, but making it a pain to work with the other parts is just silly |
| 18:25 | hiredman | how about if you want something to be public you do ^:public |
| 18:25 | technomancy | resolving vars is not really a pain |
| 18:25 | technomancy | it's like two extra chars |
| 18:25 | technomancy | if you're a big kid and you can deal with your own breakage surely you can add two extra chars |
| 18:25 | hiredman | technomancy: sure, but once you start going "oh, I'll put my private bits in a let and close over them" |
| 18:25 | technomancy | hiredman: oh, yeah that's nuts |
| 18:25 | hiredman | which, well, honestly has never stopped me |
| 18:26 | hiredman | but it is super annoying |
| 18:27 | hiredman | we 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:27 | hiredman | of course now there are deref arities with a timeout |
| 18:29 | hiredman | luckily the name of the closed over count down latch has never changed |
| 18:31 | hiredman | ,(->> (class (let [x 1] (fn [] x))) .getDeclaredFields (map #(.getName %))) |
| 18:31 | clojurebot | ("x") |
| 18:33 | Lajjla | ,(let [i "I" worship "worship" his "his" shadow "shadow"] (str I \space worship \space his \space shadow \ space)) |
| 18:33 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unsupported character: \ space> |
| 18:33 | Lajjla | ,(let [i "I" worship "worship" his "his" shadow "shadow"] (str I \space worship \space his \space shadow \space)) |
| 18:33 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: I in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:33 | Lajjla | Oops |
| 18:34 | Lajjla | ,(let [i "I" worship "worship" his "his" shadow "shadow"] (str i \space worship \space his \space shadow \space)) |
| 18:34 | clojurebot | "I worship his shadow " |
| 18:34 | Lajjla | Perfect |
| 18:43 | sandbags | Can 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:43 | sandbags | I looked at the contrib pages but it's not apparent to me from there either |
| 18:43 | amalloy | clojurebot: where did contrib go? |
| 18:43 | clojurebot | well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 18:43 | sandbags | (sorry, "version" meaning what should I put in my leiningen project.clj) |
| 18:45 | sandbags | amalloy: okay i'm a little confused .. from this i deduce there is no longer a single contrib jar file? |
| 18:46 | Raynes | The whole contrib landscape has changed. |
| 18:47 | Raynes | If you're reading the original Stuart Halloway book it's pretty extremely outdated now. |
| 18:47 | sandbags | something of an equivalent heritage it seems |
| 18:47 | brehaut | deintensifier intensifier noun |
| 18:47 | brehaut | high five raynes |
| 18:48 | Raynes | o/ |
| 18:48 | sandbags | okay i found what i needed, apparently it got moved into clojure anyway :) |
| 18:48 | sandbags | thx |
| 18:48 | brehaut | \o |
| 18:52 | tieTYT | in a let, the way the first params are symbols and second params are evaluated to values is called a binding form? |
| 18:52 | amalloy | tieTYT: please read the scrollback from last time you asked thie question before asking it again |
| 18:53 | tieTYT | sorry, i didn't see that |
| 18:53 | Raynes | lol |
| 18:54 | tieTYT | seems like the answer is "nobody knows" |
| 18:55 | tieTYT | does anyone know if Rich Hickey is anti test or just anti-tdd? |
| 18:55 | technomancy | he says regression tests are valuable |
| 18:56 | tieTYT | i see |
| 18:56 | tieTYT | in my limited experience, they're easier to write in clojure than java |
| 18:57 | tieTYT | really hard to write regression tests when you didn't write your code for testability in mind in java |
| 18:57 | tieTYT | at least write it in a way that's "good" |
| 18:57 | ztellman | writing with testing in mind != tdd, though |
| 18:58 | Apage43 | tdd == writing tests with eventually writing code in mind |
| 18:58 | tieTYT | right |
| 18:59 | Raynes | technomancy: http://static.quickmeme.com/media/social/qm.gif |
| 18:59 | dpathakj | tieTYT: you may be interested in http://www.codequarterly.com/2011/rich-hickey/ . search for 'test'. |
| 19:00 | tieTYT | thanks |
| 19:00 | tieTYT | i've read this already |
| 19:01 | Raynes | The good news about programming is that you don't have to do what Rich says. |
| 19:01 | Raynes | If you want to TDD, you go do you some TDD. |
| 19:01 | tieTYT | but Rich says... |
| 19:01 | Raynes | Insert comment about being told to jump off a bridge. |
| 19:03 | amalloy | Raynes: http://xkcd.com/1170/ |
| 19:12 | tomoj | wow, apparently you can set! even non-dynamic vars is cljs |
| 19:14 | Apage43 | does cljs have dynamic vars? |
| 19:14 | amalloy | tomoj: of course. it's the assignment operator, just like in clj-jvm where you can use it to set! public members of objects |
| 19:15 | amalloy | Apage43: does cljs have vars? (no) |
| 19:15 | Apage43 | well there we go |
| 19:17 | tomoj | amalloy: but I would've expected the compiler to throw on setting a non-dynamic var |
| 19:17 | tomoj | at least, directly |
| 19:17 | nDuff | tomoj: ...but on a variant of the languages that doesn't _have_ Vars... |
| 19:17 | amalloy | tomoj: what var? |
| 19:17 | tomoj | vs (set! (.-foo js/cljs.user) 42) |
| 19:17 | tomoj | the compiler knows about vars |
| 19:17 | amalloy | does it? |
| 19:18 | tomoj | indeed |
| 19:18 | tomoj | e.g. if you try to (binding [non-dynamic ..]) you get a warning at least |
| 19:19 | tieTYT | is var short for variable? |
| 19:19 | Apage43 | what does binding do in cljs |
| 19:19 | tomoj | it just set!'s then set!'s back after |
| 19:20 | Apage43 | ah |
| 19:20 | Apage43 | well that makes sense |
| 19:20 | Apage43 | actually |
| 19:20 | nDuff | tieTYT: In Clojure, a Var is a specific construct with specific semantics. |
| 19:20 | nDuff | tieTYT: ...thus, it's not as general a term as a "variable". |
| 19:20 | tieTYT | ok |
| 19:21 | tieTYT | I'm reading this: http://clojure.org/vars |
| 19:21 | tieTYT | Clojure 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:21 | tieTYT | but vars can only do that if theyr'e defined with ^:dynamic right? |
| 19:21 | Raynes | No. |
| 19:21 | tieTYT | i guess the with-redefs is another way |
| 19:21 | hyPiRion | tieTYT: Ever tried (def foo 10) (def foo 20) ? |
| 19:21 | Raynes | You can change a var at any time. |
| 19:22 | Raynes | Not a good example. I'm disappointed. |
| 19:22 | Raynes | $google alter-var-root clojure |
| 19:22 | lazybot | [ClojureDocs - clojure.core/alter-var-root] http://clojuredocs.org/clojure_core/1.2.0/clojure.core/alter-var-root |
| 19:22 | Raynes | Ugh |
| 19:22 | tomoj | (set! + -) |
| 19:22 | tomoj | seems nuts |
| 19:22 | Raynes | I wish I hadn't done that now. |
| 19:22 | hyPiRion | tomoj: Well, you can do that in Java too |
| 19:22 | tieTYT | Raynes: what hyPiRion said isn't a good example? |
| 19:22 | Raynes | I like alter-var-root. |
| 19:22 | tomoj | you can't do (set! + -) in clojure at least |
| 19:23 | hyPiRion | I tried to change Boolean/TRUE to false, and the whole JVM collapsed. Fun times. |
| 19:23 | possibilities | newbie alert! what's the best way to coerce clojurescript output to be a requirejs compat module? |
| 19:23 | nDuff | tieTYT: ...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:24 | Apage43 | possibilities: how do you do it in javascript? |
| 19:24 | nDuff | possibilities: I'd look at how requirejs plays with the Google Closure ecosystem, to start |
| 19:24 | tieTYT | that alter-var-root is interesting |
| 19:25 | possibilities | ok, nuff said, nice way of saying "don't be dumb", thank you. (: |
| 19:25 | hyPiRion | you could do it through java calls too, with .bindRoot |
| 19:26 | hyPiRion | Though well, it's obvious that this dangerous material. |
| 19:26 | nDuff | possibilities: ...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:29 | corecode | oh nice, there is clj->scm |
| 19:29 | corecode | maybe my dream of clj-on-microcontroller will work out? |
| 19:29 | Denommus | hi |
| 19:30 | Denommus | how do I make leiningen detect my $HOME/Projects directory as the root of where I put my projects? |
| 19:30 | hyPiRion | corecode: https://github.com/halgari/clojure-metal |
| 19:30 | corecode | hyPiRion: ooooh |
| 19:30 | corecode | hyPiRion: i was looking at picobit http://www.iro.umontreal.ca/~feeley/papers/StAmourFeeleyIFL09.pdf |
| 19:30 | technomancy | Denommus: leiningen only really works on one project at a time |
| 19:31 | hyPiRion | corecode: oh dang, sweet |
| 19:31 | corecode | hyPiRion: the arm version compiles to 8KB VM code |
| 19:31 | possibilities | thanks peeps. |
| 19:31 | technomancy | Denommus: what is it exactly you're looking for? |
| 19:31 | corecode | hyPiRion: and i think if needed assembler/different coding could get it down to 4KB. |
| 19:32 | hyPiRion | corecode: ooh, I'll find you an interesting one, sec |
| 19:33 | Denommus | technomancy: I'm trying to work with clojure in Emacs, and I'm used to Common Lisp with quicklisp workflow |
| 19:33 | Raynes | technomancy: What are your thoughts on el-get? |
| 19:34 | technomancy | Raynes: it kinda bums me out |
| 19:34 | Raynes | Justin made me write a refheap.el recipe and send the guy a pull request because he won't use elpa directly. :p |
| 19:34 | corecode | ya el-get seemed like The Solution, but now melpa/elpa/marmalade are much better |
| 19:34 | technomancy | Raynes: 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:34 | Raynes | technomancy: 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:35 | Raynes | Makes my skull ache. |
| 19:35 | technomancy | Raynes: 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:35 | jack_rabbit | So... 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:35 | Raynes | technomancy: I do typically do that, but Justin is, you know, my boss more or less. :P |
| 19:36 | technomancy | Raynes: well, if your hands are tied... =) |
| 19:36 | Raynes | technomancy: 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:36 | technomancy | my 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:37 | hyPiRion | corecode: http://hypirion.com/pdf/igor.pdf <- |
| 19:37 | hyPiRion | Sorry, my server spazzed out |
| 19:37 | technomancy | but I'm not the boss of anyone, and package.el has horrible political contribution barriers |
| 19:37 | nDuff | jack_rabbit: a cancel won't do anything that a thread interrupt method won't |
| 19:38 | nDuff | jack_rabbit: see http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#cancel(boolean) |
| 19:38 | nDuff | jack_rabbit: ...note that Java's thread interrupts are, err, somewhat voluntary. |
| 19:39 | nDuff | jack_rabbit: see http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html for more details on that. |
| 19:39 | jack_rabbit | Yeah, 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:39 | Denommus | guys, how do you require your projects in nrepl inside of Emacs? |
| 19:39 | hyPiRion | jack_rabbit: oh hahaahah |
| 19:40 | jack_rabbit | Is 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:40 | hyPiRion | you have the blocking read issue in Java |
| 19:40 | technomancy | Denommus: nrepl-jack-in is the most common way |
| 19:40 | hyPiRion | jack_rabbit: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4514257 |
| 19:40 | Denommus | technomancy: I understand that, but this only opens the repl. I'm asking how to load my project |
| 19:40 | Denommus | I mean, I have no idea how to run a project from inside emacs |
| 19:41 | technomancy | Denommus: usually C-c C-k |
| 19:41 | hyPiRion | Essentially it's a 12 year old unresolved bug report about the impossibility of killing threads on a blocking read |
| 19:41 | technomancy | you can also add :repl-options {:init-ns my.init.namespace} to have things loaded on startup |
| 19:41 | jack_rabbit | hyPiRion, I don't think that's it. This method I'm running doesn't call read anywhere. |
| 19:41 | technomancy | but I'm not sure whether that's checked in nrepl.el yet |
| 19:41 | hyPiRion | Denommus: C-c C-k and then C-k M-n (to switch namespace) |
| 19:41 | hyPiRion | jack_rabbit: oh, lucky you |
| 19:41 | nDuff | jack_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:41 | nDuff | jack_rabbit: Do see the last link I provided. |
| 19:42 | jack_rabbit | nDuff, I'm reading it now. Thanks. |
| 19:42 | Denommus | CompilerException java.lang.RuntimeException: Unable to resolve symbol: defproject in this context, compiling:(/home/yuri/Projetos/test-clojure/project.clj:1) |
| 19:43 | jack_rabbit | nDuff, So it appears I might just need to catch that exception, then. |
| 19:43 | nDuff | jack_rabbit: Not quite. |
| 19:43 | technomancy | Denommus: Leiningen isolates in-project code from code that runs in Leiningen itself |
| 19:44 | nDuff | jack_rabbit: The issue here is that you aren't calling anything that _throws_ that exception |
| 19:44 | nDuff | jack_rabbit: so setting the interrupted flag on the thread isn't actually having any effect. |
| 19:44 | technomancy | Denommus: so C-c C-k will only work on stuff inside src/ |
| 19:44 | technomancy | you should never need to evaluate project.clj yourself |
| 19:44 | nDuff | jack_rabbit: ...you can poll it yourself, if need be. |
| 19:44 | jack_rabbit | hmm. |
| 19:44 | corecode | hyPiRion: boh, a lot to read |
| 19:44 | Denommus | technomancy: so, do I have to do C-c C-k for each of my files? |
| 19:45 | technomancy | Denommus: typically your project will have a single entry point which will require everything that's needed |
| 19:45 | corecode | hyPiRion: also i'd like to use existing microcontrollers :) |
| 19:45 | jack_rabbit | I 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:46 | nDuff | That... doesn't sound like an ideal use case for an atom. |
| 19:46 | mpenet | that sounds likes a promise |
| 19:47 | jack_rabbit | mpenet, I'll have a look at promises. |
| 19:50 | jack_rabbit | Okay. 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:51 | jack_rabbit | I think getting rid of busy-waiting will solve the thread-not-dying problem as well. |
| 19:54 | nDuff | The "atom distributed amongst the futures" part doesn't make sense to me. |
| 19:54 | nDuff | Sounds more like a job for a queue. |
| 19:54 | jack_rabbit | Well it's basically a queue, yes. |
| 19:54 | nDuff | There are places where using java.util.concurrency primitives rather than native Clojure ones makes sense. |
| 19:54 | nDuff | ...indeed, rhickey has explicitly endorsed the practice |
| 19:54 | jack_rabbit | The order in which they come isn't really that important. |
| 19:56 | jack_rabbit | There'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:58 | nDuff | Do these futures eventually deliver values? |
| 19:58 | mpenet | couldn't this be solved with an agent and throw away all the futures |
| 19:59 | mpenet | but anyway atoms+futures are probably not what you are looking for |
| 20:02 | jack_rabbit | nDuff, No. |
| 20:02 | Denommus | technomancy: ok, I tried to clone the compojure project from github, open core.clj and run C-c C-k |
| 20:02 | Denommus | this 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:04 | technomancy | Denommus: you must have launched your nrepl session from the wrong project |
| 20:05 | Denommus | technomancy: ok, now I understand better |
| 20:06 | jack_rabbit | So I could do this with agents and watches instead it looks like. |
| 20:10 | jack_rabbit | Not 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:19 | thm_prover | dumb 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:19 | thm_prover | What 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:23 | thm_prover | http://hpaste.org/85064 |
| 20:31 | ivan | thm_prover: see data.xml/src/main/clojure/clojure/data/xml.clj and write an emit that doesn't (.writeStartDocument ...) |
| 20:32 | thm_prover | ivan: actually, I found that having that little header is acceptable |
| 20:32 | thm_prover | :-) |
| 20:32 | clojurebot | No entiendo |
| 20:32 | thm_prover | :- (+ 1 2) |
| 20:32 | thm_prover | : (+ 1 2) |
| 20:32 | ivan | ,(+ 1 2) |
| 20:32 | clojurebot | 3 |
| 20:32 | thm_prover | :-) |
| 20:32 | thm_prover | how did I trigger the "No entiendo" ? |
| 20:33 | ivan | a glitch in the matrix, or perhaps a limit to spewing the same response |
| 20:36 | gfredericks | clojurebot occasionally assumes you're talking to him for no particular reason |
| 20:38 | technomancy | there's a reason |
| 20:38 | technomancy | it's because it's occasionally hilarious |
| 20:39 | gfredericks | there's no denying that |
| 20:40 | amalloy | jack_rabbit: i know i recommended it already, but it really sounds like you're crying out for lamina |
| 20:41 | jack_rabbit | amalloy, Well if it can solve this stuff, maybe I'll give it a look. |
| 20:41 | amalloy | it is for doing exactly what you are trying to do |
| 20:41 | corecode | hyPiRion: that lisp machine is real cool |
| 20:41 | ztellman | jack_rabbit: can you explain the intent of all those futures and watches? |
| 20:41 | jack_rabbit | Thanks. I'll be checking it out right now, although I think I almost have it working with agents. |
| 20:42 | amalloy | ztellman: do you have a highlight for lamina? |
| 20:42 | ztellman | amalloy: ha, yes |
| 20:43 | jack_rabbit | ztellman, 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:44 | ztellman | jack_rabbit: https://github.com/ztellman/aleph#websockets |
| 20:44 | `arrdem | corecode: which machine? |
| 20:45 | ztellman | doing the same thing with TCP consists of changing about two lines |
| 20:45 | jack_rabbit | ztellman, 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:46 | ztellman | jack_rabbit: fair enough, but the underlying implementation in no way resembles what you're doing with futures |
| 20:46 | jack_rabbit | ztellman, Maybe I'll have a look at your implementation then. |
| 20:47 | ztellman | okay, let me know if you have any questions :) |
| 20:47 | jack_rabbit | thanks! |
| 20:49 | jack_rabbit | ztellman, Do you think you could point me to a particular source file that might be of interest to me? |
| 20:49 | ztellman | jack_rabbit: there are a few |
| 20:49 | ztellman | but for some context, I use netty, not java sockets |
| 20:49 | jack_rabbit | okay. |
| 20:50 | ztellman | which adds some capabilities, but does make the implementation a bit less minimal |
| 20:50 | ztellman | so with that in mind: |
| 20:50 | ztellman | https://github.com/ztellman/aleph/blob/perf/src/aleph/netty/server.clj |
| 20:50 | ztellman | https://github.com/ztellman/aleph/blob/perf/src/aleph/tcp.clj |
| 20:51 | jack_rabbit | Thanks. I'll be reading those. |
| 20:51 | ztellman | I'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:51 | ztellman | also https://github.com/ztellman/aleph/wiki/TCP |
| 20:53 | corecode | `arrdem: 01:39:27 < hyPiRion> corecode: http://hypirion.com/pdf/igor.pdf <- |
| 20:53 | `arrdem | cheers corecode |
| 20:54 | `arrdem | holy shit dude thanks for sharing this |
| 20:55 | `arrdem | hyPiRion: where'd you dig igor up? despite all my lispm googling I never found it. |
| 20:56 | `arrdem | oh. he wrote it. nvm. |
| 21:12 | corecode | he did? |
| 21:12 | corecode | yea, absolutely impressive project |
| 21:13 | corecode | maybe creating something clj-like for microcontrollers is not out of the question... |
| 21:13 | `arrdem | TBH that's going to be my next project |
| 21:14 | `arrdem | I'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 | `arrdem | we'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:20 | corecode | ah |
| 21:20 | corecode | well, i'm talking about 32KB of flash and 4KB RAM |
| 21:21 | corecode | `arrdem: http://www.iro.umontreal.ca/~feeley/papers/StAmourFeeleyIFL09.pdf |
| 21:21 | gfredericks | Raynes: okay so let's say I have a vector of nodes |
| 21:22 | gfredericks | is that a normal thing to have even? |
| 21:23 | `arrdem | corecode: 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:23 | gfredericks | is :content supposed to always be a sequence of nodes or can it be a single node as well? |
| 21:24 | hiredman | gfredericks: sequence |
| 21:25 | gfredericks | man I even manage to get nrepl into some kind of infinite exception-throwing loop |
| 21:31 | corecode | `arrdem: yes, that is my plan. |
| 21:31 | corecode | `arrdem: although for a more peripheral-heavy microcontroller |
| 21:31 | corecode | `arrdem: less disk, more ADC, etc. |
| 21:32 | corecode | usb peripheral. writing USB stacks in C is no fun. |
| 21:36 | gfredericks | Raynes: https://www.refheap.com/paste/13221 getting a cast exception with a single node |
| 21:38 | tieTYT2 | i saw this as a parameter to a function, what is this called? [#^HeaderIterator headers] |
| 21:38 | tieTYT2 | the #^ |
| 21:38 | gfredericks | metadata |
| 21:39 | gfredericks | there's just one parameter there |
| 21:39 | gfredericks | that's a typehint to say what the java type of the argument is |
| 21:39 | tieTYT2 | ah |
| 21:39 | brehaut | its the old notation for metadata, just ^ now |
| 21:39 | tieTYT2 | why do you need to do that? |
| 21:39 | gfredericks | so it compiles to better bytecode |
| 21:39 | tieTYT2 | so it's for performance only? |
| 21:39 | gfredericks | I believe so |
| 21:40 | tieTYT2 | ah |
| 21:40 | tieTYT2 | new topic |
| 21:40 | tieTYT2 | is there a way to get counterclockwise to give you compilation errors? |
| 21:40 | nDuff | tieTYT: If you're curious, see the *warn-on-reflection* flag |
| 21:40 | tieTYT2 | i always have to load it in the repl to find errors |
| 21:40 | tieTYT2 | nDuff: nice |
| 21:42 | tieTYT2 | ok thanks guys |
| 22:07 | amalloy | gfredericks: there are unusual cases where typehints affect correctness rather than just performance |
| 22:08 | gfredericks | they'll at least cause class cast exceptions...are you thinking of something beyond that? |
| 22:08 | brehaut | amalloy: java method overide selection? |
| 22:08 | gfredericks | ,((fn [^String x] x) 12) |
| 22:08 | clojurebot | 12 |
| 22:08 | amalloy | brehaut: that's one of the two i know, yes |
| 22:08 | brehaut | amalloy: whats the other one? |
| 22:08 | gfredericks | you guys know way more about computers than I do |
| 22:09 | mthvedt | ,(if (java.lang.Boolean. false) 1 0) |
| 22:09 | clojurebot | 1 |
| 22:09 | brehaut | gfredericks: that is a sad indictment of my social life |
| 22:09 | mthvedt | whyyy |
| 22:09 | amalloy | brehaut: imagine an interface Fooable {void foo();} and a private class FooImpl implements Fooable {...} |
| 22:09 | brehaut | mthvedt: everything other than primative false and null are true in clojure |
| 22:10 | amalloy | if 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:10 | brehaut | huh interesting |
| 22:10 | amalloy | if you treat it as an instance of the public Fooable interface, that's allowed |
| 22:10 | brehaut | ah right, that makes sense |
| 22:10 | mthvedt | ,(if (boolean (java.lang.Boolean false)) 1 0) |
| 22:10 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn> |
| 22:10 | mthvedt | : ,(if (boolean (java.lang.Boolean. false)) 1 0) |
| 22:11 | amalloy | the clojure compiler could do a little more work and find that out for you, probably |
| 22:11 | mthvedt | ,(if (boolean (java.lang.Boolean false)) 1 0) |
| 22:11 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn> |
| 22:11 | amalloy | mthvedt: don't ever use (Boolean. anything) |
| 22:11 | mthvedt | man i'm bad at typing |
| 22:11 | mthvedt | ,(if (boolean (java.lang.Boolean. false)) 1 0) |
| 22:11 | clojurebot | 0 |
| 22:11 | amalloy | bad in java, bad in clojure, bad everywhere |
| 22:11 | samedhi | Are we supposed to be using clojure.core.contracts or trammel? |
| 22:11 | brehaut | core.contracts |
| 22:11 | mthvedt | amalloy: i was using a library that returns Booleans |
| 22:12 | amalloy | write them a nasty letter |
| 22:12 | brehaut | ಠ_ಠ |
| 22:12 | amalloy | they are returning bad objects to you |
| 22:12 | mthvedt | because boolean objects print as false, i spent a long time trying to debug |
| 22:12 | gfredericks | so clojure boxes everything except booleans? |
| 22:12 | samedhi | ok, thanks. |
| 22:12 | mthvedt | unknowing i had a Boolean, not a boolean lurking in the code |
| 22:12 | gfredericks | ,(type true) |
| 22:12 | clojurebot | java.lang.Boolean |
| 22:12 | gfredericks | ?? |
| 22:12 | lazybot | gfredericks: What are you, crazy? Of course not! |
| 22:13 | amalloy | gfredericks: huh? it boxes booleans, most of the time anyway |
| 22:13 | gfredericks | amalloy: but you were not just saying that boxed booleans are terrible? |
| 22:13 | amalloy | no |
| 22:13 | scottj | mthvedt: from docs of that constructor: "Note: It is rarely appropriate to use this constructor." |
| 22:13 | gfredericks | guys I'm really bad at computers |
| 22:13 | amalloy | constructing new booleans is terrible |
| 22:13 | scottj | mthvedt: opps, scroll was messed up on my window |
| 22:13 | amalloy | reusing boxed booleans like ##(Boolean/FALSE) is great |
| 22:13 | lazybot | ⇒ false |
| 22:13 | gfredericks | amalloy: wow, that really IS great! |
| 22:13 | brehaut | gfredericks: type requires an object to call get class on it, so of course it boxes to a Boolean |
| 22:14 | gfredericks | brehaut: yeah that part made sense; it was my perception of amalloy's point that didn't jive with anything else |
| 22:15 | gfredericks | the string version of the constructor doesn't have the warning o_O |
| 22:16 | gfredericks | ,(if (Boolean. "false") 1 0) |
| 22:16 | clojurebot | 1 |
| 22:16 | `arrdem | amalloy: why would you ever use Boolean/FALSE given that we have false |
| 22:16 | amalloy | oh, i wouldn't, not by hand. but false *us* Boolean/FALSE |
| 22:16 | `arrdem | sure. qualified names and whatnot. just making sure. |
| 22:17 | gfredericks | ,(identical? false Boolean/FALSE) |
| 22:17 | clojurebot | true |
| 22:18 | gfredericks | ,(identical? (identical? true Boolean/TRUE) (Boolean/TRUE)) |
| 22:18 | clojurebot | true |
| 22:21 | scottj | ,(identical? (Boolean/valueOf "false") false) |
| 22:21 | clojurebot | true |
| 22:24 | mthvedt | two things considered identical are logical opposites… makes sense |
| 22:29 | tieTYT2 | can 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:30 | gfredericks | ,(or 1 2 3)? |
| 22:30 | clojurebot | 1 |
| 22:30 | tieTYT2 | oh nm, that first "param" is metadata, not a variable |
| 22:30 | rationalrevolt | when using println in a ring app and the jetty adapter - do i need to configure the logging explicitly to see the outputs? |
| 22:30 | tieTYT2 | thanks |
| 22:32 | gfredericks | rationalrevolt: depends on how you're running it -- i.e., where STDOUT for the process is going |
| 22:33 | rationalrevolt | i'm running it within nrepl |
| 22:33 | rationalrevolt | .el |
| 22:33 | gfredericks | should just work I would think |
| 22:33 | gfredericks | assuming (println "foo") by itself works as well |
| 22:34 | ztellman | has anyone had issues with 'definterface' and 'hadoop jar' not playing well together? |
| 22:34 | Raynes | amalloy: So false *us* it? |
| 22:34 | Raynes | ;) |
| 22:34 | ztellman | replacing it with a corresponding 'defprotocol' fixes the problem, for no reason that I can see |
| 22:35 | rationalrevolt | hmm, println by itself works, but the same doent print to the repl when it gets called from the handler on an incomming reques |
| 22:35 | amalloy | ztellman: what goes wrong? a bad jar is generated, no jar...? |
| 22:35 | rationalrevolt | ztellman: could you elaboarate? |
| 22:35 | amalloy | if you have a jar, i'd look through it to see if the generated interface looks right |
| 22:36 | ztellman | oh, right, I get something to the effect of "Type cannot be cast to IType" |
| 22:36 | ztellman | which would typically lead me to believe that the interface is being double defined, but that doesn't appear to be the case |
| 22:36 | scottj | rationalrevolt: maybe buffer *nrepl-server*? |
| 22:37 | rationalrevolt | scottj: haha! yea, its there |
| 22:37 | rationalrevolt | thanks! |
| 22:39 | scottj | rationalrevolt: 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:40 | gfredericks | scottj: that sounds super plausible |
| 22:45 | `arrdem | is there a way to get the arity of a function? |
| 22:45 | gfredericks | try calling it with all possible arities |
| 22:45 | gfredericks | I mean no I don't think so |
| 22:45 | `arrdem | that's unfortunate. |
| 22:46 | `arrdem | thanks. |
| 22:46 | brehaut | some functions in core have an :arglists meta property but thats not really universal |
| 22:46 | gfredericks | and that's a var |
| 22:46 | brehaut | and presumably you could do some shenanigans with reflection |
| 22:46 | brehaut | yeah |
| 22:47 | `arrdem | I was just wondering.. rolling my own internal macro system for a compiler and I'm trying to add arity checking to my macros. |
| 22:52 | brehaut | (map #(-> % .getParameterTypes seq count) (.getDeclaredMethods (class map))) ; `arrdem |
| 22:52 | brehaut | ,(map #(-> % .getParameterTypes seq count) (.getDeclaredMethods (class map))) |
| 22:52 | clojurebot | (3 2 4 5 0) |
| 22:53 | brehaut | you'd probably want to modify it so that it knows about .isVarArgs too |
| 22:53 | `arrdem | mm... thanks brehaut |
| 22:53 | `arrdem | (inc brehaut) |
| 22:53 | lazybot | ⇒ 11 |
| 22:54 | brehaut | huh. maybe .isVarArgs is useless on clojure? |
| 22:54 | brehaut | map's arity-5 method is the varargs, but it doesnt get listed as such |
| 22:55 | brehaut | ,(map (juxt #(-> % .getParameterTypes seq count) #(.isVarArgs %)) (.getDeclaredMethods (class map))) |
| 22:55 | clojurebot | ([3 false] [2 false] [4 false] [5 false] [0 false]) |
| 22:55 | `arrdem | ah juxt.. so much better than (map vec & seqs) |
| 22:56 | brehaut | `arrdem: fwiw http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html |
| 22:57 | brehaut | ,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class map))) ; `arrdem you probably only want invoke and doInvoke rather than all methods in hindsight |
| 22:57 | clojurebot | (["invoke" 3 false] ["invoke" 2 false] ["invoke" 4 false] ["doInvoke" 5 false] ["getRequiredArity" 0 false]) |
| 22:58 | brehaut | `arrdem: i suspect doInvoke is for varargs? |
| 22:59 | brehaut | `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:59 | amalloy | brehaut: doinvoke is probably an implementation detail |
| 23:00 | `arrdem | brehaut: *shrug* I'll just restructure this with a wrapper macro so I can get the arity at declaration. |
| 23:00 | brehaut | amalloy: everything about the reflection crap i experimented with above is probably an implementation detail |
| 23:00 | amalloy | oh, of course |
| 23:00 | amalloy | but varargs are IFn/applyTo, not AFn/doInvoke or whatever |
| 23:00 | brehaut | oh ok |
| 23:00 | amalloy | i mean it's a *boring* implementation detail |
| 23:01 | amalloy | otoh 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:02 | brehaut | amalloy: `arrdem wants to find out arities of functions |
| 23:02 | amalloy | slit your throat to save time |
| 23:02 | amalloy | it's not a thing you can find out |
| 23:02 | `arrdem | lol |
| 23:02 | brehaut | i handwaved a vague solution based on stupid reflection |
| 23:03 | hiredman | if you with-meta a function anywhere |
| 23:03 | hiredman | if you use a multimethod |
| 23:03 | brehaut | ,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (partial + 1)))) |
| 23:03 | hiredman | etc |
| 23:03 | clojurebot | (["doInvoke" 1 false] ["getRequiredArity" 0 false]) |
| 23:03 | brehaut | heh |
| 23:03 | `arrdem | ... well that makes sense... |
| 23:03 | amalloy | seriously though, every IFn has dozens of arities defined, most of which are implemented as (throw (ArityException.)) |
| 23:03 | brehaut | amalloy: right, but only some of those are declared on a particular instance |
| 23:03 | `arrdem | mmkay I'll just give up on arity checking then. |
| 23:04 | `arrdem | thanks amalloy, brehaut, hiredman |
| 23:04 | hiredman | ,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (fn [x] x))))) |
| 23:04 | clojurebot | (["invoke" 1 false]) |
| 23:04 | hiredman | ,(map (juxt #(.getName %) #(-> % .getParameterTypes count) #(.isVarArgs %)) (.getDeclaredMethods (class (with-meta (fn [x] x) {}))))) |
| 23:04 | clojurebot | (["meta" 0 false] ["withMeta" 1 false] ["doInvoke" 1 false] ["getRequiredArity" 0 false]) |
| 23:04 | amalloy | oh, declared method? that might work, but hiredman is right |
| 23:05 | amalloy | it can't possibly work all the time |
| 23:05 | brehaut | not to mention its worthless in teh face of a partial frinstance |
| 23:08 | `arrdem | ppft why do I need arity checking on functions anyway... |
| 23:09 | amalloy | (try (f a b c) (catch Exception "lol whatever man")) |
| 23:09 | hiredman | _ |
| 23:09 | amalloy | oh yeah |
| 23:09 | `arrdem | oh please. this compiler is just going to ignore extra argument l3ik a bau5 |
| 23:10 | hiredman | in the fine tradition of javascript |
| 23:11 | `arrdem | I mean as long as I get em off the stack... |
| 23:13 | hiredman | be sure to allow for multivalue returns |
| 23:13 | `arrdem | This edition is staticly typed Pascal, no such awesome here. |
| 23:13 | `arrdem | next edition will be clojure, then we'll talk |
| 23:16 | nonuby | i 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:58 | yacin | any recommendations for a good xmlrpc lib for clojure? |
| 23:59 | yacin | necessary-evil? |