2012-08-09
| 00:00 | KirinDave | Raynes: Isn't Noir the flavor of the quarter? |
| 00:06 | technomancy | Noir is very prescriptive |
| 00:06 | technomancy | but you lose out on a number of things that make compojure particularly charming |
| 00:11 | Raynes | KirinDave: Yeah. Hell, I'm a developer of it. But even I've been using Compojure lately. |
| 00:12 | technomancy | I love how defroutes compose <3 |
| 00:12 | KirinDave | Raynes: I just do way more APIs. |
| 00:12 | technomancy | and you can just M-. your way through them from a single route |
| 00:12 | technomancy | *root |
| 00:12 | technomancy | so rad |
| 00:45 | dhkl | mefisto`: I use Rails professionally, but for my own projects, I have been using noir/compojure. Can't say I miss much from the Rails world. Sure, you get less hand holding and there's no scaffolding to get you up and running in seconds. But I'm sure you'll find noir/compojure much more liberating. |
| 01:07 | lynaghk` | ping: seancorfield |
| 01:08 | A_TURBAN_ON_STER | lynaghk, why don't you ping me? |
| 01:08 | A_TURBAN_ON_STER | Am I not important enough for you? |
| 01:08 | A_TURBAN_ON_STER | Am I not a man, and a brother? |
| 01:31 | technomancy | http://people.gnome.org/~michael/images/2012-08-08-german-comments.png |
| 01:31 | technomancy | ^ libreoffice |
| 01:32 | porco | I have no experience on Java, should I learn some Java before learning clojure? |
| 01:33 | technomancy | heavens no |
| 01:33 | Peregrine | I have no java experience and I am doing ok with clojure. |
| 01:33 | Peregrine | In fact in my professional life I program in perl. |
| 01:33 | technomancy | you'd go crazy |
| 01:34 | technomancy | I mean unless your goal is to appreciate clojure more =) |
| 01:37 | Peregrine | Grab Chas Emericks book and go to down on learning clojure. |
| 01:37 | Peregrine | I'm sure you can look up the java you need to |
| 01:38 | porco | what kind of book should I pick up? |
| 01:38 | porco | I program in php and python at work |
| 01:38 | Peregrine | http://www.clojurebook.com/ |
| 01:39 | hiredman | java (the language) is trivial to pick up if you know some other class based language |
| 01:39 | Peregrine | I also like Programming Clojure by Stu Halloway but the standard response seems to be clojurebook.com |
| 01:40 | amalloy | Joy of Clojure |
| 01:40 | hiredman | the non-trivial part is all the packages in the jre, the glut of libraries available on the internet, etc |
| 01:50 | brainproxy | porco: I can also recommend the Clojure Programming book pub'd by OReilly, already mentioned by others |
| 01:51 | brainproxy | I came from a mostly JavaScript background, with a smattering of some other things here and there, but little java knowledge |
| 01:52 | brainproxy | that book really helped me dive into clojure (and Java for that matter), it was a good guide for a lisp noob, though it will certainly challenge and stretch you |
| 01:54 | dhkl | porco: Go for Clojure Programming to learn the basics. It's the most up-to-date book practical book out there. Then go for Joy of Clojure for an in depth exposure. |
| 01:54 | porco | ok, I'm going to read it, I learned some haskell before |
| 01:59 | KirinDave | So, technomancy |
| 02:00 | KirinDave | I found something _really_ funny in one of our projects |
| 02:00 | KirinDave | https://gist.github.com/85842a22bfb6203b7dd5 |
| 02:00 | KirinDave | I nearly lost it. |
| 02:00 | technomancy | oh dear |
| 02:00 | technomancy | oooooh my |
| 02:00 | KirinDave | technomancy: I know |
| 02:00 | KirinDave | Really good |
| 02:00 | KirinDave | Like gold medal lol |
| 02:01 | technomancy | $kill |
| 02:01 | lazybot | KILL IT WITH FIRE! |
| 02:01 | KirinDave | Best part is git blame pins this on me because of how the repo was moved |
| 02:01 | KirinDave | I _know_ I did not write that |
| 02:01 | KirinDave | I'd sooner cut my fingers off. |
| 02:05 | adu | KirinDave: is that ruby? |
| 02:05 | KirinDave | adu: Capistrano tasks, yes. |
| 02:05 | KirinDave | cap maven:clean |
| 02:05 | KirinDave | cap maven:idk:yolo |
| 02:06 | adu | what's Capistrano? |
| 02:07 | antifuchs | one edit distance away from crapistano, is what it is (bitter, me?) (: |
| 02:07 | adu | hmm, something about servers |
| 02:07 | antifuchs | it's a deploy tool |
| 02:10 | adu | is Capistrano related to Clojure? |
| 02:10 | antifuchs | it's written in ruby, but I guess you can use it to deploy clojure apps |
| 02:10 | antifuchs | it's a parallel ssh driver, essentially |
| 02:11 | KirinDave | Yeah |
| 02:14 | sthuebner | no |
| 02:18 | ro_st | is there any particular benefit to using java 1.7 for clojure work? is it perhaps faster? |
| 02:18 | adu | you mean (1.)7? |
| 02:19 | ro_st | ok, that |
| 02:19 | ro_st | :p |
| 02:19 | adu | the 1. disappeared awhile ago |
| 02:19 | ro_st | i have java version "1.6.0_33" installed |
| 02:19 | ro_st | that's a paste from running java -version |
| 02:20 | ro_st | anyway, that wasn't my question :-) |
| 02:20 | adu | I suppose that's the difference between continuity and marketing |
| 02:21 | ro_st | antares_: lol @ https://github.com/michaelklishin/validateur/blob/master/src/clojure/validateur/validation.clj#L107 |
| 02:22 | antifuchs | I was trying to use the lein-ritz plugin in leiningen 2 just now, and it complains "Exception in thread "main" java.lang.RuntimeException: org.sonatype.aether.resolution.DependencyResolutionException: Could not find artifact lein-ritz:lein-ritz:jar:0.3.2 in central (http://repo1.maven.org/maven2)" |
| 02:23 | antifuchs | I've put {:user {:plugins [[lein-ritz "0.3.2"]]}} in my ~/.lein/profiles.clj |
| 02:23 | antifuchs | anyone know how to resolve this? I'm completely in the dark re. maven and such things |
| 02:23 | ro_st | antifuchs: have you looked at nrepl.el? |
| 02:23 | ro_st | or is this not for use with emacs |
| 02:24 | antifuchs | ro_st: yes, I have. ritz is something I want to try. |
| 02:24 | ro_st | ah ok |
| 02:24 | antifuchs | yeah, can't find the artifact in clojars or the central maven repo |
| 02:24 | antifuchs | guess I have to build it myself (: |
| 02:25 | technomancy | antifuchs: clojars only has 0.3.1 |
| 02:25 | antifuchs | oh, cool then. |
| 02:25 | antifuchs | technomancy: how could I have checked this? (: |
| 02:26 | technomancy | antifuchs: https://clojars.org/search?q=ritz |
| 02:26 | antifuchs | sweet! thanks! (: |
| 02:27 | technomancy | no problem |
| 02:28 | tutysra | I am seeing some improper output format in the repl when I run this - (defn tst [] |
| 02:28 | tutysra | (fn [aseq] |
| 02:28 | tutysra | (let [mapfn (fn [v] |
| 02:28 | tutysra | (let [v (identity v) |
| 02:28 | tutysra | _ (println :x) |
| 02:28 | tutysra | _ (println :y)] |
| 02:29 | tutysra | v))] |
| 02:29 | tutysra | (map mapfn aseq)))) ((tst) (range 5)) |
| 02:29 | tutysra | the output from the println in let is getting mixed up with the resulting seq of tst |
| 02:31 | tutysra | is this a known issue? |
| 02:33 | amalloy | yes, known issue with your code |
| 02:33 | amalloy | also, please use gist or refheap for pasting enormous code samples |
| 02:34 | tutysra | amalloy, sure... |
| 02:36 | amalloy | seriously though, map is lazy, printing is lazy. the repl says "oh hey, a list, i'll print a (. what's the first element? <your function now does some printing> oh gosh, it's 0? i'll print a zero", and so on |
| 02:37 | antifuchs | heh, looks like ritz is targeting a pretty outdated version of slime, too. *cracks knuckles* time to upgrade things, then, I guess (: |
| 02:38 | technomancy | you should ping hugod |
| 02:38 | antifuchs | will do! |
| 02:38 | antifuchs | (is hugod the ritz maintainer?) |
| 02:39 | technomancy | yeah |
| 02:39 | antifuchs | cool cool. will ping. |
| 02:39 | antifuchs | I wish there was an easy way to get a recent & relatively stable slime version that doesn't involve installing a cl (: |
| 02:40 | antifuchs | because right now, I think quicklisp is the de-facto release channel for slime |
| 02:40 | antifuchs | xach does testing on it, and does timeslotted releases |
| 02:40 | antifuchs | (and best of all, the slime maintainers don't complain much!) |
| 02:41 | antifuchs | slight negative: you pretty much have to have a lisp installed to get the quicklisp-slime-helper (and the attached slime package). |
| 02:43 | tutysra | amalloy, yes, i could see that - (def res ((tst) (range 5))), initially when I ask for the value of res, I see the print vals in res but from next time it prints only the range values |
| 02:47 | tutysra | I am using emacs, normally the output from (println x) shows in a different color than return value, but in this case with tst everything is shown in the same color as return value, why it is so? |
| 02:51 | tutysra | here is the gist of tst function - https://gist.github.com/3301766 |
| 03:04 | antifuchs | tutysra: I'm guessing you're using slime & swank-clojure? |
| 03:05 | tutysra | antifuchs, you are right, i am using slime + swank-clojure |
| 03:05 | antifuchs | tutysra: it simply shows the return value in a different face from regular output (the print mechanisms slime-side are different, too) |
| 03:05 | antifuchs | I think it may even try to highlight the return values as a presentation thing that you can rightclick and such |
| 03:05 | antifuchs | (but that may be only if you use common lisp) |
| 03:07 | antifuchs | I think slime's intention is that it tries to highlight things it knows are values differently from arbitrary text output |
| 03:08 | tutysra | ok, in my case the output from the println statements are mixed up with the return value due to lazy evals, I am expecting the println output to show in a different color than return value as it does normally |
| 03:10 | antifuchs | ah, yeah, that's yucky. |
| 03:10 | antifuchs | don't think there's much that can be done to fix, other than changing lazy data structure printing, I guess |
| 03:12 | tutysra | as amalloy pointed out, the repl prints "(" when it starts to realize the lazy seq and after that the output from println follows... got a bit confused when I saw this for the first time |
| 03:16 | tutysra | antifuchs, ok, it is not a big concern if it cannot be fixed, I got the reason...would look nice to eye if some thing can be done to fix it |
| 03:17 | tutysra | thx antifuchs, amalloy for the explanation |
| 04:39 | Peregrine | When I try to use ring.util.serve I get an error ClassNotFoundException org.mortbay.log.Logger java.net.URLClassLoader$1.run (:-1) |
| 04:41 | hiredman | is ring.util.serve on your classpath? |
| 04:41 | Peregrine | It is. |
| 04:41 | hiredman | are you sure? |
| 04:41 | hiredman | because that error message says no |
| 04:41 | hiredman | what makes you think you do? |
| 04:42 | Peregrine | Yes because the time before when it wasn't on my classpath it gave me a different error about not being able to find ring.util.serve class... |
| 04:42 | Peregrine | That's not the exact error message it gave |
| 04:42 | hiredman | oh of course sorry, org.mortbay.log.Logger is the missing class |
| 04:43 | hiredman | do you have some dependency pulling in jetty? |
| 04:43 | Peregrine | C:\Users\peregrine\.m2\repository\ring-serve\ring-serve\0.1.2\ring-serve-0.1.2.jar is in the classpath I just checked to make sure. |
| 04:43 | hiredman | ring-serve should, but you might want to check and see |
| 04:44 | hiredman | org.mortbay is jetty |
| 04:44 | Peregrine | Well I expect ring.util.serve should pull in jetty but I am also using ring.adapter.jetty as a dependency |
| 04:44 | hiredman | what version? |
| 04:45 | hiredman | can you pastebin the entire exception? |
| 04:46 | hiredman | the entire stacktrace |
| 04:46 | no7hing | isn't the mortbay package a relict of very old jetty versions? |
| 04:46 | Peregrine | Hmm it seems the eclipse repl is hiding it. |
| 04:46 | Peregrine | Give me a moment |
| 04:47 | Peregrine | Hmm that does seem to be the entire exception. |
| 04:47 | hiredman | no7hing: well, it depends what you mean by "very old" |
| 04:48 | Peregrine | I just did lein repl and tried using ring.util.serve and it gives the exact same exception. |
| 04:48 | no7hing | yeah, very old is relative |
| 04:48 | no7hing | ver 6 |
| 04:48 | Peregrine | I do suspect it is an issue with mismatched versions. |
| 04:48 | hiredman | yeah |
| 04:48 | no7hing | the bundled jetty adapter with ring is 7.6 |
| 04:48 | no7hing | ring.adapter.jetty |
| 04:49 | hiredman | I expect ring moved to jetty 7, and ring-serve depends on 6 |
| 04:49 | Peregrine | ring.adapter.jetty refers to [org.eclipse.jetty/jetty-server "7.6.1.v20120215"] |
| 04:49 | Peregrine | Ok thanks. |
| 04:49 | hiredman | Peregrine: is there a reason to not just use lein-ring? |
| 04:49 | hiredman | https://github.com/weavejester/lein-ring/ |
| 04:50 | Peregrine | Probably not. |
| 04:50 | no7hing | funny, i was about to ask something about ring&jetty too |
| 04:51 | Peregrine | It seemed more convenient to be able to stop and start the server from inside my repl. |
| 04:51 | hiredman | ah, well, you just need the jetty adapter for that |
| 04:52 | Peregrine | How do I stop the server? |
| 04:52 | hiredman | (.stop return-value-of-whatever) |
| 04:52 | no7hing | (.stop server-var) |
| 04:53 | no7hing | does the bundled jetty adapter in ring use one thread / request? |
| 04:53 | Peregrine | Ahh I'll need to make sure to set join? to false so it doesn't block on the run-jetty command. |
| 04:54 | weavejester | I've been meaning to deprecate ring-serve and add its functionality into the more general ring-server |
| 04:58 | clj_newb_23982 | is there av erson of conjure.contrib.seq-utils/find-first that is in core? |
| 04:58 | clj_newb_23982 | or somethign like it? |
| 05:01 | Peregrine | (first (filter pred coll))? |
| 05:01 | clj_newb_23982 | doh; I actually need index of the element |
| 05:01 | weavejester | Yeah, that's literally what find-first is |
| 05:08 | weavejester | clj_newb_23982: You probably want the keep-indexed function then. |
| 05:08 | clj_newb_23982 | weavejester: yeah, got it working |
| 05:12 | otfrom | morning |
| 05:14 | clj_newb_23982 | string has .substring in java |
| 05:14 | clj_newb_23982 | do lists / vectors have a "subsequence" ? |
| 05:16 | no7hing | nobody? i seem to have a conceptual gap concerning threads and in this case servers |
| 05:16 | clojure-newcomer | hey guys, is it possible to output two forms from a macro, like a defmulti and a defmethod ? I'm failing on this in the REPL atm |
| 05:17 | no7hing | like in: what get's executed in a thread and what get's executed in clojure's own (main) thread |
| 05:17 | hiredman | no7hing: http://en.wikipedia.org/wiki/Java_Servlet |
| 05:18 | hiredman | the standard servlet stuff (which ring is built on) is 1 thread per request |
| 05:18 | hiredman | no7hing: clojure as such doesn't have a "main" thread |
| 05:19 | hiredman | the jvm has a main thread |
| 05:19 | hiredman | but webapps are often deployed to containers where your app never gets anywhere near the jvm's main thread |
| 05:20 | no7hing | so as long as i or jetty don't use async servlets with manual setting of continuations (e.g. for a db call) the thread is bound to execute my servlet, yes? |
| 05:20 | hiredman | "bound to execute my servlet" ? |
| 05:20 | weavejester | clojure-newcomer: Yes, just use "do", e.g. `(do (form-one) (form-two)) |
| 05:20 | clojure-newcomer | or would I have a macro that calls two macro's to do this ? |
| 05:20 | clojure-newcomer | think I read somewhere a macro can only return one form ? |
| 05:20 | no7hing | @hiredman: won't do other stuff |
| 05:21 | clojure-newcomer | weavejester: thanks |
| 05:21 | clojure-newcomer | will give it a go |
| 05:21 | no7hing | like accept other inbound requests |
| 05:21 | weavejester | no7hing: Your handler function gets its own thread |
| 05:22 | weavejester | no7hing: So a request comes in, a thread is grabbed from a pool, and then the handler is evaluated in that thread. |
| 05:23 | no7hing | thanks, that fills in that gap |
| 05:24 | no7hing | and if i have potentially long running tasks in context of a request, i'll have to use async servlets or something like netty, yes? |
| 05:25 | no7hing | to not hog the thread for the time it takes to finish the long running task |
| 05:25 | weavejester | Aleph is probably the most "clojurey" solution. |
| 05:25 | weavejester | But you should only have long running requests if you're using long-polling or websockets. |
| 05:26 | no7hing | aloha, from the same dev, is a slimmer wrapper around netty |
| 05:26 | no7hing | and more approachable ;) |
| 05:26 | no7hing | https://github.com/ztellman/aloha |
| 05:27 | no7hing | @weavejester: i'am thinking of using server sent events/chunked transfer encoding |
| 05:27 | weavejester | Does aloha have anything for async stuff? |
| 05:28 | no7hing | as it's using netty under the hood it probably has no other choice |
| 05:28 | weavejester | Ah, oops, gotta go or I'll be late |
| 05:28 | no7hing | haven't checked yet if the interface allows for it, tho |
| 05:28 | weavejester | no7hing: I meant is there any Clojure interface to the async sutuff |
| 05:28 | no7hing | bye |
| 05:28 | weavejester | bye for now |
| 05:29 | no7hing | oh erlang, don't let anybody tell you again that you're hard to grasp |
| 05:33 | clgv | for (defmacro defbla [symb expr] `(def ~(vary-meta symb assoc :type :bla) ~expr)) when calling (defbla x 20) I get "ClassCastException clojure.lang.Var cannot be cast to clojure.lang.IObj clojure.core/with-meta (core.clj:211)". why? |
| 05:46 | magopian | hello guys, a quick question |
| 05:46 | magopian | i can't understand why (reduce str [\1]) gives \1 |
| 05:46 | magopian | and not "1" |
| 05:47 | magopian | ok got it, with a simple RTFM ;) |
| 05:47 | magopian | If coll has only 1 item, it |
| 05:47 | magopian | is returned and f is not called. |
| 05:52 | magopian | thanks everybody for being my rubber duck ;) |
| 06:39 | clgv | why does (def ^{:type :bla} mydef 1) result in a "ClassCastException clojure.lang.Var cannot be cast to clojure.lang.IObj clojure.core/with-meta (core.clj:211)"? |
| 06:47 | hyPiRion | clgv: It doesn't for me. |
| 06:48 | clgv | hyPiRion: clojure 1.4.0? |
| 06:48 | hyPiRion | yup, lein repl. |
| 06:49 | hyPiRion | Is that what you wrote verbatim? |
| 06:49 | clgv | thats weird. |
| 06:50 | clgv | in CCW repl it has the exception - in "lein2 repl" not. specifying :type seems to be the reason |
| 06:50 | hyPiRion | Strange. |
| 06:50 | hyPiRion | In 1.3.0 it throws off the exception you mentioned. |
| 06:51 | hyPiRion | If you try out (def ^{:type Integer} mydef 1) instead? |
| 06:52 | clgv | that works. I think there is a good error missing |
| 06:52 | clgv | *good error message |
| 06:52 | hyPiRion | yeah, seems like it. |
| 06:55 | cemerick | What are people using for their ClojureScript REPL-ing? Just a bare terminal? |
| 07:02 | ejackson | cemerick: I use the repl provided by lein-cljsbuild |
| 07:02 | cemerick | ejackson: which is in a terminal, I presume? |
| 07:02 | ejackson | yup |
| 07:03 | naeg | you could use light table playground |
| 07:03 | ejackson | there was a nice setup w/ emacs and clojurescript1 |
| 07:03 | naeg | it's like a REPL in the terminal - but in the browser :o |
| 07:03 | ejackson | where you could get eval from buffers and run a simultaneous clj repl. But it was a bit of fuss |
| 07:04 | cemerick | ejackson: that uses inferior-lisp, I think? |
| 07:04 | ejackson | yeah, that's what I recall |
| 07:04 | cemerick | (i.e. still a terminal, essentially) |
| 07:04 | cemerick | Right. |
| 07:04 | ejackson | well, the eval stuff raises it above that :p |
| 07:04 | ejackson | sweetness |
| 07:05 | cemerick | nrepl.el is getting quite decent, from what Raynes and technomancy have been saying |
| 07:06 | cemerick | naeg: I'm afraid I'm pretty well locked into ccw. :-) |
| 07:07 | cemerick | ejackson: does lein-cljsbuild allow you to specify different repl environments, or does it always just use the Rhino one from cljs.repl.rhino? |
| 07:07 | naeg | I'm still not sure what to use, atm I'm just using light table to try out stuff while learning |
| 07:10 | ejackson | cemerick: dunno. |
| 07:10 | ejackson | just a brief encounter |
| 07:11 | ejackson | it was a faff and I ended up programming eye and debugging by js/log |
| 07:12 | cemerick | wahoo! |
| 07:13 | ejackson | cemerick: settle, settle... |
| 07:14 | cemerick | ;-) |
| 07:15 | ejackson | cemerick: well that was very cheshire cat dramatic of you ! |
| 07:15 | cemerick | ragequit |
| 07:16 | cemerick | mostly, getting my irc client to stop freezing up |
| 07:16 | cemerick | it gets a bit oversensitive after a couple weeks without a restart |
| 07:17 | ejackson | well, so do I. |
| 07:31 | hyPiRion | People have said that http://java.ociweb.com/mark/clojure/article.html is the best free online resource/"book" for learning Clojure. Is that still valid? |
| 07:33 | scottj | hyPiRion: yeah |
| 07:33 | otfrom | does nrepl.el solve the lein repl OOM error? https://github.com/technomancy/leiningen/issues/691 |
| 07:36 | Raynes | I guess, in that those are two entirely different things. |
| 07:37 | hyPiRion | scottj: Humm, I wish there were some sort of http://tour.golang.org/ - but for Clojure instead. |
| 07:37 | otfrom | Raynes: how so? I thought that nrepl used REPLy same as lein repl |
| 07:37 | otfrom | would be great if I was wrong as I'd like to give nrepl.el a go |
| 07:37 | ohpauleez | hyPiRion: labrepl? |
| 07:38 | Raynes | For usage with nrepl.el, you want to use lein repl :headless, otfrom. All it does is start an nrepl server. |
| 07:38 | ohpauleez | https://github.com/relevance/labrepl |
| 07:38 | Raynes | ohpauleez, otfrom: tryclojure would serve a similar purpose if people would contribute an actual worthwhile tutorial and/or I had time to do it myself. |
| 07:38 | Raynes | Er, not otfrom. Sorry. |
| 07:38 | ohpauleez | Raynes: agreed |
| 07:39 | otfrom | Raynes: np ;-) |
| 07:39 | hyPiRion | ohpauleez: If it's not hosted on some webpage, it will increase the threshold for people interested in learning. |
| 07:39 | otfrom | Raynes: ok so lein repl :headless doesn't have the same issue that REPLy has with holding on to head and blowing up with OOM. That's cool. I'll give that a go then |
| 07:39 | ohpauleez | Shoreleave's demo is using catnip for an interactive tutorial/walkthrough |
| 07:40 | hyPiRion | And yeah, tryclj is the step I want to see, it shouldn't be too difficult making it like redis' tutorial. |
| 07:40 | hyPiRion | Famous last word and all that. |
| 07:40 | ohpauleez | haha for sure |
| 07:41 | hyPiRion | I'll have a look into labrepl, and figure out if that's good enough. |
| 07:42 | hyPiRion | I just wish the threshold were lower, I want to work with Clojure dangit. |
| 07:42 | hyPiRion | As in, work at work with Clojure. |
| 07:43 | ohpauleez | hyPiRion: What's your industry? Clojure was introduced to Comcast without much trouble, and I've built a number of startups up with Clojure |
| 07:43 | ohpauleez | Industry and current language/tooling |
| 07:51 | hyPiRion | ohpauleez: Hahah - I'm doing video codecs. |
| 07:51 | russfrank | I wrote my first clojure program.. comments? https://gist.github.com/3303549 |
| 07:51 | ohpauleez | in C? |
| 07:52 | hyPiRion | yup |
| 07:52 | ohpauleez | ahhh |
| 07:52 | russfrank | is there any better way to represent those bits that are just essentially if else if chains? |
| 07:52 | cemerick | russfrank: cond |
| 07:52 | cemerick | or condp |
| 07:53 | ohpauleez | russfrank: Use if-let and cond |
| 07:53 | russfrank | ok, will try, thanks |
| 07:54 | hyPiRion | russfrank: (defn fn-name docstring arglist) |
| 07:54 | russfrank | well, so one of the issues here is that I have some cases where I *know* I need to return false |
| 07:54 | ohpauleez | russfrank: Also functions should look like (defn some-name "What this does" [arg1 & args] ..) etc |
| 07:54 | ohpauleez | with the comment first, on a newline, and the arg list next, on a newline |
| 07:55 | russfrank | ok, nvm, I see how cond is useful |
| 07:55 | russfrank | yeah I'll fix the docstrings |
| 07:55 | ohpauleez | &(doce some-fn) |
| 07:55 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: doce in this context |
| 07:56 | ohpauleez | &(doc some-fn) |
| 07:56 | lazybot | ⇒ "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-... https://www.refheap.com/paste/4194 |
| 07:56 | ohpauleez | russfrank: http://clojuredocs.org/clojure_core/clojure.core/some-fn |
| 07:57 | ohpauleez | Also: #(not (lookup % model)) |
| 07:57 | ohpauleez | or better |
| 07:57 | ohpauleez | #(false? (lookup % model)) |
| 07:58 | ohpauleez | likewise: nil? |
| 07:59 | ohpauleez | russfrank: You shouldn't use identical? like that. Use the predicate functions you're looking for or use (= thing-1 thing-2) |
| 08:01 | ohpauleez | russfrank: Likewise, you should try to use restructuring to help you pull out the values you're looking for. |
| 08:01 | ohpauleez | Hope these tips help! |
| 08:02 | russfrank | they do |
| 08:02 | russfrank | ohpauleez: https://gist.github.com/3303613 little better with cond |
| 08:03 | russfrank | I'm using identical? because I need to know if it's exactly false |
| 08:03 | russfrank | it can return nil if the variable is simply unset |
| 08:03 | russfrank | so each variable can be nil, true, or false in the model, and (= nil false) => true of course, so that's why I'm using identical |
| 08:04 | ohpauleez | &(false? nil) |
| 08:04 | lazybot | ⇒ false |
| 08:04 | ohpauleez | &(false? false) |
| 08:04 | lazybot | ⇒ true |
| 08:04 | russfrank | hah, ok. |
| 08:04 | ohpauleez | &(nil? false) |
| 08:04 | lazybot | ⇒ false |
| 08:04 | ohpauleez | &(nil? nil) |
| 08:04 | lazybot | ⇒ true |
| 08:06 | ohpauleez | So the next thing you should do, is patch up the predicates. Then I can help you through putting some let blocks in that destructure these args a bit |
| 08:06 | russfrank | https://gist.github.com/3303640 |
| 08:06 | russfrank | that makes things considerably nicer |
| 08:07 | ohpauleez | russfrank: (true? (satisfiable? clause model))) that can be simpler. How? |
| 08:08 | russfrank | it can be just (satisfiable? clause model) but I like the symmetry of explicit truth testing |
| 08:08 | russfrank | since we have to test if it's specifically false in the following test |
| 08:08 | ohpauleez | (we're going to refactor that later haha) |
| 08:09 | ohpauleez | But right now, we're going to introduce some lets - I'll comment on the gist itself in a second |
| 08:09 | russfrank | oh alright I'll change it haha |
| 08:09 | russfrank | ok |
| 08:28 | ohpauleez | russfrank: anytime you see and (if … (let [] )), you should think - if-let |
| 08:29 | ohpauleez | anytime you find yourself using (get ...) |
| 08:29 | ohpauleez | you should use destructuring |
| 08:30 | ohpauleez | using (let (if-let … )) or (if-let (let …)) are fine, but usually means there might be a better way to structure and process your data |
| 08:31 | ohpauleez | put the some before the every?, so you can potentially avoid going through the entire collection |
| 08:31 | estebann | how can I tell if a form has been quoted? |
| 08:32 | hyPiRion | ,(= [] '[]) |
| 08:32 | clojurebot | true |
| 08:33 | ohpauleez | similarly - |
| 08:33 | ohpauleez | &(type (quote (1 2 3 4))) |
| 08:33 | hyPiRion | I don't believe you can, unless I interpret you wrong. |
| 08:33 | lazybot | ⇒ clojure.lang.PersistentList |
| 08:33 | ohpauleez | you cannot, unless you're the author of the macro or quoting form |
| 08:33 | estebann | weird |
| 08:34 | ohpauleez | if you're in a situation where you need to know if something is quoted, chances are you're programming to the implementation, not to an interface |
| 08:34 | hyPiRion | Do you need to differentiate between quoted and "unquoted" values? |
| 08:34 | ohpauleez | and need to refactor the approach |
| 08:35 | estebann | i'm just sort of exploring options at this point... but it seems strange that there are aspects to a data structure to which only eval has access |
| 08:35 | naeg | ,(print "hello naeg") |
| 08:35 | clojurebot | hello naeg |
| 08:36 | ohpauleez | estebann: You have access to the reader too |
| 08:36 | dmedvinsky | ,(print ",(print \"hello clojurebot\")") |
| 08:36 | clojurebot | ,(print "hello clojurebot") |
| 08:37 | ohpauleez | my example above shows that the reader sees a quoted form AS the data structure |
| 08:37 | ohpauleez | code is data is code |
| 08:38 | estebann | ,(= (eval '(+ 1 1)) (eval ''(+ 1 1)) |
| 08:38 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 08:38 | estebann | ,(= (eval '(+ 1 1)) (eval ''(+ 1 1))) |
| 08:38 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 08:38 | estebann | well, that second one would have been false |
| 08:39 | ohpauleez | right, and you'd expect that, you eval'd the data |
| 08:39 | estebann | ,(= '(+ 1 1) ''(+ 1 1)) |
| 08:39 | clojurebot | false |
| 08:40 | ohpauleez | right, you're just proving the reader works |
| 08:40 | ohpauleez | the first one returns the raw list, as a list |
| 08:40 | ohpauleez | the second one returns a quoted list |
| 08:41 | ohpauleez | (1 2 3 4) does not equal (quote (1 2 3 4)) |
| 08:41 | estebann | but the members of both are the same, and they both have the same type |
| 08:41 | estebann | i'm probably just not getting something |
| 08:41 | ohpauleez | they don't have the same members |
| 08:41 | ohpauleez | totally, let's try one more thing |
| 08:42 | ohpauleez | (1 2 3 4) has four members: 1 2 3 4 |
| 08:42 | estebann | ok |
| 08:42 | ohpauleez | (quote (1 2 3 4)) had two members: quote and (1 2 3 4) |
| 08:42 | ohpauleez | so '(1 2 3 4) and ''(1 2 3 4) can't be equal |
| 08:43 | estebann | ,(first '(1 2 3)) |
| 08:43 | clojurebot | 1 |
| 08:43 | estebann | ,(first ''(1 2 3)) |
| 08:43 | clojurebot | quote |
| 08:43 | estebann | gotcha |
| 08:43 | estebann | ok thanks, that's helpful |
| 08:43 | ohpauleez | it's just the reader, reading forms. Quote just says, "Hey, this is data" |
| 08:43 | ohpauleez | totally welcome |
| 08:46 | hyPiRion | russfrank: Here's how I'd do it https://gist.github.com/3303586 |
| 08:46 | hyPiRion | It's a good program for being your first though. |
| 08:47 | ohpauleez | hyPiRion: That's good. Destructure in the first function, and put some before every? |
| 08:48 | ohpauleez | I'd consider take-while or drop-while too, to make things a little more readable |
| 08:48 | hyPiRion | Oh, yeah, find is a special function you'd usually use to get a value |
| 08:49 | hyPiRion | Look at this: ##(do (println (get {:a nil} :a)) (println (get {:b :a-does-not-exist} :a))) |
| 08:49 | lazybot | ⇒ nil nil nil |
| 08:50 | hyPiRion | So if you have a nil value, you're unable to distinguish it between not being there at all. |
| 08:50 | ohpauleez | hyPiRion: I'm just talking about (= (get v 0) \-) |
| 08:50 | hyPiRion | ohpauleez: Ah. |
| 08:51 | ohpauleez | I would throw a let up top, (let [[first-char] v] ...) |
| 08:51 | russfrank | hyPiRion: thanks -- will read through this |
| 08:51 | ro_st | ohpauleez: had any issues with enfocus's set-style and :top or :height ? |
| 08:51 | ohpauleez | but the get is fine, since the value isn't really needed anywhere else |
| 08:51 | hyPiRion | ohpauleez: (defn lookup [[c :as v] model] would be a nice one |
| 08:51 | ohpauleez | ro_st: I don't use those |
| 08:52 | djcoin | Putting function name then doc then args of functions seems kinda weird to me (but I guess that's a deeply rooted coding style). I would rather bundle together function name then functions args then doc |
| 08:52 | ro_st | ok |
| 08:52 | ohpauleez | djcoin: It's because you can have multiple arg lists |
| 08:52 | hyPiRion | russfrank: My pleasure, thanks for giving me a break at work ;) |
| 08:52 | ro_st | djcoin: args close to the impl is better |
| 08:52 | ohpauleez | and often do in production code |
| 08:52 | djcoin | Oh yeah, right |
| 08:52 | hyPiRion | I really like 4clojure, so if you're interested in learning about many different functions, go there. |
| 08:53 | ohpauleez | I read it as: Name, meaning, implementation |
| 08:53 | hyPiRion | I believe the reason why arglist is after docstring is a technical one |
| 08:53 | ohpauleez | I shouldn't need to see the implementation if I just want the name or the meaning of something |
| 08:53 | ohpauleez | for sure, because of multiple arg lists |
| 08:54 | hyPiRion | consider (defn foo "docstring" ([a b] ...) ([a b c] ...)) |
| 09:07 | pandeiro | what fn would take a seq '(1 2 3) and produce an infinite seq '(1 2 3 1 2 3 1 2 3 ...) ? |
| 09:07 | pandeiro | repeat produces '((1 2 3) (1 2 3) (1 2 3)) |
| 09:07 | hyPiRion | cycle |
| 09:07 | hyPiRion | #(cycle '(1 2 3)) |
| 09:07 | hyPiRion | ,(cycle '(1 2 3)) |
| 09:07 | clojurebot | (1 2 3 1 2 ...) |
| 09:09 | pandeiro | hyPiRion: thanks, can never remember the names |
| 09:11 | pandeiro | ,(let [f '(nil nil "fizz") b '(nil nil nil nil "buzz")] (take 30 (map vector (range) (cycle f) (cycle b)))) |
| 09:11 | clojurebot | ([0 nil nil] [1 nil nil] [2 "fizz" nil] [3 nil nil] [4 nil "buzz"] ...) |
| 09:11 | TimMc | haha |
| 09:11 | pandeiro | just translating the HN post on functional fizzbuzz from Haskell to Clojure :) |
| 09:12 | TimMc | It's almost right. |
| 09:12 | pandeiro | yeah? |
| 09:12 | TimMc | Off by one. |
| 09:12 | hyPiRion | Which one? |
| 09:12 | pandeiro | ah 1 indexed? |
| 09:12 | TimMc | Switch fizz and buzz to be the first in their lists, maybe. |
| 09:13 | pandeiro | hyPiRion: it was on front page this morning, read it on the train, sorry no link |
| 09:14 | hyPiRion | pandeiro: ah, okay |
| 09:14 | hyPiRion | Can't find it. |
| 09:14 | pandeiro | TimMc: enlighten me? i know it should technically produce '(1 2 "fizz" 4 "buzz"...) but i was ignoring the post-processing part :) |
| 09:14 | pandeiro | hyPiRion: one sec |
| 09:15 | pandeiro | http://pragprog.com/magazines/2012-08/thinking-functionally-with-haskell ? |
| 09:16 | hyPiRion | thanks |
| 09:16 | hyPiRion | (inc pandeiro) |
| 09:16 | lazybot | ⇒ 1 |
| 09:17 | pandeiro | woohoo! |
| 09:17 | pandeiro | look out, #clojure |
| 09:17 | russfrank | lol |
| 09:18 | pandeiro | thank you thank you, i will be doing fizzbuzz all week |
| 09:24 | hyPiRion | ,(map #({"" %} %2 %2) (range) (map str (cycle ["Fizz" "" ""]) (cycle ["Buzz" "" "" "" ""]))) |
| 09:24 | clojurebot | ("FizzBuzz" 1 2 "Fizz" 4 ...) |
| 09:27 | TimMc | The issue is that it should be replacing the multiples of 3 and 5, but it looked like you were hitting the multiples-minus-one. |
| 09:32 | pandeiro | hyPiRion: i am still parsing that, impressive |
| 09:34 | TimMc | #({a b} c d) -> #(if (= a c) b d) |
| 09:35 | hyPiRion | pandeiro: It's not that complicated - TimMc hit the nail on the hackish part. |
| 09:38 | ToxicFrog | Clever. |
| 09:39 | pandeiro | yeah it is |
| 09:39 | pandeiro | (clever, not complicated) |
| 09:39 | pandeiro | the optional second arg to the hash-map-as-fn is the trick |
| 09:39 | pandeiro | as TimMc illustrated |
| 09:41 | jrheard | hi folks - can someone please explain this to me? |
| 09:41 | jrheard | => (some #{:a} {:a 1 :b 2}) |
| 09:41 | jrheard | nil |
| 09:41 | ToxicFrog | Yeah, I didn't know you could do that |
| 09:42 | jrheard | (i would expect to see :a instead of nil) |
| 09:42 | duck11231 | and obviously, it's not very useful |
| 09:42 | ToxicFrog | ,(some #{:a} {1 :a 2 :b}) |
| 09:42 | clojurebot | nil |
| 09:42 | ToxicFrog | Hmm |
| 09:43 | ToxicFrog | Oh, I think I see what's happening |
| 09:43 | jrheard | ! |
| 09:43 | XPherior | Is there a way to declare my data at the bottom of a Midje test? I have a let form at the top of most facts. It kind of obscures what the test does. |
| 09:43 | ToxicFrog | ,(some #{[:a 1]} {:a 1 :b 2}) |
| 09:43 | clojurebot | [:a 1] |
| 09:43 | jrheard | hm! |
| 09:43 | jrheard | that makes sense |
| 09:43 | ToxicFrog | jrheard: a map is, conceptually, an unordered collection of [key value] pairs |
| 09:44 | ToxicFrog | So that's what some looks for |
| 09:44 | jrheard | so if i want to know if a map contains a key, the only recourse i have is to use contains? |
| 09:44 | jrheard | i was hoping to write a general in? function that would return True if an item is in a collection |
| 09:44 | duck11231 | XPherior: you can set up some data in an around at the end, but I had diffuculties doing that, so I just use let |
| 09:45 | jrheard | first-pass implementation looked like (some #(= x %) coll) , but it doesn't work on dicts :) |
| 09:45 | hyPiRion | jrheard: use find |
| 09:45 | XPherior | duck1123: Hm, alright. That's kind of a shame. It would make the test so much more readable. |
| 09:45 | jrheard | ! |
| 09:45 | ToxicFrog | jrheard: contains? works on non-maps as well |
| 09:45 | jrheard | ! |
| 09:45 | jrheard | both of those are great to know! |
| 09:45 | jrheard | thanks folks :) |
| 09:45 | XPherior | contains? is such a misleading function. Ugh |
| 09:45 | ToxicFrog | jrheard: however, contains? looks for keys, not values |
| 09:45 | ToxicFrog | Which can be unpleasantly surprising |
| 09:45 | duck11231 | XPherior: it works, but I just found it to brittle when working with lazy seqs, and dynamic bindings and whatnot |
| 09:45 | ToxicFrog | (eg, [:a :b :c] contains? 3 but does not contains? :a) |
| 09:46 | jrheard | ToxicFrog: buh |
| 09:46 | XPherior | ToxicFrog: Yeah I understand. :/ |
| 09:46 | djcoin | What are the advantages of dynamic typing other static typing ? Curious about what clojurians think about this :) - if there are any except that lisp language can't be statically typed easily - |
| 09:46 | XPherior | Just makes me wish Clojure had a where clause, sort of thing |
| 09:47 | hyPiRion | where clause? |
| 09:47 | XPherior | ((+ a b) (where a => 1 b => 2)) |
| 09:47 | hyPiRion | oh. |
| 09:47 | XPherior | Like Haskell has. |
| 09:47 | ToxicFrog | jrheard: this is actually harder that I would have expected, now that we're looking at it. |
| 09:47 | jrheard | yeah, right? |
| 09:47 | ToxicFrog | Partly, I think, because you want to search for keys in maps but values in everything else |
| 09:47 | jrheard | exactly yeah |
| 09:47 | XPherior | ToxicFrog: How about using a protocol? |
| 09:47 | jrheard | i just want python's "in" operator |
| 09:48 | jrheard | is it idiomatic in clojure to do different things based on the type of your input? e.g. pattern-matching in haskell, do this if it's a map or that if it's anything else |
| 09:48 | hyPiRion | djcoin: Well, it's less verbose, and I like that. It's also easier to prototype. |
| 09:49 | jrheard | the impression i've been getting is that instead you're encouraged to code to the abstractions, not the implementations |
| 09:49 | babilen | jrheard: The main problem is that you don't see a map as a collection of [k v] pairs for your "in" function. Once you do that the content tests in Clojure make a lot of sense |
| 09:49 | hyPiRion | jrheard: Have you looked at multimethods? It's pattern-matching-ish |
| 09:49 | jrheard | hyPiRion: yeah and i love that they exist, but they don't seem to also let me match on types |
| 09:49 | djcoin | Type inference on static language does not make it too verbose (besides when it comes to optimization in clojure you may need to add type hint) |
| 09:49 | djcoin | hyPiRion: ^ |
| 09:49 | djcoin | Agreed for prototyping :] |
| 09:50 | XPherior | jrheard: I think Rich said pattern matching was overly complex, and to rely on polymorphism - which protocols basically are |
| 09:50 | jrheard | babilen: fair enough; so i'll just not write my in? function and instead use contains? on maps and some on non-maps |
| 09:50 | XPherior | You're not saying if this is a map, do this.. More, each type handles it if it ops to do so |
| 09:50 | jrheard | XPherior: yeah, that fits with the impression "clojure programming" has been giving me |
| 09:50 | XPherior | Takes a while to get used to :) |
| 09:50 | jrheard | :) |
| 09:50 | jrheard | thanks again for the help folks |
| 09:50 | hyPiRion | djcoin: Well, it's a personal opinion. Go has managed to make static typing nice, whereas I haven't yet used Haskell or anything static and functional. |
| 09:51 | babilen | jrheard: exactly -- And collections are also functions of their keys -- But then you would argue that you don't want keys (i.e. indices) for lists and vectors as in &(["a" "b" "c"] 1) |
| 09:51 | hyPiRion | I'm comparing to C/Java, in which things becomes somewhat verbose in my opinion. |
| 09:52 | ToxicFrog | I still haven't used go |
| 09:52 | babilen | ,(juxt (["a" "b" "c"] 1) (1 ["a" "b" "c"])) |
| 09:52 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 09:52 | ToxicFrog | But it was Scala that convinced me I actually like static typing, I just don't like statically typed languages |
| 09:52 | ToxicFrog | *most statically typed languages |
| 09:53 | mdeboard | and that's how I met your mother |
| 09:53 | ToxicFrog | Honestly I keep going back and forth on it. Dynamic typing means I know the type system will never get in my way, which still happens from time to time in Scala. But static typing makes debugging and constructing large programs so much more convenient. |
| 09:54 | djcoin | I guess people think being a lisp, macro etc. outweights static typing. Well i'm maybe telling non sense, you can't really compare such things |
| 09:55 | djcoin | What's may be kinda clear to me is that, if you ahve to pick for a dynamic typed language, make it empowering and choose a lispy |
| 09:55 | XPherior | Found what I was looking for. Hah. https://github.com/myguidingstar/clojure/commit/17f43bc2d9284571a12559978b55c58f026a49ec |
| 09:55 | clgv | ToxicFrog: when comming from a statical typed language without a repl you certain have to change the way you are working in clojure with the repl. but when you manage that writing large programs works good, as well |
| 09:58 | hyPiRion | I would really love optional static typing and type inference based on that. |
| 09:58 | ToxicFrog | clgv: I'm coming from statically typed languages with repls, actually |
| 09:58 | ToxicFrog | Haskell and Scala |
| 09:58 | djcoin | ToxicFrog: how did you happend to make a move to clojure ? |
| 09:59 | djcoin | happen* |
| 10:00 | hyPiRion | For me, it's not so much about being static, dynamic, compiled or interpreted, but more about being interactive. |
| 10:00 | ToxicFrog | djcoin: I did some fiddling around with other lisps but none of them really clicked with me. Clojure is the first lisp-1 I've seen that I actually find practical for day to day use (easy to deploy on all OSes, lots of library support, etc) |
| 10:01 | ToxicFrog | It came up while I was looking for a new language to learn, and I was already in a JVM mood from working with Scala a lot, so I decided to have a go at it. |
| 10:01 | ToxicFrog | And so far it's pretty nice. |
| 10:01 | djcoin | Cool :) |
| 10:02 | augustl | when I start a server with "lein ring server-headless", killing the process "bash /home/augustl/local/bin/lein ring server-headless" does _not_ kill the actual java process. How can I fix that? |
| 10:06 | augustl | currently having some "fun" writing a Swing app that starts a bunch of services for testing etc. Using ProcessBuilder and Process to call "lein ring server-headless", but destroying that process doesn't destroy the actual java server |
| 10:07 | augustl | just like killing it with "kill" in a terminal doesn't destroy the java server |
| 10:08 | ToxicFrog | swing :suicide: |
| 10:09 | augustl | "lein trampoline", yay |
| 10:13 | jsabeaudry | What determines if clojure-mode will figure out how to indent the & body of a macro correctly or not? |
| 10:15 | jsabeaudry | Is it only when the macro name starts with "with-" |
| 10:19 | pjstadig | http://groups.google.com/group/clojure-dev/msg/6a5b044fd3b70ad7 |
| 10:19 | pjstadig | ? |
| 10:20 | pandeiro | anyone looked at the clojurescript/lua source/announcement on HN today? is there any overlap between the python, scheme, and lua targeting projects? |
| 10:21 | ohpauleez | pjstadig: Are you asking the status of that or RH's reply? |
| 10:39 | llasram | jsabeaudry: Take a look at `define-clojure-indent` and related |
| 10:40 | llasram | jsabeaudry: It automatically applies certain indentation rules to symbols starting with `with-`, but also uses properties on the (in-elisp version of) the symbol to determine how to indent that symbol's invocation form |
| 10:41 | jweiss | If i want a macro expansion to be able to refer to the same symbol in both generated and passed-in code, what's the best way to handle it? i can't think of any hygenic solution. |
| 10:41 | llasram | jweiss: Do you have an example? |
| 10:43 | jweiss | llasram: https://www.refheap.com/paste/4205 the problem is req# - i want both the generated code and the passed in code to refer to the whole map. |
| 10:44 | jsabeaudry | llasram, thanks for the pointer, I'll have a look at that |
| 10:45 | llasram | Usually what I'll do is have the macro take a symbol argument in some `let`-ish syntax which is then bound via let around the expansion of the body form |
| 10:49 | jweiss | llasram: ok i'll try that thanks |
| 10:51 | S11001001 | I've just noticed a particular idiomatic tic of mine that I don't think is quite as widespread as I thought |
| 10:51 | S11001001 | I refer to packages that use a particular library as "clients" of the library |
| 10:51 | S11001001 | is this normal? |
| 10:53 | russfrank | ohpauleez: I liked hyPiRion's use of map, ended up with this https://gist.github.com/3303640 |
| 10:54 | arkh | when at a repl, if I do a (load-file "path/project.core") and (in-ns project.core), and it 'require's project.supplemental, is there a way to reload project.supplemental when changed? |
| 10:55 | arkh | sorry, typo with (in-ns ...) |
| 10:55 | dgrnbrg | Is there something in clojure's libraries that's like a future, but it runs on the same thread when I try to deref it? |
| 10:55 | clgv | dgrnbrg: delay |
| 10:56 | dgrnbrg | i thought i remembered that, but i couldn't remember the name |
| 10:56 | dgrnbrg | thanks! |
| 10:56 | uvtc | S11001001: I like using "client" for local/remote interactions because it's one of a pair: "client/server". Are there matching terms like that for "user-of-library/library"? (Hm. Maybe I'm having brain lock.) |
| 10:56 | arkh | delay runs on the same thread but doesn't (necessarily) immediately execute |
| 10:56 | S11001001 | uvtc: the only ones I can think of are dependent and reverse dependency; both of these are terrible |
| 10:57 | S11001001 | uvtc: and there's no rule against using one name for different things; else assoc should be called something else :) |
| 10:57 | ohpauleez | russfrank: That's looking better. Consider using take-while/drop-while instead of that sort of weird filter in line 53, remove the blank lines between arg-list and the bodies, and consider [model [c :as v]] for line 4 |
| 10:57 | ohpauleez | russfrank: then run the whole thing through kibit |
| 10:58 | uvtc | S11001001: Oh. caller/callee |
| 10:58 | S11001001 | uvtc: (map my-function my-list) |
| 10:58 | uvtc | S11001001: Oh, well, that would be too general, since of course it applies to regular functions too... |
| 11:02 | TimMc | S11001001: I don't talk about packages as clients but instead just refer to "client code" or "relying code". |
| 11:03 | TimMc | "Caller" focuses on function signatures, not other contracts. |
| 11:03 | jkkramer | "consumer" is used sometimes, too |
| 11:03 | S11001001 | TimMc: hmm, nice qualifier |
| 11:03 | russfrank | hm, the kibit installation is not working.. I added the thing to my user profile but lein is saying kibit is not a task |
| 11:04 | TimMc | "Dependent" really gets to the heart of it, though: It's a DAG. |
| 11:06 | S11001001 | TimMc: it's truth, but too easily confused with dependency in prose |
| 11:07 | arkh | regarding my previous babble, it seems I could just do (use 'project.core :reload) |
| 11:08 | S11001001 | TimMc: and the situation is even worse when speaking, where "dependents" vs "dependency"... |
| 11:08 | uvtc | Hm ... availor/availee (Calling code avails upon the library code.) :) |
| 11:11 | S11001001 | jkkramer: that might work |
| 11:12 | TimMc | S11001001: Yeha. :-( |
| 11:12 | TimMc | *yeah |
| 11:17 | russfrank | lein doesn't seem to want to install kibit .. https://gist.github.com/29d3785de75e62f7814c |
| 11:17 | russfrank | ohpauleez: any ideas? |
| 11:23 | treehug | is there anything similar to a mathematica/ipython repl for clojure? |
| 11:25 | antares_ | treehug: reply is a "more advanced" REPL, leiningen 2 (leiningen.org) uses it |
| 11:27 | nDuff | ...which gives you far more capabilities than IPython's -- keystrokes for moving things in and out of blocks, code-structure-sensitive copy/paste, etc. |
| 11:28 | nDuff | treehug: ...personally, I'm using the out-of-the-box configuration from Emacs Live (https://github.com/overtone/emacs-live#readme) |
| 11:30 | nDuff | treehug: ...see the videos linked there to get an idea of what the workflow feels like. |
| 11:30 | treehug | cools thanks |
| 11:32 | TimMc | russfrank: I was getting the same last night. Lein 1.7.1, Ubuntu Phornicating Phoenix or whatever. |
| 11:33 | TimMc | russfrank: I only got as far as determining that lein could successfully download from both Maven Central and Clojars and that Clojars had a valid-looking kibit 0.0.4 jar. |
| 11:37 | naeg | Wow. Clojure's collections and the functions conj, seq, into, empty, etc. just blew my mind. This really make use of dynamic typing. Python seems so inferior in this aspect now |
| 11:37 | russfrank | python isn't functional ;P |
| 11:37 | naeg | "this aspect" -> dynamica typing :P |
| 11:37 | russfrank | oh, I suppose I see what you're saying |
| 11:38 | russfrank | that python doesn't really take advantage of dynamic typing by not being functiona l |
| 11:38 | scriptor | russfrank: it's not really related to being functional |
| 11:38 | russfrank | TimMc: yeah, I noticed the same thing. it seems like when it copies the jar into ~/.lein/plugins/, it screws that up and ends up just creating a 0 byte jar.. |
| 11:38 | scriptor | it's about using dynamic typing to have a seq interface |
| 11:38 | naeg | I'm not yet sure whether what blew my mind was part of being functional - but if it is, then yes |
| 11:39 | TimMc | Python goes a few steps in that direction with duck-typing, of course. |
| 11:41 | naeg | as far as I understood duck-typing, it's just so inferior |
| 11:41 | naeg | I just love good abstractions |
| 11:42 | piranha | well python has protocols and they aren't that bad |
| 11:42 | piranha | like len(x) calling x.__len__ or x.attr calling x.__getattr__ (or, if attr is a descriptor, attr.__get__) |
| 11:43 | naeg | that's a nice concept too, yeah. but when using them, you're still bound to the type (e.g. whether it's an array or a map) except for len |
| 11:44 | piranha | naeg: in which case? |
| 11:44 | piranha | not sure I understood what you mean |
| 11:46 | piranha | I mean I love conj and friends, but in this case Python isn't that bad. All stuff like 'a in b' or slicing is backed by some protocol (__contains__ and __slice__ in those cases)... |
| 11:46 | naeg | piranha: writing an example for you...(takes some time, still a beginner to clojure :P) |
| 11:46 | piranha | ok sure :) |
| 11:48 | naeg | piranha: http://cljbin.com/paste/5023db70e4b09bebef3e5ff5 |
| 11:49 | naeg | depending on what kind of seq (list, hash table, ...) and what you're doing with it, you could have a bad time in Python |
| 11:49 | naeg | because you would have to check whether you're working with a list or a dic now |
| 11:50 | piranha | naeg: yes, this case makes sense... |
| 11:50 | ro_st | dnolen: seen this? https://code.google.com/p/leak-finder-for-javascript/ |
| 11:51 | dnolen | ro_st: no why? |
| 11:51 | piranha | naeg: well, in type it would be something like type(seq)(x for x in <your code>) :-) |
| 11:51 | piranha | s/in type/in python/ |
| 11:51 | ro_st | just saw it now. thought it might be interesting for clojurescript hackers :) |
| 11:51 | naeg | piranha: that's actually an example from Clojure Programming |
| 11:53 | ro_st | dnolen: also, i wanted to ask you, the sourcemap stuff that's working now, is that from the generated js to the compiled js? |
| 11:53 | scriptor | naeg: if you disregard hash tables, wouldn't the equivalent be straightforward to do with lists, generators, and tuples? |
| 11:54 | piranha | scriptor: it would be even with dictionaries, if code looks like the thing I wrote earlier. |
| 11:54 | dnolen | ro_st: yes, which isn't that useful. |
| 11:55 | ro_st | it is to me :-) how do i switch it on? |
| 11:55 | piranha | also, it's trivial to make your own type which behaves like a some sort of sequence |
| 11:55 | naeg | yeah, but it's even more trivial not doing it at all :P |
| 11:55 | dnolen | ro_st: it's only available in the sourcemap branch. Add compiler option :sourcemap true I believe. |
| 11:56 | pepijndevos | How do you solve the multiple o |
| 11:56 | naeg | I'm sure there are better examples in which you would have to do further type checking in Python... |
| 11:56 | dnolen | ro_st: and actually you're quite right, it is useful :) |
| 11:56 | pepijndevos | *index problem |
| 11:57 | piranha | naeg: yeah, that's always the problem with abstract examples, they don't make much sense IMO. :) I think that this is nice property of Clojure but it's not much better than Python here. It's other properties of Clojure which make it better than Python |
| 11:57 | ro_st | dnolen: ah, ok. i've only got the cljs that lein-cljsbuild fetches. i'll figure out how to use the one from that branch in git |
| 11:58 | naeg | piranha: I'll think about a more concrete example (and maybe even write a blog post) later, so I can show it to you can scriptor. Have to conintue learning clj now :P |
| 11:59 | piranha | sure :) |
| 11:59 | dnolen | there's a good chance I might tackle sourcemap soon, since I'd like to demo that at StrangeLoop |
| 11:59 | dnolen | ro_st: we'll see |
| 11:59 | naeg | but made a note, might not come up with it today but it's in my head |
| 12:00 | ro_st | dnolen: awesome. i'm quite happy to spelunk in the :whitespace js if it means i can step through :advanced js. |
| 12:00 | ro_st | not like i haven't been doing that for a year already, anyway :-) |
| 12:01 | ro_st | dnolen: are you using cljs for anything? or are you just wizarding on it for laughs? |
| 12:02 | dnolen | ro_st: heh yeah, I'll try to see if I can't figure out something basic to land in master. |
| 12:02 | ro_st | i'm looking at lein's sample project.clj, i don't see anything in there about using git as a dep |
| 12:03 | ro_st | ah, a plugin |
| 12:03 | dnolen | ro_st: currently just hacking on the compiler. |
| 12:03 | dnolen | ro_st: you can do it without checkouts feature s well. |
| 12:04 | dnolen | s/without/with |
| 12:04 | ro_st | and the :sourcemap true can go into the cljsbuild options? |
| 12:04 | dnolen | ro_st: yes that should work. |
| 12:06 | nDuff | ...that is, translating foo > 3 AND foo < 5 into {:foo [...what goes here?]} |
| 12:07 | metajack | (where (and {:foo [> 3]} {:foo [< 5]})) |
| 12:07 | metajack | there is a similar exmaples in the docs for korma |
| 12:08 | nDuff | ...so at that point I no longer can pass my complete where clause around as a map, but have to pass around the query it's going to be merged into. |
| 12:08 | nDuff | That's not insurmountable, but a touch annoying. |
| 12:09 | metajack | the map as where clause is sugar. you can't have duplicate keys in a map, so you can never do multiple constraints on the same field that way |
| 12:10 | metajack | also, the map is implicit AND, so you can't do OR that way either |
| 12:11 | metajack | if all you need is multi-constraint fields, just pass around the list, or add more sugar to korma |
| 12:11 | ro_st | dnolen: took a quick stab at the checkouts thing. don't i have to specify a path for the sourcemap, or does it infer from output path? |
| 12:11 | metajack | seemd reasonable to support something like {:foo [[> 3] [< 5]]} |
| 12:12 | metajack | or change it to a vector, [:foo [> 3] :foo [< 5]] |
| 12:12 | nDuff | Hrm. Right now I have "middleware" for my queries -- removing some clauses and inserting others. Pondering whether I want to keep that workflow and adopt it to work without the sugar, dump it altogether, or extend korma. |
| 12:12 | metajack | if your value field here is integers, you can use in to get around this :) |
| 12:13 | metajack | also assuming the range is smallish |
| 12:13 | nDuff | They're integers, but they're several million values apart from each other. |
| 12:13 | metajack | from looking at it, i think about extending korma to support a vector syntax instead of or in addition to the map syntax. then you could keep the simpler middleware |
| 12:16 | dnolen | ro_st: to be honest I haven't look at it recently, I think it outputs a sourcemap file based on the name of the output file. |
| 12:18 | nDuff | Hmm. Can parameters be used with (raw) in korma? |
| 12:19 | ro_st | ok, thanks |
| 12:19 | nDuff | ...hrm, looks like it only takes a string |
| 13:34 | dgrnbrg | hello clojurians |
| 13:35 | dgrnbrg | I have a fascinating performance problem in my clojure code |
| 13:35 | dgrnbrg | in my AOTed namespace, I am seeing a defn take 100s of ms |
| 13:35 | dgrnbrg | i'm not sure what could cause this--perhaps it's causing a cascade of classes to be loaded? |
| 13:36 | dgrnbrg | or maybe there's some name resolution mechanism that needs to run? |
| 13:36 | dgrnbrg | there's a lot of reflected calls to classes in symbols defined in a let around the defn--perhaps somehow those reflections cause something to happen? (although warn-on-reflection remains silent) |
| 13:39 | llasram | dgrnbrg: If there are reflected calls, why is warn-on-reflection remaining silent...? |
| 13:40 | hyPiRion | have you set warn-on-reflection to true? |
| 13:41 | mrb_bk | dnolen: ping |
| 13:42 | mrb_bk | Come see #clojure's own dnolen speak at our lovely NYC offices! http://dev.paperlesspost.com/blog/2012/08/08/paperless-post-tec-talks-david-nolen/ |
| 13:44 | hyPiRion | duck11232: Where do you live? |
| 13:44 | duck11232 | Detroit, MI |
| 13:44 | hyPiRion | Ah. At least you're in US of A ;( |
| 13:44 | TimMc | I could take the bus down from Boston, I suppose... |
| 13:45 | scriptor | I could, uhm, walk there |
| 13:45 | TimMc | Show-off. :-P |
| 13:45 | casion_ | are there any nifty ways to browse clojure docs, or cheatsheets or whatnot? |
| 13:46 | scriptor | :D |
| 13:46 | TimMc | ~cheatsheet |
| 13:46 | clojurebot | Cheatsheets with tooltips can be found at http://jafingerhut.github.com/ . |
| 13:46 | hyPiRion | casion_: lein repl with cdoc and doc |
| 13:46 | casion_ | I know of find-doc/doc obv, and browring clojure.org |
| 13:46 | casion_ | those dont seem to get me far when I dont know what I"m trying to find heh |
| 13:46 | scriptor | clojuredocs.org is nice, if you haven't check that out yet |
| 13:46 | AWizzArd | It is really unfortunate that doc now went into clojure.repl. Why was it moved? I think it is nice to have in clojure.core. |
| 13:46 | casion_ | hyPiRion: oh there we do |
| 13:46 | casion_ | that's great |
| 13:47 | acheng | hyPiRion: what is cdoc? |
| 13:47 | duck11232 | checkout clojureatlas if you know the type of data you're working with, but not the fn you need |
| 13:47 | acheng | casion_: there is the findfn project ... |
| 13:47 | hyPiRion | cdoc is a function dragging out data from clojuredoc |
| 13:49 | hyPiRion | maybe even it works here, though it would be spammy. |
| 13:50 | hyPiRion | ,(cdoc map) |
| 13:50 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cdoc in this context, compiling:(NO_SOURCE_PATH:0)> |
| 13:50 | dgrnbrg | llasram: they are calls w/ the ffi syntax (i.e. ".") |
| 13:50 | dgrnbrg | i guess i meant that they are interop calls, whcih may have classloader ramifications |
| 13:53 | dnolen | mrb_bk: pong! |
| 14:03 | casion_ | thanks for the suggestions guys |
| 14:04 | acheng | i see. cdoc requires cd-client.core |
| 14:05 | casion_ | clojureatlas looks super neat |
| 14:08 | babilen | That reminds me: Do you have any idea when clojuredocs and/or the cheatsheet will be updated for clojure 1.4? |
| 14:21 | emezeske | dnolen: Have you had a chance to look at http://dev.clojure.org/jira/browse/CLJS-340 at all ? |
| 14:27 | hyPiRion | babilen: I suspect when 1.5 comes out. |
| 14:27 | naeg | I've got a question about this line of code: |
| 14:27 | naeg | (repeatedly 10 (partial rand-int 50)) |
| 14:28 | naeg | is partial 'abused' to create a function which takes no arguments in order to supply it to repeatedly? |
| 14:29 | raek | I wouldn't consider it abuse |
| 14:29 | naeg | I considered it abuse beacuse the documentation says "Takes a function f and fewer than the normal arguments to f [...]" |
| 14:29 | S11001001 | any distastefulness is offset by the coolness of using partial |
| 14:29 | raek | maybe I would have written (repeatedly 10 #(rand-int 50)) |
| 14:29 | ohpauleez | I don't know that I'd use partial |
| 14:29 | raek | true. |
| 14:29 | ohpauleez | yes, what raek said |
| 14:30 | ohpauleez | S11001001: haha |
| 14:30 | naeg | seems more straightforward indeed, wondering why the authors of Programming Clojure did it that way... |
| 14:31 | S11001001 | for the time/space tradeoff |
| 14:31 | naeg | but it basically does what I assume? |
| 14:31 | raek | they're equivalent |
| 14:32 | S11001001 | unless you are running very very low on permgen space :) |
| 14:32 | naeg | lol |
| 14:32 | naeg | thanks all |
| 14:33 | dnolen | emezeske: yes, I posted about it on the clojure-dev ML no responses yet |
| 14:33 | emezeske | dnolen: Oh, I didn't see that, I'll look there. Thanks! |
| 14:33 | dnolen | emezeske: mostly trying to gauge opinions around transition. |
| 14:34 | emezeske | dnolen: Yeah, it's a big change |
| 14:36 | augustl | what's a good way to create a vector of N items where all items have the same value? |
| 14:36 | augustl | what I'm actually trying to do: turn [{:id "123abc"} {:id "456def"}] into {"123abc" "on" "456def" "on"} |
| 14:37 | lynaghk | augustl: try something like (zipmap (keys v) (repeat "on")) |
| 14:37 | lynaghk | er, that should be (values v) |
| 14:37 | dnolen | lynaghk: in this case probably want vals. |
| 14:38 | augustl | hmm, repeat |
| 14:38 | augustl | hah, cool |
| 14:42 | jcromartie | is there an idiomatic way to map over a collection for side effects? like (doall (map fn coll)) or (doseq [x coll] (fn x)) but with one call? |
| 14:42 | acheng | off topic: in erc (emacs' irc client) is there a key chord for cycling through previous nicks (vs typing it like "hyPiRion: ") |
| 14:43 | jcromartie | doall + map strikes me as the wrong way to go since it builds a resulting sequence of nils |
| 14:43 | casion_ | acheng: I use hippie-expand |
| 14:43 | casion_ | that works quite well for the task (and others) |
| 14:43 | raek | jcromartie: you can use dorun + map instead of doall + map |
| 14:44 | jcromartie | dorun huh |
| 14:44 | raek | but there is no function that does both the dorun and map parts |
| 14:44 | jcromartie | I see someone saying "be careful when you find yourself doing (dorun (map …)) |
| 14:44 | acheng | casion_: nice! |
| 14:44 | raek | (except for 'doseq' of course) |
| 14:44 | jcromartie | looks like doseq is the best |
| 14:46 | antifuchs | da-dorun-run-run da-dorun-run? |
| 14:46 | emezeske | One thing I feel compelled to point out is that if your function is just doing side-effects, you're not really "mapping" per se |
| 14:47 | emezeske | A "map" being a transformation from one list of values to another |
| 14:47 | jcromartie | yeah |
| 14:48 | jcromartie | so doseq is definitely the right way to go |
| 14:48 | jcromartie | no need to just build up a seq of n nils |
| 14:48 | jcromartie | also, it's worth turning off spellchecking when talking about Clojure |
| 14:48 | emezeske | If you really like the syntax of map, you can just (defn doeach [f coll] (doseq [x coll] (fn x))) |
| 14:50 | casion_ | jcromartie: or add clojure terms to your dictionary |
| 14:50 | jcromartie | import all public vars :) |
| 14:50 | casion_ | I've done it ;) |
| 14:51 | casion_ | along with the c standard library |
| 14:51 | casion_ | makes life easier on irc |
| 14:52 | uvtc | jcromartie: if you just need to do something $n times, see `dotimes` |
| 14:52 | uvtc | . |
| 14:53 | jcromartie | uvtc: yeah |
| 14:59 | mrb_bk | dnolen: just wanted to share the invite with you :) |
| 14:59 | mrb_bk | looking forward to it |
| 15:00 | dnolen | mrb_bk: the same! |
| 15:00 | mrb_bk | throwing down the plastic in case you get jelly everywhere |
| 15:01 | dnolen | mrb_bk: haha |
| 15:02 | mrb_bk | and strangeloop is coming so soon too! exciting |
| 15:02 | dnolen | mrb_bk: yep, I'm really excited about StrangeLoop. |
| 15:11 | acheng | oskarth -> xbot -> coffee -> Guest33534 -> oskarth ? |
| 15:12 | oskarth | acheng: oh, sorry. Just testing out nicks and freenode for helping a friend with a irc bot |
| 15:12 | oskarth | so for example "googlebot" was taken, which is what she wanted it to be called in the first place |
| 15:12 | oskarth | coffee was just showcasing a registered nick |
| 15:13 | acheng | oskarth: :) reading about that guy chasing down a ddos in an irc chat room was fun |
| 15:13 | oskarth | acheng: link? haven't seen that one |
| 15:13 | acheng | oskarth: was on HN recently. but pretty old... |
| 15:14 | oskarth | ah |
| 15:14 | oskarth | reminds me of the guy who started chatting to a trojan creator in the trojan |
| 15:14 | acheng | oskarth: http://www.crime-research.org/library/grcdos.pdf |
| 15:15 | acheng | might be the same thing? |
| 15:15 | oskarth | ah thanks |
| 15:15 | oskarth | don't think so |
| 15:15 | acheng | oh yeah. i saw that other one too. haha |
| 15:15 | oskarth | http://blogs.avg.com/news-threats/chatted-hacker-virus/ |
| 15:15 | oskarth | thats the one I thought of |
| 15:17 | acheng | oskarth: ah i think yours was on HN and mine was in a comment on HN |
| 15:18 | oskarth | ah |
| 15:18 | oskarth | interesting article |
| 15:20 | daganu | join #java |
| 15:20 | daganu | ups! |
| 15:24 | foodoo | (let [a 1 b 2 a 3] (+ a b)); would you consider assigning a value to the same symbol twice as bad style? |
| 15:25 | S11001001 | foodoo: no |
| 15:26 | uvtc | foodoo: I could see assigning multiple times to the same symbol if you're building it up to use inside the body of the `let`. |
| 15:26 | S11001001 | foodoo: it helps to avoid a frequent source of errors; commonly, you'll do (fn [a] (let [a' (slight-transform-of-a)] (do-stuff-with-a))), and forget to use a' instead of a because of name similarity. Shadowing prevents that confusion |
| 15:27 | foodoo | S11001001: so you argue that because you don't need the old value in the current context, you can just shadow it? |
| 15:28 | S11001001 | foodoo: not just can, but in many cases should |
| 15:28 | foodoo | funny. I thought that the bindings in let were more intended for constants. But thanks for clarifying that :) |
| 15:29 | hiredman | it's not assignment |
| 15:29 | hiredman | and let bindings are immutable |
| 15:30 | hiredman | ,(let [a 1 f (fn [] a) a 2 f2 (fn [] a)] [(f) (f2)]) |
| 15:30 | clojurebot | [1 2] |
| 15:30 | uvtc | foodoo: One thing I learned from listening to the elders in here is that, in a `let`, you're binding symbols directly to values. This is in contrast to what happens when you do `(def x 1)`, where you're making a symbol x refer to a var which then contains the value 1. |
| 15:36 | foodoo | I see |
| 15:37 | XPherior | Is it possible to evaluate a form before passing it to a macro? |
| 15:38 | nDuff | XPherior: What are you trying to accomplish? |
| 15:38 | acheng | XPherior: you can operate on read-time stuff while building your return expression |
| 15:39 | XPherior | Hm.. Gimmie a second. I want to phrase this clearly. |
| 15:40 | XPherior | I'm passing the result of a macro to another macro. The macro that gets a macro is complaining at compile time because it sees the macro, not the expanded form |
| 15:42 | llasram | XPherior: usually you just want the "outer" macro to include any inner forms in its expansion. Then normal macro expansion will recursively expand any macros in the resulting expansion |
| 15:42 | XPherior | llasram: That's exactly what I want. Isn't that like, the default behavior?\ |
| 15:43 | llasram | XPherior: Yes, it is the default behavior. So if that's not what's happening, then you have a bug in your macro :-) |
| 15:44 | XPherior | Hm, alright. I'll poke at it for a while longer and Gist something if I give up. |
| 15:44 | amalloy | no, you two are saying two different things and thinking they're the same |
| 15:44 | XPherior | Thanks guys. |
| 15:44 | XPherior | amalloy: Oh? |
| 15:45 | amalloy | XPherior: the default (indeed only) behavior is for the outer macro to have absolute control over the forms it's passed. some other macro inside can't magically expand first, because that breaks everything |
| 15:47 | amalloy | consider: (defmacro do-reversed [& body] (cons 'do (reverse body))) (do-reversed (x [x 1] let)) |
| 15:47 | amalloy | if x were a macro in scope, it would be incorrect to expand it inside the body of do-reversed, because in the expansion x isn't supposed to be in call position |
| 15:48 | XPherior | amalloy: Ah, I see. |
| 15:48 | amalloy | as an aside, i think my implementation of do-reversed is totally broken, but you get the idea |
| 15:48 | XPherior | Yeah, I do |
| 15:48 | XPherior | So what is the solution to this type of problem? |
| 15:48 | amalloy | usually it's to realize that it's not a problem and you're doing something else conceptually wrong |
| 15:50 | XPherior | Haha. Alright, I will rethink my approach. |
| 15:50 | acheng | this is why nDuff asked what you're trying to accomplish instead of attempting to answer the question |
| 15:50 | XPherior | acheng: Yeah, that's fair. |
| 15:50 | mk | what's the right way to conceive of if? Does it perform a common-in-clojure type conversion? Does it just check = false or = nil, and don't worry about truth? |
| 15:50 | acheng | (whereas i just jumped in :-P) |
| 15:50 | XPherior | Long day at work. Think I just need to step away from it |
| 15:51 | amalloy | mk: it checks = false or = nil, and that's exactly what truth is defined to be, so i do'nt understand "don't worry about truth" |
| 15:52 | mk | amalloy: that's often been called "truthiness" rather than truth |
| 15:52 | amalloy | okay, so? |
| 15:54 | XPherior | It's not as complicated in our little land. :) |
| 15:56 | emezeske | ,(map true? [true false nil]) |
| 15:56 | clojurebot | (true false false) |
| 15:56 | emezeske | ,(map true? [true 42 false nil]) |
| 15:56 | clojurebot | (true false false false) |
| 15:56 | mk | well, in different languages ifs behave differently. In some low level languages, if operates on numbers. In Java it operates on truth only. In javascript, type conversion is performed, and you can cast various objects into either true or false |
| 15:56 | joly | ,(map #(if % true false) [true false nil]) |
| 15:56 | clojurebot | (true false false) |
| 15:56 | amalloy | (= #(if % true false) boolean) |
| 15:56 | mk | ,(map boolean [true false nil [] 1]) |
| 15:56 | clojurebot | (true false false true true) |
| 15:56 | nDuff | Hmm. |
| 15:56 | uvtc | ,(map #(if % true false) [true 42 [] '() false nil]) |
| 15:56 | clojurebot | (true true true true false ...) |
| 15:57 | S11001001 | ,(boolean (Boolean. false)) |
| 15:57 | clojurebot | false |
| 15:57 | nDuff | Shame korma.sql.engine/predicates isn't dynamic -- it would be awfully nice to be able to rebind it to add custom predicates |
| 15:57 | joly | amalloy: cool, hadn't realized that |
| 15:57 | S11001001 | ,(if (Boolean. false) true false) |
| 15:57 | clojurebot | true |
| 15:57 | S11001001 | :] |
| 15:57 | dnolen | foodoo: that said, wise to not get too crazy w/ that - I've run into trouble with it before. |
| 16:02 | amalloy | hah. i forgot about that, S11001001. good counterattack: "what you said is true, unless the user is a madman who constructs Booleans" |
| 16:02 | S11001001 | curse of serialization |
| 16:02 | mk | I guess the code I just tried shows that if is intimately tied to boolean casting... maybe there are other things of note? (I think boolean casting is pretty terrible. Casting doesn't make sense unless it's reflexive...) |
| 16:02 | amalloy | S11001001: how is that relevant? |
| 16:02 | foodoo | dnolen: Sure. Always strive for clarity |
| 16:02 | Raynes | amalloy: Because Java's serialization stuff reads back in boolean objects that are blown to crap in Clojure, I think. |
| 16:02 | amalloy | true enough |
| 16:02 | S11001001 | ,(let [bs (java.io.ByteArrayOutputStream.) os (java.io.ObjectOutputStream. bs)] (.writeObject os [false]) (.flush os) (if (first (.readObject (java.io.ObjectInputStream. bs))) 1 2)) |
| 16:02 | clojurebot | #<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0)> |
| 16:02 | S11001001 | yeah, something like that |
| 16:02 | S11001001 | => 1 |
| 16:02 | S11001001 | ,(let [bs (java.io.ByteArrayOutputStream.) os (java.io.ObjectOutputStream. bs)] (.writeObject os [false]) (.flush os) (if (first (.readObject (java.io.ObjectInputStream. (java.io.ByteArrayInputStream. (.toByteArray bs))))) 1 2)) |
| 16:02 | clojurebot | #<CompilerException java.lang.NoClassDefFoundError: Could not initialize class java.io.ObjectOutputStream, compiling:(NO_SOURCE_PATH:0)> |
| 16:02 | S11001001 | ugh |
| 16:03 | mk | where else besides (if) and (boolean) does this sort of casting occur? |
| 16:03 | mk | when-let? |
| 16:03 | amalloy | mk: nowhere. it occurs only in if |
| 16:04 | S11001001 | ,(filter identity [(Boolean. false)]) |
| 16:04 | clojurebot | (false) |
| 16:04 | S11001001 | if has a lot of transitive implications :) |
| 16:04 | amalloy | S11001001: that's the joke, so to speak |
| 16:04 | S11001001 | amalloy: ah, I see what you're doing now |
| 16:04 | amalloy | just don't call functions that depend on 'if, if you're bothered by clojure's truthiness |
| 16:05 | mk | amalloy: is if defined in terms of boolean, or is boolean defined in terms of if? |
| 16:05 | gtrak | ,(source or) |
| 16:05 | clojurebot | Source not found |
| 16:05 | gtrak | &(source or) |
| 16:05 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: source in this context |
| 16:05 | amalloy | ~def or |
| 16:05 | Raynes | $source or |
| 16:05 | lazybot | or is http://is.gd/Z6BNy8 |
| 16:06 | gtrak | both of them are out of date :-) |
| 16:06 | Raynes | Patches welcome. |
| 16:06 | gtrak | https://github.com/clojure/clojure/blob/1.2.x/src/clj/clojure/core.clj#L663 |
| 16:06 | Raynes | (for lazybot, not clojurebot) |
| 16:06 | Raynes | (screw clojurebot) |
| 16:06 | Raynes | (:P) |
| 16:07 | Raynes | I think... |
| 16:07 | Raynes | $cd clojure.core/or |
| 16:07 | mk | looks like both if and boolean are probably defined in terms of RT/booleanCast |
| 16:08 | Raynes | $cd clojure.core or |
| 16:08 | lazybot | clojure.core/sorted-map: http://clojuredocs.org/v/1494 |
| 16:08 | lazybot | clojure.core/keyword?: http://clojuredocs.org/v/1497 |
| 16:08 | lazybot | clojure.core/vector-of: http://clojuredocs.org/v/1503 |
| 16:08 | Raynes | Hey, it's only completely wrong. |
| 16:08 | scriptor | https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L791 |
| 16:10 | uvtc | Raynes: could be worse. |
| 16:14 | mabes | I need to prepend a single element onto a lazy-seq, is there a better way than using concat? |
| 16:14 | foodoo | mabes: cons? |
| 16:15 | S11001001 | mabes: as foodoo says, cons is the standard way to do that |
| 16:15 | mabes | foodoo: hrmm.. I thought I had tried that and it forced evaluation.. you are right though, cons is what I'm looking for |
| 16:16 | S11001001 | conj will force |
| 16:16 | amalloy | S11001001: really? |
| 16:17 | amalloy | &(do (conj (map print (range 10)) 0) nil) |
| 16:17 | lazybot | ⇒ 0123456789nil |
| 16:17 | amalloy | &(do (cons 0 (map print (range 10))) nil) |
| 16:17 | lazybot | ⇒ nil |
| 16:18 | amalloy | S11001001: do you have a simple explanation for why that is? |
| 16:20 | amalloy | hm. apparently LazySeq.cons calls RT.cons(x, seq()) rather than RT.cons(x, this). i assume there's a reason, but it seems like a non-obvious choice |
| 16:20 | scriptor | amalloy: looks like it calls seq() inside LazySeq's cons |
| 16:21 | scriptor | yep |
| 16:21 | mk | I wouldn't bother with conj anyway. It's not even a real function |
| 16:21 | amalloy | wat |
| 16:21 | mk | ,(= (conj '(1) 2) (conj [1] 2)) |
| 16:21 | clojurebot | false |
| 16:22 | mk | ,(= (1) [1]) |
| 16:22 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 16:22 | amalloy | mk: that is the most ludicrous evidence for "not even a real function" that you could have produced |
| 16:22 | mk | ,(= '(1) [1]) |
| 16:22 | clojurebot | true |
| 16:22 | mk | not referentially transparent |
| 16:22 | amalloy | completely untrue, and basically irrelevant if it were true |
| 16:23 | emezeske | It's definitely referentially transparent. Note that '(1) is actually not the same argument as [1]. |
| 16:23 | gtrak | mk: it depends on its arguments, how is that not referentially transparent? |
| 16:23 | mk | proof above. The same values (1) and [1] go in, different values come out (true, false) |
| 16:23 | gtrak | a list and a vector are different values |
| 16:23 | emezeske | '(1) and [1] are emphatically not the same values. |
| 16:24 | mk | emphatically they are |
| 16:24 | scriptor | no |
| 16:24 | scriptor | = checks for contents in seqs |
| 16:24 | hiredman | = divides things in to "equality partitions" |
| 16:24 | hiredman | lists and vectors are in the "sequential" partition |
| 16:26 | mk | scriptor: I'm not sure why that's not just an implementation detail that you're describing |
| 16:26 | TimMc | clojurebot: equality partition is http://www.brainonfire.net/files/seqs-and-colls/main.html#tbl-eqpart |
| 16:26 | clojurebot | Ok. |
| 16:26 | dnolen | mk: you seem to like saying things which make no sense. |
| 16:26 | mk | TimMc: thanks |
| 16:27 | TimMc | (and patches welcome...) |
| 16:27 | gtrak | is a set #{1} and a vector [1] the same value for some definition of value? |
| 16:29 | Chousuke | they are the same when treated as a sequence |
| 16:29 | Chousuke | but that is purely because the set has only one item |
| 16:29 | mk | dnolen: yes, and the things that others say sound silly to me as well. That sort of thing is usually due to a misunderstanding that tends to be cleared up in channels like these... |
| 16:29 | emezeske | (dec mk) |
| 16:29 | lazybot | ⇒ -1 |
| 16:29 | gtrak | Chousuke: that's running through a seq function first, no? |
| 16:29 | hiredman | look, I dunno why you all are still talking to him |
| 16:30 | scriptor | mk: conj behaves differently according to the sequence's type, = checks the contents of the sequence, regardless of the type |
| 16:30 | Chousuke | gtrak: yes |
| 16:30 | scriptor | hiredman: good point |
| 16:30 | hiredman | scriptor: that is not true |
| 16:30 | gtrak | mk: you could be clearer at identifying what are your own assumptions |
| 16:31 | hyPiRion | ##(doc =) explains how = works. |
| 16:31 | lazybot | ⇒ "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus... https://www.refheap.com/paste/4211 |
| 16:31 | hiredman | scriptor: vectors are not sequences, so conj behaving differently for vectors is not conj behaving differently for different sequences |
| 16:31 | gtrak | mk: just saying X is so because it is doesn't cut it |
| 16:31 | hyPiRion | ,(= 1.0 1) |
| 16:31 | clojurebot | false |
| 16:32 | hyPiRion | oh, they need to update the docs again. |
| 16:32 | mk | gtrak: sets and vectors are different. Vectors and lists are the same. Under Java's definition of equality, a linkedlist is equal to an arraylist that contains the same items. |
| 16:32 | scriptor | hiredman: right, sorry, collection maybe? |
| 16:32 | Chousuke | mk: it's not really meaningful to compare sets and vectors for equality |
| 16:32 | Chousuke | since sets have no order. |
| 16:33 | mk | Chousuke: exactly |
| 16:33 | mk | it does make sense though. You just return false, just like you do when comparing 1 to :hello |
| 16:33 | gtrak | mk: I would say any semantics bound to the type of the value are part of the value-ness of it |
| 16:33 | Chousuke | well yeah. |
| 16:33 | mk | emezeske: what was the dec for? |
| 16:34 | Chousuke | but then, comparing lists and vectors does make sense because their structure is essentially the same. plus, it's useful |
| 16:34 | dnolen | ,(subvec '(1 2 3) 1) |
| 16:34 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IPersistentVector> |
| 16:34 | dnolen | mk: so why doesn't this work ^ |
| 16:34 | gtrak | clojure makes an equality partition choice to group them together because it's useful, you could easily do something else if you wish |
| 16:35 | mebaran151 | Hey #clojure, I'm having a weird deps problem: Failed to collect dependencies for clojure.lang.LazySeq; was working this morning and haven't touched my project.clj file. Any idea how to start to debug? |
| 16:35 | mk | Chousuke: yes, I agree. This is why (= '(1) [1]) |
| 16:35 | gtrak | that's a semantic on the = function |
| 16:35 | technomancy | mebaran151: try upgrading leiningen; recent versions will give a more helpful error |
| 16:35 | TimMc | Worst type signature I've seen all week: List<P3<String, Integer, List<List<List<String>>>>> |
| 16:35 | mebaran151 | technomancy: what's a good version to self-install? |
| 16:35 | TimMc | mebaran151: lein update |
| 16:36 | konr | Yeah, got a job in a company that uses clojure :D |
| 16:36 | mebaran151 | TimMc: on windows |
| 16:36 | technomancy | mebaran151: preview7 |
| 16:36 | TimMc | lein upgrade* |
| 16:36 | Chousuke | mk: oh and if you're saying = is not referentially transparent because (conj '(1) 2) is not the same as (conj [1] 2) then you're just not making sense :P |
| 16:36 | TimMc | What happens on Windows? |
| 16:36 | mk | dnolen: it's probably explicitly a function for converting between representations of the same value |
| 16:36 | mebaran151 | TimMc: unsupported operation for us windows users :( |
| 16:36 | TimMc | Ouch. |
| 16:37 | gtrak | representations of values are themselves values |
| 16:37 | mk | Chousuke: no, conj isn't |
| 16:37 | TimMc | mk: I think what you mean is that conj does not preserve =. |
| 16:37 | emezeske | mk: So, by your definition, is this function referentially transparent or not: vector? |
| 16:37 | Chousuke | mk: sure it is |
| 16:37 | emezeske | ,(vector? [1]) |
| 16:37 | clojurebot | true |
| 16:37 | Chousuke | mk: give an example where it isn't :) |
| 16:37 | emezeske | ,(vector? '(1)) |
| 16:37 | clojurebot | false |
| 16:37 | TimMc | mk: Referential transparency... you keep using that phrase. I do not think it means what you think it means. |
| 16:37 | mk | ,(= (conj '(1) 2) (conj [1] 2)) |
| 16:37 | clojurebot | false |
| 16:37 | dnolen | mk: anyways if you continue along these lines people will just ignore you as I am feeling inclined to do. |
| 16:38 | Chousuke | mk: so? that does not violate referential transparency |
| 16:38 | Raynes | I'm surprised this conversation is still happening. |
| 16:38 | Chousuke | you're not giving the same arguments to conj |
| 16:38 | TimMc | mk: Seriously, Go look it up. You have the wrong term. |
| 16:38 | aperiodic | mk: 'referential transparency' is not defined in terms of 'things that look the same to =' |
| 16:39 | mebaran151 | technomancy: the error message did get better, but it can't seem to find anything now, even org.clojure/clojure 01.3.0 |
| 16:39 | Chousuke | ,(= (conj [1] 2) (conj [1] 2)) you can call this as many times as you want and it will return true. |
| 16:39 | clojurebot | true |
| 16:39 | Chousuke | unless your hardware is falling apart |
| 16:39 | Raynes | I always get confused about people who are like "They're all wrong. It's amazing how much smarter than them that I am." |
| 16:39 | mk | TimMc: if the same values go in, the same values come out. Suppose I evaluate (conj [1] 2) and attempt to cache the result for instances of (conj '(1) 2). This fails. |
| 16:39 | scriptor | mk: just because = returns true for two different values does not necessarily mean either value can be substituted for the other |
| 16:40 | scriptor | = does not mean 'the same' |
| 16:40 | scriptor | in the sense that you're assuming it does |
| 16:40 | Chousuke | mk: '(1) is not the same value as [1] |
| 16:40 | mk | do vectors and lists both implement the List interface? |
| 16:40 | gtrak | = is a function like anything else, it could be called in-the-same-equality-partition, it's semantics don't affect what semantics conj should have, because conj does not call = |
| 16:41 | amalloy | that's actually an interesting point, though: ##(let [conj (memoize conj)] [(conj [1] 2) (conj '(1) 2)]) |
| 16:41 | lazybot | ⇒ [[1 2] [1 2]] |
| 16:41 | Chousuke | mk: no. |
| 16:41 | Chousuke | mk: vectors don't |
| 16:41 | TimMc | mk: Does clojure.core/class violate this thing you are calling rt? |
| 16:41 | gtrak | amalloy: aha! |
| 16:42 | gtrak | because memoize uses =, it binds the semantics, then it starts to matter |
| 16:42 | Chousuke | amalloy: that means memoize breaks referential transparency :/ huh |
| 16:42 | Chousuke | because it uses mk's version of it, I guess :P |
| 16:42 | scriptor | well, shit |
| 16:43 | technomancy | mebaran151: typo? |
| 16:43 | Chousuke | or in short, memoize seems to have a bug :P |
| 16:43 | mebaran151 | it says it can't find anything actually |
| 16:43 | TimMc | konr: Cool! Where? |
| 16:43 | mebaran151 | I'm wondering if my .m2 got corrupted somehow |
| 16:43 | Chousuke | a rather silly one but nonetheless a bug |
| 16:44 | konr | TimMc: Brazil! A business intelligence startup |
| 16:44 | gtrak | the bug is the fact that the thing returned is different depending on what's called first |
| 16:44 | amalloy | Chousuke: that can't be a bug in memoize; it has to be a "bug" in either =, or how maps work |
| 16:44 | amalloy | or how conj works, i suppose |
| 16:44 | mk | TimMc: they probably do violate rt, but that's fine, because they deal with things at a different level of value-equivalence. This is a bit like the difference between java's == and .equals |
| 16:45 | TimMc | &({[] 3} ()) |
| 16:45 | lazybot | ⇒ 3 |
| 16:45 | Chousuke | m |
| 16:45 | Chousuke | I guess that's useful behaviour |
| 16:45 | amalloy | TimMc was just looking for an excuse to type ({[ |
| 16:45 | mebaran151 | technomancy: let me make a paste: what's the best one for clojure? |
| 16:45 | mk | perhaps the bug isn't in memoize, but in conj like I've been suggesting |
| 16:45 | TimMc | 'strue |
| 16:45 | Chousuke | conj does what it's supposed to do. |
| 16:46 | TimMc | mebaran151: refheap! |
| 16:46 | Chousuke | it's just that maps use = semantics |
| 16:46 | nDuff | ibdknox: Around? I'm trying to come up with a suitable patch for https://github.com/ibdknox/Korma/issues/82, but having some trouble. |
| 16:46 | Chousuke | now that I think about it |
| 16:46 | amalloy | my opinion is there's not a bug anywhere, just some unfortunate consequences of design decisions that are useful in most cases |
| 16:46 | Chousuke | so memoize inherits that, and you get this weirdness. But I think the solution is worse than the problem. |
| 16:46 | TimMc | (with-equality-semantics identical? ({[] 3} ())) => nil |
| 16:46 | mebaran151 | https://www.refheap.com/paste/4212 << here is my paste, I don't see any typos at first blush |
| 16:47 | amalloy | TimMc: identical? is totally nuts anyway |
| 16:47 | emezeske | ,(let [vector? (memoize vector?)] [(vector? [1]) (vector? '(1))]) |
| 16:47 | clojurebot | [true true] |
| 16:47 | emezeske | I guess it's important to be careful with memoize |
| 16:47 | TimMc | emezeske: lulz |
| 16:48 | Chousuke | TimMc: but then you wouldn't even be able to do ({[1] 5} (vector 1)) with that. |
| 16:48 | TimMc | Too bad! identical? is the standard equality predicate. |
| 16:49 | Chousuke | so it'd be (with-equality-semantics sometimes-cares-about-type ...) |
| 16:49 | mebaran151 | the local salesforce and local echosign libraries aren't problematic; commenting them out it still isn't working... |
| 16:49 | mk | amalloy: sure, I probably agree. But I think the right way to describe the design decision is to say that conj was made not rt |
| 16:50 | Chousuke | because of course you wouldn't want (seq '(1 2 3)) and (seq [1 2 3]) to be considered different |
| 16:50 | emezeske | mk: If conj is not RT, then neither is vector? and that just doesn't make sense to me |
| 16:50 | Chousuke | which they would be if it were type strict :P |
| 16:50 | gtrak | ,(conj (seq [1 2 3]) 3) |
| 16:50 | clojurebot | (3 1 2 3) |
| 16:51 | Chousuke | mk: conj is again not problematic at all. it returns the same values for everything you pass to it. |
| 16:51 | Chousuke | the problem is memoize's implementation |
| 16:51 | Chousuke | the function it returns is not RT |
| 16:52 | Chousuke | in some theoretical cases :P |
| 16:52 | TimMc | So hey, how about that one sports team? |
| 16:52 | TimMc | I hear they scored so many points! |
| 16:52 | technomancy | The sports team from my area is superior to the sports team from your area. |
| 16:52 | emezeske | TimMc: My local sporting team is better, because their HQ is near me |
| 16:52 | technomancy | It is a demonstrable fact. |
| 16:53 | emezeske | technomancy: If your sporting team fought my sporting team, would there be a tear in the fabric of space time? |
| 16:54 | Chousuke | maybe they are the same team |
| 16:54 | gtrak | woohoo, score a goal unit |
| 16:54 | Chousuke | that would solve the conflict |
| 16:54 | emezeske | Whoa... very zen |
| 16:55 | TimMc | Chousuke: My equality predicate for sports teams is (constantly true). |
| 16:55 | Chousuke | one team to rule them all huh |
| 16:55 | Chousuke | must be boring, with no-one to play against |
| 16:56 | mebaran151 | technomancy: so deleting my .m2, it redownloads all the artifacts correctly, but then says it failed to find them. Any ideas why? |
| 16:56 | Chousuke | or maybe you have many teams, and they all win every game |
| 16:56 | Chousuke | or you can't tell the difference anyway |
| 16:56 | S11001001 | I use cons more than conj, but I use into more than either |
| 16:57 | scriptor | they tore a hole in spacetime and are playing a version of themselves form one planck time in the future |
| 16:59 | technomancy | mebaran151: it's specifically complaining about org.clojure/clojure "1.3.0"? |
| 16:59 | mebaran151 | all of them :/ |
| 17:00 | technomancy | if it's all of them then it's probably a connectivity issue |
| 17:00 | clojurebot | ev4l, I think your issue is that you didn?t include the [] for the arguments to your method. |
| 17:00 | technomancy | maybe you need to specify a proxy or something |
| 17:01 | technomancy | rlb: hey, any further word on emacs in wheezy? |
| 17:02 | mebaran1` | technomancy: no proxies that I know of |
| 17:03 | mebaran1` | if you run lein deps on my project.clj, does it work for you? (excepting teamlazer.beez, a jar installed in my local repo, which I have commented out but to no avail) |
| 17:13 | mk | emezeske: vector? isn't referentially transparent over values proper for roughly the same reason java's == isn't rt. In java equivalent linkedlists and arraylists are the precisely same value. That doesn't mean that instanceof or == are broken. |
| 17:14 | Raynes | Oh God, no more. No more! |
| 17:14 | technomancy | o_O |
| 17:16 | hyPiRion | Oh, we've just started. |
| 17:19 | pjthomas | anyone here play with overtone at all? |
| 17:19 | aperiodic | mk: you define RT in terms of =, everyone else defines it in terms of type & =, and as long as nobody changes their definitions, you'll call some things non-RT which everyone else calls RT. if you want to change people's minds, present an argument as to why referential transparency should disregard type, instead of just saying 'x is not RT' over and over. |
| 17:20 | mattmoss | I don't know what I just read. o_O |
| 17:21 | scriptor | don't worry too much about it |
| 17:21 | acheng | a set is not ordered, but once a set exists, will it always get mapped/seq'd over in a repeatable order? |
| 17:22 | acheng | or is that a bad thing to rely on? |
| 17:22 | jkkramer | acheng: bad |
| 17:22 | acheng | ok |
| 17:22 | hyPiRion | ,(let [id (memoize identity)] (id (java.util.ArrayList.)) (id [])) |
| 17:22 | clojurebot | #<ArrayList []> |
| 17:22 | hyPiRion | oh, the joy. |
| 17:22 | acheng | maybe i should avoid situations where the response is acheng: bad |
| 17:23 | jkkramer | :) |
| 17:23 | hyPiRion | acheng: sorted-set |
| 17:23 | amalloy | i don't think that's a bad thing to rely on |
| 17:23 | mk | aperiodic: it doesn't disregard type. It wouldn't make sense to do so because every value has only a single type. I've tried to explain the distinction with reference to java's different implementations of lists. Whether it's linked or array, equivalent lists are value-equal. |
| 17:24 | acheng | hyPiRion: thanks |
| 17:24 | acheng | amalloy: please say more |
| 17:25 | dnolen | acheng: can you be more specific, *how* were you planning on relying it? |
| 17:25 | aperiodic | mk: if 'every value has only a single type', then how is ##(= [1] '(1))? what is your definition of type? |
| 17:25 | lazybot | ⇒ true |
| 17:26 | hyPiRion | acheng: On second though, it may not be exactly what you want: ##(sorted-set 2 6 4 -2 0) |
| 17:26 | lazybot | ⇒ #{-2 0 2 4 6} |
| 17:26 | hiredman | ~troll |
| 17:26 | clojurebot | according to troll lore living beings move backwards through time |
| 17:26 | acheng | while using map with a fn that takes multiple arguments, it just so happens that the last two arguments could be a particular set ... i was wondering if i could put it in there as a set twice |
| 17:27 | acheng | might as well use sorted set and be done with it |
| 17:27 | hyPiRion | acheng: wait a second. |
| 17:27 | mk | aperiodic: yeah, [] and () are the same type. You know how you can have the same string value residing in different places in memory? Well, sometimes, the same value can be implemented in different classes (again, the various list implementations). We bother with different classes because the classes offer different performance characteristics. |
| 17:28 | hyPiRion | acheng: https://github.com/flatland/ordered is what you want |
| 17:28 | aperiodic | mk: ok, change 'type & =' in my really long respone up there to 'class & =' |
| 17:28 | acheng | hyPiRion: ok will check it out |
| 17:30 | mk | aperiodic: "everyone" excludes the java language spec for lists |
| 17:31 | hyPiRion | Well, that was a surprise: ##(= (class '(1)) (class ())) |
| 17:31 | lazybot | ⇒ false |
| 17:31 | acheng | hyPiRion: oh, i don't care about maintaining a particular order that isn't sorted... i just want to map an fn over the members of a set -- i want the same member of the set to be used for arg1 and arg2 of fn |
| 17:32 | mebaran151 | technomancy: after a lot of thwacking, I've found the two packages making problems are noir-cljs and fetch: any idea about a workaround? |
| 17:32 | acheng | (gotta take off) |
| 17:32 | TimMc | acheng: I believe the order for an instance is deterministic, yes -- just like vals and keys on a map give the same arbitrary ordering. |
| 17:32 | hyPiRion | acheng: Oh, then I misunderstood completely. Sorry. If it is exactly the same map, you could assume that the operations on it are deterministic. |
| 17:32 | acheng | ok |
| 17:33 | acheng | TimMc: does this just happen to be the case, or is it part of the spec (can it be relied on)? |
| 17:33 | technomancy | mebaran151: I thought noir-cljs was replaced by something else |
| 17:33 | technomancy | isn't that just a template for new apps? |
| 17:33 | mk | if the sets to list thing seems weird, just pretend that you're generating a list using (sort-set-by-hash the-set) |
| 17:34 | mebaran151 | technomancy: it adds some middleware to automate clojurescript compiling |
| 17:34 | technomancy | ok, must be thinking of something else |
| 17:34 | technomancy | you could browse the clojars repo to see what versions are available |
| 17:35 | mk | obviously sets don't define a "first element", but you can produce a list by sorting a set |
| 17:35 | acheng | I might as well use sorted set and then i don't have to wonder |
| 17:35 | mebaran151 | so it looks like some strange dependency issue, I bet on conflicting versions of the apache libraries |
| 17:35 | hyPiRion | acheng: I don't believe it is part of the spec, but it would make sense to believe that the iteration over the same set isn't random ;) |
| 17:35 | mebaran151 | I'm wondering why it broke today though.... |
| 17:36 | hyPiRion | couldn't you just use the same element twice though? |
| 17:36 | hyPiRion | As in (map #(vector % %) #{1 2}) instead of (map vector #{1 2} #{1 2}). |
| 17:37 | TimMc | acheng: Not part of any spec I've seen, but if core changed it, they'd get lynched. |
| 17:37 | TimMc | I believe it is very common to rely on that behavior. |
| 17:38 | S11001001 | it's definitely safe to rely on the order of (seq some-set) being repeatable, for a given seq call |
| 17:38 | S11001001 | so if you assume something about the seq function... |
| 17:39 | mebaran151 | I think it might be a conflict between commons codec 1.5 and 1.6; anyway to tell lein to just use 1.6 and be done with it? |
| 17:39 | technomancy | mebaran151: some noir stuff uses version ranges, which can break at unpredictable times when new versions are released |
| 17:39 | technomancy | mebaran151: add a top-level dependency on the version you want and an :exclusions entry under noir |
| 17:39 | technomancy | see `lein help sample` |
| 17:39 | mk | S11001001: will two values always appear in the same order every time seq is called on any set? |
| 17:40 | S11001001 | probably |
| 17:41 | madsy | If you couldn't depend on the order of seqs, I don't see how it would be useful |
| 17:41 | mk | seqs sort sets using hashcode, right? |
| 17:41 | madsy | Since every container is seqable |
| 17:41 | madsy | And the clojure libraries depends on it so much |
| 17:41 | hiredman | a seq is just an iterator |
| 17:42 | madsy | hiredman: Right, but would it make sense that the order depended on the underlying container? |
| 17:42 | mk | madsy: the problem is that sets by definition don't define order. But you can get order out of a set by sorting its elements using some property p (which in clojure might be hashcode) |
| 17:43 | hiredman | madsy: sure, and IPersistentSet is an interface, so anything can be a "set" |
| 17:43 | hiredman | http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Set.html#iterator%28%29 similar issue |
| 17:43 | mebaran151 | technomancy: so it looks like I |
| 17:43 | madsy | hiredman: Yeah. I don't see how that would be useful. Since seq is used so much. |
| 17:44 | madsy | Suddenly you have a seq you don't know if is a vector or a set |
| 17:44 | mebaran151 | (sorry, enter fail) narrowed it down to noir-cljs, but the general error message is that it just can't load the dependency |
| 17:44 | mk | madsy: it probably does, but you don't need to make it depend on the container |
| 17:44 | mebaran151 | seems like within the package there are mutually conflicting deps |
| 17:44 | hiredman | madsy: a seq is a seq, it is not a vector or a set |
| 17:44 | hiredman | madsy: and a given seq is immutable and is always the same |
| 17:45 | madsy | yep |
| 17:45 | hiredman | madsy: but there why should calling seq on a set multiple times always return the same seq? |
| 17:45 | technomancy | mebaran151: usually with the right :exclusions you can make it work |
| 17:46 | mk | ,(= (seq [1 2 3]) [1 2 3] '(1 2 3)) |
| 17:46 | clojurebot | true |
| 17:46 | hyPiRion | mk: two values will NOT neccesarily appear in same order |
| 17:47 | madsy | hiredman: I wouldn't focus on sets, but that the behavior was consistent no matter what the seq refers to. |
| 17:47 | mk | hyPiRion: that's no good. Why is that? |
| 17:47 | hyPiRion | ,(= (into #{} (range -10 10)) (into #{} (range 9 -11 -1))) |
| 17:47 | clojurebot | true |
| 17:47 | hiredman | the equality comparison for sets done in c.l.APS doesn't depend on order, it iterates over one of the set's elements and checks if the other set contains each |
| 17:47 | hyPiRion | mk: bucket increase/resizing probably |
| 17:48 | hyPiRion | ,(into #{} (range -10 10)) |
| 17:48 | clojurebot | #{-1 0 -2 1 -3 ...} |
| 17:48 | hyPiRion | meh. |
| 17:48 | hyPiRion | ,(prn (into #{} (range -10 10))) |
| 17:48 | clojurebot | #{-1 0 -2 1 -3 ...} |
| 17:48 | mebaran151 | technomancy: any way to hint it to tell me what to exclude: I'm not having much luck :/ |
| 17:48 | hyPiRion | Okay, anyway, try printing out (into #{} (range -10 10)) and (into #{} (range 9 -11 -1)) - they contain the same result, but not in the same order |
| 17:49 | mk | if you want to use sets safely, just turn the set into a list using a sort |
| 17:49 | hiredman | madsy: what makes you think I am focused on sets? |
| 17:50 | hiredman | seqs for vectors and lists will always be in that order because the colelction is ordered |
| 17:50 | mebaran151 | it looks as noir-cljs itself no longer can be pulled down by lein |
| 17:50 | mebaran151 | hmpppph |
| 17:51 | mebaran151 | as I built this whole app on noir and cljs, I am now in a bit of a pickle... |
| 17:51 | hiredman | mebaran151: I would recommend not using anything with "noir" in the name |
| 17:51 | hiredman | noir tends to be broken and busted and side effecty and just bad |
| 17:52 | mebaran151 | it looked like the best documented web framework at the time, and seemed to go well with jquery jayq |
| 17:52 | hiredman | :/ |
| 17:52 | mk | what's the replacement? |
| 17:53 | emezeske | Noir is just a thin layer on top of compojure |
| 17:53 | hiredman | emezeske: nah |
| 17:53 | hiredman | emezeske: noir is full of sideffecting add-middleware calls, and the versions never work, and etc |
| 17:53 | emezeske | hiredman: I am talking about noir proper, and that's definitely what it is |
| 17:54 | hiredman | emezeske: noir is junk |
| 17:54 | emezeske | It *is* just a thin layer on top of compojure. Anyway, my point was that the "replacement" is just using compojure. |
| 17:54 | hiredman | compojure+lein-ring |
| 17:54 | emezeske | Yes. |
| 17:54 | mk | then why have noir to begin with? |
| 17:55 | Peregrine | Because the author wrote it |
| 17:55 | mebaran151 | I suppose I could knowck down to compojure, as I do most of my templating in plain ol' hiccup functions |
| 17:55 | Peregrine | and posted it |
| 17:55 | mk | hiredman: I see |
| 17:55 | gtrak | it does all the session cookie stuff? |
| 17:55 | Peregrine | We don't have the ability to stop someone from posting stuff. |
| 17:55 | mebaran151 | the biggest things I'd have to work around is teh clojurescript stack, which seemed to work most effectively |
| 17:55 | mk | Peregrine: not yet, huh? |
| 17:55 | hiredman | emezeske: noir is a thin layer on compojure, and hiccup, and etc |
| 17:56 | emezeske | hiredman: Well that's true. I guess my emphasis was just on the "thin" part, e.g. it's easy to just not use it |
| 17:56 | mebaran151 | since noir was a thin layer on top of compojure, I figured it couldn't mess with too many things... |
| 17:56 | mebaran151 | but now I am in dependency hell |
| 17:57 | hiredman | yeah, because noir is junk, with a nice website |
| 17:57 | pandeiro | i think noir is/was a good stab at removing some boilerplate but i do find most of my web programming falling into some of its cracks |
| 17:57 | Peregrine | mk, we could ask github to require hiredman to review clojure libs before they're posted. |
| 17:57 | pandeiro | mebaran151: i think you can resolve it w/o too much problem |
| 17:57 | Peregrine | I don't think it would work so well. |
| 17:57 | emezeske | mebaran151: Have you tried lein-cljsbuild? I think it might take care of the cljs stuff for you |
| 17:57 | technomancy | Peregrine: bring popcorn |
| 17:58 | mebaran151 | emezeske: yeah I've tried it, but it throws random NPE's |
| 17:58 | mefisto` | a bit of cannibalism going on here it seems |
| 17:58 | emezeske | mebaran151: I see. That is not typical; did you try creating an issue on github? |
| 17:58 | mebaran151 | I was actually planning on sending some bug reports your way, but was limping along with noir cljs |
| 17:59 | hiredman | someone told me the first time they paired with my at work I just sort of walked through the code base at work going "this is bad, this is crap, ughh, why?" which I have no memory of |
| 17:59 | emezeske | mebaran151: A simple stack trace would be a good start |
| 18:00 | mebaran151 | until I had time to try to track it down |
| 18:00 | hiredman | lein-cljsbuild works |
| 18:00 | mebaran151 | Clojure on windows always seems to have its "interesting" moments |
| 18:00 | emezeske | OH |
| 18:00 | hiredman | mebaran151: did you configure it in project.clj? you don't just add the dependency you need to configure options in there |
| 18:00 | emezeske | You didn't mention the "Windows" part |
| 18:01 | emezeske | Haha, yeah, I am not going to track down any Windows bugs |
| 18:01 | emezeske | If someone else does, though, that's cool |
| 18:01 | mebaran151 | once I get my build running again, I'd be more than happy to help, though usually I find Windows bugs need my own TLC |
| 18:01 | technomancy | hiredman: I can totally picture that scene |
| 18:02 | technomancy | even though I don't think it was with me |
| 18:02 | amalloy | hiredman: really, noir is a thin layer? it seems like if it manages to do so many things that infuriate you (not wrongly, imo) it's a fairly bulky layer |
| 18:02 | mebaran151 | to be honest, Clojure dependency hell can't be any worse than Haskell dependency hell |
| 18:03 | mebaran151 | amalloy: noir doesn't seem very heavy weight to me; had a couple of nice utility functions and good clojurescript support when I chose it |
| 18:03 | mebaran151 | but right now it's magically breaking my build |
| 18:03 | jsabeaudry | I'm trying to writeShort with a RandomAccessFile (in a with-open scope) and somehow the short does not get written and no exception is thrown ?! |
| 18:03 | mebaran151 | which is sad, because I was close to releasing this nice piece of software (after writing my own salesforce wrapper too...) |
| 18:03 | hiredman | jsabeaudry: pastebin? |
| 18:04 | amalloy | sounds like probably missing a flush or close or something |
| 18:04 | hiredman | my guess is written in a lazy seq that isn't forced |
| 18:04 | hiredman | amalloy: he did say it is in a with-open |
| 18:05 | amalloy | okay, i'm changing my mind to your guess |
| 18:05 | mebaran151 | the noir deps don't seem to insane btw, except that lein is choking on them |
| 18:06 | emezeske | mebaran151: I used noir originally for my app, and when I went about dropping it in favor of just compojure, hiccup, etc, it took probably a few hours to get rid of it |
| 18:06 | mebaran151 | the thing is I use his jquery wrapper pretty extensively |
| 18:06 | emezeske | mebaran151: It wasn't a lot of work, mostly it was learning good things about compojure that noir hid from me |
| 18:06 | technomancy | noir uses version ranges; they are known to be problematic |
| 18:06 | emezeske | mebaran151: You can use jayq without noir... |
| 18:06 | mebaran151 | let me try |
| 18:06 | mebaran151 | then I'll have to debug cljsbuild, which I suppose I should do anyway |
| 18:07 | mebaran151 | (I haven't had a cljs repl for really long time...) |
| 18:07 | emezeske | I've had various reports of people having it work or not work under Windows |
| 18:07 | emezeske | I don't know what the state is these days |
| 18:08 | emezeske | I haven't had a "doesn't work under windows" report in a while, if that means anything |
| 18:08 | jsabeaudry | hiredman, http://pastebin.com/cAQ4GkAe |
| 18:08 | mebaran151 | the only thing that would be a little pesky is that I used the "fetch" library, which implicitly makes noir routes |
| 18:08 | emezeske | mebaran151: Heh, I used fetch too |
| 18:08 | emezeske | mebaran151: That was most of the work for me |
| 18:09 | jsabeaudry | hiredman, all the println do happen |
| 18:09 | mebaran151 | emezeske: fetch was pretty nice |
| 18:09 | technomancy | emezeske: are some of those issues trampoline problems? |
| 18:09 | emezeske | technomancy: Maybe, I don't remember, it's been a while :( |
| 18:09 | mebaran151 | trampoline I think is doing weird things on Windows |
| 18:09 | mebaran151 | I've been meaning to reinvestigate |
| 18:09 | Raynes | technomancy: Whoa, what? |
| 18:10 | emezeske | mebaran151: Fetch has basically the same problems as noir, because it depends on noir |
| 18:10 | Raynes | technomancy: Noir uses version ranges? Where? |
| 18:10 | emezeske | mebaran151: If you want to modify the routes it creates, it's kind of a pain |
| 18:10 | mebaran151 | emezeske: exactly |
| 18:10 | hiredman | jsabeaudry: try writing it to a regular file |
| 18:10 | emezeske | mebaran151: I ended up making my own "fetch" library which I like a lot better |
| 18:10 | technomancy | Raynes: I think it might not in git, but someone said the stable release did |
| 18:10 | emezeske | mebaran151: Unfortunately it's pretty tied into my app logic atm so no open-sauce :( |
| 18:10 | technomancy | Raynes: it triggered a bunch of issues when central dropped their clojure artifacts |
| 18:11 | hiredman | jsabeaudry: my guess is randomaccessfile doesn't work on /proc/fpga/file for whatever reason, but I've never tries so I dunno |
| 18:11 | jsabeaudry | hiredman, alright, will try that, but I can write fine to that character device using dd bs=2 seek=30... |
| 18:11 | emezeske | mebaran151: Do you do auth in your app? |
| 18:11 | jsabeaudry | hiredman, the read works |
| 18:11 | hiredman | *shrug* |
| 18:12 | mebaran151 | emezeske: not exactly |
| 18:12 | Raynes | technomancy: Apparently it used a version range in 1.2.2. |
| 18:12 | mebaran151 | all the auth is handled by my salesforce bindings |
| 18:12 | Raynes | technomancy: It does not anymore and never will again. |
| 18:12 | mebaran151 | all the perm stuff lives in salesforce and the management side is salesforce side too |
| 18:12 | emezeske | Ah, gotcha, I was just going to mention auth pains in noir, nevermind though |
| 18:13 | mebaran151 | Salesforce is nifty for that sort of thing, gives me user management for free |
| 18:13 | mebaran151 | I was porting a hacked together Rails app for this project |
| 18:14 | mebaran151 | I'd also love a general way to disable colorize |
| 18:14 | emezeske | mebaran151: colorize? |
| 18:14 | mebaran151 | makes color ascii codes in clojure, or random trash in Windows :) |
| 18:15 | emezeske | Oh, heh, sometimes I will "... | grep --color=never ." to get rid of color, under linux. Super ugly hack :) |
| 18:16 | mebaran151 | I think fetch is abandonware :/ |
| 18:16 | emezeske | Pretty much all of ibdknox' stuff is gathering dust right now, I think -- he's working on Light Table |
| 18:17 | amalloy | emezeske: you can also | grep ... | cat, since it won't color if output isn't a tty |
| 18:17 | emezeske | amalloy: Nice, that's easier to type! |
| 18:18 | amalloy | but why do you want to disable color sometimes? i can understand wanting it off always if you hate colors, but sometimes? |
| 18:18 | emezeske | It's a silly story, having to do with the way colors are displayed on a particular machine of mine |
| 18:18 | jsabeaudry | hiredman, thanks, It does work on a regular file. I guess I'll ask around linux to try to spy on the kind of calls java makes on the OS. |
| 18:18 | S11001001 | I like it when a program unconditionally writes color codes, so when I'm in emacs shell I get funny bits all over my buffer |
| 18:19 | S11001001 | or in a file I >ed to |
| 18:20 | jsabeaudry | I gotta say, I'm very far from loving java, even after a year of clojure |
| 18:20 | S11001001 | status spinners and bars are also neat. blahblah 0%^Mblahblah 1%^Mblahblah 1.5%^M... |
| 18:20 | amalloy | jsabeaudry: you thought java would teach you to love java? |
| 18:20 | amalloy | er, clojure would |
| 18:21 | arrdem | amalloy: let's give Java credit for giving birth to the JVM and pretend the rest never happened |
| 18:22 | amalloy | well, the jvm would still suck if people hadn't liked java |
| 18:25 | mebaran151 | I'm not such a huge anti-fan of Java |
| 18:25 | jsabeaudry | amalloy, Yes, I hoped working with clojure would help me be more respectful of the java world |
| 18:25 | mebaran151 | I just got fetch back out of deps hell with a well placed, exclude [noir] |
| 18:26 | technomancy | mebaran151: maybe you could open a bug report on noir so other people could find it if they had the same problem |
| 18:26 | mebaran151 | I'll rip out my noir bits later; there are already a huge number of flaky abominations in this app dealing with the fact that Echosign has an insane wsdl that doesn't really work except with Apache CXF |
| 18:27 | mebaran151 | which uses a jaxb that is incompatible with the salesforce jaxb |
| 18:27 | mebaran151 | so I've been fighting dependency hell for a long time :) |
| 18:28 | dnolen | CLJS poll - opinions about names. In CLJS we overload aget/set to deal with primitive objects, I'm thinking obj-set/get is perhaps better - relevant ticket http://dev.clojure.org/jira/browse/CLJS-353 |
| 18:29 | jsabeaudry | hiredman, looks like I should be able to probe with strace and perhaps find a workaround to the java |
| 18:29 | mebaran151 | dnolen: I watched your video about core.logic; really nice intro |
| 18:29 | dnolen | mebaran151: thx |
| 18:31 | hiredman | dnolen: what is the point? the two are not compatible either way |
| 18:31 | pandeiro | mebaran151: dnolen: link? |
| 18:32 | hiredman | dnolen: why not just make people use the (.-foo ...) syntax we already have? |
| 18:33 | mebaran151 | I knew it, colorize is secretly destroying my build |
| 18:33 | mebaran151 | it's this colorize dep that is apparently in fighting |
| 18:33 | dnolen | hiredman: it will get munged. |
| 18:33 | dnolen | hiredman: I mean mangled |
| 18:34 | dnolen | hiredman: they are conveniently equivalent for JS, but not necessarily for other hosts. |
| 18:34 | dnolen | hiredman: just another step at making core.cljs a bit more reusable. |
| 18:36 | hiredman | dnolen: the lua port is done though, isn't? this isn't |
| 18:36 | hiredman | "required" isn't it already reusable? |
| 18:37 | dnolen | hiredman: not required, but it's a minor fix and it makes the types more sensible. |
| 18:37 | hiredman | basically, what I see is the addition of special forms to make static analysis easier for less capable hosts |
| 18:38 | dnolen | hiredman: in this case it really is a complecting - primitive array types and primitive object types are handled in the same way. Even though the semantics really are not the same even in JS. |
| 18:39 | hiredman | maybe the right answer is when it can be determined that x in (aget a x) is an int, or not the compiler can emit something more specialized, but otherwise needs more general logic |
| 18:41 | dnolen | hiredman: in CLJS aget/set is used in a way that doesn't make sense in Clojure JVM currently. the aFOO fns in Clojure JVM are specifically about primitve arrays. |
| 18:42 | hiredman | dnolen: so maybe they shouldn't be cross platform in anyway, aget/aset are part of interop and behave diferently on different hosts |
| 18:42 | mebaran151 | alright: quesiton of the hour, can anyone tell me why lein chokes on the "colorize" dependency |
| 18:42 | dnolen | hiredman: every host I can think of will have some efficient array rep. I agree that's not the case for obj-set/get |
| 18:43 | dnolen | implementors may need to provide for that. but I doubt it. |
| 18:43 | dnolen | obj-set/get are used for ObjMap which is a JS centric map implementation anyway. |
| 18:43 | kenneth | Exception in thread "main" java.lang.RuntimeException: java.lang.NoClassDefFoundError: clojure/lang/ILookupHost |
| 18:44 | kenneth | what could this be about? i'm getting this in a clojar dependency (beanstalk) |
| 18:44 | hiredman | kenneth: are mxing code aot compiled with one version of clojure with a different version of clojure |
| 18:44 | hiredman | you |
| 18:44 | hiredman | dnolen: so what is the compelling need for obj-set/get again? |
| 18:46 | dnolen | hiredman: making the difference explicit. making it easier to bootstrap new backends. |
| 18:46 | dnolen | hiredman: ObjMap will be easy to get up and running on Python/Ruby/Lua etc. |
| 18:46 | kenneth | hiredman: would that be a problem with the library i'm using? is that something i can get around? |
| 18:46 | dnolen | even if implementations abandon it, it's easy to get up and running. |
| 18:46 | kenneth | https://gist.github.com/7c21052f4d192abc362d stack trace fwiw |
| 18:47 | hiredman | dnolen: but doesn't ObjMap actually use arrays? exactly what aset and aget are for? |
| 18:47 | dnolen | hiredman: w/o the different I imagine people will need to emit some kind of conditional in the aget/set fn and macro. |
| 18:48 | hiredman | oh, I guess it doesnt |
| 18:48 | dnolen | hiredman: it does not use arrays, strobj. |
| 18:48 | hiredman | dnolen: I have no idea what strobj is |
| 18:49 | dnolen | hiredman: a JavaScript Object being used a HashMap of String -> Object |
| 18:49 | hiredman | :( |
| 18:50 | hiredman | js sure is lousy |
| 18:51 | hiredman | it should be pretty easy to just have a simple impl of a redblack tree map using arrays |
| 18:51 | dnolen | hiredman: and we have those in sorted-set, but unlikely to beat JS Objects since this use case has been optimized like crazy. |
| 18:51 | hiredman | or even a rb map based just on deftypes |
| 18:52 | hiredman | dnolen: sure, I am not offering as a replacement for objmap in clojurescript |
| 18:52 | hiredman | but for a portable immutable map |
| 18:54 | hiredman | ObjMap is not a very good map, so saying "it would be easily portable everywhere" isn't an argument that I find compelling |
| 18:55 | hiredman | and I know "just use it to get up and running" but still |
| 18:57 | dnolen | hiredman: well core.cljs is the best we have at the moment, and this was a real hurdle an implementer encountered, which others will as well. I'm not saying this is best solution - but it's not a big change, and doesn't really effect CLJS users much. |
| 18:58 | dnolen | so a temporary fix until we have an optimal simple Map type for small sizes that works in most places reasonably well. |
| 18:59 | hiredman | erm, cross platform optimal simple Map type? |
| 19:00 | hiredman | I imagine that would just be array-map |
| 19:00 | dnolen | hiredman: A simple redblack tree could suffice. I've always been curious how skew binary random access lists perform. |
| 19:01 | dnolen | hiredman: array-map is pretty slow. It always funny to see the perf change when you cross into PHM on the JVM. |
| 19:01 | hiredman | dnolen: sure, but you wanted cross platform |
| 19:02 | hiredman | and simple, and optimal |
| 19:02 | technomancy | pick any two |
| 19:03 | dnolen | hiredman: technomancy: heh. |
| 19:04 | mebaran151 | so I'm having one strange error now: my build complains that clojure.instant__init.class doesn't exist |
| 19:05 | hiredman | mebaran151: most likely conflicting versions of clojure |
| 19:05 | hiredman | clojure.instant is in clojure 1.4, but not before |
| 19:09 | technomancy | is anyone using a BUILDPACK_URL on heroku? would like help testing a change. |
| 19:11 | rlb | technomancy: won't be possible, unfortunately. |
| 19:11 | rlb | technomancy: though I may go ahead with a backport. |
| 19:11 | technomancy | tragic =\ |
| 19:12 | rlb | release was just too close to the freeze |
| 19:12 | rlb | (when coupled with a little delay on my part -- but even without that, it was pretty close) |
| 19:13 | tos9 | Hash maps are unordered, correct? How come the following two seemingly equivalent fns produce hashmaps that println with consistently different orders? http://bpaste.net/show/ABjdNgUA0o7Mow6IETcv/ |
| 19:13 | technomancy | rlb: well thanks for your work on it regardless |
| 19:14 | hiredman | tos9: because maps are unordered |
| 19:14 | technomancy | I'll probably stick with nix anyway, but it would have been nice |
| 19:14 | rlb | you're certainly welcome |
| 19:14 | mebaran151 | hiredman: anyway to see who is trying to use 1.4? |
| 19:14 | rlb | (I've also been tied up a bit with bup lately...) |
| 19:14 | technomancy | it's funny that they're worried about stability; in my experience 24 was significantly more stable than 23 even way before it was released |
| 19:15 | hiredman | mebaran151: why aren't you using 1.4? |
| 19:15 | technomancy | bup? |
| 19:15 | hiredman | 1.3 is horrible |
| 19:15 | rlb | technomancy: sure, but my *packages* might not be ;> |
| 19:15 | technomancy | I guess so =) |
| 19:15 | rlb | (and they weren't -- emacs24 was broken on i386 (completely)) |
| 19:15 | technomancy | oh, well there you go |
| 19:15 | technomancy | I guess they have a point |
| 19:15 | mebaran151 | hiredman: I just bumped to 1.4, but now I'm getting a strange stackoverflow error |
| 19:16 | rlb | Turns out that there was an upstream bug wrt use of fabs() that our buildd's demonstrated quite clearly. |
| 19:16 | hiredman | mebaran151: when? |
| 19:16 | mebaran151 | the cljs compiler doesn't make it easy to find these things |
| 19:16 | tos9 | hiredman: Right, got that. I asked about consistency, so I guess I'm asking in what order the implementation displays them. They are going to be ordered based on hash value and when keys are inserted I'd assume. I'm just curious as to where that differs between the two implementations I had. |
| 19:16 | hiredman | mebaran151: pastebin |
| 19:16 | rlb | (took me most of debconf to track that down -- with help) |
| 19:16 | mebaran151 | I think it's actually in the cljs compiler |
| 19:16 | hiredman | tos9: check the types |
| 19:16 | technomancy | rlb: I do appreciate the radical commitment to stability, but it can be a pain being on the other side of the fence |
| 19:16 | rlb | (though maybe that says more about me than the bug...) |
| 19:16 | rlb | yep -- but if I do get a good backport, then you're set. |
| 19:17 | rlb | (and it shouldn't be hard, assuming I have the time) |
| 19:17 | tos9 | hiredman: The types of what? |
| 19:17 | hiredman | the maps you produce |
| 19:18 | emezeske | tos9: Are you just asking about this out of curiousity? |
| 19:18 | tos9 | emezeske: Yes. |
| 19:18 | emezeske | tos9: Cool, that's a good reason. I just wanted to make sure you weren't trying to find out so you could rely on the order somehow :) |
| 19:18 | tos9 | hiredman: That's going to be something other than what hash-map gives me? (println type ...) for all three says they're PersistentHashMaps. |
| 19:18 | tos9 | Dropped a paren there. |
| 19:18 | tos9 | emezeske: A noble cause :) |
| 19:19 | amalloy | tos9: no way it says PHM for the one built with zipm-2 |
| 19:19 | hiredman | tos9: your gist only has 2 |
| 19:19 | tos9 | hiredman: Sorry. 2, I have a third locally that was uninteresting. |
| 19:20 | tos9 | Oh hey. I can't read. |
| 19:20 | hiredman | we already know :) |
| 19:20 | tos9 | Apologies to you both, yes, it says PersistentArrayMap. |
| 19:20 | hiredman | PAM infact *must* preserve order |
| 19:20 | tos9 | Cool. Guess I'd better figure out what those are then. Thanks. |
| 19:21 | amalloy | hiredman: must? |
| 19:21 | hiredman | otherwise map literals could execute code in random order |
| 19:21 | hiredman | (random, hashcode ordering) |
| 19:21 | amalloy | hiredman: they already can, if you have a large map literal |
| 19:21 | hiredman | ok, sure, if you have a large map literal |
| 19:21 | emezeske | Wow, I had never thought about that |
| 19:22 | emezeske | I guess that wouldn't usually cause problems, though |
| 19:22 | amalloy | IMO depending on the order of execution of a map literal is an error, but i'm not sure about that |
| 19:22 | emezeske | I can't think of any sensible code that would care about the order, but if things had side effects it could be very confusing without this prior knowledge |
| 19:23 | arrdem | ,(cons nil [1 2]) |
| 19:23 | clojurebot | (nil 1 2) |
| 19:23 | mebaran151 | so I think it is time for me to bite the bullet |
| 19:23 | mebaran151 | and get rid of noir-cljs |
| 19:23 | mebaran151 | I have gotten enough of the other libs running that I don't think I'm going to run into too much trouble with this excision |
| 19:24 | emezeske | mebaran151: I'll be happy to help with lein-cljsbuild on windows, insofar as I can without touching a windows box |
| 19:24 | mebaran151 | emezeske: they're not so bad :) |
| 19:26 | mebaran151 | let me try and configure the plugin in first to find my files |
| 19:26 | technomancy | emezeske: did you see the "Is that precate TRUE?" thread on the leiningen mailing list? |
| 19:27 | emezeske | technomancy: Glanced at it just now |
| 19:28 | technomancy | I am also a bit too intimidated to look more closely. |
| 19:29 | emezeske | technomancy: Good call |
| 19:29 | technomancy | no idea what's going on there or how it became such a mess, but it's insane. |
| 19:30 | emezeske | Agreed! |
| 19:38 | mebaran151 | so emezeske: I'm getting one error, that it can't make an input-stream from nil |
| 19:39 | mebaran151 | it looks like it doesn't set up the resources the same way my project does when it loads it |
| 19:40 | mebaran151 | though I'm not completely sure why it's trying to compile my clj file anyway |
| 19:40 | hiredman | mebaran151: sounds like you are missing something in project.clj, so when it looks up the value it gets nil instead of a value |
| 19:42 | mebaran151 | it looks like it's coming from the fact it's trying to compile my own code but the cljsbuild plugin has a difference conception of where clojure.java.io/resource should be searching |
| 19:43 | emezeske | mebaran151: resource should always look in the classpath. |
| 19:43 | mebaran151 | I have some defs that internally refer to resources via clojure.java.io/resource |
| 19:44 | mebaran151 | does cljsbuild use my classpath? |
| 19:44 | emezeske | Well, it builds up a classpath based on settings in your project.clj file |
| 19:44 | mebaran151 | (with-open [stream (io/input-stream (io/resource "encryption/f1.keystore"))] |
| 19:44 | mebaran151 | (doto (KeyStore/getInstance "JKS") |
| 19:44 | mebaran151 | (.load stream keystore-password))) << why would this line fail then |
| 19:45 | hiredman | ah |
| 19:45 | hiredman | I believe I have it |
| 19:46 | hiredman | mebaran151: you have that as a def? |
| 19:46 | mebaran151 | yep, it's a def |
| 19:46 | hiredman | and you have macros in that file that are used from clojurescript? |
| 19:46 | mebaran151 | no |
| 19:46 | hiredman | damn |
| 19:47 | mebaran151 | I am unclear why clojurescript is compiling my main project anyway |
| 19:47 | hiredman | do you have clojure and clojurescript files in the same directory structure? |
| 19:47 | mebaran151 | they both live under src, but I keep the clojurescript with cljs as the extension and in a folder called client |
| 19:48 | mebaran151 | okay scoping it to client has helped, but now I'm getting a Stackoverflow error |
| 19:49 | hiredman | pastebin it |
| 19:51 | mebaran151 | https://www.refheap.com/paste/4215 << here's a paste |
| 19:52 | hiredman | huh |
| 19:53 | hiredman | mebaran151: what jvm is this? |
| 19:54 | hiredman | mebaran151: client? server? 32bit, 64bit? |
| 19:55 | mebaran151 | 1.7 64bit |
| 19:55 | hiredman | you may just try upping the stacksize with -Xss |
| 19:55 | hiredman | -Xss2m or something crazy |
| 19:56 | mebaran151 | how do I pass that to lein cljsbuild? |
| 19:56 | hiredman | https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L242 |
| 19:56 | hiredman | you set it for lein |
| 19:59 | mebaran151 | still overflowing the stack :/ |
| 19:59 | mebaran151 | if I accidentally had a recursive require, would that lead to a stackoverflow? |
| 19:59 | emezeske | Possible to paste your project.clj? |
| 20:00 | hiredman | mebaran151: you mean a circular dependency? |
| 20:00 | hiredman | yeah, that would do it, those are not allowed |
| 20:01 | hiredman | (in clojure or clojurescript) |
| 20:01 | mebaran151 | I know, but would it stackoverflow? |
| 20:01 | mebaran151 | https://www.refheap.com/paste/4216 |
| 20:01 | hiredman | sure |
| 20:01 | hiredman | that line is in the ns form part of the analyzer |
| 20:02 | emezeske | mebaran151: Underneat src/f1/client, are the cljs files arranged with their directory structure matching their namespace structure? |
| 20:02 | mebaran151 | ok I found the circular flaw |
| 20:02 | hiredman | emezeske: I have found that cljs-build doesn't seem to are about that |
| 20:02 | mebaran151 | I'm surprised it worked before |
| 20:03 | emezeske | hiredman: I think weird things can happen, depending on how a file is loaded |
| 20:03 | emezeske | hiredman: If it's loaded from a build in a different dir, it will break, maybe? I don't remember exactly what the problem was |
| 20:05 | Frozenlock | I just installed lein2 and now I can't `clojure-jack-in'. Is this normal, or is my config messed up? |
| 20:06 | amalloy | Frozenlock: you need the lein2 swank plugin, presumably |
| 20:06 | Frozenlock | Oh right |
| 20:10 | mebaran151 | it would be nice instead of stack overflowing, to tell me about the mutual depends |
| 20:12 | technomancy | Frozenlock: nrepl.el does though =) |
| 20:13 | Frozenlock | And leaving slime behind 0_o |
| 20:13 | xeqi | technomancy: did the new version come out this week? |
| 20:14 | technomancy | not yet |
| 20:15 | mebaran151 | technomancy: hiredman: emezeske: thanks for you help |
| 20:15 | mebaran151 | I'm now back to where I was yesterday morning, with an actual working clojurescript stack to boot |
| 20:15 | emezeske | mebaran151: You up and running? |
| 20:15 | emezeske | Nice!! |
| 20:16 | mebaran151 | I have some questions about advance compilation coming (i.e. I don't think I'm externing all the symbols I need to; can the compiler help me?) |
| 20:16 | emezeske | Externs are a persistently painful problem |
| 20:17 | mebaran151 | under simple compile, everything works dandy; I'd love to deploy advance compile on release |
| 20:18 | emezeske | It's definitely doable -- I have a working project with probably 6-7 external JS dependencies |
| 20:18 | emezeske | But there is pretty much no documentation on how to create externs files. It sucks. |
| 20:18 | mebaran151 | I just wish the compiler would give me some more guidance as to what I need to extern |
| 20:19 | mebaran151 | even if it's just warnings |
| 20:19 | emezeske | How could it possibly know? |
| 20:19 | mebaran151 | It could track unbound variables |
| 20:19 | mebaran151 | the same way the real javascript knows that the function doesn't exist :) |
| 20:20 | emezeske | What is an unbound variable? |
| 20:20 | mebaran151 | if I define an f(x) and there is no externs f(x) or f(x) imported in my compilation chain, the compiler could throw a warning |
| 20:21 | mebaran151 | basically if sees a reference to something without a definition (either in an externs.js or in another clojurescript file), it could complain |
| 20:22 | emezeske | If you define...? You mean if you reference? |
| 20:22 | mebaran151 | sorry reference (been a long day) |
| 20:22 | emezeske | The compiler can't know in advance what fields may or may not exist on any given JS object |
| 20:22 | mebaran151 | oh because some function might create new fields I suppose |
| 20:23 | emezeske | Yes |
| 20:23 | mebaran151 | still a warning might be nice to help guide the externs process :) |
| 20:23 | mebaran151 | I don't think this object has this field, though it very well might... |
| 20:24 | emezeske | Just grep for '(\.', that's a good start |
| 20:24 | mebaran151 | heh yeah |
| 20:25 | mebaran151 | if I use a function from the googe closure library, do I have to declare it in my externs? |
| 20:25 | emezeske | No |
| 20:25 | emezeske | The closure library is included during advanced optimization, so it's symbols are mangled with the rest |
| 20:25 | Frozenlock | technomancy: Could it be that profiles.clj isn't created automatically? |
| 20:26 | technomancy | Frozenlock: it's definitely not |
| 20:26 | mebaran151 | I actually think it might not be too many functions |
| 20:26 | Frozenlock | And all this time I was scanning my drive because I couldn't find it in .lein :( |
| 20:27 | emezeske | It probably isn't. And note that jayq includes its own externs file for jQuery, so that's already covered |
| 20:27 | emezeske | (Although you do need to add it to :externs manually) |
| 20:28 | mebaran151 | do I have to put it in my project tree or no? |
| 20:28 | mebaran151 | also I think I use more jquery functions than ibdnox wrapped |
| 20:29 | emezeske | No, it is included in the jayq JAR so it will be on the classpath, which :externs knows to look for |
| 20:29 | mebaran151 | cool |
| 20:29 | emezeske | Yeah, there are lots of non-jayq functions |
| 20:29 | mebaran151 | and I'd have to wrap them most likely |
| 20:29 | emezeske | And, for some reason, jayq is inconsistent in how it names functions -- some of them are not named the same as their jquery implementations. Yay! |
| 20:30 | emezeske | Nah, you don't have to wrap them. You might want to, but they'll work file unwrapped |
| 20:30 | mebaran151 | I mean extern.js them |
| 20:30 | emezeske | If they're in jQuery, you do not need to add them |
| 20:30 | emezeske | The jayq externs file covers all of the main jquery lib |
| 20:31 | mebaran151 | cool, so that would leave just bootstrap tabs I probably need to externify |
| 20:33 | mebaran151 | also parseInt, would I have to externs that? |
| 20:33 | Frozenlock | technomancy: The key binding seem to be the same for slime and nrepl, is there any difference for the user? |
| 20:33 | mebaran151 | set! expressions too... |
| 20:34 | technomancy | Frozenlock: the switch-ns one is C-c C-n since it discards the "package" terminology inherited from CL |
| 20:34 | technomancy | also the interrupt binding is different |
| 20:35 | technomancy | I think the rest is the same, for the stuff that's been implemented |
| 20:35 | technomancy | the inspector is still missing =( |
| 20:35 | emezeske | mebaran151: Core JS stuff like parseInt is already handled |
| 20:35 | danlarkin | my poor muscle memory |
| 20:35 | Frozenlock | Any chance it could run cljscript and clojure at the same time? :P |
| 20:36 | technomancy | Frozenlock: cemerick is working on that |
| 20:38 | cemerick | Frozenlock: yes, coming shortly |
| 20:38 | Frozenlock | For this, I would drop slime like there's no tommorow! |
| 20:38 | cemerick | e.g. with Leiningen: https://gist.github.com/3308381 |
| 20:39 | cemerick | nrepl.el and reply and ccw use the same backend, so… |
| 20:39 | Frozenlock | Oh nvm then... but it will still be terrific! |
| 20:42 | Frozenlock | Btw, anyone can recommend a good read to learn cljscript/javascript? Not knowing javascript, I feel a bit like when I started learning Clojure without knowing Java... I feel like a big ball of slime. |
| 20:43 | cemerick | technomancy: I see nrepl.el constructs a clojure.core/load-file form; FWIW, that'll need to change once cljs support is taken for granted. |
| 20:43 | gfredericks | Frozenlock: the best way to learn a new language is to use a clojure that compiles to that language |
| 20:44 | antifuchs | gfredericks: …and then find all the places where your expectations clash with the generated code's (: |
| 20:44 | technomancy | cemerick: hrm; I spose so, but I don't know what you'd use instead |
| 20:44 | cemerick | actually, it's a bug as-is anyway; won't work with any remote REPL connections |
| 20:44 | Frozenlock | antifuchs: pain |
| 20:44 | mebaran151 | for a super lazy clojure, I wonder if anybody has ever considered compiling clojure to Haskell core |
| 20:44 | mebaran151 | it's not a bad little asm |
| 20:44 | technomancy | cemerick: good point |
| 20:45 | cemerick | technomancy: clojure.tools.nrepl.helpers/load-file-command is the best there is AFAIK |
| 20:45 | cemerick | Though, that's going to need updating as well. |
| 20:45 | cemerick | Attack of the middlewares! |
| 20:45 | aperiodic | mebaran151: wouldn't you need to figure out how to get a stackless tagless G-machine to run clojure code? |
| 20:46 | hiredman | I hear they are moving off of the stg |
| 20:46 | hiredman | they have some new intermediate rep |
| 20:46 | aperiodic | oh really? i haven't been keeping up |
| 20:46 | hiredman | I just heard this week sometime |
| 20:47 | aperiodic | what's the motivation? |
| 20:47 | hiredman | http://hackage.haskell.org/trac/ghc/blog/newcg-update |
| 20:47 | Frozenlock | lein-gnome.. wait... wait.. is this a way to expand an OS in clojure? |
| 20:48 | hiredman | I just finished reading the stg paper a month or so ago |
| 20:48 | technomancy | Frozenlock: of course |
| 20:49 | technomancy | cemerick: nice |
| 20:58 | mebaran151 | aperiodic: probably nice interaction with haskell, though I suspect the impendence mismatch is probably comparable to the JVM for function oriented languages |
| 20:58 | mebaran151 | it's optimizer also is very good at in lining little tiny functions like clojure does, so it might produce relatively efficient clojure code |
| 21:01 | aperiodic | mebaran151: i was under the impression that a lot of those optimizations it uses were only possible because everything's pure, or represented as such using a monad |
| 21:03 | amalloy | aperiodic: "represented as such"? everything is pure, for reals |
| 21:07 | mebaran151 | In the clojure core, certain functions are most definitely pure, with a quick little :^pure tag, you might be able to compile them outside some sort of monad |
| 21:07 | mebaran151 | and then throw the rest of the program execution into monadic flow |
| 21:07 | aperiodic | amalloy: i will confess to not really grokking how monads and purity interact. how does a monad make, say, println pure? because it makes the execution history (the monad?) an argument? |
| 21:08 | mebaran151 | aperiodic: the monad doesn't make something pure, it just marks it as impure |
| 21:08 | mebaran151 | (well the IO monad) |
| 21:09 | mebaran151 | Monads are just containers that have convenient combination properties |
| 21:09 | amalloy | aperiodic: the signature of that function is String -> IO (). it's a function which takes in a string, and returns (roughly) a set of instructions for performing IO at some later date |
| 21:10 | amalloy | for any given string, it always returns the same set of instructions |
| 21:10 | mebaran151 | that's actually a nice description... |
| 21:11 | amalloy | at the top level of your program (ie main), your main function is called with no arguments, and all IO within it is composed into a single gigantic IO "instruction set" |
| 21:11 | aperiodic | so the impurity only comes in when you want to execute those instructions, which you can do after all the pure code has run? |
| 21:11 | amalloy | yes |
| 21:11 | aperiodic | (inc amalloy) |
| 21:11 | lazybot | ⇒ 26 |
| 21:12 | amalloy | (not only "can do", actually "must do") |
| 21:13 | aperiodic | ok, mebaran151's comments make sense to me now |
| 21:18 | aperiodic | mebaran151: so, how would you deal with haskell's auto-currying vs clojure's var args? keep track of which functions came from where and use different calling conventions accordingly? |
| 21:22 | mebaran151 | well var args vs auto-currying is the same as just passing a list |
| 21:23 | mebaran151 | varargs are syntactic sugar around lists (and the rest argument internally even Clojure looks a lot like a seq) |
| 21:23 | mebaran151 | Java does the same thing mapping varargs to Object[] |
| 21:28 | mebaran151 | in fact all multiple arity functionality might be a little tricky to emulate in clojure given the auto-currying |
| 21:30 | aperiodic | ah... i guess you know when the clojure fns are being called with all of their args, and the haskell functions are totally ok with getting all of their args at once, as you can just apply them one-at-a-time. does that mean this would only work one way? |
| 21:31 | mebaran151 | http://www.haskell.org/haskellwiki/Varargs << a nice little discussion |
| 21:32 | aperiodic | oh rad, thanks. i didn't know that was even possible |
| 21:35 | mebaran151 | it looks like you just set up your own strategy for currying essentially |
| 21:36 | mebaran151 | http://okmij.org/ftp/Haskell/polyvariadic.html#polyvar-fn << for a more detailed overview |
| 21:39 | aperiodic | mmm, I think I'm going to have to do some remedial Haskell before this makes sense to me. |
| 21:40 | aperiodic | thanks, though! |
| 21:40 | Raynes | emezeske: Why does lein-cljsbuild require a version of Clojure? |
| 21:42 | mk | what exactly happens when the repl reads (symbolname)? When does var lookup occur? Does the reader produce a symbol? |
| 21:43 | aperiodic | mk: the reader does not evaluate, it produces a symbol. var lookup occurs during evaluation, for details see http://clojure.org/evaluation |
| 21:44 | aperiodic | mk: well, if it reads "(symbolname)" it produces a list containing a symbol, pardon |
| 21:44 | mk | how does one produce a var? |
| 21:45 | mebaran151 | mk, #'symbol |
| 21:45 | mebaran151 | ,(class #'identity) |
| 21:45 | clojurebot | clojure.lang.Var |
| 21:46 | mebaran151 | also (var symbol) can do the trick to if you're running through a macro |
| 21:47 | mk | I guess #'x is essentially converted to (var x) at read-time? |
| 21:47 | emezeske | Raynes: I forget, but I seem to remember there was a good reason |
| 21:48 | Raynes | emezeske: It's weird though. I'm targeting nodejs, so I don't need Clojure. Stop giving me things I don't need man. Stop it. |
| 21:48 | Raynes | :p |
| 21:48 | mebaran151 | doesn't the clojure compiler actually run in java? |
| 21:48 | mebaran151 | *clojurescript |
| 21:48 | emezeske | Raynes: But, you need clojure to build clojurescript |
| 21:48 | mk | for some reason I was thinking that the reader actually hooks up symbols to vars, or something like that |
| 21:49 | Raynes | emezeske: Yeah, but lein-cljsbuild requires clojurescript, not me. |
| 21:49 | mebaran151 | ,'(+ 1 2 3) |
| 21:49 | clojurebot | (+ 1 2 3) |
| 21:49 | emezeske | lein-cljsbuild shouldn't depend on clojure |
| 21:49 | emezeske | cljsbuild does (the support jar) |
| 21:49 | mebaran151 | ,(eval '(+ 1 2 3)) |
| 21:49 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 21:49 | aperiodic | ,(class (first (read-string "(+ 1 2 3)"))) |
| 21:49 | clojurebot | clojure.lang.Symbol |
| 21:50 | mebaran151 | ah it wouldn't let me show, but the + sign in a quoted list doesn't even know t's var for a while |
| 21:50 | Raynes | emezeske: Couldn't lein-cljsbuild check for a version of Clojure in the project and add it itself if it isn't there? |
| 21:50 | Raynes | (if it really needs it in the projects) |
| 21:50 | Raynes | I mean, I don't care about any of this. |
| 21:50 | Raynes | Just discussing. |
| 21:50 | Raynes | <3 |
| 21:50 | emezeske | I don't understand what's happening -- lein-cljsbuild the JAR doesn't depend on clojure |
| 21:50 | mk | are symbols resolved to their namespace at read-time? |
| 21:50 | emezeske | cljsbuild the JAR does, because, well, it depends on clojure |
| 21:52 | emezeske | Raynes: Oooooooooh I see what you're talking about now |
| 21:52 | emezeske | Raynes: You are right, it shouldn't require that. That's an accidental side-effect of it trying to warn people when they used clojure 1.2 |
| 21:53 | Raynes | I see. |
| 21:53 | emezeske | 'Tis a bug, I think! |
| 21:53 | emezeske | https://github.com/emezeske/lein-cljsbuild/blob/master/plugin/src/leiningen/cljsbuild/subproject.clj#L26 |
| 21:53 | emezeske | That's the error message you're seeing? |
| 21:54 | aperiodic | mk: nope. read http://clojure.org/evaluation |
| 21:54 | mk | ,(var 'undefined32423) |
| 21:54 | clojurebot | #<CompilerException java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol, compiling:(NO_SOURCE_PATH:0)> |
| 21:54 | mk | what's cons got to do with this? |
| 21:55 | Raynes | emezeske: Yessir. |
| 21:55 | mk | aperiodic: thanks |
| 21:56 | emezeske | Raynes: It's odd, I very specifically made it error out. I can't remember why, though... :( |
| 21:56 | emezeske | Raynes: That can probably just be removed. |
| 21:58 | emezeske | Raynes: https://github.com/emezeske/lein-cljsbuild/issues/113 |
| 21:58 | Raynes | Nice |
| 22:04 | mk | the reader itself evaluates the contents of lists? |
| 22:11 | aperiodic | mk: no, the only thing the reader does is turn strings into data structures (well, excepting a read-eval reader macro, but let's not talk about that for the moment) |
| 22:14 | mk | what is quoting then? I thought that a quote prevented the reader from evaluating certain parts of the... I guess that's wrong though, since all the reader would do is turn the '... into (quote ...) |
| 22:16 | aperiodic | mk: yeah, it's a little subtle. all the reader does is that substitution you mentioned. then, when the resulting form is evaluated, the quote fn does the work of preventing evaluation of its arg |
| 22:16 | xeqi | technomancy: do you have a template for new heroku/compojure projects? |
| 22:18 | mk | when defn is read and then evaluated, what happens to the function-body form after the var bindings? |
| 22:18 | mk | are the symbols in that form converted to vars? |
| 22:21 | gfredericks | the symbols that resolve to vars are compiled into references to those vars |
| 22:24 | mk | how might I get the value of what they are compiled into? |
| 22:24 | gfredericks | the var itself or the value in the var? |
| 22:26 | mk | if I (defn f [] (class 'foo)) I get c.l.Symbol. I was expecting that fn would replace '(class 'foo) with '(class <ref value here>), but that doesn't seem right |
| 22:26 | gfredericks | you quoted foo |
| 22:26 | mk | yes. That wasn't right. |
| 22:27 | gfredericks | try (class #'foo) |
| 22:27 | mk | I'd like the var itself, I think... unless I can get what you called the "reference to the var" |
| 22:27 | gfredericks | which is equivalent to (class (var foo)) |
| 22:27 | gfredericks | mk: I didn't mean anything special by "reference to the var" |
| 22:27 | gfredericks | just a reference in the sense that anytime you "have" an object in java you have a reference to it |
| 22:27 | mk | I see |
| 22:28 | gfredericks | compiling the symbol certainly doesn't generate a var, so maybe I was just trying to avoid that interpretation |
| 22:29 | mk | does defn evaluate the function body form? I thought that it did something special with symbols, because I wasn't able to ns-unmap vas used in functions, until I unmapped those functions. But I can't replicate that now. |
| 22:29 | gfredericks | defn mostly just expands to (def foo (fn [...] ...)) |
| 22:29 | mk | I can (def foo 1), then (defn f [] foo), and then (ns-unmap *ns* 'foo) |
| 22:30 | gfredericks | and it still returns 1? |
| 22:30 | mk | yes |
| 22:30 | gfredericks | I suppose the var itself still exists, you've just removed it from the namespace |
| 22:30 | gfredericks | namespaces provide the mapping from symbols to vars |
| 22:31 | aperiodic | yeah, because foo was resolved when you defined f, so it's not a big deal if you remove it later |
| 22:32 | mk | right, but now I do (def foo 2), and then (f) yields 1 |
| 22:32 | gfredericks | yep |
| 22:32 | gfredericks | f still refers to the original var |
| 22:32 | aperiodic | yeah, because it's still returning the value of the old var that foo resolved to when you defined f |
| 22:32 | gfredericks | regardless of the fact that you've now wired 'foo in your namespace to a new var that has 2 in it |
| 22:33 | mk | weird, because when I do (def foo 1) (defn f [] foo) (def foo 2), (f) then yields 2 |
| 22:33 | gfredericks | def again just changes the value of the existing var |
| 22:33 | gfredericks | so the fact that you hadn't unmapped it meant there's only one var the whole time |
| 22:34 | mk | I see, right |
| 22:35 | mk | seems a bit... broken. |
| 22:35 | gfredericks | well ns-unmap is not meant for normal use |
| 22:35 | gfredericks | the redefining-with-the-same-var behavior is what you want to happen when you redefine things |
| 22:35 | mk | I could have sworn that at an earlier time, when I tried to unmap it threw an exception if the var in question was being used in some function |
| 22:36 | arrdem | does Clojure have an 'infinity' constant? |
| 22:37 | gfredericks | just the Double value |
| 22:39 | mk | how can I look at the structure that a fn uses as its body? |
| 22:39 | uvtc | ,(print Double.MAX_VALUE) |
| 22:39 | clojurebot | #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: Double.MAX_VALUE, compiling:(NO_SOURCE_PATH:0)> |
| 22:40 | gfredericks | mk: the compiled bytecode? |
| 22:40 | gfredericks | ,(print Double/MAX_VALUE) |
| 22:40 | clojurebot | 1.7976931348623157E308 |
| 22:40 | uvtc | ,(print Double/MAX_VALUE) |
| 22:40 | clojurebot | 1.7976931348623157E308 |
| 22:40 | uvtc | gfredericks: beat me to it. Thanks. :) |
| 22:40 | mk | ,(print Double/POSITIVE_INFINITY) |
| 22:40 | clojurebot | Infinity |
| 22:40 | gfredericks | uvtc: that's what #clojure is all about |
| 22:41 | gfredericks | ,Infinity |
| 22:41 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: Infinity in this context, compiling:(NO_SOURCE_PATH:0)> |
| 22:41 | mk | gfredericks: right, I guess not the bytecode. I was under the impression that functions merely held on to whatever structure the reader gave them, with a few interesting replacements |
| 22:42 | gfredericks | mk: nope; despite the wishes of various tool-designers the forms are not kept |
| 22:42 | gfredericks | you can define a macro to replace fn that keeps them of course |
| 22:43 | gfredericks | but I doubt that would help you |
| 22:43 | uvtc | xeqi regarding a template for new heroku/compojure projects, if you come across one, I'd love to hear about it. |
| 22:43 | weavejester | lein new compojure blah |
| 22:43 | mk | I doubt it would, because I'm only interested in that weird var-referencing thing |
| 22:43 | weavejester | will work with lein2 |
| 22:44 | weavejester | and lein1 if you install the plugin |
| 22:44 | gfredericks | mk: you can play with vars directly using (var foo) |
| 22:44 | uvtc | weavejester: will try that. Thanks. |
| 22:44 | xeqi | weavejester: neat, thanks |
| 22:45 | gfredericks | lein2 is compojure-aware? |
| 22:45 | weavejester | No, but it automatically downloads templates |
| 22:45 | gfredericks | from where? |
| 22:45 | weavejester | I believe "lein new foo bar" will look for a project foo/lein-template in the repositories |
| 22:45 | mk | so when fn is called, a new Runnable-implementing class is generated, and an instance of it is assigned to the var (the var that resides in the namespace map) |
| 22:45 | gfredericks | nice |
| 22:46 | mk | is that correct? |
| 22:46 | xeqi | gfredericks: it uses lein-newnew underneath which has the autodiscovery |
| 22:46 | gfredericks | mk: fn doesn't necessarily have anything to do with vars |
| 22:46 | mk | oops, defn |
| 22:46 | gfredericks | mk: probably best to think about def and fn separately |
| 22:47 | mk | where fn generates the class, creates an instance, and returns that instance |
| 22:47 | mk | gfredericks: right |
| 22:48 | mk | is a new class created every time fn is called? |
| 22:48 | gfredericks | I think every time a fn expression is compiled, yes |
| 22:50 | mk | so are classes garbage collected, just like instances? |
| 22:51 | gfredericks | I doubt it; and I can't think of any normal situation where that would matter |
| 22:51 | gfredericks | maybe a long-running repl? |
| 22:51 | mk | well, if I'm looping over a (fn) call millions of times, I seem to be generating millions of classes |
| 22:52 | gfredericks | I don't think that's true unless you're evaling fn a million times |
| 22:52 | gfredericks | or the fn appears a million times in your code |
| 22:52 | gfredericks | it should only be compiled once |
| 22:52 | mk | hmm. What sort of loop might use a fn? |
| 22:53 | uvtc | weavejester: I see two seemingly-related projects at clojars: https://clojars.org/compojure-template and https://clojars.org/compojure/lein-template . But they both point to the same github repository... |
| 22:53 | gfredericks | mk: I don't understand the question |
| 22:53 | weavejester | uvtc: The first was made before auto-discovery was implemented, or, more likely, before I knew about it :) |
| 22:53 | mk | gfredericks: I'm trying to think of a case where fn would be evaluated millions of times, and this is normal |
| 22:54 | gfredericks | mk: you have to be calling eval directly |
| 22:54 | gfredericks | simply calling a function is not something that generates a class |
| 22:55 | gfredericks | under normal circumstances there is just one class for each time you see fn in your code |
| 22:55 | uvtc | weavejester: Ah. So, https://clojars.org/compojure/lein-template is the current/modern one that uses lein2 autodiscovery. Thanks. |
| 22:55 | mk | oh, so if I have a fn inside a fn, this will generate the bytecode for only the outer fn? |
| 22:55 | weavejester | uvtc: Correct |
| 22:55 | gfredericks | mk: no, a class for both of them |
| 22:55 | gfredericks | mk: they both get compiled at compile-time |
| 22:56 | antifuchs | hugod: so I was just reading up on the wire format discussion of 11/06; looks like something I would like to take on in ritz soon, unless you have any objections (: |
| 22:58 | antifuchs | (the websocket derailing and consequent frustration aside, I don't see a technical reason why ritz shouldn't implement that new wire format) (: |
| 22:58 | mk | ,(defn makefn [] (fn [] 1)) |
| 22:58 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 22:59 | muhoo | hmm, i wonder if this is on-topic (clojure being used for these applications IIRC): http://www.technologyreview.com/view/428756/watch-high-speed-trading-bots-go-berserk |
| 22:59 | mk | (makefn) seems to return ... oh, it's the same class, but a different instance: #<user$makefn$fn__22 user$makefn$fn__22@ab7165> |
| 22:59 | hugod | antifuchs: I'm actually pretty close to having nrepl working with ritz |
| 23:00 | antifuchs | hugod: ah, ok... |
| 23:00 | antifuchs | hugod: well, I'd love to continue using slime (: |
| 23:00 | antifuchs | whatever works best for either of us, I guess. I'm just not ready to give up on it yet (: |
| 23:01 | mk | ok, mystery mostly solved I guess |
| 23:01 | gfredericks | mk: yep; that's a good example for why a fn-class could have more than one instance |
| 23:01 | hugod | antifuchs: I'll clean up what I have and push it - lots left to do - I'm not removing slime support |
| 23:01 | antifuchs | oh, neat! (: |
| 23:01 | antifuchs | hugod: what does nrepl support mean? |
| 23:01 | antifuchs | just speaking the nrepl wire protocol? |
| 23:02 | hugod | it means the debugger will work in nrepl - with commands to add breakpoints, enable break on exception, etc |
| 23:02 | antifuchs | ! (: |
| 23:02 | antifuchs | pretty neat |
| 23:03 | hugod | at the moment it is a separate plugin for lein |
| 23:03 | hugod | which starts a headless nrepl session |
| 23:03 | mk | so it's effectively safe to assume that a given read-eval (of a block of potentially nested functions) will generate only one class per function (and potentially many instances, but that doesn't matter) |
| 23:04 | antifuchs | so the current slime wire protocol is pretty nice. three bytes, hex-encoded as length prefix, plus utf-8 code bytes. |
| 23:04 | antifuchs | I'll try and frob rpc.clj to speak that next week when I'm on hackation, then see how much of slime breaks (: |
| 23:04 | gfredericks | mk: yep |
| 23:04 | hugod | the swank wire protocol is very simple |
| 23:05 | antifuchs | hugod: it is! |
| 23:05 | antifuchs | hugod: I've never looked too closely at it, but now that I am looking for something to do… (; |
| 23:06 | hugod | antifuchs: sounds like I should get this code cleaned up asap - would really appreciate help with it |
| 23:06 | antifuchs | awesome |
| 23:06 | antifuchs | looking forward to helping in any way I can |
| 23:07 | antifuchs | now that I've tasted a bit of clojure, I'm getting pretty excited, actually (: |
| 23:07 | antifuchs | not that I'm going to be using it at work immediately, but it's good to know strengths of things (: |
| 23:07 | hugod | there will also be elisp code to do for nrepl.el to make using it a pleasant experience |
| 23:07 | antifuchs | hah yayyy |
| 23:07 | antifuchs | THAT I know rather well (: |
| 23:07 | hugod | clojure grows on you pretty quickly |
| 23:08 | arrdem | I' |
| 23:08 | mk | gfredericks: thanks, many things make more sense now |
| 23:08 | antifuchs | I know, it's very very common lispy |
| 23:08 | antifuchs | (which is a very very pleasing thing to me) (: |
| 23:08 | hugod | indeed - with nice hash maps, and atoms, and immutable collections :) |
| 23:10 | gfredericks | mk: success! |
| 23:11 | arrdem | let's try that one again, hands OFF the enter key. I'm trying to write a Levenshtein distance calculator for arbitrarry Clojure ISeqs. Unfortunartely, the efficint solution to this involves much mucking with 2d arrays. I have a working version written in Clojure, but I was wondering what it would take to write the same function in Java. The algorithm is easy, but where is ISeq documented? |
| 23:13 | arrdem | nvm, found javadocs |
| 23:14 | arrdem | Nope, not worth the effort. |
| 23:22 | hugod | antifuchs: just realised you probably meant that you want to use SLIME with a nrepl backend |
| 23:24 | hugod | what I'm doing at the moment is an nrepl backend intended for nrepl.el - a nrepl backend for SLIME would have to look a little different. How different depends on how far the nrepl.el ui departs from SLDB. |
| 23:26 | scottj | hugod: are you abandoning ritz for nrepl? |
| 23:27 | hugod | scottj: no, the idea is that ritz will support slime and nrepl |
| 23:27 | scottj | hugod: nice |
| 23:55 | gfredericks | $mail amalloy just pushed a rewrite to currj/master that includes let and works at compile time; implementing amalloy-fn is 8 lines: https://gist.github.com/3310866 |
| 23:55 | lazybot | Message saved. |