2011-03-05
| 00:50 | amalloy | hm. i wind up defining a lot of functions that are basically just (defn foo "docs" [args] (f1 (f2 (f3 args)))) |
| 00:51 | amalloy | i could write like a defcomp macro that lets me write this as (defcomp foo "docs" [args] f1 f2 f3); do people think this would be more or less readable? |
| 00:51 | pdk | dude |
| 00:52 | pdk | (apply (comp f1 f2 f3) args) |
| 00:52 | amalloy | pdk: what's your point? |
| 00:52 | amalloy | should the caller do that instead of my function ever existing, or should i write that in the body of my defn? |
| 00:53 | pdk | though a general form for writing fns that just compose others like that and return the values they return would be useful so i'd go with this defcomp idea |
| 00:53 | amalloy | the former is clearly silly imo, and the latter is nonoptimal if args is a long list |
| 01:01 | amalloy | huh. despite having recently helped someone with this in #clojure, i can't seem to get a macro to def something with specific metadata |
| 01:23 | amalloy | pdk: can you explain to me why i need the ' in https://gist.github.com/856176 - it seems like the arglists are being evaluated at expansion time, not evaluation time, but it doesn't work without ' |
| 01:38 | tomoj | seems like it's specific to def |
| 01:38 | tomoj | take (defmacro notdefcomp [name args] (with-meta name {:arglists (list args)})) |
| 01:38 | tomoj | same thing, really, no errors |
| 01:39 | tomoj | err.. not the same thing. but I'd have guessed the error would show up in both or neither |
| 01:44 | iwillig | hi, i can't seem to figure this out. But I have an Java class that I want to extend to implement ISeq |
| 01:44 | iwillig | does any one have any pointers ? |
| 01:45 | tomoj | yeah, stack trace from DefExpr suggests compiler weirdness |
| 01:45 | tomoj | damn you for puzzling me |
| 01:46 | iwillig | this is my start |
| 01:46 | iwillig | https://gist.github.com/856189 |
| 01:46 | tomoj | hmm, maybe not that puzzling |
| 01:46 | tomoj | (do (def xyz "foo") (def ^xyz bar 3) (meta #'bar)) |
| 01:47 | tomoj | nah, I'm still puzzled |
| 01:47 | tomoj | iwillig: ISeq is an interface, I think you're out of luck |
| 01:48 | iwillig | mmm |
| 01:48 | tomoj | this is why protocols were invented :) |
| 01:48 | tomoj | unfortunately until cinc the expression problem remains in clojure's core |
| 01:49 | iwillig | so there is no way to extend an Java type to take advantage of clojure seq libraries |
| 01:49 | iwillig | ha |
| 01:50 | iwillig | i guess i could use reify |
| 01:50 | iwillig | err i mean proxy |
| 01:50 | tomoj | why do you want points to be seqs anyway? |
| 01:50 | iwillig | but that does not really solve my issue |
| 01:50 | iwillig | good question |
| 01:51 | iwillig | i think it makes things a lot easier |
| 01:51 | iwillig | so with an Point object is not such a big deal |
| 01:52 | tomoj | maybe work with vectors and convert to Points at your clojure-java bridge? |
| 01:52 | tomoj | and vice-verso |
| 01:52 | iwillig | brb |
| 01:54 | amalloy | tomoj: yeah, i would have guessed the same |
| 01:55 | amalloy | in fact i tried (list args) first; i imagine i could have written (list 'quote (list args)) or something but `' seemed clearer |
| 01:55 | tomoj | my example was just a short way to cause the error |
| 01:55 | tomoj | (or not) |
| 01:57 | tomoj | but let's see |
| 01:57 | tomoj | your macro is expanding to, say (def foo ...) |
| 01:57 | tomoj | and the metadata is already on foo |
| 01:58 | tomoj | nope, thought I made sense of it again, but I keep coming back to: it's just a damn list |
| 01:58 | amalloy | tomoj: exactly |
| 01:58 | tomoj | coming back to that from: it's the same as (def ^{:arglists [a b c]} foo ..) |
| 01:58 | amalloy | i tried macroexpanding it, and it happily expands to (def foo (comp ...)) |
| 01:58 | tomoj | but that looks different to me now |
| 01:59 | amalloy | but for some reason the meta on foo gets evaled when i eval the def |
| 01:59 | tomoj | &(meta (second '(def ^{:arglists ([a b c])} foo))) |
| 01:59 | sexpbot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 02:00 | tomoj | I need to give up |
| 02:01 | amalloy | you tripped the alarm! giving up is lame! |
| 02:01 | tomoj | if you crack it, let me know - feel like there's a bit of metadata/macro enlightenment involved |
| 02:01 | tomoj | :) |
| 02:01 | amalloy | tomoj: i thought i'd cracked it a couple days ago, but what worked then doesn't work now :P |
| 02:02 | tomoj | I see something in Compiler.java that seems relevant (DefExpr analyzing the metadata) |
| 02:02 | tomoj | but don't have the patience to try to understand Compiler.java right now |
| 02:02 | amalloy | maybe i'll take my own advice, and put a ;;TODO wtf why does this work |
| 02:02 | tomoj | does it, though? |
| 02:03 | tomoj | with your version I end up with {:arglists (quote [a b c])} or something like htat |
| 02:03 | amalloy | my version works the way i want it to |
| 02:03 | tomoj | ooh |
| 02:04 | amalloy | slime gives me arglist prompts, etc |
| 02:04 | tomoj | (meta (second (macroexpand-1 '(defcomp foo "bar" [a b c] inc dec)))) |
| 02:04 | tomoj | then it's eval'd to the right thing, I see |
| 02:05 | tomoj | I can't help but think again that that is just like you'd have to (def ^{:arglists '[a b c]} foo) |
| 02:05 | tomoj | and of course shortly after thinking that I'm just as confused :( |
| 02:05 | amalloy | yes, and that works outside a macro |
| 02:05 | amalloy | if i `(def ^{...} ~name ...) inside the macro, no good |
| 02:09 | tomoj | yeah, but |
| 02:09 | tomoj | no, nevermind. giving up. |
| 02:10 | amalloy | lol |
| 02:10 | amalloy | i felt that way too |
| 02:10 | tomoj | I thought I understood metadata and I thought I understood macros |
| 02:10 | tomoj | but together... |
| 02:10 | amalloy | hahahaha |
| 02:11 | amalloy | Learn, Internalize, Surprise, Perplex |
| 02:12 | tomoj | iswydt |
| 02:14 | khaliG | has anyone integrated icanter into their own app? |
| 03:13 | clojurebot | PONG! |
| 03:13 | clojurebot | Invalid token: /3 |
| 03:13 | clojurebot | #<core$constantly$fn__3551 clojure.core$constantly$fn__3551@b670cd> |
| 03:13 | clojurebot | c'est bon! |
| 03:13 | clojurebot | 42 |
| 03:13 | clojurebot | what is cells |
| 03:13 | clojurebot | java.lang.NullPointerException: Expecting Symbol + Namespace |
| 03:13 | clojurebot | 42 |
| 03:13 | clojurebot | multimethods is what separates the boys from the men. |
| 03:13 | Ptival | wow clojurebot speaks French |
| 03:15 | tomoj | :D |
| 03:16 | tomoj | I think that was a |
| 03:16 | tomoj | 6 hour delay |
| 03:16 | tomoj | or so |
| 03:17 | Ptival | extreme buffering |
| 03:18 | tomoj | hiredman: how?! |
| 03:33 | amalloy | nice |
| 03:34 | amalloy | tomoj: the tubes were all blocked up |
| 03:35 | amalloy | ~testing42 |
| 03:35 | clojurebot | 42 |
| 03:35 | amalloy | ~botsnack i guess? kinda hard to say |
| 03:35 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 03:35 | amalloy | anyway night folks |
| 03:35 | amalloy | tomoj: i put my macro confusion on the google group. we'll see if anyone has ideas |
| 06:56 | fmw | how do you write something to the extend of 'if foo == "bar" or foo == "foobar"' in clojure? i.e. an if with multiple clauses. |
| 06:56 | mrBliss | ,(let [foo "bar"] (if (#{"bar" "foobar"} "bar") 1 2)) |
| 06:56 | clojurebot | 1 |
| 06:57 | fmw | mrBliss: thanks! |
| 06:57 | mrBliss | (don't mind the let clause) |
| 07:02 | pyr | hey |
| 07:42 | fmw | mrBliss: hmm, I'm still trying to wrap my head around that line, but it seems like it isn't a good fit for what I'm trying to do (not your fault, obviously, because I should've been more precise) |
| 07:42 | fmw | basically I'm trying to make http://paste.pocoo.org/show/348413/ more concise |
| 07:42 | fmw | as you can see from that paste, I'm trying to learn Clojure by porting some Python code. |
| 07:43 | bawr | fmw: That's probably not a good idea. Rewriting from scrach, maybe. Porting, not so much. ;) |
| 07:43 | raek | fmw: you can use the or and and not macros to form compound conditions |
| 07:43 | fmw | bawr: In this context I mean rewriting when I say porting ;) |
| 07:44 | mrBliss | fmw: I can see that ;-) In Clojure, one does not use def for local variables. (Gotta grab dinner now) |
| 07:44 | fmw | mrBliss: thanks, I'll read up on the local variables thing :) |
| 07:44 | raek | if foo == "bar" or foo == "foobar" would be written (if (or (= foo "bar") (= foo "foobar")) ... ...) |
| 07:44 | __name__ | fmw: what about (and (integer? n) (> n 0)) |
| 07:44 | fmw | raek: ah, those macros are exactly what I need |
| 07:45 | __name__ | fmw: instead of positive-integer? |
| 07:45 | raek | there's even 'pos?' |
| 07:45 | raek | fmw: you can use let to introduce a named value for a scope: (let [x 1] ...code that uses x...) |
| 07:46 | bawr | raek: Just do be sure, nested defns are okay if they make the code more clear, right? :) |
| 07:46 | bawr | Or is that a schemism? |
| 07:46 | raek | you can think of it as { int x = 1; ...code that uses x... } in C, only that you can only assign once... |
| 07:46 | fmw | raek: so def for global variables, let for vars in the local scope? |
| 07:47 | fmw | or rather, global to the namespace |
| 07:47 | raek | bawr: no, nested defn probably does not do what you think |
| 07:47 | raek | def defines a *global* variable |
| 07:47 | raek | unlike define in scheme |
| 07:48 | raek | you can use private global defn if you want helper functions: (defn- helper-fn [x] ...) |
| 07:48 | bawr | SO something like (defn mangle [x y] (defn mingle [i] (+ i y)) (map mingle x)) is bad? |
| 07:48 | bawr | Oooh. |
| 07:48 | fmw | ah, so thats what the - after defn is for |
| 07:48 | raek | or you can use let or letfn: (defn f [x] (let [g (fn [y] ...)] (g (inc x)))) |
| 07:49 | fmw | seen that in a lot of library functions |
| 07:49 | raek | bawr: yes. |
| 07:49 | raek | two invokations of the same function will overwrite the other one's sate |
| 07:49 | raek | *state |
| 07:49 | bawr | raek: Hey, thanks. |
| 07:50 | raek | a rule of thumb: a def form should never be executed at runtime |
| 07:50 | bawr | Aha, gotcha. I was just looking for a solution cleaner than a towering abomination of adding arguments with partial. |
| 07:51 | raek | (the above example with letfn: (defn f [x] (letfn [(g [y] ...)] (g (inc x)))) |
| 07:51 | fmw | __name__: yes, thanks for that line, its a better approach. |
| 07:52 | raek | fmw: also, you usually write just (> n 0) instead of (if (> n 0) true false) |
| 07:54 | fmw | raek: as in leave out the if macro and the parenthesis block after (> n 0) is only evaluated if (> n 0) is true? |
| 07:55 | fmw | raek: hmm, seems like I misunderstood you there, because (> n 0) doesn't work on its own |
| 07:56 | raek | ,(let [x 5] (> x 1)) |
| 07:56 | clojurebot | true |
| 07:56 | raek | it is an expression |
| 07:56 | raek | well, everything is an expression in clojure |
| 07:57 | raek | the if does not add anything in that case |
| 07:59 | fmw | raek: ok, but you do need if (or a similar macro) if you want to execute something based on the boolean value, right? |
| 07:59 | fmw | just not to get a boolean? |
| 08:00 | raek | yes |
| 08:00 | fmw | ok, that clears it up |
| 08:00 | fmw | BTW, thanks for answering all these silly questions ;) |
| 08:00 | raek | the special form 'if' lets you control which branch that will be evaluated |
| 08:01 | raek | np |
| 08:36 | raek | fmw: in clojure you usually structure the code so that each function returns the value of interest, rather changes global variables. |
| 08:36 | fmw | raek: are you the one that just replied to my paste with a better version? |
| 08:37 | raek | http://paste.pocoo.org/show/348431/ |
| 08:37 | raek | this one? |
| 08:37 | fmw | yes |
| 08:37 | raek | yes, I was just going to say that I took the liberty |
| 08:37 | raek | of showing what a funcitonal solution might look like |
| 08:37 | fmw | raek: cool, I'm reading it as we speak :) |
| 08:37 | raek | functional programming is very different from imperative programming and it takes time to adjust to the thinking |
| 08:38 | fmw | raek: I just cleaned it up a bit already (see http://paste.pocoo.org/show/348433/), but I'll go over your functional version of the code |
| 08:39 | fmw | raek: yes, clearly. it is a very different approach and a good thing to be forced to wrap my head around while learning clojure |
| 08:46 | fmw | raek: I'm slowly digesting the code code you wrote right now (the general concept as well as functions I wasn't previously familiar with, e.g. update-in) and its starting to become more clear to me |
| 08:46 | fmw | raek: I really appreciate the fact that you took the time to write this |
| 08:46 | khaliG | i'm looking for some advice for integrating incanter into my clojure app. i'd like to draw a chart, how should i best go about this task? |
| 08:48 | raek | fmw: I wanted to tell you that you should never use def in the body of a function, but without an example on how to do otherwise, I guess that wouldn't be very helpful |
| 08:48 | khaliG | i know incanter can draw charts onto a new window, but if possible i'd like to have them done in a JPanel of mine. |
| 08:49 | raek | this video "Clojure Concurrency" explains the rational for the "mutable variables has to go" approach taken by clojure |
| 08:49 | raek | http://clojure.blip.tv/file/812787/ |
| 08:51 | fmw | raek: yes, I took your suggestion to use let instead of def to heart in http://paste.pocoo.org/show/348433/ , but didn't get further than replacing one def because I was still following the some approach as I would in other languages I'm familiar with, instead of the functional paradigm. |
| 08:51 | fmw | but the example you wrote sort of make the functional approach click with my brain |
| 08:53 | fmw | ok, watching the video now :) |
| 08:58 | khaliG | hm i might just do it by hand using Java 2D, will give me a bit more practice writing clojure anyways |
| 09:06 | raek | khaliG: I just found this, but I don't know how much it helps: http://clojuredocs.org/incanter/incanter.core/data-table |
| 09:17 | khaliG | raek, oooh that is cool. i'll remember for that later :) |
| 09:18 | fliebel | raek: What are these magic datasets? |
| 09:19 | raek | fliebel: in the pocoo paste? |
| 09:20 | raek | fliebel: also, you mentioned something re my blog post yesterday. was something written in a misleading way? |
| 09:23 | fliebel | raek: poco? No just in general, Incanter seems to be using 'datasets' a lot, I was wondering what they are. |
| 09:24 | raek | I dunno :-) haven't used incanter much |
| 09:24 | fliebel | raek: Your blog post… I'm not sure. I was trying to figure out how the thread pools behind feature work. You said it is the same pool used by agents, but only by send-off. So I was 'tricked' into thinking that future would use a fixed pool. |
| 09:26 | raek | yeah, agents have two pools and of them (the non-fixed one) is shared with future |
| 09:27 | fliebel | I figured :) |
| 09:42 | TimMc | Haha, I'm glad I checked the scrollback! clojurebot, you so silly. |
| 09:48 | __name__ | fmw: np |
| 10:14 | khaliG | hm ive tried close to everything to no avail. How the eck does one instantiate java.awt.geom.Line2D.Double |
| 10:14 | khaliG | (in clojure that is) |
| 10:16 | khaliG | ooh got it, it needs a dollar sign :) |
| 10:16 | raek | khaliG: java.awt.geom.Line2D$Double |
| 10:16 | raek | ah, you figured it out... |
| 10:16 | khaliG | raek, thanks |
| 10:21 | pyr | can't you import java.awt.geom.Line2D Double :as Something ? |
| 10:23 | TimMc | pyr: I wish. |
| 10:23 | TimMc | It would make working with AffineTransform in hinted code a lot nicer. |
| 10:24 | pyr | 'k |
| 10:24 | pyr | i thought that would be possible |
| 10:24 | pyr | but if i get this right |
| 10:24 | pyr | this is only a real concern for class names which clash with (like some.thing.foo.String or java.awt.geom.Line2D.Double) |
| 10:25 | pyr | s,with,with standard names from java.lang |
| 10:26 | TimMc | pyr: Nota bene: The compiler will sometimes refer to Point2D$Double as Double in error messages. |
| 10:26 | pyr | luckily my clojure stuff relies on very few java libs |
| 10:26 | pyr | but good to know |
| 10:27 | TimMc | I'm writing a Swing program, so... yeah. |
| 10:48 | fliebel | What is the syntax for version ranges in lein/cake? |
| 10:49 | fliebel | https://github.com/cgrand/moustache/commit/c2a8adef899f08b0847b1e7feb9d2367efdbbbf7 |
| 10:50 | raek | fliebel: same as in maven: http://maven.apache.org/plugins/maven-enforcer-plugin/rules/versionRanges.html |
| 10:50 | raek | "If you've confirmed that your project will work with a number of different versions of a given dependency, you can provide a range instead of a single version." |
| 10:50 | raek | "Don't do this unless you have manually confirming that it works with each of those versions though. You can't assume that your dependencies will use semantic versions; some projects even introduce backwards-incompatible changes in bugfix point releases." |
| 10:51 | raek | from the leiningen tutorial |
| 10:51 | fliebel | raek: I understand the implications, just curious. |
| 10:53 | fliebel | raek: It seems that just the version number is already a range? How is that... |
| 10:56 | bawr | What should I read if I want to understand cake, as opposed to just using it? I've had no real experience writing anything big in Java before. |
| 10:58 | fliebel | raek: Using a range is just as bad as using a snapshot, right? |
| 10:59 | raek | I have not used it for my own projects |
| 11:00 | raek | but I belive version ranges are legitimate to use in stable releases |
| 11:00 | raek | unlike SNAPSHOT dependencies |
| 11:07 | TimMc | Mature dependency managers like Firefox and APT use version ranges quite successfully. |
| 11:07 | Cozey | Hi! Is there some clojure community favourite alternative to SASS language for generating css? |
| 11:07 | fliebel | Cozey: I think someone wrote one, but it's not in wide use, like SASS. |
| 11:08 | Cozey | mhm |
| 11:11 | fliebel | Cozey: It's practically just a serialization of a map. |
| 11:12 | Cozey | :-) |
| 11:24 | gfrlog | algorithms trivia: it's possible to detect an arbitrarily long cycle in an (iterate) seq using constant space |
| 11:24 | fliebel | gfrlog: … how? |
| 11:25 | gfrlog | create two seqs, and consume one twice as fast as the other |
| 11:25 | gfrlog | if there's a cycle, they will eventually have identical heads |
| 11:26 | gfrlog | learned that in my crypto class; was part of some factoring algorithm |
| 11:26 | gfrlog | a bit of wikipedia clicking reveals: http://en.wikipedia.org/wiki/Floyd's_cycle-finding_algorithm#Tortoise_and_hare |
| 11:27 | fliebel | gfrlog: But, how do you know it is not the same head 'by accident'? |
| 11:27 | gfrlog | fliebel: if they're the same head, that means that head value comes up twice |
| 11:27 | DespiteItAll | fliebel -- it's iterate, so it doesn't matter :) |
| 11:27 | gfrlog | exactly |
| 11:27 | gfrlog | once you know a value comes up twice, you know it cycles |
| 11:28 | fliebel | gfrlog: But how do you know one cycle does not include the same head twice? |
| 11:28 | gfrlog | if you're iterating with a pure function, that's impossible |
| 11:28 | fliebel | hm…. that is true |
| 11:31 | fliebel | gfrlog: And what about the time? That is everything but constant, but I wouldn't know how to express it. |
| 11:32 | gfrlog | fliebel: I think it will take perhaps up to twice as long as if you had infinite memory and could just hold all the past values |
| 11:32 | DespiteItAll | you could be iterating for a LONG time before they sync up. reminds me of steve reich's early works |
| 11:33 | gfrlog | I think it depends on the size of the cycle? once both seqs are inside the cycle, you shouldn't spin around more than one extra time |
| 11:33 | gfrlog | you also have to include the fact that each iteration is being performed twice instead of once |
| 11:34 | gfrlog | but even for cycles of manageable size, I would think it still has a chance at being faster than caching, as it uses so little memory |
| 11:34 | __name__ | What's the difference between the PersistentHashMap and the PersistentArrayMap? |
| 11:34 | gfrlog | __name__ the array map is sorted sorta |
| 11:34 | __name__ | sorta? |
| 11:34 | gfrlog | and also has linear lookup time |
| 11:35 | __name__ | Instead of O(log32 n) |
| 11:35 | gfrlog | yeah I was reading about it just yesterday. By sorta I mean that it somehow gets out of order if you assoc onto it |
| 11:35 | gfrlog | __name__: yes |
| 11:35 | __name__ | gfrlog: Do you have any resources on how the ArrayMap works? |
| 11:35 | gfrlog | docs say it's only appropriate for tiny maps |
| 11:35 | fliebel | gfrlog: Have you tried implementing the cycle thing in Clojure? |
| 11:35 | gfrlog | yeah let me find what I was reading |
| 11:35 | __name__ | I understand the way the HashMap works, kind of, |
| 11:35 | gfrlog | fliebel: no, but I'd think it'd be trivial |
| 11:35 | __name__ | It's just a tree after all |
| 11:35 | __name__ | gfrlog: Thanks! |
| 11:36 | gfrlog | __name__: http://clojure.org/data_structures#Data Structures-ArrayMaps |
| 11:36 | __name__ | Links with spaces :( |
| 11:36 | fliebel | __name__: the array version is simple as well, just iterate until you find the correct key. |
| 11:36 | __name__ | Ah, that's trivial. |
| 11:36 | __name__ | I read constant instead of linear … |
| 11:37 | fliebel | __name__: So it is only used for maps smaller than 16 items |
| 11:37 | __name__ | fliebel: The interpreter decides which to use? |
| 11:37 | __name__ | Oh, no, you do. |
| 11:37 | gfrlog | __name__: I think it's mostly used in the implementation of certain things. I've never used one directly myself. |
| 11:38 | __name__ | gfrlog: Normal sorted-maps are trees too, right? |
| 11:38 | gfrlog | __name__: probably |
| 11:38 | __name__ | I hate this printing dialogue :( |
| 11:38 | gfrlog | __name__: I think they're performant, so I'm sure that's the case |
| 11:38 | gfrlog | __name__: you hate chat rooms? |
| 11:39 | __name__ | gfrlog: no, the printing thing of firefox. |
| 11:39 | gfrlog | hmmm...don't know what that is |
| 11:39 | __name__ | When you press Ctrl-P, a dialog window opens. |
| 11:40 | gfrlog | why else would you press it? |
| 11:40 | __name__ | gfrlog: That dialog refuses to let me choose A4 :( |
| 11:40 | __name__ | I don't want stupid letter :( |
| 11:40 | gfrlog | fliebel: this would do it, right? https://gist.github.com/856492 |
| 11:41 | gfrlog | __name__: oooh -- I thought you hated that Ctrl-P opened the dialog. I guess you hate the dialog itself. That's fine. |
| 11:41 | __name__ | :) |
| 11:41 | gfrlog | down with the firefox print dialog! |
| 11:42 | gfrlog | fliebel: I guess it's a bit weird to name it as if it's a predicate, since it never returns false |
| 11:42 | gfrlog | it's like the halting problem... |
| 11:43 | fliebel | gfrlog: I can;t see it, because a Java applet is obscuring my view :S |
| 11:43 | pdk | name it return-true |
| 11:43 | pdk | it'll be fun |
| 11:43 | gfrlog | pdk: :-D |
| 11:44 | gfrlog | cycle detection? that's what the return-true function does of course. Don't you understand the naming conventions? |
| 11:44 | TimMc | (defn did-not-throw-error? [] true) |
| 11:44 | gfrlog | hah |
| 11:44 | fliebel | gfrlog: ##(doc nnext) |
| 11:44 | sexpbot | ⟹ "([x]); Same as (next (next x))" |
| 11:45 | gfrlog | ah I knew it |
| 11:45 | gfrlog | I was about to rewrite it with destructuring actually |
| 11:45 | fliebel | gfrlog: Will that solve the duplicate itterate? |
| 11:46 | TimMc | wait wait |
| 11:46 | TimMc | (defn did-not-throw-error? [] (if (> (rand) 0.5) (throw (Exception. "Oops!")) true)) |
| 11:46 | gfrlog | https://gist.github.com/856492 |
| 11:46 | gfrlog | fliebel: no |
| 11:46 | gfrlog | you have to duplicate iterate |
| 11:46 | fliebel | because with (defn really-huge [] (sleep long)) it will take twice the time. |
| 11:46 | gfrlog | yes, I think the duplication is inescapable |
| 11:47 | gfrlog | it's what you sacrifice for the memory benefits |
| 11:47 | gfrlog | that code got a LOT shorter with destructuring... |
| 11:47 | fliebel | gfrlog: But not duplicate the effort. I thin a lazy seq keeps the realized elements somewhere as state, so letting the itterate will help. |
| 11:47 | fliebel | oh… hm |
| 11:48 | gfrlog | fliebel: you don't want anything cached or your memory will blow up |
| 11:48 | gfrlog | fliebel: So I think letting the iterate will kill you |
| 11:48 | gfrlog | LITERALLY |
| 11:48 | fliebel | probably... |
| 11:48 | fliebel | http://xkcd.com/725/ |
| 11:48 | gfrlog | keeping track of all the in-between values eventually gets too much |
| 11:49 | fliebel | hm |
| 11:49 | gfrlog | fliebel: well played |
| 11:49 | gfrlog | that comic confirst that I spelled literally correctly |
| 11:50 | gfrlog | I literally spelled it correctly |
| 11:50 | gfrlog | s/confirst/confirms |
| 11:50 | gfrlog | sexpbot: you can't look back one extra comment? just one? |
| 11:50 | gfrlog | clojurebot: teach sexpbot how to respond to direct messages |
| 11:50 | clojurebot | sexpbot is not a clojurebot |
| 11:51 | TimMc | nice |
| 11:51 | fliebel | gfrlog: So, what about the destructuring? |
| 11:51 | gfrlog | fliebel: I don't know what that question means. What about it? |
| 11:51 | gfrlog | I was just saying it made the code cleaner |
| 11:51 | fliebel | gfrlog:Can I see it :) |
| 11:52 | gfrlog | oh I gave a link |
| 11:52 | gfrlog | https://gist.github.com/856492 |
| 11:52 | gfrlog | I haven't tested either of those functions |
| 11:53 | gfrlog | I will paste it into the repl right now and see what happens |
| 11:53 | fliebel | The hardest part is defining a function that does a cycle :P |
| 11:54 | gfrlog | => (return-true #(rem (inc %) 83800) 88) |
| 11:54 | gfrlog | true |
| 11:54 | gfrlog | also: |
| 11:54 | gfrlog | => (return-true #(rem (* % %) 83879) 88) |
| 11:54 | gfrlog | true |
| 11:55 | gfrlog | doing anything at all within a fixed domain will have to cycle |
| 11:55 | gfrlog | e.g., any hash function |
| 11:56 | fliebel | hash function? |
| 11:56 | gfrlog | hash function |
| 11:56 | fliebel | $google hash function |
| 11:56 | sexpbot | First out of 551000 results is: Hash function - Wikipedia, the free encyclopedia |
| 11:56 | sexpbot | http://en.wikipedia.org/wiki/Hash_function |
| 11:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception: 503> |
| 11:56 | gfrlog | :) |
| 11:57 | gfrlog | who told clojurebot to do anything? |
| 11:57 | gfrlog | ,"I dunno" |
| 11:57 | clojurebot | "I dunno" |
| 11:58 | gfrlog | fliebel: hash functions are good. |
| 11:58 | gfrlog | they're one of my favorite things. |
| 11:59 | TimMc | clojurebot randomly throws that 503 exception on URLs |
| 11:59 | gfrlog | ooh |
| 11:59 | gfrlog | http://github.com |
| 12:00 | gfrlog | maybe it only accepts URLs from sexpbot |
| 12:00 | sineer | Hi! I am going nuts trying to setup swank-clojure Classpath!! Someone Please Tell Me Why no matter how hard I try to set the swank-clojure-classpath var it always end up set as: (swank-clojure-default-classpath) instead of whatever I try to set it to... |
| 12:01 | sineer | Even this won't work: (eval-after-load "swank-clojure" '(progn (add-to-list 'swank-clojure-classpath "~/.emacs.d/site-lisp/swank-clojure/src/"))) |
| 12:01 | fliebel | gfrlog: Hm, I want to see what the cycle part was... |
| 12:01 | sineer | I've spent the last 2 hours trying to fix this :( |
| 12:03 | sineer | in swank-clojure.el... this line: (defcustom swank-clojure-classpath |
| 12:03 | sineer | (swank-clojure-default-classpath) |
| 12:03 | sineer | can this prevent me somehow from using add-to-list ? |
| 12:04 | gfrlog | fliebel: you mean why I say a hash function will cycle? |
| 12:04 | fliebel | gfrlog: No, I ran a cycle, and I wanted to see when it started to repeat. |
| 12:05 | gfrlog | oh...add some prints? |
| 12:05 | gfrlog | if you run the return-true function with a hash function you will probably never see it repeat |
| 12:05 | gfrlog | unless it's a bad hash function |
| 12:07 | fliebel | user=> (return-true #(.hashCode (str %)) "hallo wereld") => true |
| 12:09 | fliebel | gfrlog: ^ |
| 12:09 | gfrlog | fliebel: will have to check what .hashCode does |
| 12:10 | gfrlog | ah yes |
| 12:10 | fliebel | gfrlog: but for (defn return-truthy [it ob] (let [[f & r] (iterate it ob)] (take-while (partial not= f) r))): (doall (return-truthy #(.hashCode (str %)) "hallo wereld")) => java.lang.OutOfMemoryError |
| 12:10 | gfrlog | so for certain purposes you can use bad hash functions |
| 12:11 | gfrlog | .hashCode is a bad hash function |
| 12:11 | fliebel | why? |
| 12:11 | clojurebot | why not? |
| 12:11 | gfrlog | because its range is 256 I believe |
| 12:11 | gfrlog | or maybe 2^32 |
| 12:11 | gfrlog | both of which are small |
| 12:11 | gfrlog | for crypto purposes |
| 12:12 | gfrlog | they are fine for programming language purposes like hash maps |
| 12:12 | fmw | raek: just watched the whole 2:32+ hours of that with a short break to read over the concepts he was talking about in my "Seven Languages in Seven Weeks" book. I guess I learned a lot, but the information is still working its way to seep through the cracks in my brain ;) |
| 12:12 | fmw | raek: thanks |
| 12:12 | gfrlog | which I believe is the expected usage |
| 12:12 | gfrlog | when I said 'would never return' I was referring to any crypto hash function, which would have a much bigger range |
| 12:13 | fliebel | gfrlog: But why does it return true instantly for you function, and not at all for mine? |
| 12:13 | fliebel | oh, wait, I know... |
| 12:14 | gfrlog | you're letting the iterate, right? |
| 12:15 | gfrlog | another reason that algorithm might not work is that the first object in the iterate doesn't have to be part of the cycle |
| 12:15 | fliebel | gfrlog: I'm doing something completely different, namely, looking if the first value comes back later. |
| 12:15 | gfrlog | (btw, in your code f == ob) |
| 12:16 | gfrlog | right |
| 12:16 | gfrlog | okay then, as long as it's on purpose |
| 12:16 | gfrlog | I would guess for a given hash function there is a good chance the initial value will not show up again |
| 12:17 | gfrlog | also, take-while will probably keep the whole seq |
| 12:17 | gfrlog | another cause for the memory error |
| 12:17 | fliebel | gfrlog: *That* was intended. I wanted to see the whole cycle. |
| 12:17 | gfrlog | man I'm always incorrectly guessing your intentions |
| 12:18 | gfrlog | ,(.hashCode "fliebel") |
| 12:18 | clojurebot | -771880729 |
| 12:18 | gfrlog | looks like the range is 2^32 |
| 12:18 | fliebel | Maybe I'm just not clear in my intentions ;) |
| 12:18 | gfrlog | so that'd be too big |
| 12:18 | gfrlog | if you use #(rem (.hashCode %) 256) |
| 12:18 | gfrlog | as the hash function |
| 12:18 | gfrlog | it would cycle much faster |
| 12:18 | gfrlog | adjust 256 to your liking |
| 12:19 | fliebel | yea... |
| 12:23 | fliebel | victory! I changed true into a in your code, and used that in mine :) |
| 12:24 | gfrlog | but mine doesn't keep all the values... |
| 12:24 | fliebel | 1018032231 has a cycle of 37525 |
| 12:25 | gfrlog | did you use the raw hashCode or reduce it? |
| 12:25 | fliebel | raw |
| 12:25 | gfrlog | huh |
| 12:26 | gfrlog | I have a visual javascript implementation of SHA-1 that I need to clean up and publish |
| 12:35 | ApeShot | So I'm using lein, and I have a "general purpose" library in one project and a specific project that depends on it, and I am working in the project directory, but want clojure/swank-clojure to handle things correctly when I update the utility library |
| 12:35 | ApeShot | There is a specific idiom for this that I can't remember, as I've been in CL land for awhile. |
| 12:35 | ApeShot | I put a symlink somewhere? |
| 12:36 | ApeShot | I'm in emacs and on ubuntu |
| 12:36 | ApeShot | checkout dependencies, it seems, is the answer |
| 12:36 | ApeShot | Thanks! |
| 12:37 | gfrlog | man I can never remember whether the reader macro is ~@ or @~ |
| 12:37 | gfrlog | ~@ apparently |
| 12:37 | clojurebot | @ is splicing unquote |
| 12:38 | gfrlog | so if you want to unquote the result of derefing something... you add whitespace? |
| 12:38 | gfrlog | ,`~(deref (atom 0)) |
| 12:38 | clojurebot | 0 |
| 12:38 | gfrlog | ,`~@(atom 0) |
| 12:38 | clojurebot | splice not in list |
| 12:38 | gfrlog | ,`~ @(atom 0) |
| 12:38 | clojurebot | 0 |
| 12:38 | gfrlog | guess so |
| 12:41 | ApeShot | Ok, so using checkout dependencies, do I need to add something to my project.clj file to reflect that dependency or does Lein keep track of it itself/ |
| 12:41 | raek | ApeShot: iirc, you should include the library in :dependencies as usual |
| 12:42 | ApeShot | raek: what do I write for a personal library? |
| 12:43 | raek | and in addition to that, have a symlink to the project dir |
| 12:43 | ApeShot | raek: in the checkouts directory, right? |
| 12:43 | raek | yes |
| 12:43 | ApeShot | raek: or do I need yet another |
| 12:44 | raek | ApeShot: in :dependencies, you put whatever you called your private library in its project.clj |
| 12:45 | ApeShot | raek: thanks a ton |
| 12:45 | ApeShot | raek: all these configuration things are the most frustrating wall between me and hacking |
| 12:45 | ApeShot | worth it later to be organized now |
| 12:45 | ApeShot | but frustrating now |
| 13:08 | jjjjjjj | what's the best way to store data 10 elements long in clojure? |
| 13:08 | jjjjjjj | list or vector? |
| 13:08 | ApeShot | jjjjjjj: almost certainly depends on what you do with it |
| 13:08 | ApeShot | jjjjjjj: do you want random access or sequential access |
| 13:09 | jjjjjjj | generally I will iterate through it at some time |
| 13:09 | ApeShot | jjjjjjj: probably with only ten elements it doesn't matter |
| 13:09 | jjjjjjj | it does IMO |
| 13:09 | ApeShot | jjjjjjj: iteration is fast with lists or vectors |
| 13:09 | jjjjjjj | yeah but creation cost is lower with list |
| 13:09 | ApeShot | jjjjjjj: are you creating tons of these things? |
| 13:09 | ApeShot | jjjjjjj: in an inner loop? |
| 13:09 | jjjjjjj | I tried testing this and I think list was like 5 times faster |
| 13:10 | ApeShot | jjjjjjj: "vectors" in clojure are functional so conj on a vector should be as fast as cons on a list, I think. |
| 13:10 | ApeShot | jjjjjjj: I am not any sort of functional data structures expert, though |
| 13:10 | ApeShot | jjjjjjj: or even novice |
| 13:10 | ApeShot | jjjjjjj: what is your application? |
| 13:10 | jjjjjjj | I know what you're thinking... if you do this once in a program, it doesn't matter right? |
| 13:10 | jjjjjjj | but I use short sequential data all throughout my program |
| 13:11 | ApeShot | jjjjjjj: I'm actually thinking, "without more information about his use case, how can he expect me to answer his question meaningfully?" |
| 13:11 | jjjjjjj | :D |
| 13:11 | gfrlog | you both are missing the obvious answer: A sorted map of finger trees |
| 13:11 | ApeShot | golomb forest |
| 13:11 | ApeShot | sql database |
| 13:12 | jjjjjjj | look it's your basic CRUD app |
| 13:12 | ApeShot | what if you need to map reduce on the ten elements |
| 13:12 | ApeShot | COUCHDB |
| 13:12 | amalloy | ApeShot: hadoop! |
| 13:12 | jjjjjjj | after zeroing down to some unit like a single user or so, you pull related data from DB |
| 13:12 | ApeShot | TEN INDEX CARDS |
| 13:13 | ApeShot | Hire a grad student to wait around to type them in when needed. |
| 13:13 | jjjjjjj | for instance one user has relationship with 5 locations, 3 companies etc |
| 13:13 | jjjjjjj | this is where a bunch of short lists come from |
| 13:13 | amalloy | ApeShot: see if you can distribute like seti@home |
| 13:13 | ApeShot | jjjjjjj: sorry, we are on a tangent here |
| 13:13 | Ptival | ^^ |
| 13:13 | jjjjjjj | I'm just explaining why most my programs involve creation of bajillion lists of ~10 elements |
| 13:13 | ApeShot | jjjjjjj: clojure should make it easy to change the seq type later |
| 13:14 | ApeShot | jjjjjjj: If you aren't doing random access, use lists |
| 13:14 | jjjjjjj | I was thinking about using transients when filling lists, but it slowed down actually |
| 13:14 | ApeShot | a conj should be real cheap |
| 13:14 | jjjjjjj | it's not |
| 13:15 | ApeShot | anyone know more about this than me? |
| 13:15 | ApeShot | Honestly, 95% of the lisp code I write is in Emacs Lisp. |
| 13:15 | ApeShot | In EL we have lists and we HAVE TO LIKE IT. |
| 13:15 | amalloy | the overhead of creating a transient and then turning it into a persistent is probably larger than the cost of making a list to begin with |
| 13:15 | amalloy | ApeShot: oooo you write EL. plz to fix everything i don't like about clojure-mode |
| 13:16 | ApeShot | amalloy: what don't you like |
| 13:16 | amalloy | ApeShot: this gets indented wrong: ((juxt + -) 10 <RET> 5) |
| 13:16 | ApeShot | amalloy: this is more my kind of thing |
| 13:16 | ApeShot | amalloy: https://github.com/VincentToups/emacs-utils/blob/master/README.md |
| 13:17 | jjjjjjj | I tried the test of inserting 100000 numbers into short lists of 10 and java kinda outperformed clojure vectors 40 to 1 |
| 13:17 | ApeShot | jjjjjjj: well, 40/1 isn't bad |
| 13:17 | ApeShot | jjjjjjj: did you add type annotations to the clojure code? |
| 13:17 | jjjjjjj | sounds bad when that's all your code does :D |
| 13:17 | ApeShot | amalloy: the indentation looks ok to me |
| 13:18 | ApeShot | amalloy: what would you like it to be like? |
| 13:18 | jjjjjjj | annotations? for normal numbers? |
| 13:18 | amalloy | ApeShot: 5 should line up with 10, not with ( |
| 13:18 | amalloy | as it does for (+ 10<RET>5) |
| 13:18 | ApeShot | amalloy: you know, you are right. |
| 13:18 | amalloy | ApeShot: i doubt typehints would make a difference when you're just conjing numbers onto a list and not doing any math with them |
| 13:19 | ApeShot | amalloy: well, like I said, I'm not really a major clojure guy |
| 13:19 | jjjjjjj | however we have a tight loop where another difference maker is i++ vs (inc i) |
| 13:19 | fmw | raek: after watching the video, I'm trying to fully understand the code you wrote by writing unit tests for the individual functions. I feel like I'm starting to grok it, but chaining lets like here: http://paste.pocoo.org/show/348510/ feels a bit clunky. Am I doing that optimally, right now? |
| 13:20 | amalloy | jjjjjjj: good news: you can use modern computers instead of 1985 mainframes, so the 40:1 difference really won't matter for almost any program |
| 13:20 | fmw | I must say that the functional paradigm is awesome while writing tests. |
| 13:21 | ApeShot | amalloy: I believe a better name for juxt, incidentally, is "cleave" |
| 13:21 | jjjjjjj | amalloy I'm not so sure about that... I had careless "don't look at performance look at ease of programming" bite me in the ass before |
| 13:21 | ApeShot | amalloy: If I am not mistaken, it is the equivalent of the concatenative language cleave combinator. |
| 13:22 | gfrlog | I had performance issues once. The solution iirc was to remove all the (Thread/sleep ...) statements |
| 13:22 | amalloy | jjjjjjj: the programmer's time costs a zillion dollars per hour, and the computer's time is pennies per hour. write it right to begin with, and if you really need the computer to go faster you can improve it |
| 13:22 | ApeShot | amalloy: which coincidentally I am adding to my utility library for clojure right now |
| 13:22 | amalloy | hah |
| 13:23 | amalloy | fmw: it seems weird to me to see (let [...] (let [...])) |
| 13:23 | gfrlog | amalloy: It's a clever way to think about it, but I think for most applications that's not really accurate; e.g., when a user is waiting on something |
| 13:23 | ApeShot | amalloy: admittedly, its not clear to me that "cleave" is a more intuitive name than "juxt" |
| 13:23 | amalloy | you might as well just (let [... ...]) |
| 13:23 | jjjjjjj | amalloy...if only it were that simple...one time I had a problem with JSF where page had 3 sec load time with a single user, adding more servers didn't help. Also if you use software like IBM WebSphere portal you pay licenses per CPU power, expensive licenses at that |
| 13:23 | jjjjjjj | so usually customer says...here you have 4 cores, deal with it |
| 13:24 | jjjjjjj | because they have 4 cores worth of licenses for software |
| 13:24 | gfrlog | amalloy: tweaking performance is fun! |
| 13:25 | gfrlog | and sometimes you get into these situations where the only way to save the princess is to mathematically prove that no algorithm runs faster than your algorithm |
| 13:25 | jjjjjjj | :D |
| 13:26 | gfrlog | times like those it doesn't matter what's in your inner loop and what's not. Bowser doesn't care. |
| 13:27 | fmw | amalloy: ah, like so: http://paste.pocoo.org/show/348518/ |
| 13:27 | fmw | that seems to work |
| 13:30 | fmw | raek: ok, nevermind bothering you, it was resolved (just letting you know in case you can't see with all the activity in the channel) |
| 13:30 | fmw | amalloy: thanks :) |
| 13:30 | amalloy | fmw: that's a perfectly reasonable change to make to your code but it's not the one i was suggesting |
| 13:30 | fmw | amalloy: oh |
| 13:31 | fmw | what were you suggesting? |
| 13:31 | amalloy | i meant (let [stats {...}, new-stats (reduce ...)] ...) |
| 13:31 | amalloy | because let allows multiple bindings |
| 13:31 | fmw | amalloy: cool, I didn't know that |
| 13:32 | amalloy | $source defn |
| 13:32 | sexpbot | defn is http://is.gd/6dmcr0 |
| 13:32 | amalloy | fmw: ^ is an especially gross use of that fact |
| 13:33 | jjjjjjj | doesn't need the comma |
| 13:33 | amalloy | jjjjjjj: obviously |
| 13:33 | jjjjjjj | just saying...in case fmw doesn't know |
| 13:33 | fmw | jjjjjjj: I did know that, but thanks anyway :) |
| 13:33 | jjjjjjj | comma is whitespace in clojure |
| 13:33 | jjjjjjj | [1 2 3] is same as [1,2,3] |
| 13:33 | fmw | its very safe to assume I don't know that kind of stuff, but in this case I did |
| 13:33 | gfrlog | especially if your font is white |
| 13:34 | gfrlog | &(doc defn) |
| 13:34 | sexpbot | ⟹ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata" |
| 13:35 | gfrlog | amalloy: Do you happen to know why the 'defn' source uses 'def' instead of 'defmacro'? |
| 13:35 | amalloy | gfrlog: defmacro doesn't exist yet |
| 13:35 | gfrlog | yes but defn is a macro |
| 13:35 | gfrlog | so just using (def x (fn [args]...)) shouldn't ... do that |
| 13:35 | gfrlog | oh I see the next line |
| 13:35 | amalloy | gfrlog: see the end. it alters the var root |
| 13:35 | gfrlog | okay very good |
| 13:36 | gfrlog | I will start using that in my code everywhere |
| 13:36 | amalloy | which is in fact how defmacro works, once it's defined |
| 13:36 | gfrlog | ,(.setMacro (var clojure.core/conj)) |
| 13:36 | clojurebot | nil |
| 13:36 | fmw | amalloy: so ^ is not a technical language construct, but its just a let binding the value of that documentation map to to ^? |
| 13:36 | gfrlog | ,(conj [] 2) |
| 13:36 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/conj |
| 13:37 | gfrlog | did I just break clojurebot? |
| 13:37 | fmw | i.e. not a keyword, just a variable name convention |
| 13:37 | amalloy | fmw: *squint* i don't think i understand the question |
| 13:37 | gfrlog | ,(cons 7 []) |
| 13:37 | clojurebot | (7) |
| 13:37 | amalloy | gfrlog: it's not as difficult as you would think |
| 13:37 | gfrlog | how does it get unbroken? |
| 13:37 | gfrlog | ,(.setMacro (var clojure.core/cons)) |
| 13:37 | clojurebot | nil |
| 13:38 | gfrlog | ,(cons 7 []) |
| 13:38 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$cons |
| 13:38 | amalloy | gfrlog: hiredman will reboot it, or someone will make these things un-macros |
| 13:38 | amalloy | ,(alter-meta! #'cons assoc :macro false) |
| 13:38 | clojurebot | {:macro false, :ns #<Namespace clojure.core>, :name cons, :file "clojure/core.clj", :line 22, :arglists ([x seq]), :doc "Returns a new seq where x is the first element and seq is\n the rest.", :ad... |
| 13:38 | amalloy | ,(cons 7 []) |
| 13:38 | clojurebot | (7) |
| 13:38 | gfrlog | oh okay |
| 13:38 | gfrlog | every is dynamic at runtime, I assure myself soothingly |
| 13:39 | fmw | amalloy: you were using ^ as an example of let binding multiple values. so from that I can assume that ^ is variable name which is getting assigned that documentation map as a value instead of a language keyword? or well, I guess the concept of a language keyword is different in lisp, because code is data. |
| 13:39 | amalloy | uh, i was using ^ as a way to point above me |
| 13:39 | amalloy | to the defn link |
| 13:40 | spewn | It's tempting to set alter-meta! to be a macro and yell "Checkmate!" |
| 13:40 | gfrlog | I will create a homoiconic language where data is code |
| 13:40 | amalloy | spewn: good luck with that |
| 13:40 | amalloy | ,alter-var-root |
| 13:40 | clojurebot | #<core$alter_var_root clojure.core$alter_var_root@1c63b78> |
| 13:40 | amalloy | there are a lot of ways to change meta |
| 13:41 | gfrlog | so...2 ways? |
| 13:41 | fliebel | I'd like to see you guys try to break and unbreak clojurebot :) |
| 13:41 | amalloy | anyway guys i gotta run. hope that clarified things for you, fmw; ^ is kinda an irc convention |
| 13:41 | fmw | amalloy: ok, thanks for the input :) |
| 13:41 | fmw | amalloy: and it did |
| 13:47 | gfrlog | how do I get a new string writer? |
| 13:48 | gfrlog | ah nevermind |
| 13:48 | jjjjjjj | :) |
| 13:48 | jjjjjjj | (java.io.StringWriter.) |
| 13:48 | gfrlog | is there a clojure method for it? |
| 13:48 | gfrlog | that's what I found |
| 13:48 | jjjjjjj | which is same as (new java.io.StringWriter) |
| 13:49 | jjjjjjj | you can also import classes same as java to make this shorter |
| 13:49 | gfrlog | right |
| 13:50 | gfrlog | ah well; can't complain |
| 13:53 | jjjjjjj | you expected a clojure idiom for making string writer objects? |
| 13:55 | gfrlog | no, just something in c.c.duck-streams or something like that |
| 13:55 | gfrlog | so (println) respects *out*, but (.printStackTrace e) does not -- that's expected, right? |
| 13:56 | gfrlog | is there a clojure function for printing stack traces to *out*? |
| 13:57 | jjjjjjj | maybe print stack trace uses System.err not System.out |
| 13:57 | jjjjjjj | different stream |
| 13:57 | gfrlog | yes; it doesn't respect *err* either though |
| 13:57 | jjjjjjj | ah... |
| 13:57 | gfrlog | I would imagine clojure couldn't affect the behavior of that function |
| 13:57 | gfrlog | I see a clojure.stacktrace namespace, so I'd bet anybody $15 this will be helpful |
| 13:57 | jjjjjjj | you want to print stack trace into a string |
| 13:58 | gfrlog | jjjjjjj: no, I want it to go to *out* or *err* -- something I can control |
| 13:58 | raek | gfrlog: .printStackTrace has a variant that takes a PrintWriter as an arg |
| 13:58 | gfrlog | raek: that sounds like it would work; but would the clojure.stacktrace functions not be preferred? |
| 13:59 | jjjjjjj | last resort use (.getStackTrace e) and |
| 13:59 | raek | I guess it depends on what you need to do |
| 13:59 | jjjjjjj | do whatever you want with it |
| 13:59 | gfrlog | jjjjjjjj: that is exactly what I was trying to avoid |
| 13:59 | raek | clojure.stacktrace provides functions that know about clojure naming conventions |
| 13:59 | gfrlog | jjjjjjj: your name makes it hard to address you directly |
| 13:59 | jjjjjjj | how so? |
| 13:59 | gfrlog | jjjjjjj: Have to count the j's |
| 14:00 | jjjjjjj | :D |
| 14:00 | gfrlog | don't you like any other letters? I know a few good ones. |
| 14:00 | spewn | gfrlog: No tab completion in your client? |
| 14:00 | EDCBA | :) |
| 14:00 | gfrlog | spewn: apparently there is |
| 14:00 | gfrlog | spewn: many hugs |
| 14:01 | EDCBA | I was wondering the same thing |
| 14:01 | gfrlog | spewn: what other tricks do I need to learn? |
| 14:01 | gfrlog | I'm just going to start complaining about IRC and see what people recommend: |
| 14:01 | gfrlog | (am using irssi) |
| 14:01 | raek | gfrlog: re you previous question: some java methods print to System.out. rebinding clojure's *out* var does not change it. so yes, that behaviour is expected. |
| 14:02 | gfrlog | raek: right - that's what I assume would be different about clojure.stacktrace |
| 14:02 | gfrlog | raek: I guess you're thinking that passing *out* to .printStacktrace is easier than :requiring clojure.stacktrace? |
| 14:03 | gfrlog | first of all, using a terminal client means I don't get notifications when somebody is talking to me |
| 14:03 | gfrlog | second, I don't know how to make passive statements |
| 14:03 | gfrlog | third, I don't get as much work done when I'm on IRC |
| 14:04 | EDCBA | I think you can change System.out to a stream of your own |
| 14:04 | gfrlog | fourth, my three-item-lists always run long |
| 14:04 | spewn | gfrlog: "/set beep" will show you some notification-related settings in irssi |
| 14:04 | gfrlog | EDCBA: really? |
| 14:04 | EDCBA | I don't see why not |
| 14:04 | gfrlog | EDCBA: because Java isn't good |
| 14:04 | EDCBA | it's not declared final so I assume you can do that |
| 14:05 | gfrlog | n |
| 14:06 | gfrlog | it even has a .setOut function |
| 14:06 | gfrlog | spewn: thanks |
| 14:46 | rata_ | what's await return value? |
| 14:54 | chouser | rata_: nil |
| 14:54 | rata_ | chouser: thanks =) |
| 15:01 | rata_ | can agents launch programs using c.c.shell-out? |
| 15:04 | gfrlog | if I have (defn foo* ...) and (defmacro foo [...] `(foo* ...)), shouldn't the foo* symbol resolve correctly no matter where I call foo from? |
| 15:05 | edbond | how to get list of alphabet chars? ["A" "B" ... "Z"] ? |
| 15:05 | gfrlog | ,(map str (seq "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) |
| 15:05 | clojurebot | ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" ...) |
| 15:05 | gfrlog | that's the best I know of :-/ |
| 15:06 | rata_ | I don't see what else could be the problem here: https://gist.github.com/856670 |
| 15:06 | raek | ,(map char (range (int \A) (inc (int \Z)))) |
| 15:06 | clojurebot | (\A \B \C \D \E \F \G \H \I \J ...) |
| 15:07 | gfrlog | ,(ruby-eval "[*'A'..'Z']") |
| 15:07 | clojurebot | java.lang.Exception: Unable to resolve symbol: ruby-eval in this context |
| 15:07 | gfrlog | had to try |
| 15:07 | raek | or replace "char" with (comp str char) if you want strings |
| 15:07 | Derander | gfrlog: too bad |
| 15:08 | gfrlog | Derander: yeah why doesn't clojure include JRuby yet? |
| 15:08 | Derander | :-) |
| 15:08 | gfrlog | and Jerlang for that matter |
| 15:09 | gfrlog | if I have (defn foo* ...) and (defmacro foo [...] `(foo* ...)), shouldn't the foo* symbol resolve correctly no matter where I call foo from? |
| 15:11 | rata_ | gfrlog: yes, it should |
| 15:11 | raek | gfrlog: yes |
| 15:11 | gfrlog | stranger and stranger... |
| 15:11 | raek | if you have (defn foo* ...) and you are in namespace "user", `foo* should evaluate to the symbol user/foo* |
| 15:12 | raek | gfrlog: do you know about macroexpand-1? |
| 15:12 | clojurebot | Cool story bro. |
| 15:12 | gfrlog | raek: yes |
| 15:12 | gfrlog | raek: I'm doing mildly more complicated things, so probably it would all work fine at the repl |
| 15:14 | rata_ | gfrlog: gist it, maybe we can help you |
| 15:15 | gfrlog | rata_: it's not any more complex than what I gave, and indeed it does work at the repl |
| 15:15 | gfrlog | I'll have to sort this one out myself |
| 15:16 | __name__ | hm, i am trying to read the source of persistenthashmap, but it is poorly documented :( |
| 15:16 | __name__ | what does http://bit.ly/evHFJg do? |
| 15:17 | __name__ | Hm, ah. |
| 15:17 | __name__ | 0x01f is just 11111. |
| 15:17 | raek | __name__: have you seen http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/ ? |
| 15:17 | __name__ | raek: yes |
| 15:17 | __name__ | The >>> just confused me. I am no Java guy. |
| 15:18 | raek | ah, logical shift right... |
| 15:18 | raek | it's interesting that java has both >> and >>>, but C does not |
| 15:22 | __name__ | Yes, the three > confused me. |
| 15:25 | EDCBA | gfrlog I tried that macro |
| 15:25 | EDCBA | worked fine for me |
| 15:25 | EDCBA | make sure that macro and function are in same namespace |
| 15:52 | EDCBA | stupid question but if I want to typehint do I use ^String or #^String |
| 15:52 | EDCBA | and how do I typehint primitives |
| 15:54 | spewn | EDCBA: As far as I know, you can't typehint primitives because until 1.3, functions can't accept unboxed values. I could be wrong about that though. |
| 15:55 | dnolen | EDCBA: in 1.2.0 you can't type hint primitives fn args or return values. You can cast them in let binding and the primitive type information will flow through. You also need to type hint literals. |
| 15:55 | dnolen | (let [x (float 1.0)] ...) |
| 15:55 | dnolen | not also that 1.2.0 since functions can't return primitives you'll need to type hint return values as well. |
| 15:55 | dnolen | (int (+ (int 1) (int 2)) |
| 15:55 | raek | EDCBA: ^String is the syntax since clojure 1.2. #^String was used in 1.1 and earlier |
| 15:56 | dnolen | EDCBA: in 1.3.0 this tediousness is largely eliminated. |
| 16:06 | TimMc | The 1.2 compiler accepts primitive type hints, but apparently just ignores them. |
| 16:14 | dnolen | TimMc: ignore them in the sense that nothing than can be done in 1.2 w/ that information since in 1.2 functions can only take objects. |
| 16:14 | TimMc | But it's forward compatible! :-) |
| 16:15 | TimMc | Mmm, I wonder if ^double effectively results in ^Double or ^Object in 1.2? |
| 16:18 | EDCBA | thanks dnolen |
| 16:19 | EDCBA | what did you mean about type hinting literals |
| 16:20 | dnolen | EDCBA: in 1.2.0, literals are interpreted as their object variants. 1 is Integer not int. |
| 16:20 | EDCBA | ah |
| 16:20 | EDCBA | so (int ^int 1)? |
| 16:20 | dnolen | not |
| 16:20 | dnolen | (int 1) |
| 16:20 | EDCBA | yes |
| 16:20 | TimMc | ,(int ^int 1) |
| 16:20 | clojurebot | Metadata can only be applied to IMetas |
| 16:20 | EDCBA | I wasn't aware that (int x) was type hint |
| 16:21 | EDCBA | that confused me |
| 16:21 | dnolen | EDCBA: it's a cast. |
| 16:21 | dnolen | ^int doesn't mean anything. |
| 16:22 | EDCBA | ah |
| 16:22 | EDCBA | is there any type casting operation in clojure (for the sake of java interop) |
| 16:26 | mrBliss | ,(find-doc "cast") |
| 16:26 | clojurebot | ------------------------- |
| 16:26 | clojurebot | clojure.core/cast |
| 16:26 | clojurebot | ([c x]) |
| 16:26 | clojurebot | Throws a ClassCastException if x is not a c, else returns x. |
| 16:28 | raek | EDCBA: when you do an interop call, like (defn matches [^String s] (.matches s)) the bytecode of the clojure fn will have a cast from Object to String |
| 16:29 | TimMc | I believe this is equivalent, but less likely: (defn matches [s] (.matches ^String s)) |
| 16:30 | raek | so casting for the sake of interop is insterted automatically by the compiler for non-reflective method calls |
| 16:30 | raek | the class to cast to can be controlled with typehints |
| 16:31 | raek | (in some cases, you need to hint an object as an instance of a public interface if the concrete class is a private one) |
| 16:31 | raek | (as the compiler would infer the concrete type) |
| 16:35 | EDCBA | right |
| 16:35 | EDCBA | so if I typehint fn argument then it propagates to calls in that fn |
| 16:36 | raek | yes |
| 16:36 | EDCBA | what's the purpose of typehints in fn that only call clojure functions? |
| 16:36 | EDCBA | I see that sometimes in clojure.core source |
| 16:36 | raek | in 1.2, that would be a no-op |
| 16:36 | EDCBA | faster clojure interfaces? |
| 16:36 | EDCBA | do typehints make interfaces faster? |
| 16:37 | EDCBA | another question that's been bugging me for some time, when I use defmulti, I specify dispatch fn. What arguments can that fn expect |
| 16:38 | raek | any arguments the user of the multimethod would pass it |
| 16:38 | TimMc | Is there a HOF to sequence thunks? Like (foo f g) => (do (f) (g)) ? |
| 16:39 | raek | EDCBA: where do you see those typehints? |
| 16:39 | EDCBA | I might have been mistaken |
| 16:40 | raek | note that core.clj also uses the alternative (. x (method 1 2 3)) syntax instead of (.method x 1 2 3) sometimes |
| 16:40 | EDCBA | so if I have multimethod that takes 2 args and I want to dispatch based on first arg's class I need to state #(class %1) as fn? |
| 16:40 | raek | that dispatch fn only takes one argument |
| 16:40 | raek | you need something like (fn [x _] (class x)) |
| 16:41 | EDCBA | I can't use reader macro for fn? |
| 16:41 | gfrlog | so if the macro doesn't use backticks...and it rewrites using an unqualified symbol...and the macro is called from outside the namespace...how will the symbol be interpreted? |
| 16:41 | EDCBA | oh crap I see now |
| 16:41 | raek | or (fn [x & _] (class x)) if you want to allow arbitrary number of arguments |
| 16:42 | EDCBA | I can't use reader macro because #(class %1) will make a single arg fn |
| 16:42 | EDCBA | I see it now |
| 16:42 | gfrlog | EDCBA: your nick is hard to type with all the caps. Why not change it to something easy to type and repetitive like jjjjjjj? |
| 16:42 | raek | gfrlog: it will be resolved in the context where it is called, which is bad |
| 16:43 | gfrlog | raek: okay. thus the default backtick behavior |
| 16:43 | raek | where the macro is expanded, not where the macro was defined |
| 16:43 | raek | unlike the backtick behavior |
| 16:43 | gfrlog | right |
| 16:44 | raek | gfrlog: if you do something like (cons 'conj ...) to build the code, you can use (cons `conj ...) instead |
| 16:44 | EDCBA | so 'user will become user/user? |
| 16:44 | gfrlog | raek: that's a good tip |
| 16:44 | EDCBA | gfrlog macros use backtick 90% of the time |
| 16:45 | gfrlog | yep |
| 16:45 | TimMc | gfrlog: tab-completion is case-insensitive in irssi |
| 16:45 | EDCBA | unless you know why you aren't quoting with backtick you shouldn't use normal quote :D |
| 16:45 | gfrlog | TimMc: dang |
| 16:45 | TimMc | :-) |
| 17:19 | TimMc | raek: Does (fn [x] (boolean (pos? x))) give any benefit in 1.2 over (fn [x] (pos? x)) ? |
| 17:21 | raek | TimMc: not that I know of. what would the benefit be? |
| 17:23 | TimMc | Wasn't sure if boolean *specifically* acted to annotate the return with type information (besides casting), or whether anything that returns a strict boolean would do that. |
| 17:24 | TimMc | I don't have any reason to believe it does, but I wanted to make sure I wasn't missing something. |
| 17:25 | waxrose | Hello every body, I threw together a 1920x1080 clojure wallpaper. Enjoy. :) http://i.imgur.com/n7P9k.jpg |
| 17:27 | TimMc | spiffy |
| 17:28 | johnmn3 | I like it |
| 17:28 | waxrose | :D |
| 17:28 | TimMc | But a JPG? |
| 17:28 | waxrose | Oh, it's in jpg? |
| 17:29 | TimMc | I guess imgur changed it. |
| 17:29 | waxrose | Yeah, I can put it up on dropbox if you want. |
| 17:29 | TimMc | Looks fine, though. |
| 17:30 | waxrose | Alright. :) |
| 17:30 | TimMc | waxrose: This shall replace my old, uh, "GNU-themed" wallpaper: http://i.imgur.com/88Jgz.jpg :-P |
| 17:30 | waxrose | TimMc, haha! |
| 17:30 | waxrose | Epic |
| 17:31 | TimMc | (found on Reddit a while ago) |
| 17:31 | waxrose | Lol that is awesome. |
| 17:32 | johnmn3 | I'd probably wear that fragrance |
| 17:32 | TimMc | Contrary to popular opinion, RMS does not actually smell bad in person. |
| 17:32 | johnmn3 | while chewing my toenails |
| 17:32 | waxrose | Real men don't shave. |
| 17:33 | TimMc | ...but I think he posed for that picture knowing exactly how it would be used. He's that kind of guy. |
| 17:33 | waxrose | lol |
| 17:33 | waxrose | I wish I could meet him in person. |
| 17:33 | waxrose | Him and Sussman. |
| 17:34 | amac | sussman seems like he'd be more fun |
| 17:34 | amac | stallman is... odd |
| 17:34 | waxrose | How so? |
| 17:35 | TimMc | I've met RMS once at MIT. He looked just like the pictures. |
| 17:35 | amac | I've helped organize conferences where he was a keynote |
| 17:35 | waxrose | Lucky. |
| 17:35 | amac | look online for a copy of his term sheet |
| 17:35 | dfan | rms is a pretty weird guy in real life |
| 17:35 | TimMc | Sussman I met at a PL event at Northeastern. He regaled us with tales of making fault tolerant software + hardware for a giant telescope. |
| 17:35 | waxrose | I wish I would have gotten my things in order during high school and had applied for MIT in order to meet these guys. |
| 17:36 | TimMc | waxrose: How far are you from Boston? |
| 17:36 | waxrose | TimMc, I live in Texas. |
| 17:37 | dfan | Sussman is actually a reasonable human being |
| 17:37 | amac | his video classes for sicp are awesome |
| 17:37 | TimMc | I should watch those! |
| 17:37 | amac | tres 80's |
| 17:37 | dfan | I took SICP in the 80s :) |
| 17:37 | amac | nice! it hasn't changed. |
| 17:38 | waxrose | TimMc, http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ |
| 17:38 | dfan | Has it not? I thought they moved from Scheme to Python or something |
| 17:38 | TimMc | waxrose: Yeah, but... not enough time right now. |
| 17:38 | waxrose | I was actually given a PERFECT copy of SICP that was published during that time, a couple weeks ago. |
| 17:38 | johnmn3 | I've been watching those on the metro to work the last few weeks |
| 17:38 | amac | that's the nice thing about lisp... its basically been feature-complete for 40 years |
| 17:39 | waxrose | dfan, Yeah to Python. |
| 17:39 | amac | waxrose: get sussman to sign it |
| 17:39 | amac | :) |
| 17:39 | waxrose | amac, I have to find him first! haha |
| 17:39 | waxrose | That or get a plane ticket out of Texas. |
| 17:40 | dfan | A shame |
| 17:40 | amac | I want to get knuth to sign my taocp books |
| 17:40 | amac | waxrose: travel is good for you ;) |
| 17:40 | TimMc | The reason given for moving to Python was that there was a good robotics package in Python, and they wanted the students to get more experience with both hardware and software. |
| 17:40 | waxrose | amac, I hope after I'm done with school I can go find these guys. |
| 17:41 | dfan | Huh, I thought they were moving away from the hardware side too |
| 17:41 | dfan | like the computers we assembled in 6.004 |
| 17:41 | TimMc | dfan: Oh, huh. |
| 17:42 | TimMc | I really enjoyed Northeastern's Fundamentals of Computer Programming intro course, even though I was a transfer student with a fair amount of Java and functional JS under my belt. |
| 17:42 | TimMc | Fundies is taught in Racket (PLT Scheme). |
| 17:43 | dfan | I respect the PLT guys a lot |
| 17:43 | TimMc | dfan: Eli is a nutcase, in a good way. |
| 17:43 | waxrose | Is the Clojure Conj pretty big? |
| 17:43 | amac | where *is* clojureconj? |
| 17:43 | TimMc | Matthias scares all his students. :-P |
| 17:44 | TimMc | amac: NC, I think. |
| 17:44 | waxrose | amac, Says Durham |
| 17:44 | waxrose | http://www.clojure-conj.org/ |
| 17:44 | TimMc | I might make it down, escpecially if I get a job at Akamai doing Clojure work. |
| 17:44 | waxrose | I wish every thing wasn't so far from Texas. |
| 17:45 | dfan | At least everything is equally far from Texas |
| 17:45 | waxrose | True. |
| 17:45 | waxrose | I'm actually surprised Austin does not have a Clojure conference of some sort. ( not that I know of) |
| 17:45 | amac | I'm in Montreal, getting anywhere in the US costs a fortune. |
| 17:47 | TimMc | waxrose: The East and West coasts being everything? |
| 17:49 | waxrose | TimMc, Seems like it. |
| 17:49 | TimMc | Boston is amazing. I could see staying here a long time. |
| 17:50 | dfan | I never left :) |
| 17:50 | waxrose | I've lived around the D.C. area before but I've heard that Boston itself is a great place to live. |
| 17:50 | TimMc | I'm from Charlottesville, VA. |
| 17:50 | TimMc | Might combine Clojure Conj with a visit to my folks. |
| 17:50 | waxrose | And I imagine there are many Lispish type jobs in that area. |
| 17:51 | dfan | Every time I travel somewhere warmer during the winter I wonder why I live in Boston |
| 17:51 | amac | I'd go to SF over Boston... I've had enough of winters. |
| 17:51 | dfan | but then it passes |
| 17:51 | TimMc | dfan: I love the snow. :-) |
| 17:51 | waxrose | I should save up to go to next years Clojure Conj. |
| 17:52 | waxrose | TimMc, I love the snow as well despite living in TX most of my life. |
| 17:52 | amac | TimMc: playing in snow is awesome, living in it sucks ass |
| 17:52 | TimMc | waxrose: That's probably why you like it. :-) |
| 17:53 | TimMc | Wow, you apparently can't get from Austin, TX to Durham, NC by Amtrak. |
| 17:53 | TimMc | That, or their website is screwed up as usual. |
| 17:54 | waxrose | Ouch. |
| 17:54 | waxrose | Would probably have to go to Dallas instead. |
| 17:55 | gfrlog | TimMc: they're pretty bad about connections |
| 17:55 | TimMc | gfrlog: I know they can find two-leg routes. |
| 17:55 | gfrlog | TimMc: they don't |
| 17:55 | gfrlog | TimMc: well sometimes they do. |
| 17:56 | TimMc | I travel from CVS to BOS all the time, and used to transfer at NYP or WAS. |
| 17:57 | gfrlog | there's a route I would request that involves transferring at WAS, but they won't show it |
| 17:57 | waxrose | How is the transportation like there? I'd be great to live some where that does not require a car. |
| 17:57 | TimMc | waxrose: I bike to school, 5.5 miles. |
| 17:57 | gfrlog | I am not a fan of cars. |
| 17:57 | gfrlog | when the cars play, I cheer for the other team. |
| 17:57 | gfrlog | unless they are playing trucks |
| 17:57 | waxrose | haha |
| 17:58 | dfan | Public transportation in Boston is great in theory |
| 17:58 | waxrose | TimMc, That is awesome. I wish I could do the same here. |
| 17:58 | waxrose | I actually just paid off my car too. |
| 17:58 | TimMc | If you have an ebook reader, public transit probably isn't so bad. |
| 17:58 | TimMc | You'll get a lot of reading done. |
| 17:59 | gfrlog | and you probably won't die in a car accident |
| 17:59 | gfrlog | or pay thousands of dollars getting anything fixed |
| 17:59 | waxrose | TimMc, I work at B&N, so I see my fair share of Nooks. |
| 18:00 | gfrlog | Books&Nooks |
| 18:00 | TimMc | haha |
| 18:00 | TimMc | You could transfer through... Chicago. -.- |
| 18:00 | gfrlog | ,(map #(str % "ooks") ["B" "N"]) |
| 18:00 | clojurebot | ("Books" "Nooks") |
| 18:02 | waxrose | I'm actually waiting for that new Clojure book, The Joy of Clojure to come out. |
| 18:02 | waxrose | Going to grab it from the back of the store as soon as I see it too. ( benefits of working there) |
| 18:03 | TimMc | waxrose: http://i.imgur.com/RfACt.png <-- source and destination are both annoying close to major lines. |
| 18:04 | waxrose | Wow |
| 18:04 | TimMc | I hate our stupid, inadequate ground transit system. |
| 18:04 | waxrose | SA is not that far way though thankfully. |
| 18:05 | TimMc | You could drive 40 miles to San Antonio, use Amtrak to get to Greensboro, and maybe catch a ride 40 miles to Durham. |
| 18:05 | spewn | waxrose: Loving the wallpaper. Could we get a non-JPEG version? And is the background based on anything? It looks familiar. |
| 18:06 | gfrlog | Greyhound compared to Amtrak is much better about coverage and routing; much worse about experience |
| 18:06 | gfrlog | also cheaper usually |
| 18:06 | waxrose | spewn, Sure, imgur changed it to jpg and yes the background was made by, ( forgot source ). All I did was threw the Clojure logo on top and change a couple of image settings. |
| 18:06 | TimMc | gfrlog: No power outlets, no room to walk around. |
| 18:06 | waxrose | spewn, Would you like the actual background as well? |
| 18:07 | spewn | No, I think your composition of the two is great. |
| 18:07 | TimMc | waxrose: You wouldn't want to go through Chicago, by the way. The squiggly lines in the WV area mean really slow transit as the train winds through mountains. Gorgeous, but slow as hell. |
| 18:08 | TimMc | (longer distance anyway, of course) |
| 18:08 | waxrose | TimMc, Yeah I would much rather go through the southern most route merely because of familiarity. |
| 18:10 | gfrlog | TimMc: their newer buses have outlets |
| 18:10 | TimMc | gfrlog: That would almost make it bearable. |
| 18:10 | waxrose | spewn, http://dl.dropbox.com/u/21959941/clojure-flower-1920_1080.png |
| 18:10 | gfrlog | I personally can bear it. But that's only because I have weird ideals. |
| 18:11 | gfrlog | I don't think less of people who choose not to |
| 18:11 | TimMc | gfrlog: It's not a matter of ideals so much as I can't stand being cooped up. |
| 18:12 | TimMc | I get super fidgety. |
| 18:12 | waxrose | I think if I can catch a plane, I would just do it that way. |
| 18:12 | gfrlog | TimMc: ah, then you should get the ticket for the fidgety seat |
| 18:13 | spewn | waxrose: Merci. Much prettier when the lines are crisp. |
| 18:13 | gfrlog | just kidding their tickets have nothing to do with seats |
| 18:13 | TimMc | gfrlog: The one with straps? :-( |
| 18:13 | waxrose | spewn, You are welcome. :D |
| 18:15 | TimMc | waxrose: If you do decide to use Amtrak, make sure to buy a Student Advantage card. You'll more than pay it off on the first trip. (15% off or so on fares.) |
| 18:15 | waxrose | Oh wow, thanks for the tip. |
| 18:16 | TimMc | You can get other discounts with it, but that's the only one I've found applicable to me. :-P |
| 18:16 | waxrose | hehe |
| 18:17 | waxrose | Hopefully by the time I use it I'll have made some Android apps in Clojure. -_- |
| 18:23 | waxrose | TimMc, About how long do you think it would take to get to Durham via amtrak? |
| 18:24 | TimMc | waxrose: I already closed the window... but the one-transfer route doesn't run on Nov 9, just on Nov 10 (which is the first day of the Conj). $193. |
| 18:24 | TimMc | Didn't check the length. |
| 18:25 | waxrose | Okay thanks. So it would be smart to arrive maybe the 8th then. |
| 18:25 | TimMc | SAS -> GRO |
| 18:26 | TimMc | The fuck... |
| 18:26 | waxrose | Hmm I probably could go with it being $193. Just would have to find a hotel. |
| 18:26 | TimMc | The alternate routes both go through WAS. (DC) |
| 18:26 | TimMc | And Chicago! |
| 18:27 | TimMc | Nov 8 won't cut it, you have to go back to Nov 7. |
| 18:28 | TimMc | That's a redeye: 12:00 Nov 7 -> 16:00 Nov 8 |
| 18:28 | waxrose | That would at least give me some time to sight see. |
| 18:28 | waxrose | :) |
| 18:28 | gfrlog | I had a 4 hr amtrak layover in chicago once. That was when I found out the Sears Tower was not called that anymore. |
| 18:30 | waxrose | gfrlog, haha |
| 18:30 | TimMc | WAS is a nice layover, if you have little enough luggage to sight-see. I once spent a layover on a cold, rainy day in the Botanical Conservatory, which is basically a huge greenhouse. |
| 18:31 | waxrose | TimMc, Thanks a lot for the help. This with the added discount really makes me making it to the Clojure Conj a possibility. |
| 18:31 | TimMc | gfrlog: On Greyhound, is there enough seat room to open up a laptop and code? |
| 18:31 | TimMc | waxrose: Yay! (Now I'll feel bad if I don't make it.) |
| 18:32 | waxrose | haha |
| 18:32 | TimMc | I pretty much spend my entire Amtrak ride programming, or tagging my photos. |
| 18:32 | waxrose | I went ahead and put my e-mail in for notification because I know I'll forget. |
| 18:33 | devn | hmmm... I'd like to create mock of the twitter stream using clojure. Any suggestions on existing libraries to model a stream like that? |
| 18:34 | amac | TimMc: greyhounds are a tight squeeze but doable, the problem is that there are no trays to put the laptop on |
| 18:34 | TimMc | amac: Tray for height or keeping your lap cool? |
| 18:35 | amac | both |
| 18:35 | amac | my laptop gets crazy hot |
| 18:35 | gfrlog | TimMc: it's pushing it for sure |
| 18:35 | TimMc | Mine doesn't/ |
| 18:35 | amac | and in tight squeezes the height can be a plus |
| 18:35 | gfrlog | TimMc: Another issue is at night you feel like a jerk if the screen is bright |
| 18:35 | TimMc | Hmm. |
| 18:35 | waxrose | amac, I've never travel via bus long term. How well is the power management for your laptop? |
| 18:36 | waxrose | I assumed they would provide sockets. |
| 18:36 | amac | few of the busses have power |
| 18:36 | gfrlog | only the new buses |
| 18:36 | amac | at least that's the case in canada |
| 18:36 | gfrlog | those even have wifi |
| 18:36 | gfrlog | I only rode on one once |
| 18:36 | TimMc | devn: Are you talking about modeling a producer/consumer architecture, or what? |
| 18:36 | amac | I took greyhound from vancouver to ottawa in october last year, and only one bus had power |
| 18:36 | gfrlog | ironically that was the same trip that a group of kids brought peeing cats on board |
| 18:37 | gfrlog | so the luxury of the newer bus was lost |
| 18:37 | devn | TimMc: i want to basically make a fake version of the twitter stream to load test an application im working on |
| 18:37 | devn | im wondering how to best achieve that goal |
| 18:37 | amac | gfrlog: hah |
| 18:38 | amac | devn: the aleph project has a twitter stream api key in their examples |
| 18:38 | amac | use that to pump out a dataset |
| 18:39 | devn | amac: beautiful |
| 18:39 | devn | thanks |
| 19:17 | gfrlog | what's the way you can get a stack overflow when using lazy seqs? |
| 19:21 | TimMc | gfrlog: I know how to use up memory, but not stack. |
| 19:21 | raek | gfrlog: some combinations of reduce and map can cause it |
| 19:22 | gfrlog | TimMc: I think it's when you try to print a real long lazy seq |
| 19:22 | gfrlog | maybe it's an issue with the c.c.json specifically |
| 19:22 | TimMc | Holding onto the head of a lazy seq as you force the contents will eventually use up arbitrarily much memory. |
| 19:22 | gfrlog | of course |
| 19:23 | TimMc | Oh, you are actually getting a stack overflow in existing code? |
| 19:23 | gfrlog | ,(take 14 (clojure.contrib.json/json-str (range 100000))) |
| 19:23 | clojurebot | java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.json |
| 19:23 | gfrlog | TimMc: yeah |
| 19:23 | amac | hah, I thought you arbitrarily wanted to break your code |
| 19:24 | gfrlog | oh no; not this time |
| 19:24 | gfrlog | [[dishes]] |
| 19:25 | raek | ,(nth (iterate #(map inc %) [1 2 3]) 10) |
| 19:25 | clojurebot | (11 12 13) |
| 19:25 | raek | ,(nth (iterate #(map inc %) [1 2 3]) 100) |
| 19:25 | clojurebot | (101 102 103) |
| 19:25 | raek | ,(nth (iterate #(map inc %) [1 2 3]) 1000) |
| 19:25 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.StackOverflowError> |
| 19:25 | raek | ,(nth (iterate #(doall (map inc %)) [1 2 3]) 1000) |
| 19:25 | clojurebot | (1001 1002 1003) |
| 19:25 | amac | lol |
| 19:25 | raek | there |
| 19:25 | amac | poor clojurebot |
| 19:25 | raek | you end up with somthing like (map f (map f (map f (map f ...)))) |
| 19:26 | raek | and when the first element out the outermost map is forced, it triggers a cascade of forcings, each one requiring its own stack frame |
| 19:26 | amac | though I think you can change the stack size in the java vm if you're ligitimately running out |
| 19:27 | raek | gfrlog: so there you have it... that's one way you can get a stack overflow from lazy sequences. :-) |
| 19:27 | gfrlog | I had been doing the dishes for a few minutes |
| 19:27 | gfrlog | and came to the same conclusion |
| 19:27 | gfrlog | and came back to state it |
| 19:28 | gfrlog | this is what caused my problem before as well as this time |
| 19:28 | gfrlog | I'm hoping (dorun) will make it better |
| 19:28 | gfrlog | apparently not |
| 19:28 | gfrlog | I should call (vec) I guess? |
| 19:29 | raek | gfrlog: doall is sufficient for my example |
| 19:30 | raek | it will have the same effect as vec, except that you don't allocate a new data structure |
| 19:31 | raek | having a doall in the loop will "flush out the laziness" at each iteration, so that it doesn't build up |
| 19:32 | TimMc | I find this surprising. |
| 19:32 | TimMc | I'm going to have to sit awhile and think about how those stack frames build up. |
| 19:33 | raek | it's all about where each map step is forced |
| 19:33 | TimMc | I think I get it... |
| 19:33 | TimMc | nth forces iterate, but the maps aren't forced until println |
| 19:34 | TimMc | ,((fn [_] nil) (nth (iterate #(map inc %) [1 2 3]) 1000)) |
| 19:34 | clojurebot | nil |
| 19:34 | TimMc | \o/ |
| 19:37 | TimMc | Why is def bad for the sandbox? I've seen Scheme eval bots that set up a sandbox where you can define things that last for a while. |
| 19:41 | TimMc | ,(loop [l (list)] (recur (conj l 4))) |
| 19:42 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/conj |
| 19:42 | TimMc | Interesting. Anyway, on my own box that gave me an IndexOutOfBoundsException. |
| 19:43 | TimMc | ,*clojure-version* |
| 19:43 | clojurebot | {:major 1, :minor 2, :incremental 0, :qualifier ""} |
| 19:45 | waxrose | TimMc, Thanks again for the amtrak info. Time for work so I'll be back on later. See ya! |
| 19:45 | TimMc | cheers |
| 19:47 | pyr | hi |
| 19:47 | pyr | I'm having some problems with a specific type of problem in clojure |
| 19:48 | pyr | i have a recursive function which exits due to stack overflow |
| 19:48 | pyr | and which would be a good client for loop/recur |
| 19:49 | pyr | but it calls itselfs more than one through map |
| 19:49 | spewn | pyr: Some example code might help. |
| 19:50 | TimMc | pyr: Would trampoline help? |
| 19:50 | pyr | might |
| 19:50 | pyr | hold on |
| 19:51 | pyr | http://pastie.org/1637834 |
| 19:52 | pyr | here goes, a simple path finder which goes through a 5x5 grid |
| 19:52 | pyr | and finds out unique paths |
| 19:54 | pyr | i'll look and try to see if trampoline can help me |
| 19:55 | TimMc | pyr: By the way, assoc on a vector gives you back a vector. No need for into. |
| 19:56 | pyr | true |
| 19:58 | TimMc | Are you trying to count the number of unique paths? |
| 19:59 | pyr | yep |
| 19:59 | amalloy | ,(alter-meta! #'conj assoc :macro false) |
| 19:59 | clojurebot | {:macro false, :ns #<Namespace clojure.core>, :name conj, :file "clojure/core.clj", :line 71, :arglists ([coll x] [coll x & xs]), :doc "conj[oin]. Returns a new collection with the xs\n 'added'. (... |
| 19:59 | amalloy | ,(loop [l (list)] (recur (conj l 4))) |
| 19:59 | clojurebot | java.lang.OutOfMemoryError: Java heap space |
| 20:00 | amalloy | TimMc: someone was messing around with breaking clojurebot earlier today and didn't bother to fix him, apparently |
| 20:00 | TimMc | hah! |
| 20:00 | gfrlog | me? |
| 20:00 | clojurebot | your assessment smacks of bias, thus undermining your credibility further. (http://wondermark.com/560/) |
| 20:01 | amalloy | i mean, as the co-owner of sexpbot i don't mind seeing clojurebot get beat up on a little, but it's polite to fix him later :P |
| 20:01 | gfrlog | I guess I was a little shaken by the experience |
| 20:01 | gfrlog | I remember I only macro'd conj and cons I think |
| 20:02 | gfrlog | and you un-macro'd one of them? |
| 20:02 | amalloy | gfrlog: yeah, it's all fixed up now |
| 20:02 | amac | lol |
| 20:02 | gfrlog | oh okay. pardon my childishness. Poor bot. |
| 20:02 | gfrlog | ,(doc dorun) |
| 20:02 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is co... |
| 20:02 | gfrlog | ,(doc doall) |
| 20:02 | amalloy | there there |
| 20:02 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is co... |
| 20:02 | gfrlog | dorun and doall are the same? |
| 20:02 | amalloy | &(doc dorun) |
| 20:03 | sexpbot | ⟹ "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the su... http://gist.github.com/856902 |
| 20:03 | amalloy | &(doc doall) |
| 20:03 | sexpbot | ⟹ "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the su... http://gist.github.com/856903 |
| 20:03 | gfrlog | these dang bots |
| 20:03 | gfrlog | where's printslongstringsbot when you need him? |
| 20:03 | spewn | gfrlog: doall returns the head, dorun returns nil |
| 20:03 | amalloy | gfrlog: the end of the doc is different but clojurebot truncates |
| 20:03 | gfrlog | I'm ignoring the return value |
| 20:03 | spewn | Then use dorun. |
| 20:03 | gfrlog | and (dorun) didn't fix my problem |
| 20:03 | amalloy | sexpbot truncates too of course, but he gists to the rest |
| 20:04 | gfrlog | oooh that's what that link is about |
| 20:04 | gfrlog | good job sexpbot |
| 20:04 | amalloy | yeah, anything that's too long for an irc message |
| 20:04 | gfrlog | &(println (vec (range 10000))) |
| 20:04 | sexpbot | ⟹ [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 ... failed to gist: Connection reset |
| 20:04 | gfrlog | &(println (vec (range 10000))) |
| 20:04 | sexpbot | ⟹ [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92... failed to gist: Broken pipe |
| 20:04 | amalloy | and that's too long for a gist :P |
| 20:04 | gfrlog | oh |
| 20:04 | gfrlog | &(println (vec (range 1000))) |
| 20:04 | sexpbot | ⟹ [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 ... http://gist.github.com/856904 |
| 20:05 | amac | ,(= (doc dorun) (doc doall)) |
| 20:05 | gfrlog | brilliant |
| 20:05 | clojurebot | false |
| 20:05 | TimMc | ,(doc doc) |
| 20:05 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 20:05 | amalloy | though in practice there are some things that i didn't bother to plug gisting into, on the assumption that it would never get that long |
| 20:06 | spewn | Interesting... in my REPL, (= (doc dorun) (doc doall)) evaluates to true. |
| 20:06 | spewn | Since each returns nil. |
| 20:06 | amalloy | spewn: the bots use special versions of doc |
| 20:06 | TimMc | doc prints, ,doc is a bot command |
| 20:06 | amalloy | TimMc: no |
| 20:06 | TimMc | ,(doc ...) I mean |
| 20:06 | clojurebot | Pardon? |
| 20:07 | amalloy | ,'anything tells the bot to eval that |
| 20:07 | clojurebot | anything |
| 20:07 | amalloy | he redefines def to be something that returns a string so that he can capture the output, i imagine |
| 20:07 | amalloy | er, doc |
| 20:07 | spewn | ,(meta #'doc) |
| 20:07 | clojurebot | {:macro true, :ns #<Namespace clojure.core>, :name doc, :file "clojure/core.clj", :line 3880, :arglists ([name]), :added "1.0", :doc "Prints documentation for a var or special form given its name"} |
| 20:08 | TimMc | It must intercept it, then. |
| 20:08 | amalloy | &(meta #'doc) |
| 20:08 | sexpbot | ⟹ {:macro true, :ns #<Namespace clojure.core>, :name doc, :file "clojure/core.clj", :line 3880, :arglists ([name]), :added "1.0", :doc "Prints documentation for a var or special form given its name"} |
| 20:08 | amalloy | sexpbot rebinds it |
| 20:08 | TimMc | ,~ |
| 20:09 | clojurebot | EOF while reading character |
| 20:09 | amalloy | the var #'doc still has the same meta, but it resolves to something different because the eval'ed form is wrapped in (binding [doc sexpbot-doc] ...) |
| 20:10 | TimMc | ,(conj [] 5) |
| 20:10 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/conj |
| 20:10 | TimMc | ,(alter-meta! #'conj assoc :macro false) |
| 20:10 | amalloy | huh. i thought we fixed that |
| 20:10 | clojurebot | {:macro false, :ns #<Namespace clojure.core>, :name conj, :file "clojure/core.clj", :line 71, :arglists ([coll x] [coll x & xs]), :doc "conj[oin]. Returns a new collection with the xs\n 'added'. (... |
| 20:10 | TimMc | You did. I unfixed it in privmgs. |
| 20:10 | TimMc | *privmsg |
| 20:10 | amalloy | okay, that's what i guessed |
| 20:10 | TimMc | Turns out there isn't one sandbox per channel/query. That's good to know. |
| 20:11 | amalloy | yeah. it's expensive to run a lot of sandboxes |
| 20:11 | gfrlog | how does this sandboxing get done? is it a JVM feature? |
| 20:12 | amalloy | gfrlog: the jvm sandbox is one facet |
| 20:12 | amalloy | clojail is the library behind sexpbot's sandboxing |
| 20:12 | gfrlog | $google jvm sandbox |
| 20:12 | sexpbot | First out of 7900 results is: Java's security architecture - JavaWorld |
| 20:12 | sexpbot | http://www.javaworld.com/javaworld/jw-08-1997/jw-08-hood.html |
| 20:13 | gfrlog | I might find this useful actually... |
| 20:13 | amac | ,(map println "abc") |
| 20:13 | clojurebot | a |
| 20:13 | clojurebot | b |
| 20:13 | clojurebot | c |
| 20:13 | clojurebot | (nil nil nil) |
| 20:14 | amalloy | &(map println "abc") |
| 20:14 | sexpbot | ⟹ (abnil cnil nil) |
| 20:14 | TimMc | hah! |
| 20:14 | amac | hmm... my repl mangles the output of the side effect prints and the return nils |
| 20:14 | amalloy | haha, i knew the result would be different but i didn't think it would be that |
| 20:15 | amac | yay, I broke something! |
| 20:15 | gfrlog | sexpbot: that wasn't very sexp |
| 20:15 | amac | clojurebot actually handles that pretty gracefully |
| 20:16 | TimMc | &(first (doall (map println "abc"))) |
| 20:16 | sexpbot | ⟹ a b c nil |
| 20:16 | TimMc | &(map println "abc") |
| 20:16 | sexpbot | ⟹ (abnil cnil nil) |
| 20:16 | TimMc | &(first (map println "abc")) |
| 20:16 | sexpbot | ⟹ a nil |
| 20:16 | amac | sexpbot's output is what I get at my (slime/swank) repl |
| 20:17 | TimMc | amac: That exact string? |
| 20:17 | amac | yeah, but with linebreaks |
| 20:17 | amac | a b nil c nil nil |
| 20:17 | TimMc | ah |
| 20:18 | TimMc | &(map println "abcdef") |
| 20:18 | sexpbot | ⟹ (abnil cnil dnil enil fnil nil) |
| 20:18 | TimMc | Oh, it is actually quite regular. |
| 20:18 | amac | weeeeeird |
| 20:18 | TimMc | I mean, I see what it is doing. |
| 20:18 | amalloy | TimMc: the behavior there is certainly my fault, though i don't know exactly how :P |
| 20:18 | gfrlog | I think it makes sense... |
| 20:18 | amac | actuall, not that weird |
| 20:19 | amac | just return a's nil last |
| 20:19 | gfrlog | ##(println "What's the diff between & and ##?") |
| 20:19 | gfrlog | that must be the difference |
| 20:19 | gfrlog | one works and the other doesn't |
| 20:19 | TimMc | &((constantly "") (map println "abcdef")) |
| 20:19 | sexpbot | ⟹ "" |
| 20:20 | gfrlog | lazy |
| 20:20 | amalloy | gfrlog: the ## at the end is messing up the regex |
| 20:20 | amalloy | ##(println "What's the diff between & and the other thing?") |
| 20:20 | sexpbot | ⟹ What's the diff between & and the other thing? nil |
| 20:20 | gfrlog | &((constantly "") (doall (map println "abcdef")) |
| 20:20 | sexpbot | java.lang.Exception: EOF while reading |
| 20:20 | TimMc | OK, there goes that theory... I figured map would eagerly compute the first value. |
| 20:20 | gfrlog | &((constantly "") (doall (map println "abcdef"))) |
| 20:20 | sexpbot | ⟹ a b c d e f "" |
| 20:20 | amalloy | the difference is that things like ##((constantly 'this)) work mid-string |
| 20:20 | sexpbot | ⟹ this |
| 20:21 | gfrlog | amalloy: so what's ## for? |
| 20:21 | gfrlog | oh |
| 20:21 | gfrlog | you just told me |
| 20:21 | amalloy | indeed i did |
| 20:21 | gfrlog | you were sitting there waiting for me to see it weren't you? |
| 20:21 | amalloy | it is an activity i have grown to enjoy |
| 20:21 | gfrlog | with me or with people? |
| 20:22 | amalloy | well, i meant you |
| 20:22 | amac | amalloy: that's nifty |
| 20:22 | amalloy | ## was one of my first contributions to sexpbot |
| 20:22 | gfrlog | why does the regex mess up my original string? |
| 20:23 | amac | tries to parse the end of the print statement as another expr |
| 20:23 | amalloy | righto |
| 20:23 | gfrlog | I'd like to see the regex |
| 20:23 | amalloy | gfrlog: no you wouldn't :P |
| 20:23 | amalloy | it's horrible |
| 20:23 | amac | hahaha |
| 20:23 | amac | there's no such thing as a nice regex |
| 20:24 | gfrlog | couldn't you just use (read-string) or some such thing after any "##"? |
| 20:24 | amalloy | "##(([^#]|#(?!#))+)\s*((##)?(?=.*##)|$)" |
| 20:24 | gfrlog | ,(doc read-string) |
| 20:24 | spewn | That's hardly horrible... |
| 20:24 | clojurebot | "([s]); Reads one object from the string s" |
| 20:24 | amalloy | gfrlog: that would probably be best |
| 20:24 | amalloy | but i wanted to make it possible to end a ## section with another ## and go back to talking normally |
| 20:25 | gfrlog | that would take care of the nested parentheses that regular expressions are not powerful enough for... |
| 20:25 | amalloy | gfrlog: it does use read-string eventually |
| 20:25 | gfrlog | so that's why it ##'ignores what's after the first ## but before another |
| 20:25 | sexpbot | ⟹ ignores |
| 20:26 | amalloy | if you commit an improvement to use read-string more sensible i'll pull it in :P |
| 20:26 | gfrlog | okay, which file was that in? |
| 20:26 | amalloy | gfrlog: the regex is in .sexpbot/info.clj |
| 20:26 | amalloy | it gets used in src/sexpbot/plugins/clojure.clj |
| 20:26 | TimMc | How does git collaboration via pull work anyway? Do I just fork, commit, push, and make a pull request? |
| 20:26 | amalloy | TimMc: yep |
| 20:27 | amac | I'm really curious how clojurebot is getting proper formatting on that ugly map |
| 20:27 | gfrlog | I've done that once and got rebuked for it |
| 20:27 | amalloy | clojurebot: source? |
| 20:27 | clojurebot | source is http://github.com/hiredman/clojurebot/tree/master |
| 20:27 | TimMc | And the recipient chooses which branch to target? |
| 20:27 | amalloy | TimMc: yeah |
| 20:27 | TimMc | That's not very scary at all! |
| 20:27 | amalloy | gfrlog: well, you might want to see whether the owner is looking for collaborations, but it seems weird for anyone to get annoyed about a pull request |
| 20:28 | gfrlog | amalloy: I was fixing a typo in a doc; owner said pull request was too much trouble for such a thing and I should send him a message |
| 20:28 | amalloy | eg clojure.core doesn't accept pull requests if you haven't signed a contributor agreement, but i can't see anyone being mad about it |
| 20:28 | amalloy | gfrlog: he's just dumb. pull requests are mad simple |
| 20:28 | gfrlog | yeah we hate him |
| 20:29 | amalloy | if you want to go egg his house or something, sign me up |
| 20:29 | gfrlog | just realized he's the owner of a prominent clojure project that I like |
| 20:30 | amalloy | haha |
| 20:30 | amalloy | well don't tell me who |
| 20:30 | gfrlog | nope |
| 20:30 | gfrlog | I'm too grownup for that |
| 20:30 | gfrlog | not grownup enough to have forgotten it by now |
| 20:31 | gfrlog | I'll quote his message though: "Its far easier for me just to add the missing char then to pull your branch, merge it, repush etc. For larger patches, pulls are preferred." |
| 20:33 | TimMc | Urgh, I don't want to print out a form, fill it out, and mail it. |
| 20:33 | gfrlog | TimMc: and that's why I'm not a contributor either |
| 20:33 | amalloy | TimMc: yeah, it's a pain, but c'est la vie. i sent mine in eventually |
| 20:33 | amac | like... on paper? |
| 20:33 | amac | how passe |
| 20:34 | TimMc | amac: and a stamp and everything! |
| 20:34 | gfrlog | I don't own a printer, a pen, or a postal service |
| 20:34 | TimMc | amac: You even have to write out your email address longhand! |
| 20:34 | gfrlog | in cursive |
| 20:34 | amac | that just seems so... wrong |
| 20:34 | gfrlog | I've long forgotten how to do a cursive '@' |
| 20:35 | amalloy | gfrlog: they probably teach that in elementary schools now |
| 20:35 | amac | wonder why its not an online form, I'm fairly sure its still legally binding |
| 20:35 | amalloy | the internet makes the @ so much more important |
| 20:36 | gfrlog | amalloy: my son ain't lurnin no at-sine |
| 20:36 | amalloy | amac: rich is a closet luddite |
| 20:36 | amac | hahahaha |
| 20:37 | TimMc | Or his attorney is. :-) |
| 20:37 | gfrlog | he writes code with a hammock instead of a build tool |
| 20:38 | gfrlog | amalloy: does the ## apply to all of sexpbot, or just the clojure plugin? |
| 20:38 | amalloy | just clojure |
| 20:38 | amalloy | TimMc: good luck with that |
| 20:39 | amalloy | gfrlog: there's an "embed" plugin that's supposed to allow something like $#command#$ but i don't think it works |
| 20:40 | amac | &(battle 'clojurebot) |
| 20:40 | sexpbot | java.lang.Exception: Unable to resolve symbol: battle in this context |
| 20:40 | gfrlog | I think I'm finding it |
| 20:40 | gfrlog | amalloy: This whole repo has plenty of test coverage, right? |
| 20:40 | amalloy | hahaha |
| 20:40 | amalloy | no not at all |
| 20:41 | amalloy | clojail has decent testing because it might actually be bad if that broke |
| 20:41 | amac | ,(kill 'sexpbot) |
| 20:41 | clojurebot | java.lang.Exception: Unable to resolve symbol: kill in this context |
| 20:41 | amalloy | but i wrote all of those tests, and Raynes is too lazy to write any for sexpbot |
| 20:41 | gfrlog | clojail doesn't have any mechanism for loading code in a sandboxed way does it? |
| 20:41 | amac | one of these days they'll start fighting, I know it |
| 20:41 | amalloy | gfrlog: that's practically what clojail *is* |
| 20:42 | gfrlog | amalloy: I don't mean just evalling, I mean vars and namespaces and all |
| 20:42 | amac | TimMc: funny enough, no one would probably notice |
| 20:42 | amac | :) |
| 20:42 | gfrlog | e.g., two sandboxed threads with two different root bindings for the same var |
| 20:43 | amalloy | gfrlog: no, but you can start another clojail process from the command line :P |
| 20:44 | gfrlog | I wonder if rebinding def would be an effective way of doing it... |
| 20:44 | amalloy | def is a special form |
| 20:44 | gfrlog | dackbutton |
| 20:44 | gfrlog | it's not *that* special |
| 20:45 | gfrlog | ,(let [def 12] (+ 5 def 83 3)) |
| 20:45 | clojurebot | DENIED |
| 20:45 | gfrlog | &&(let [def 12] (+ 5 def)) |
| 20:45 | sexpbot | java.lang.Exception: Unable to resolve symbol: & in this context |
| 20:45 | gfrlog | &(let [def 12] (+ 5 def)) |
| 20:45 | sexpbot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 20:45 | gfrlog | I suck at bots |
| 20:45 | amalloy | &(let [if 10 do 20] (do if)) |
| 20:45 | sexpbot | ⟹ 10 |
| 20:46 | gfrlog | you've done that before |
| 20:47 | TimMc | &(let [a 4 def 5] (+ a def)) |
| 20:47 | sexpbot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 20:47 | amalloy | gfrlog: and yet, every time it's still funny |
| 20:47 | gfrlog | amalloy: that's exactly the point I was making |
| 20:49 | TimMc | I find the patents section of the CCA unreadable. |
| 20:49 | TimMc | Also, is "Clojure" the project name? |
| 20:49 | amalloy | yeah |
| 20:50 | TimMc | And I use my GitHub username? |
| 20:50 | TimMc | Maybe I will remember to print this at school on Monday. |
| 20:51 | amac | I find most legalese unreadable |
| 20:51 | amalloy | i thought the CA was pretty readable |
| 20:51 | amac | my brain can't be bothered to parse that shit, I just stare at the paper |
| 20:51 | TimMc | I'm pretty good at reading legalese, but I'm unsure of how to interpret "with respect to" in 3. |
| 20:52 | TimMc | Needs parens. |
| 21:13 | gfrlog | $google polyomino tiler |
| 21:13 | sexpbot | First out of 1850 results is: Sandbox: Polyomino Tiler |
| 21:13 | sexpbot | http://gfredericks.com/sandbox/polyominoes |
| 21:15 | amac | gfrlog: that's pretty neat |
| 21:17 | amac | gfrlog: what algorithm does it use for packing? |
| 21:19 | gfrlog | oh |
| 21:19 | gfrlog | um |
| 21:19 | gfrlog | lessee |
| 21:20 | gfrlog | it tries everything by backtracking; just about all of the algorithmic details are how it chooses which square to try to tile next |
| 21:21 | amac | been a while since i've looked at knapsack/bin packing algorithms... something I should brush up on |
| 21:21 | gfrlog | every step of the algorithm is displayed visually |
| 21:21 | gfrlog | I just did it as a bipartite graph, by pre-generating all possible placements |
| 21:22 | gfrlog | not feasible for real big grids, but works for this |
| 21:22 | gfrlog | it's much easier after that too, because I didn't have to think about directions or squares anymore; just graph algorithms |
| 21:23 | amac | do you memoize some common open paterns to fill? |
| 21:24 | gfrlog | no; I've thought of that; more I've thought of memoizing unfillable spaces |
| 21:24 | amac | would probably speed things up considerably |
| 21:24 | gfrlog | maybe |
| 21:25 | gfrlog | there would be a lot of combinations.... |
| 21:25 | gfrlog | have to be careful about memory |
| 21:25 | amac | true, but easy to address if you keep the common fillable/unfillable spaces small |
| 21:25 | amac | then just stack those together to get approximate fillings, then backtrace the rest |
| 21:26 | gfrlog | I'm skeptical...I think there's more promise in looking at the parity of different pieces |
| 21:26 | gfrlog | at least in certain situations |
| 21:27 | gfrlog | how would you generate these common fillable spaces? |
| 21:29 | amac | generate a bunch of randomly populated maps and parse out the open spaces, sort by the number of times the patterns appear in your dataset, then run your packer on them and label them as fillable/unfillable |
| 21:30 | gfrlog | oh, are you using the "Random Grid" button? |
| 21:30 | amac | I filled mine in by hand |
| 21:31 | amac | but randomizing the grid would give you a set of commonly occuring patterns |
| 21:31 | gfrlog | I guess I'm thinking that the 'common spaces' wouldn't come up very often |
| 21:31 | gfrlog | and they'd be specific to a set of polyominoes |
| 21:32 | gfrlog | so just by that any kind of pre-generation of the data would be implausible |
| 21:32 | amac | I guess it depends on how big the empty spaces are |
| 21:32 | gfrlog | since the app allows any arbitrary set of polyominoes |
| 21:32 | amac | ...there's a reason this is np-hard ;) |
| 21:32 | gfrlog | is it? |
| 21:32 | amac | yeah, I'm fairly sure |
| 21:33 | gfrlog | of course NP-hard is just worst case |
| 21:33 | gfrlog | the algorithm works quite well in a lot of cases |
| 21:33 | amalloy | i don't remember who was asking about this a while ago, but apparently clojure.lang.Compiler/specials is a map of all the compiler-level special forms |
| 21:34 | gfrlog | ,clojure.lang.Compiler/specials |
| 21:34 | clojurebot | {deftype* #<DeftypeParser clojure.lang.Compiler$NewInstanceExpr$DeftypeParser@257ce0>, new #<Parser clojure.lang.Compiler$NewExpr$Parser@1bf0f5b>, quote #<Parser clojure.lang.Compiler$ConstantExpr$Pa... |
| 21:34 | gfrlog | ,(keys clojure.lang.Compiler./specials) |
| 21:34 | clojurebot | java.lang.ClassNotFoundException: clojure.lang.Compiler. |
| 21:34 | amac | tell me more, clojurebot! |
| 21:34 | amalloy | gfrlog: c'mon, remember the gisting |
| 21:34 | amalloy | &clojure.lang.Compiler/specials |
| 21:34 | sexpbot | ⟹ {deftype* #<DeftypeParser clojure.lang.Compiler$NewInstanceExpr$DeftypeParser@1676e67>, new #<Parser clojure.lang.Compiler$NewExpr$Parser@1822dc7>, quote #<Parser clojure.lang.Compiler$ConstantExpr$Parser@e417de>, & nil, var #<Parser clojure.lang.Compiler$TheVarExpr$... http://gist.github.com/856970 |
| 21:35 | gfrlog | amalloy: I'm an old man. I've been using clojurebot for most of my life. I can't just switch because it's a good idea. |
| 21:35 | amac | haha |
| 21:36 | amac | also, commas are much sexier punctuation |
| 21:36 | gfrlog | ,(keys clojure.lang.Compiler/specials) |
| 21:36 | clojurebot | (deftype* new quote & var set! monitor-enter recur . case* ...) |
| 21:36 | gfrlog | augh |
| 21:36 | amalloy | BAM! |
| 21:36 | gfrlog | YOU SHOT CLOJUREBOT |
| 21:36 | gfrlog | somebody take his gun |
| 21:38 | TimMc | Why is one of my sexprs in Emacs suddenly bright red? |
| 21:38 | clojurebot | emacs is best configured for Clojure with instructions at http://technomancy.us/126 |
| 21:38 | amalloy | TimMc: it's embarrassed |
| 21:39 | gfrlog | amac: I'm about to rewrite that algorithm in clojure, sorta |
| 21:39 | amac | gfrlog: pastebin it |
| 21:40 | amac | :) |
| 21:40 | gfrlog | amac: in a month or two, sure |
| 21:40 | TimMc | It compiles, though. |
| 21:41 | gfrlog | ,(println "&(println \"Hey clojurebot\")") |
| 21:41 | clojurebot | &(println "Hey clojurebot") |
| 21:41 | sexpbot | ⟹ Hey clojurebot nil |
| 21:42 | gfrlog | oh now I need to look up how to do quines in clojure |
| 21:42 | amalloy | gfrlog: you won't be able to make it work |
| 21:42 | amac | holy shit they're talking to each other! |
| 21:42 | gfrlog | amalloy: why not? |
| 21:42 | gfrlog | I'll have to invent some kind of trampoline-quine... |
| 21:43 | TimMc | amalloy: Eli got a loop going between several bots in #scheme at one point. |
| 21:43 | amalloy | irc doesn't send you back your own messages, so you can't self-quine. you can't co-quine because sexpbot prefaces everything with ⟹ |
| 21:43 | amac | ok, we've gotta do this |
| 21:43 | amac | and let them fight to the death |
| 21:44 | TimMc | amalloy: And the bots ignore each other, right? Right? |
| 21:44 | amalloy | TimMc: of course not. didn't you just see the counterexample? |
| 21:44 | gfrlog | &(println ",(println \"Hey sexpboty\")") |
| 21:44 | sexpbot | ⟹ ,(println "Hey sexpboty") nil |
| 21:44 | gfrlog | get hiredman to add ## to clojurebot |
| 21:44 | TimMc | amalloy: Oh! Misread. |
| 21:45 | amalloy | heh |
| 21:45 | gfrlog | does sexpbot preface for ##(println "as well?") |
| 21:45 | sexpbot | ⟹ as well? nil |
| 21:45 | gfrlog | dorn |
| 21:45 | gfrlog | s/o/a |
| 21:45 | sexpbot | <gfrlog> darn |
| 21:46 | amalloy | clojurebot might actually have sexpbot on ignore anyway |
| 21:46 | amalloy | $login |
| 21:46 | sexpbot | You've been logged in. |
| 21:46 | amalloy | $say #clojure ,1 |
| 21:46 | sexpbot | ,1 |
| 21:46 | clojurebot | 1 |
| 21:46 | amalloy | $logout |
| 21:46 | sexpbot | You've been logged out. |
| 21:46 | gfrlog | holy crap it's like he just stepped through a wall or something |
| 21:47 | amalloy | ? |
| 21:47 | gfrlog | your $login trick |
| 21:47 | gfrlog | it was very sexp |
| 21:47 | amalloy | *chuckle* |
| 21:47 | amac | &(println ",(+ 1 2)") |
| 21:47 | sexpbot | ⟹ ,(+ 1 2) nil |
| 21:48 | amac | stupid arrow |
| 21:48 | gfrlog | log back in and turn off the arrow |
| 21:48 | amalloy | gfrlog: that's actually hardcoded |
| 21:48 | gfrlog | everything is dynamic at runtime |
| 21:48 | gfrlog | rebind some vars, come on! |
| 21:48 | TimMc | gfrlog: Ha! |
| 21:48 | TimMc | $say $clojure hello |
| 21:48 | sexpbot | TimMc: It is not the case that you don't not unhave insufficient privileges to do this. |
| 21:49 | TimMc | Ah, OK. |
| 21:49 | TimMc | And I mistyped anyway. |
| 21:49 | amalloy_ | $login |
| 21:49 | amac | lol |
| 21:49 | gfrlog | had to try |
| 21:49 | amalloy | gfrlog: wouldn't work even if i let you have my nick |
| 21:49 | amalloy | you'd need my IP too |
| 21:50 | amac | that can be spoofed, as long as the response isn't necessary |
| 21:50 | amalloy | amac: yeah |
| 21:50 | gfrlog | which it isn't... |
| 21:51 | gfrlog | well |
| 21:51 | gfrlog | maybe it is who knows |
| 21:51 | amac | probably not |
| 21:51 | amalloy | probly not |
| 21:51 | gfrlog | dang layers upon layers of networking protocols |
| 21:51 | gfrlog | doesn't it use TCP? |
| 21:51 | gfrlog | 3-step handshake? |
| 21:52 | TimMc | You can spoof a single packet, and that's about it. |
| 21:52 | gfrlog | come on guys, it's completely inconceivable that anybody could be writing clojure code and not have come up through a normal CS department with a required networking course, right? |
| 21:53 | amac | you underestimate my ability to skip class |
| 21:53 | gfrlog | hmm |
| 21:53 | gfrlog | I think I was making a joke rather than a point |
| 21:53 | amalloy | yeah, but it sounded like a joke about your inability to get a point across |
| 21:53 | gfrlog | I'm not very good at jokes |
| 21:54 | gfrlog | I take a shotgun approach |
| 21:54 | TimMc | brb, need to pour alginate on my housemate |
| 21:55 | amac | TimMc: don't we all. |
| 22:07 | TimMc | sexpbot: commands? |
| 22:07 | TimMc | Bah, nevermind. |
| 22:07 | TimMc | It's in my history, |
| 22:08 | amalloy | speaking of which, if anyone wants to get their feet wet writing for sexpbot, he could use a commands? function :P |
| 22:08 | amac | &(learn 'commands) |
| 22:08 | sexpbot | java.lang.Exception: Unable to resolve symbol: learn in this context |
| 22:08 | amac | I tried |
| 22:10 | amalloy | good effort |
| 22:11 | TimMc | sexpbot: mail clojurebot ,1 |
| 22:11 | sexpbot | Message saved. |
| 22:11 | TimMc | clojurebot: hi |
| 22:11 | clojurebot | I don't understand. |
| 22:11 | amalloy | TimMc: interesting attack vector |
| 22:11 | TimMc | Does it use privmsg? |
| 22:11 | amalloy | yeah |
| 22:12 | TimMc | bah |
| 22:12 | TimMc | Also, switching to visual bell. These speakers are turned up too high. >_< |
| 22:13 | TimMc | amalloy: I've also considering using the title of a dynamic page on a site I control. |
| 22:15 | TimMc | clojurebot: ,(println "s/I/,'") |
| 22:15 | clojurebot | ,(println "clojure bot is the best!") |
| 22:15 | TimMc | what |
| 22:15 | amalloy | *blink* |
| 22:16 | amac | it's... alive |
| 22:16 | amalloy | oh |
| 22:16 | TimMc | what the shit |
| 22:16 | amalloy | comma only triggers eval if it's the very first char |
| 22:16 | amalloy | this was his canned response to some factoid |
| 22:17 | amac | doesn't he also just respond randomly to a small percentage of messages? |
| 22:18 | amac | clojurebot: ,(println "s/I,'") |
| 22:18 | clojurebot | ,(println "clojure is the best") |
| 22:18 | amac | scratch that, its reproducable |
| 22:19 | amac | er, almost |
| 22:20 | spewn | clojurebot: println |
| 22:20 | clojurebot | ,(println "clojure bot is the best!") |
| 22:21 | TimMc | clojurebot: setup |
| 22:21 | clojurebot | simple setup is http://www.thelastcitadel.com/dirt-simple-clojure |
| 22:21 | TimMc | ,(println "s/.*/,1") |
| 22:21 | clojurebot | s/.*/,1 |
| 22:21 | sexpbot | <clojurebot> ,1,1 |
| 22:22 | TimMc | Oh, right. |
| 22:35 | amac | ,(do (println "#*(println \"stuck\"") (println "s/*/#)) |
| 22:35 | clojurebot | EOF while reading string |
| 22:38 | amac | ,(do (println "#*(println \"stuck\")") (println "s/*/#")) |
| 22:38 | clojurebot | #*(println "stuck") |
| 22:38 | clojurebot | s/*/# |
| 22:39 | spewn | Turns out that double replacement there is not a bug in sexpbot. |
| 22:40 | spewn | ,(.replaceAll "foobar" ".*" "baz") |
| 22:40 | clojurebot | "bazbaz" |
| 22:40 | spewn | Does that look weird to anyone else? |
| 22:41 | johnmn3 | were you expecting "baz" ? |
| 22:41 | spewn | I was. |
| 22:42 | spewn | ,(.replaceAll "foobar" "^.*" "baz") |
| 22:42 | clojurebot | "baz" |
| 22:42 | mec | thats really weird |
| 22:42 | spewn | I would expect .* to match the entire string regardless of the anchor there. |
| 22:42 | johnmn3 | I dunno. "All" might seem strange otherwise |
| 22:43 | spewn | ,(.replaceFirst "foobar" ".*" "baz") |
| 22:43 | clojurebot | "baz" |
| 22:43 | spewn | What's the second? |
| 22:44 | johnmn3 | hmm. * grabs the whole string that time |
| 22:44 | spewn | As it always should. |
| 22:45 | spewn | ,(.replaceAll "foobar" ".*?" "baz") |
| 22:45 | clojurebot | "bazfbazobazobazbbazabazrbaz" |
| 22:45 | spewn | Nongreedy finds all zero-width spots, I see. |
| 22:51 | amalloy | .* matches the whole string once, and then the zero-width spot after the end of the string |
| 22:52 | amalloy | youcould use .+ |
| 22:54 | dfan | Is there a way to do quot and rem simultaneously? |
| 22:54 | amalloy | juxt |
| 22:54 | amalloy | &((juxt quot rem) 10 3) |
| 22:54 | sexpbot | ⟹ [3 1] |
| 22:55 | dfan | OK, but that doesn't actually save any time, right? |
| 22:55 | amalloy | right |
| 22:55 | dfan | OK, thanks |
| 22:56 | TimMc | The JVM might not provide a divmod operator. |
| 22:56 | TimMc | (even though it is available on most ISAs) |
| 22:58 | spewn | amalloy: It looks to me like it's the zero-width spot at the beginning that gets matched as well as the entire string, since the behaviour changes with ^.* |
| 22:58 | spewn | But why? |
| 22:59 | amalloy | spewn: huh? ^ would change my imagined behavior too |
| 22:59 | amalloy | &(re-seq #".*" "test") |
| 22:59 | sexpbot | ⟹ ("test" "") |
| 22:59 | spewn | Oh, silly of me. Of course it would. |
| 22:59 | TimMc | I consider it broken. |
| 22:59 | amalloy | and arguably wouldn't change yours |
| 23:00 | amalloy | TimMc: then you're not thinking hard enough. this is exactly the behavior you can derive from the definition of * |
| 23:00 | TimMc | Isn't * greedy by default? |
| 23:00 | amalloy | uh huh... |
| 23:02 | TimMc | What am I missing? |
| 23:02 | TimMc | I use regex *all the time*. |
| 23:03 | TimMc | ,(.replaceAll "foobar" ".*" "12") |
| 23:03 | clojurebot | "1212" |
| 23:03 | spewn | TimMc: .* matches up until the last character, but does not include the zero-width spot after the last character. Then .* matches the zero-width spot after the last character. |
| 23:04 | TimMc | That's... |
| 23:05 | TimMc | OK, I think I can accept that. Maybe. |
| 23:05 | spewn | Assuming my understanding so far is correct, I guess what I'm confused about is why the first match doesn't match the zero-width spot at the end. I suppose it's because it stops looking when it runs out of characters. |
| 23:05 | TimMc | I suppose the semantics for replace are tricky. |
| 23:05 | TimMc | Replace involves restarting the matching, but match doesn't. |
| 23:06 | TimMc | s/.+/s\/.+\/,1\// |
| 23:07 | TimMc | ,(use '[clojure.contrib.bot-quine]) |
| 23:07 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/bot_quine__init.class or clojure/contrib/bot_quine.clj on classpath: |
| 23:14 | TimMc | It does? |
| 23:15 | TimMc | Ah, nvm. |
| 23:15 | amalloy | and i even recently went through some gyrations to create an unhygenic macro on purpose. even so, i'm glad it's hard :P |
| 23:17 | joshua___ | thunk, your a fellow clojurian! Excellent! |
| 23:17 | thunk | Ahoy! I mostly lurk here |
| 23:17 | amac | everyone mostly lurks here |
| 23:18 | amac | :) |
| 23:19 | TimMc | Can the core collections be safely serialized and restored? |
| 23:21 | amalloy | TimMc: pr, read-string? |
| 23:21 | TimMc | pr... nice |
| 23:23 | amalloy | indeed, it's clever enough that if it were my original idea i'd be proud of it |
| 23:23 | amac | ,(doc pr) |
| 23:23 | clojurebot | "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print i... |
| 23:24 | amac | handy. |
| 23:25 | TimMc | amalloy: ...but it won't work here. There are Java objects in the collection. |
| 23:25 | amalloy | print-dup |
| 23:25 | TimMc | No docstring! |
| 23:25 | amac | ,(doc print-dup) |
| 23:25 | clojurebot | "; " |
| 23:25 | amac | booooooo |
| 23:26 | amac | ,(source print-dup) |
| 23:26 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 23:26 | amalloy | if the java classes you'll need to deal with are a closed set, you can implement print-dup for them |
| 23:26 | amalloy | it's a multimethod for printing readable strings |
| 23:26 | TimMc | Oh, sweet. |
| 23:27 | TimMc | Is there a read-dup? |
| 23:27 | TimMc | (There isn't by that name.) |
| 23:27 | amalloy | TimMc: it's called read-string |
| 23:27 | amalloy | &(print-dup *ns*) |
| 23:27 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$fn--3893$fn |
| 23:27 | amalloy | &(print-dup *out* *ns*) |
| 23:27 | sexpbot | java.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class java.io.StringWriter |
| 23:27 | amalloy | &(print-dup *ns* *out*) |
| 23:27 | sexpbot | ⟹ #=(find-ns sandbox11264)nil |
| 23:28 | TimMc | So, I should print the Java objects as calls to their constructors? |
| 23:28 | amalloy | yeah |
| 23:28 | TimMc | Nice. |
| 23:28 | amalloy | TimMc: when the compiler sees a #=(...) form it evaluates the code and uses it in place of the original #= form |
| 23:29 | amalloy | the bots don't allow it, but try it in your repl |
| 23:30 | TimMc | I'm entirely sure that is not documented on http://clojure.org/reader |
| 23:30 | amalloy | yeah, it's hard to find |
| 23:30 | amalloy | $google clojure print-dup |
| 23:30 | sexpbot | First out of 1150 results is: Serializing Clojure data structures - Lisp - Snipplr Social ... |
| 23:30 | sexpbot | http://snipplr.com/view/13559/serializing-clojure-data-structures/ |
| 23:39 | TimMc | whee |
| 23:45 | skelternet | (doc print-dup) gave me a bunch o'nils |
| 23:45 | clojurebot | "; " |
| 23:46 | TimMc | skelternet: It's a multimethod you implement. Check the source. :-/ |
| 23:47 | amalloy | you're not a real OSS developer until you tell someone to read the source :P |
| 23:47 | TimMc | I said it with a chagrined emoticon! |
| 23:48 | amalloy | i don't think that makes it unhappen |
| 23:48 | amalloy | i'm sorry TimMc, there's just no avoiding it...you're a nerd now |
| 23:48 | TimMc | Haw, that happened a while ago. |
| 23:49 | skelternet | The ability to "serialize" a clojure data (sequence?) directly, and load it later, in clojure syntax, instead of using json, xml, is of interest to me. |
| 23:50 | amalloy | skelternet: i'd say structure instead of sequence, just because it's more generic |
| 23:51 | amalloy | but yeah, that's one of lisp's strengths |
| 23:52 | skelternet | it seems under-represented |
| 23:52 | amalloy | skelternet: it's a direct consequence of the syntax being so minimal |
| 23:52 | skelternet | or I'm not googling for the right things |
| 23:52 | amalloy | heh |
| 23:53 | amalloy | dang, i have a favorite article about this subject but i can't remember where it is |
| 23:53 | skelternet | I'd love to read it |
| 23:54 | TimMc | amalloy: Happen to know offhand if the Clojure reader supports circular data structures using the sharp syntax? |
| 23:54 | TimMc | #3#, etc. |
| 23:54 | amalloy | TimMc: yes; no |
| 23:55 | TimMc | OK |
| 23:55 | amalloy | aha! skelternet: http://www.defmacro.org/ramblings/lisp.html |
| 23:56 | amalloy | it's only somewhat topical but still interesting |
| 23:57 | skelternet | thank you! |
| 23:57 | amalloy | it's really hard to google for "sexprs are like xml but not awful" |
| 23:57 | amalloy | because pretty much everyone says that |
| 23:57 | skelternet | :) |
| 23:59 | pdk | nah |
| 23:59 | pdk | i think they just say the xml is awful part |
| 23:59 | pdk | at least outside of our little circles |
| 23:59 | amalloy | pdk: outside our little circles everyone says xml is awesome |