#clojure logs

2011-03-05

00:50amalloyhm. i wind up defining a lot of functions that are basically just (defn foo "docs" [args] (f1 (f2 (f3 args))))
00:51amalloyi 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:51pdkdude
00:52pdk(apply (comp f1 f2 f3) args)
00:52amalloypdk: what's your point?
00:52amalloyshould the caller do that instead of my function ever existing, or should i write that in the body of my defn?
00:53pdkthough 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:53amalloythe former is clearly silly imo, and the latter is nonoptimal if args is a long list
01:01amalloyhuh. despite having recently helped someone with this in #clojure, i can't seem to get a macro to def something with specific metadata
01:23amalloypdk: 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:38tomojseems like it's specific to def
01:38tomojtake (defmacro notdefcomp [name args] (with-meta name {:arglists (list args)}))
01:38tomojsame thing, really, no errors
01:39tomojerr.. not the same thing. but I'd have guessed the error would show up in both or neither
01:44iwillighi, i can't seem to figure this out. But I have an Java class that I want to extend to implement ISeq
01:44iwilligdoes any one have any pointers ?
01:45tomojyeah, stack trace from DefExpr suggests compiler weirdness
01:45tomojdamn you for puzzling me
01:46iwilligthis is my start
01:46iwillighttps://gist.github.com/856189
01:46tomojhmm, maybe not that puzzling
01:46tomoj(do (def xyz "foo") (def ^xyz bar 3) (meta #'bar))
01:47tomojnah, I'm still puzzled
01:47tomojiwillig: ISeq is an interface, I think you're out of luck
01:48iwilligmmm
01:48tomojthis is why protocols were invented :)
01:48tomojunfortunately until cinc the expression problem remains in clojure's core
01:49iwilligso there is no way to extend an Java type to take advantage of clojure seq libraries
01:49iwilligha
01:50iwilligi guess i could use reify
01:50iwilligerr i mean proxy
01:50tomojwhy do you want points to be seqs anyway?
01:50iwilligbut that does not really solve my issue
01:50iwilliggood question
01:51iwilligi think it makes things a lot easier
01:51iwilligso with an Point object is not such a big deal
01:52tomojmaybe work with vectors and convert to Points at your clojure-java bridge?
01:52tomojand vice-verso
01:52iwilligbrb
01:54amalloytomoj: yeah, i would have guessed the same
01:55amalloyin fact i tried (list args) first; i imagine i could have written (list 'quote (list args)) or something but `' seemed clearer
01:55tomojmy example was just a short way to cause the error
01:55tomoj(or not)
01:57tomojbut let's see
01:57tomojyour macro is expanding to, say (def foo ...)
01:57tomojand the metadata is already on foo
01:58tomojnope, thought I made sense of it again, but I keep coming back to: it's just a damn list
01:58amalloytomoj: exactly
01:58tomojcoming back to that from: it's the same as (def ^{:arglists [a b c]} foo ..)
01:58amalloyi tried macroexpanding it, and it happily expands to (def foo (comp ...))
01:58tomojbut that looks different to me now
01:59amalloybut for some reason the meta on foo gets evaled when i eval the def
01:59tomoj&(meta (second '(def ^{:arglists ([a b c])} foo)))
01:59sexpbotjava.lang.SecurityException: You tripped the alarm! def is bad!
02:00tomojI need to give up
02:01amalloyyou tripped the alarm! giving up is lame!
02:01tomojif you crack it, let me know - feel like there's a bit of metadata/macro enlightenment involved
02:01tomoj:)
02:01amalloytomoj: i thought i'd cracked it a couple days ago, but what worked then doesn't work now :P
02:02tomojI see something in Compiler.java that seems relevant (DefExpr analyzing the metadata)
02:02tomojbut don't have the patience to try to understand Compiler.java right now
02:02amalloymaybe i'll take my own advice, and put a ;;TODO wtf why does this work
02:02tomojdoes it, though?
02:03tomojwith your version I end up with {:arglists (quote [a b c])} or something like htat
02:03amalloymy version works the way i want it to
02:03tomojooh
02:04amalloyslime gives me arglist prompts, etc
02:04tomoj(meta (second (macroexpand-1 '(defcomp foo "bar" [a b c] inc dec))))
02:04tomojthen it's eval'd to the right thing, I see
02:05tomojI can't help but think again that that is just like you'd have to (def ^{:arglists '[a b c]} foo)
02:05tomojand of course shortly after thinking that I'm just as confused :(
02:05amalloyyes, and that works outside a macro
02:05amalloyif i `(def ^{...} ~name ...) inside the macro, no good
02:09tomojyeah, but
02:09tomojno, nevermind. giving up.
02:10amalloylol
02:10amalloyi felt that way too
02:10tomojI thought I understood metadata and I thought I understood macros
02:10tomojbut together...
02:10amalloyhahahaha
02:11amalloyLearn, Internalize, Surprise, Perplex
02:12tomojiswydt
02:14khaliGhas anyone integrated icanter into their own app?
03:13clojurebotPONG!
03:13clojurebotInvalid token: /3
03:13clojurebot#<core$constantly$fn__3551 clojure.core$constantly$fn__3551@b670cd>
03:13clojurebotc'est bon!
03:13clojurebot42
03:13clojurebotwhat is cells
03:13clojurebotjava.lang.NullPointerException: Expecting Symbol + Namespace
03:13clojurebot42
03:13clojurebotmultimethods is what separates the boys from the men.
03:13Ptivalwow clojurebot speaks French
03:15tomoj:D
03:16tomojI think that was a
03:16tomoj6 hour delay
03:16tomojor so
03:17Ptivalextreme buffering
03:18tomojhiredman: how?!
03:33amalloynice
03:34amalloytomoj: the tubes were all blocked up
03:35amalloy~testing42
03:35clojurebot42
03:35amalloy~botsnack i guess? kinda hard to say
03:35clojurebotthanks; that was delicious. (nom nom nom)
03:35amalloyanyway night folks
03:35amalloytomoj: i put my macro confusion on the google group. we'll see if anyone has ideas
06:56fmwhow do you write something to the extend of 'if foo == "bar" or foo == "foobar"' in clojure? i.e. an if with multiple clauses.
06:56mrBliss,(let [foo "bar"] (if (#{"bar" "foobar"} "bar") 1 2))
06:56clojurebot1
06:57fmwmrBliss: thanks!
06:57mrBliss(don't mind the let clause)
07:02pyrhey
07:42fmwmrBliss: 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:42fmwbasically I'm trying to make http://paste.pocoo.org/show/348413/ more concise
07:42fmwas you can see from that paste, I'm trying to learn Clojure by porting some Python code.
07:43bawrfmw: That's probably not a good idea. Rewriting from scrach, maybe. Porting, not so much. ;)
07:43raekfmw: you can use the or and and not macros to form compound conditions
07:43fmwbawr: In this context I mean rewriting when I say porting ;)
07:44mrBlissfmw: I can see that ;-) In Clojure, one does not use def for local variables. (Gotta grab dinner now)
07:44fmwmrBliss: thanks, I'll read up on the local variables thing :)
07:44raekif 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:44fmwraek: ah, those macros are exactly what I need
07:45__name__fmw: instead of positive-integer?
07:45raekthere's even 'pos?'
07:45raekfmw: you can use let to introduce a named value for a scope: (let [x 1] ...code that uses x...)
07:46bawrraek: Just do be sure, nested defns are okay if they make the code more clear, right? :)
07:46bawrOr is that a schemism?
07:46raekyou can think of it as { int x = 1; ...code that uses x... } in C, only that you can only assign once...
07:46fmwraek: so def for global variables, let for vars in the local scope?
07:47fmwor rather, global to the namespace
07:47raekbawr: no, nested defn probably does not do what you think
07:47raekdef defines a *global* variable
07:47raekunlike define in scheme
07:48raekyou can use private global defn if you want helper functions: (defn- helper-fn [x] ...)
07:48bawrSO something like (defn mangle [x y] (defn mingle [i] (+ i y)) (map mingle x)) is bad?
07:48bawrOooh.
07:48fmwah, so thats what the - after defn is for
07:48raekor you can use let or letfn: (defn f [x] (let [g (fn [y] ...)] (g (inc x))))
07:49fmwseen that in a lot of library functions
07:49raekbawr: yes.
07:49raektwo invokations of the same function will overwrite the other one's sate
07:49raek*state
07:49bawrraek: Hey, thanks.
07:50raeka rule of thumb: a def form should never be executed at runtime
07:50bawrAha, gotcha. I was just looking for a solution cleaner than a towering abomination of adding arguments with partial.
07:51raek(the above example with letfn: (defn f [x] (letfn [(g [y] ...)] (g (inc x))))
07:51fmw__name__: yes, thanks for that line, its a better approach.
07:52raekfmw: also, you usually write just (> n 0) instead of (if (> n 0) true false)
07:54fmwraek: as in leave out the if macro and the parenthesis block after (> n 0) is only evaluated if (> n 0) is true?
07:55fmwraek: hmm, seems like I misunderstood you there, because (> n 0) doesn't work on its own
07:56raek,(let [x 5] (> x 1))
07:56clojurebottrue
07:56raekit is an expression
07:56raekwell, everything is an expression in clojure
07:57raekthe if does not add anything in that case
07:59fmwraek: ok, but you do need if (or a similar macro) if you want to execute something based on the boolean value, right?
07:59fmwjust not to get a boolean?
08:00raekyes
08:00fmwok, that clears it up
08:00fmwBTW, thanks for answering all these silly questions ;)
08:00raekthe special form 'if' lets you control which branch that will be evaluated
08:01raeknp
08:36raekfmw: in clojure you usually structure the code so that each function returns the value of interest, rather changes global variables.
08:36fmwraek: are you the one that just replied to my paste with a better version?
08:37raekhttp://paste.pocoo.org/show/348431/
08:37raekthis one?
08:37fmwyes
08:37raekyes, I was just going to say that I took the liberty
08:37raekof showing what a funcitonal solution might look like
08:37fmwraek: cool, I'm reading it as we speak :)
08:37raekfunctional programming is very different from imperative programming and it takes time to adjust to the thinking
08:38fmwraek: 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:39fmwraek: yes, clearly. it is a very different approach and a good thing to be forced to wrap my head around while learning clojure
08:46fmwraek: 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:46fmwraek: I really appreciate the fact that you took the time to write this
08:46khaliGi'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:48raekfmw: 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:48khaliGi 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:49raekthis video "Clojure Concurrency" explains the rational for the "mutable variables has to go" approach taken by clojure
08:49raekhttp://clojure.blip.tv/file/812787/
08:51fmwraek: 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:51fmwbut the example you wrote sort of make the functional approach click with my brain
08:53fmwok, watching the video now :)
08:58khaliGhm i might just do it by hand using Java 2D, will give me a bit more practice writing clojure anyways
09:06raekkhaliG: I just found this, but I don't know how much it helps: http://clojuredocs.org/incanter/incanter.core/data-table
09:17khaliGraek, oooh that is cool. i'll remember for that later :)
09:18fliebelraek: What are these magic datasets?
09:19raekfliebel: in the pocoo paste?
09:20raekfliebel: also, you mentioned something re my blog post yesterday. was something written in a misleading way?
09:23fliebelraek: poco? No just in general, Incanter seems to be using 'datasets' a lot, I was wondering what they are.
09:24raekI dunno :-) haven't used incanter much
09:24fliebelraek: 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:26raekyeah, agents have two pools and of them (the non-fixed one) is shared with future
09:27fliebelI figured :)
09:42TimMcHaha, I'm glad I checked the scrollback! clojurebot, you so silly.
09:48__name__fmw: np
10:14khaliGhm ive tried close to everything to no avail. How the eck does one instantiate java.awt.geom.Line2D.Double
10:14khaliG(in clojure that is)
10:16khaliGooh got it, it needs a dollar sign :)
10:16raekkhaliG: java.awt.geom.Line2D$Double
10:16raekah, you figured it out...
10:16khaliGraek, thanks
10:21pyrcan't you import java.awt.geom.Line2D Double :as Something ?
10:23TimMcpyr: I wish.
10:23TimMcIt would make working with AffineTransform in hinted code a lot nicer.
10:24pyr'k
10:24pyri thought that would be possible
10:24pyrbut if i get this right
10:24pyrthis is only a real concern for class names which clash with (like some.thing.foo.String or java.awt.geom.Line2D.Double)
10:25pyrs,with,with standard names from java.lang
10:26TimMcpyr: Nota bene: The compiler will sometimes refer to Point2D$Double as Double in error messages.
10:26pyrluckily my clojure stuff relies on very few java libs
10:26pyrbut good to know
10:27TimMcI'm writing a Swing program, so... yeah.
10:48fliebelWhat is the syntax for version ranges in lein/cake?
10:49fliebelhttps://github.com/cgrand/moustache/commit/c2a8adef899f08b0847b1e7feb9d2367efdbbbf7
10:50raekfliebel: same as in maven: http://maven.apache.org/plugins/maven-enforcer-plugin/rules/versionRanges.html
10:50raek"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:50raek"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:51raekfrom the leiningen tutorial
10:51fliebelraek: I understand the implications, just curious.
10:53fliebelraek: It seems that just the version number is already a range? How is that...
10:56bawrWhat 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:58fliebelraek: Using a range is just as bad as using a snapshot, right?
10:59raekI have not used it for my own projects
11:00raekbut I belive version ranges are legitimate to use in stable releases
11:00raekunlike SNAPSHOT dependencies
11:07TimMcMature dependency managers like Firefox and APT use version ranges quite successfully.
11:07CozeyHi! Is there some clojure community favourite alternative to SASS language for generating css?
11:07fliebelCozey: I think someone wrote one, but it's not in wide use, like SASS.
11:08Cozeymhm
11:11fliebelCozey: It's practically just a serialization of a map.
11:12Cozey:-)
11:24gfrlogalgorithms trivia: it's possible to detect an arbitrarily long cycle in an (iterate) seq using constant space
11:24fliebelgfrlog: … how?
11:25gfrlogcreate two seqs, and consume one twice as fast as the other
11:25gfrlogif there's a cycle, they will eventually have identical heads
11:26gfrloglearned that in my crypto class; was part of some factoring algorithm
11:26gfrloga bit of wikipedia clicking reveals: http://en.wikipedia.org/wiki/Floyd's_cycle-finding_algorithm#Tortoise_and_hare
11:27fliebelgfrlog: But, how do you know it is not the same head 'by accident'?
11:27gfrlogfliebel: if they're the same head, that means that head value comes up twice
11:27DespiteItAllfliebel -- it's iterate, so it doesn't matter :)
11:27gfrlogexactly
11:27gfrlogonce you know a value comes up twice, you know it cycles
11:28fliebelgfrlog: But how do you know one cycle does not include the same head twice?
11:28gfrlogif you're iterating with a pure function, that's impossible
11:28fliebelhm…. that is true
11:31fliebelgfrlog: And what about the time? That is everything but constant, but I wouldn't know how to express it.
11:32gfrlogfliebel: 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:32DespiteItAllyou could be iterating for a LONG time before they sync up. reminds me of steve reich's early works
11:33gfrlogI 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:33gfrlogyou also have to include the fact that each iteration is being performed twice instead of once
11:34gfrlogbut 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:34gfrlog__name__ the array map is sorted sorta
11:34__name__sorta?
11:34gfrlogand also has linear lookup time
11:35__name__Instead of O(log32 n)
11:35gfrlogyeah I was reading about it just yesterday. By sorta I mean that it somehow gets out of order if you assoc onto it
11:35gfrlog__name__: yes
11:35__name__gfrlog: Do you have any resources on how the ArrayMap works?
11:35gfrlogdocs say it's only appropriate for tiny maps
11:35fliebelgfrlog: Have you tried implementing the cycle thing in Clojure?
11:35gfrlogyeah let me find what I was reading
11:35__name__I understand the way the HashMap works, kind of,
11:35gfrlogfliebel: 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:36gfrlog__name__: http://clojure.org/data_structures#Data Structures-ArrayMaps
11:36__name__Links with spaces :(
11:36fliebel__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:37fliebel__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:37gfrlog__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:38gfrlog__name__: probably
11:38__name__I hate this printing dialogue :(
11:38gfrlog__name__: I think they're performant, so I'm sure that's the case
11:38gfrlog__name__: you hate chat rooms?
11:39__name__gfrlog: no, the printing thing of firefox.
11:39gfrloghmmm...don't know what that is
11:39__name__When you press Ctrl-P, a dialog window opens.
11:40gfrlogwhy 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:40gfrlogfliebel: this would do it, right? https://gist.github.com/856492
11:41gfrlog__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:41gfrlogdown with the firefox print dialog!
11:42gfrlogfliebel: I guess it's a bit weird to name it as if it's a predicate, since it never returns false
11:42gfrlogit's like the halting problem...
11:43fliebelgfrlog: I can;t see it, because a Java applet is obscuring my view :S
11:43pdkname it return-true
11:43pdkit'll be fun
11:43gfrlogpdk: :-D
11:44gfrlogcycle detection? that's what the return-true function does of course. Don't you understand the naming conventions?
11:44TimMc(defn did-not-throw-error? [] true)
11:44gfrloghah
11:44fliebelgfrlog: ##(doc nnext)
11:44sexpbot⟹ "([x]); Same as (next (next x))"
11:45gfrlogah I knew it
11:45gfrlogI was about to rewrite it with destructuring actually
11:45fliebelgfrlog: Will that solve the duplicate itterate?
11:46TimMcwait wait
11:46TimMc(defn did-not-throw-error? [] (if (> (rand) 0.5) (throw (Exception. "Oops!")) true))
11:46gfrloghttps://gist.github.com/856492
11:46gfrlogfliebel: no
11:46gfrlogyou have to duplicate iterate
11:46fliebelbecause with (defn really-huge [] (sleep long)) it will take twice the time.
11:46gfrlogyes, I think the duplication is inescapable
11:47gfrlogit's what you sacrifice for the memory benefits
11:47gfrlogthat code got a LOT shorter with destructuring...
11:47fliebelgfrlog: But not duplicate the effort. I thin a lazy seq keeps the realized elements somewhere as state, so letting the itterate will help.
11:47fliebeloh… hm
11:48gfrlogfliebel: you don't want anything cached or your memory will blow up
11:48gfrlogfliebel: So I think letting the iterate will kill you
11:48gfrlogLITERALLY
11:48fliebelprobably...
11:48fliebelhttp://xkcd.com/725/
11:48gfrlogkeeping track of all the in-between values eventually gets too much
11:49fliebelhm
11:49gfrlogfliebel: well played
11:49gfrlogthat comic confirst that I spelled literally correctly
11:50gfrlogI literally spelled it correctly
11:50gfrlogs/confirst/confirms
11:50gfrlogsexpbot: you can't look back one extra comment? just one?
11:50gfrlogclojurebot: teach sexpbot how to respond to direct messages
11:50clojurebotsexpbot is not a clojurebot
11:51TimMcnice
11:51fliebelgfrlog: So, what about the destructuring?
11:51gfrlogfliebel: I don't know what that question means. What about it?
11:51gfrlogI was just saying it made the code cleaner
11:51fliebelgfrlog:Can I see it :)
11:52gfrlogoh I gave a link
11:52gfrloghttps://gist.github.com/856492
11:52gfrlogI haven't tested either of those functions
11:53gfrlogI will paste it into the repl right now and see what happens
11:53fliebelThe hardest part is defining a function that does a cycle :P
11:54gfrlog=> (return-true #(rem (inc %) 83800) 88)
11:54gfrlogtrue
11:54gfrlogalso:
11:54gfrlog=> (return-true #(rem (* % %) 83879) 88)
11:54gfrlogtrue
11:55gfrlogdoing anything at all within a fixed domain will have to cycle
11:55gfrloge.g., any hash function
11:56fliebelhash function?
11:56gfrloghash function
11:56fliebel$google hash function
11:56sexpbotFirst out of 551000 results is: Hash function - Wikipedia, the free encyclopedia
11:56sexpbothttp://en.wikipedia.org/wiki/Hash_function
11:56clojurebot#<RuntimeException java.lang.RuntimeException: java.lang.Exception: 503>
11:56gfrlog:)
11:57gfrlogwho told clojurebot to do anything?
11:57gfrlog,"I dunno"
11:57clojurebot"I dunno"
11:58gfrlogfliebel: hash functions are good.
11:58gfrlogthey're one of my favorite things.
11:59TimMcclojurebot randomly throws that 503 exception on URLs
11:59gfrlogooh
11:59gfrloghttp://github.com
12:00gfrlogmaybe it only accepts URLs from sexpbot
12:00sineerHi! 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:01sineerEven this won't work: (eval-after-load "swank-clojure" '(progn (add-to-list 'swank-clojure-classpath "~/.emacs.d/site-lisp/swank-clojure/src/")))
12:01fliebelgfrlog: Hm, I want to see what the cycle part was...
12:01sineerI've spent the last 2 hours trying to fix this :(
12:03sineerin swank-clojure.el... this line: (defcustom swank-clojure-classpath
12:03sineer (swank-clojure-default-classpath)
12:03sineercan this prevent me somehow from using add-to-list ?
12:04gfrlogfliebel: you mean why I say a hash function will cycle?
12:04fliebelgfrlog: No, I ran a cycle, and I wanted to see when it started to repeat.
12:05gfrlogoh...add some prints?
12:05gfrlogif you run the return-true function with a hash function you will probably never see it repeat
12:05gfrlogunless it's a bad hash function
12:07fliebeluser=> (return-true #(.hashCode (str %)) "hallo wereld") => true
12:09fliebelgfrlog: ^
12:09gfrlogfliebel: will have to check what .hashCode does
12:10gfrlogah yes
12:10fliebelgfrlog: 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:10gfrlogso for certain purposes you can use bad hash functions
12:11gfrlog.hashCode is a bad hash function
12:11fliebelwhy?
12:11clojurebotwhy not?
12:11gfrlogbecause its range is 256 I believe
12:11gfrlogor maybe 2^32
12:11gfrlogboth of which are small
12:11gfrlogfor crypto purposes
12:12gfrlogthey are fine for programming language purposes like hash maps
12:12fmwraek: 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:12fmwraek: thanks
12:12gfrlogwhich I believe is the expected usage
12:12gfrlogwhen I said 'would never return' I was referring to any crypto hash function, which would have a much bigger range
12:13fliebelgfrlog: But why does it return true instantly for you function, and not at all for mine?
12:13fliebeloh, wait, I know...
12:14gfrlogyou're letting the iterate, right?
12:15gfrloganother reason that algorithm might not work is that the first object in the iterate doesn't have to be part of the cycle
12:15fliebelgfrlog: I'm doing something completely different, namely, looking if the first value comes back later.
12:15gfrlog(btw, in your code f == ob)
12:16gfrlogright
12:16gfrlogokay then, as long as it's on purpose
12:16gfrlogI would guess for a given hash function there is a good chance the initial value will not show up again
12:17gfrlogalso, take-while will probably keep the whole seq
12:17gfrloganother cause for the memory error
12:17fliebelgfrlog: *That* was intended. I wanted to see the whole cycle.
12:17gfrlogman I'm always incorrectly guessing your intentions
12:18gfrlog,(.hashCode "fliebel")
12:18clojurebot-771880729
12:18gfrloglooks like the range is 2^32
12:18fliebelMaybe I'm just not clear in my intentions ;)
12:18gfrlogso that'd be too big
12:18gfrlogif you use #(rem (.hashCode %) 256)
12:18gfrlogas the hash function
12:18gfrlogit would cycle much faster
12:18gfrlogadjust 256 to your liking
12:19fliebelyea...
12:23fliebelvictory! I changed true into a in your code, and used that in mine :)
12:24gfrlogbut mine doesn't keep all the values...
12:24fliebel1018032231 has a cycle of 37525
12:25gfrlogdid you use the raw hashCode or reduce it?
12:25fliebelraw
12:25gfrloghuh
12:26gfrlogI have a visual javascript implementation of SHA-1 that I need to clean up and publish
12:35ApeShotSo 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:35ApeShotThere is a specific idiom for this that I can't remember, as I've been in CL land for awhile.
12:35ApeShotI put a symlink somewhere?
12:36ApeShotI'm in emacs and on ubuntu
12:36ApeShotcheckout dependencies, it seems, is the answer
12:36ApeShotThanks!
12:37gfrlogman I can never remember whether the reader macro is ~@ or @~
12:37gfrlog~@ apparently
12:37clojurebot@ is splicing unquote
12:38gfrlogso if you want to unquote the result of derefing something... you add whitespace?
12:38gfrlog,`~(deref (atom 0))
12:38clojurebot0
12:38gfrlog,`~@(atom 0)
12:38clojurebotsplice not in list
12:38gfrlog,`~ @(atom 0)
12:38clojurebot0
12:38gfrlogguess so
12:41ApeShot 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:41raekApeShot: iirc, you should include the library in :dependencies as usual
12:42ApeShotraek: what do I write for a personal library?
12:43raekand in addition to that, have a symlink to the project dir
12:43ApeShotraek: in the checkouts directory, right?
12:43raekyes
12:43ApeShotraek: or do I need yet another
12:44raekApeShot: in :dependencies, you put whatever you called your private library in its project.clj
12:45ApeShotraek: thanks a ton
12:45ApeShotraek: all these configuration things are the most frustrating wall between me and hacking
12:45ApeShotworth it later to be organized now
12:45ApeShotbut frustrating now
13:08jjjjjjjwhat's the best way to store data 10 elements long in clojure?
13:08jjjjjjjlist or vector?
13:08ApeShotjjjjjjj: almost certainly depends on what you do with it
13:08ApeShotjjjjjjj: do you want random access or sequential access
13:09jjjjjjjgenerally I will iterate through it at some time
13:09ApeShotjjjjjjj: probably with only ten elements it doesn't matter
13:09jjjjjjjit does IMO
13:09ApeShotjjjjjjj: iteration is fast with lists or vectors
13:09jjjjjjjyeah but creation cost is lower with list
13:09ApeShotjjjjjjj: are you creating tons of these things?
13:09ApeShotjjjjjjj: in an inner loop?
13:09jjjjjjjI tried testing this and I think list was like 5 times faster
13:10ApeShotjjjjjjj: "vectors" in clojure are functional so conj on a vector should be as fast as cons on a list, I think.
13:10ApeShotjjjjjjj: I am not any sort of functional data structures expert, though
13:10ApeShotjjjjjjj: or even novice
13:10ApeShotjjjjjjj: what is your application?
13:10jjjjjjjI know what you're thinking... if you do this once in a program, it doesn't matter right?
13:10jjjjjjjbut I use short sequential data all throughout my program
13:11ApeShotjjjjjjj: I'm actually thinking, "without more information about his use case, how can he expect me to answer his question meaningfully?"
13:11jjjjjjj:D
13:11gfrlogyou both are missing the obvious answer: A sorted map of finger trees
13:11ApeShotgolomb forest
13:11ApeShotsql database
13:12jjjjjjjlook it's your basic CRUD app
13:12ApeShotwhat if you need to map reduce on the ten elements
13:12ApeShotCOUCHDB
13:12amalloyApeShot: hadoop!
13:12jjjjjjjafter zeroing down to some unit like a single user or so, you pull related data from DB
13:12ApeShotTEN INDEX CARDS
13:13ApeShotHire a grad student to wait around to type them in when needed.
13:13jjjjjjjfor instance one user has relationship with 5 locations, 3 companies etc
13:13jjjjjjjthis is where a bunch of short lists come from
13:13amalloyApeShot: see if you can distribute like seti@home
13:13ApeShotjjjjjjj: sorry, we are on a tangent here
13:13Ptival^^
13:13jjjjjjjI'm just explaining why most my programs involve creation of bajillion lists of ~10 elements
13:13ApeShotjjjjjjj: clojure should make it easy to change the seq type later
13:14ApeShotjjjjjjj: If you aren't doing random access, use lists
13:14jjjjjjjI was thinking about using transients when filling lists, but it slowed down actually
13:14ApeShota conj should be real cheap
13:14jjjjjjjit's not
13:15ApeShotanyone know more about this than me?
13:15ApeShotHonestly, 95% of the lisp code I write is in Emacs Lisp.
13:15ApeShotIn EL we have lists and we HAVE TO LIKE IT.
13:15amalloythe 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:15amalloyApeShot: oooo you write EL. plz to fix everything i don't like about clojure-mode
13:16ApeShotamalloy: what don't you like
13:16amalloyApeShot: this gets indented wrong: ((juxt + -) 10 <RET> 5)
13:16ApeShotamalloy: this is more my kind of thing
13:16ApeShotamalloy: https://github.com/VincentToups/emacs-utils/blob/master/README.md
13:17jjjjjjjI tried the test of inserting 100000 numbers into short lists of 10 and java kinda outperformed clojure vectors 40 to 1
13:17ApeShotjjjjjjj: well, 40/1 isn't bad
13:17ApeShotjjjjjjj: did you add type annotations to the clojure code?
13:17jjjjjjjsounds bad when that's all your code does :D
13:17ApeShotamalloy: the indentation looks ok to me
13:18ApeShotamalloy: what would you like it to be like?
13:18jjjjjjjannotations? for normal numbers?
13:18amalloyApeShot: 5 should line up with 10, not with (
13:18amalloyas it does for (+ 10<RET>5)
13:18ApeShotamalloy: you know, you are right.
13:18amalloyApeShot: i doubt typehints would make a difference when you're just conjing numbers onto a list and not doing any math with them
13:19ApeShotamalloy: well, like I said, I'm not really a major clojure guy
13:19jjjjjjjhowever we have a tight loop where another difference maker is i++ vs (inc i)
13:19fmwraek: 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:20amalloyjjjjjjj: 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:20fmwI must say that the functional paradigm is awesome while writing tests.
13:21ApeShotamalloy: I believe a better name for juxt, incidentally, is "cleave"
13:21jjjjjjjamalloy 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:21ApeShotamalloy: If I am not mistaken, it is the equivalent of the concatenative language cleave combinator.
13:22gfrlogI had performance issues once. The solution iirc was to remove all the (Thread/sleep ...) statements
13:22amalloyjjjjjjj: 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:22ApeShotamalloy: which coincidentally I am adding to my utility library for clojure right now
13:22amalloyhah
13:23amalloyfmw: it seems weird to me to see (let [...] (let [...]))
13:23gfrlogamalloy: 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:23ApeShotamalloy: admittedly, its not clear to me that "cleave" is a more intuitive name than "juxt"
13:23amalloyyou might as well just (let [... ...])
13:23jjjjjjjamalloy...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:23jjjjjjjso usually customer says...here you have 4 cores, deal with it
13:24jjjjjjjbecause they have 4 cores worth of licenses for software
13:24gfrlogamalloy: tweaking performance is fun!
13:25gfrlogand 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:25jjjjjjj:D
13:26gfrlogtimes like those it doesn't matter what's in your inner loop and what's not. Bowser doesn't care.
13:27fmwamalloy: ah, like so: http://paste.pocoo.org/show/348518/
13:27fmwthat seems to work
13:30fmwraek: 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:30fmwamalloy: thanks :)
13:30amalloyfmw: that's a perfectly reasonable change to make to your code but it's not the one i was suggesting
13:30fmwamalloy: oh
13:31fmwwhat were you suggesting?
13:31amalloyi meant (let [stats {...}, new-stats (reduce ...)] ...)
13:31amalloybecause let allows multiple bindings
13:31fmwamalloy: cool, I didn't know that
13:32amalloy$source defn
13:32sexpbotdefn is http://is.gd/6dmcr0
13:32amalloyfmw: ^ is an especially gross use of that fact
13:33jjjjjjjdoesn't need the comma
13:33amalloyjjjjjjj: obviously
13:33jjjjjjjjust saying...in case fmw doesn't know
13:33fmwjjjjjjj: I did know that, but thanks anyway :)
13:33jjjjjjjcomma is whitespace in clojure
13:33jjjjjjj[1 2 3] is same as [1,2,3]
13:33fmwits very safe to assume I don't know that kind of stuff, but in this case I did
13:33gfrlogespecially if your font is white
13:34gfrlog&(doc defn)
13:34sexpbot⟹ "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:35gfrlogamalloy: Do you happen to know why the 'defn' source uses 'def' instead of 'defmacro'?
13:35amalloygfrlog: defmacro doesn't exist yet
13:35gfrlogyes but defn is a macro
13:35gfrlogso just using (def x (fn [args]...)) shouldn't ... do that
13:35gfrlogoh I see the next line
13:35amalloygfrlog: see the end. it alters the var root
13:35gfrlogokay very good
13:36gfrlogI will start using that in my code everywhere
13:36amalloywhich is in fact how defmacro works, once it's defined
13:36gfrlog,(.setMacro (var clojure.core/conj))
13:36clojurebotnil
13:36fmwamalloy: so ^ is not a technical language construct, but its just a let binding the value of that documentation map to to ^?
13:36gfrlog,(conj [] 2)
13:36clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/conj
13:37gfrlogdid I just break clojurebot?
13:37fmwi.e. not a keyword, just a variable name convention
13:37amalloyfmw: *squint* i don't think i understand the question
13:37gfrlog,(cons 7 [])
13:37clojurebot(7)
13:37amalloygfrlog: it's not as difficult as you would think
13:37gfrloghow does it get unbroken?
13:37gfrlog,(.setMacro (var clojure.core/cons))
13:37clojurebotnil
13:38gfrlog,(cons 7 [])
13:38clojurebotjava.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$cons
13:38amalloygfrlog: hiredman will reboot it, or someone will make these things un-macros
13:38amalloy,(alter-meta! #'cons assoc :macro false)
13:38clojurebot{: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:38amalloy,(cons 7 [])
13:38clojurebot(7)
13:38gfrlogoh okay
13:38gfrlogevery is dynamic at runtime, I assure myself soothingly
13:39fmwamalloy: 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:39amalloyuh, i was using ^ as a way to point above me
13:39amalloyto the defn link
13:40spewnIt's tempting to set alter-meta! to be a macro and yell "Checkmate!"
13:40gfrlogI will create a homoiconic language where data is code
13:40amalloyspewn: good luck with that
13:40amalloy,alter-var-root
13:40clojurebot#<core$alter_var_root clojure.core$alter_var_root@1c63b78>
13:40amalloythere are a lot of ways to change meta
13:41gfrlogso...2 ways?
13:41fliebelI'd like to see you guys try to break and unbreak clojurebot :)
13:41amalloyanyway guys i gotta run. hope that clarified things for you, fmw; ^ is kinda an irc convention
13:41fmwamalloy: ok, thanks for the input :)
13:41fmwamalloy: and it did
13:47gfrloghow do I get a new string writer?
13:48gfrlogah nevermind
13:48jjjjjjj:)
13:48jjjjjjj(java.io.StringWriter.)
13:48gfrlogis there a clojure method for it?
13:48gfrlogthat's what I found
13:48jjjjjjjwhich is same as (new java.io.StringWriter)
13:49jjjjjjjyou can also import classes same as java to make this shorter
13:49gfrlogright
13:50gfrlogah well; can't complain
13:53jjjjjjjyou expected a clojure idiom for making string writer objects?
13:55gfrlogno, just something in c.c.duck-streams or something like that
13:55gfrlogso (println) respects *out*, but (.printStackTrace e) does not -- that's expected, right?
13:56gfrlogis there a clojure function for printing stack traces to *out*?
13:57jjjjjjjmaybe print stack trace uses System.err not System.out
13:57jjjjjjjdifferent stream
13:57gfrlogyes; it doesn't respect *err* either though
13:57jjjjjjjah...
13:57gfrlogI would imagine clojure couldn't affect the behavior of that function
13:57gfrlogI see a clojure.stacktrace namespace, so I'd bet anybody $15 this will be helpful
13:57jjjjjjjyou want to print stack trace into a string
13:58gfrlogjjjjjjj: no, I want it to go to *out* or *err* -- something I can control
13:58raekgfrlog: .printStackTrace has a variant that takes a PrintWriter as an arg
13:58gfrlograek: that sounds like it would work; but would the clojure.stacktrace functions not be preferred?
13:59jjjjjjjlast resort use (.getStackTrace e) and
13:59raekI guess it depends on what you need to do
13:59jjjjjjjdo whatever you want with it
13:59gfrlogjjjjjjjj: that is exactly what I was trying to avoid
13:59raekclojure.stacktrace provides functions that know about clojure naming conventions
13:59gfrlogjjjjjjj: your name makes it hard to address you directly
13:59jjjjjjjhow so?
13:59gfrlogjjjjjjj: Have to count the j's
14:00jjjjjjj:D
14:00gfrlogdon't you like any other letters? I know a few good ones.
14:00spewngfrlog: No tab completion in your client?
14:00EDCBA:)
14:00gfrlogspewn: apparently there is
14:00gfrlogspewn: many hugs
14:01EDCBAI was wondering the same thing
14:01gfrlogspewn: what other tricks do I need to learn?
14:01gfrlogI'm just going to start complaining about IRC and see what people recommend:
14:01gfrlog(am using irssi)
14:01raekgfrlog: 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:02gfrlograek: right - that's what I assume would be different about clojure.stacktrace
14:02gfrlograek: I guess you're thinking that passing *out* to .printStacktrace is easier than :requiring clojure.stacktrace?
14:03gfrlogfirst of all, using a terminal client means I don't get notifications when somebody is talking to me
14:03gfrlogsecond, I don't know how to make passive statements
14:03gfrlogthird, I don't get as much work done when I'm on IRC
14:04EDCBAI think you can change System.out to a stream of your own
14:04gfrlogfourth, my three-item-lists always run long
14:04spewngfrlog: "/set beep" will show you some notification-related settings in irssi
14:04gfrlogEDCBA: really?
14:04EDCBAI don't see why not
14:04gfrlogEDCBA: because Java isn't good
14:04EDCBAit's not declared final so I assume you can do that
14:05gfrlogn
14:06gfrlogit even has a .setOut function
14:06gfrlogspewn: thanks
14:46rata_what's await return value?
14:54chouserrata_: nil
14:54rata_chouser: thanks =)
15:01rata_can agents launch programs using c.c.shell-out?
15:04gfrlogif I have (defn foo* ...) and (defmacro foo [...] `(foo* ...)), shouldn't the foo* symbol resolve correctly no matter where I call foo from?
15:05edbondhow to get list of alphabet chars? ["A" "B" ... "Z"] ?
15:05gfrlog,(map str (seq "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
15:05clojurebot("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" ...)
15:05gfrlogthat's the best I know of :-/
15:06rata_I don't see what else could be the problem here: https://gist.github.com/856670
15:06raek,(map char (range (int \A) (inc (int \Z))))
15:06clojurebot(\A \B \C \D \E \F \G \H \I \J ...)
15:07gfrlog,(ruby-eval "[*'A'..'Z']")
15:07clojurebotjava.lang.Exception: Unable to resolve symbol: ruby-eval in this context
15:07gfrloghad to try
15:07raekor replace "char" with (comp str char) if you want strings
15:07Derandergfrlog: too bad
15:08gfrlogDerander: yeah why doesn't clojure include JRuby yet?
15:08Derander:-)
15:08gfrlogand Jerlang for that matter
15:09gfrlogif I have (defn foo* ...) and (defmacro foo [...] `(foo* ...)), shouldn't the foo* symbol resolve correctly no matter where I call foo from?
15:11rata_gfrlog: yes, it should
15:11raekgfrlog: yes
15:11gfrlogstranger and stranger...
15:11raekif you have (defn foo* ...) and you are in namespace "user", `foo* should evaluate to the symbol user/foo*
15:12raekgfrlog: do you know about macroexpand-1?
15:12clojurebotCool story bro.
15:12gfrlograek: yes
15:12gfrlograek: I'm doing mildly more complicated things, so probably it would all work fine at the repl
15:14rata_gfrlog: gist it, maybe we can help you
15:15gfrlograta_: it's not any more complex than what I gave, and indeed it does work at the repl
15:15gfrlogI'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:17raek__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:18raekah, logical shift right...
15:18raekit's interesting that java has both >> and >>>, but C does not
15:22__name__Yes, the three > confused me.
15:25EDCBAgfrlog I tried that macro
15:25EDCBAworked fine for me
15:25EDCBAmake sure that macro and function are in same namespace
15:52EDCBAstupid question but if I want to typehint do I use ^String or #^String
15:52EDCBAand how do I typehint primitives
15:54spewnEDCBA: 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:55dnolenEDCBA: 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:55dnolen(let [x (float 1.0)] ...)
15:55dnolennot also that 1.2.0 since functions can't return primitives you'll need to type hint return values as well.
15:55dnolen(int (+ (int 1) (int 2))
15:55raekEDCBA: ^String is the syntax since clojure 1.2. #^String was used in 1.1 and earlier
15:56dnolenEDCBA: in 1.3.0 this tediousness is largely eliminated.
16:06TimMcThe 1.2 compiler accepts primitive type hints, but apparently just ignores them.
16:14dnolenTimMc: 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:14TimMcBut it's forward compatible! :-)
16:15TimMcMmm, I wonder if ^double effectively results in ^Double or ^Object in 1.2?
16:18EDCBAthanks dnolen
16:19EDCBAwhat did you mean about type hinting literals
16:20dnolenEDCBA: in 1.2.0, literals are interpreted as their object variants. 1 is Integer not int.
16:20EDCBAah
16:20EDCBAso (int ^int 1)?
16:20dnolennot
16:20dnolen(int 1)
16:20EDCBAyes
16:20TimMc,(int ^int 1)
16:20clojurebotMetadata can only be applied to IMetas
16:20EDCBAI wasn't aware that (int x) was type hint
16:21EDCBAthat confused me
16:21dnolenEDCBA: it's a cast.
16:21dnolen^int doesn't mean anything.
16:22EDCBAah
16:22EDCBAis there any type casting operation in clojure (for the sake of java interop)
16:26mrBliss,(find-doc "cast")
16:26clojurebot-------------------------
16:26clojurebotclojure.core/cast
16:26clojurebot([c x])
16:26clojurebot Throws a ClassCastException if x is not a c, else returns x.
16:28raekEDCBA: 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:29TimMcI believe this is equivalent, but less likely: (defn matches [s] (.matches ^String s))
16:30raekso casting for the sake of interop is insterted automatically by the compiler for non-reflective method calls
16:30raekthe class to cast to can be controlled with typehints
16:31raek(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:31raek(as the compiler would infer the concrete type)
16:35EDCBAright
16:35EDCBAso if I typehint fn argument then it propagates to calls in that fn
16:36raekyes
16:36EDCBAwhat's the purpose of typehints in fn that only call clojure functions?
16:36EDCBAI see that sometimes in clojure.core source
16:36raekin 1.2, that would be a no-op
16:36EDCBAfaster clojure interfaces?
16:36EDCBAdo typehints make interfaces faster?
16:37EDCBAanother question that's been bugging me for some time, when I use defmulti, I specify dispatch fn. What arguments can that fn expect
16:38raekany arguments the user of the multimethod would pass it
16:38TimMcIs there a HOF to sequence thunks? Like (foo f g) => (do (f) (g)) ?
16:39raekEDCBA: where do you see those typehints?
16:39EDCBAI might have been mistaken
16:40raeknote that core.clj also uses the alternative (. x (method 1 2 3)) syntax instead of (.method x 1 2 3) sometimes
16:40EDCBAso 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:40raekthat dispatch fn only takes one argument
16:40raekyou need something like (fn [x _] (class x))
16:41EDCBAI can't use reader macro for fn?
16:41gfrlogso 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:41EDCBAoh crap I see now
16:41raekor (fn [x & _] (class x)) if you want to allow arbitrary number of arguments
16:42EDCBAI can't use reader macro because #(class %1) will make a single arg fn
16:42EDCBAI see it now
16:42gfrlogEDCBA: your nick is hard to type with all the caps. Why not change it to something easy to type and repetitive like jjjjjjj?
16:42raekgfrlog: it will be resolved in the context where it is called, which is bad
16:43gfrlograek: okay. thus the default backtick behavior
16:43raekwhere the macro is expanded, not where the macro was defined
16:43raekunlike the backtick behavior
16:43gfrlogright
16:44raekgfrlog: if you do something like (cons 'conj ...) to build the code, you can use (cons `conj ...) instead
16:44EDCBAso 'user will become user/user?
16:44gfrlograek: that's a good tip
16:44EDCBAgfrlog macros use backtick 90% of the time
16:45gfrlogyep
16:45TimMcgfrlog: tab-completion is case-insensitive in irssi
16:45EDCBAunless you know why you aren't quoting with backtick you shouldn't use normal quote :D
16:45gfrlogTimMc: dang
16:45TimMc:-)
17:19TimMcraek: Does (fn [x] (boolean (pos? x))) give any benefit in 1.2 over (fn [x] (pos? x)) ?
17:21raekTimMc: not that I know of. what would the benefit be?
17:23TimMcWasn'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:24TimMcI don't have any reason to believe it does, but I wanted to make sure I wasn't missing something.
17:25waxroseHello every body, I threw together a 1920x1080 clojure wallpaper. Enjoy. :) http://i.imgur.com/n7P9k.jpg
17:27TimMcspiffy
17:28johnmn3I like it
17:28waxrose:D
17:28TimMcBut a JPG?
17:28waxroseOh, it's in jpg?
17:29TimMcI guess imgur changed it.
17:29waxroseYeah, I can put it up on dropbox if you want.
17:29TimMcLooks fine, though.
17:30waxroseAlright. :)
17:30TimMcwaxrose: This shall replace my old, uh, "GNU-themed" wallpaper: http://i.imgur.com/88Jgz.jpg :-P
17:30waxroseTimMc, haha!
17:30waxroseEpic
17:31TimMc(found on Reddit a while ago)
17:31waxroseLol that is awesome.
17:32johnmn3I'd probably wear that fragrance
17:32TimMcContrary to popular opinion, RMS does not actually smell bad in person.
17:32johnmn3while chewing my toenails
17:32waxroseReal men don't shave.
17:33TimMc...but I think he posed for that picture knowing exactly how it would be used. He's that kind of guy.
17:33waxroselol
17:33waxroseI wish I could meet him in person.
17:33waxroseHim and Sussman.
17:34amacsussman seems like he'd be more fun
17:34amacstallman is... odd
17:34waxroseHow so?
17:35TimMcI've met RMS once at MIT. He looked just like the pictures.
17:35amacI've helped organize conferences where he was a keynote
17:35waxroseLucky.
17:35amaclook online for a copy of his term sheet
17:35dfanrms is a pretty weird guy in real life
17:35TimMcSussman I met at a PL event at Northeastern. He regaled us with tales of making fault tolerant software + hardware for a giant telescope.
17:35waxroseI wish I would have gotten my things in order during high school and had applied for MIT in order to meet these guys.
17:36TimMcwaxrose: How far are you from Boston?
17:36waxroseTimMc, I live in Texas.
17:37dfanSussman is actually a reasonable human being
17:37amachis video classes for sicp are awesome
17:37TimMcI should watch those!
17:37amactres 80's
17:37dfanI took SICP in the 80s :)
17:37amacnice! it hasn't changed.
17:38waxroseTimMc, http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/
17:38dfanHas it not? I thought they moved from Scheme to Python or something
17:38TimMcwaxrose: Yeah, but... not enough time right now.
17:38waxroseI was actually given a PERFECT copy of SICP that was published during that time, a couple weeks ago.
17:38johnmn3I've been watching those on the metro to work the last few weeks
17:38amacthat's the nice thing about lisp... its basically been feature-complete for 40 years
17:39waxrosedfan, Yeah to Python.
17:39amacwaxrose: get sussman to sign it
17:39amac:)
17:39waxroseamac, I have to find him first! haha
17:39waxroseThat or get a plane ticket out of Texas.
17:40dfanA shame
17:40amacI want to get knuth to sign my taocp books
17:40amacwaxrose: travel is good for you ;)
17:40TimMcThe 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:40waxroseamac, I hope after I'm done with school I can go find these guys.
17:41dfanHuh, I thought they were moving away from the hardware side too
17:41dfanlike the computers we assembled in 6.004
17:41TimMcdfan: Oh, huh.
17:42TimMcI 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:42TimMcFundies is taught in Racket (PLT Scheme).
17:43dfanI respect the PLT guys a lot
17:43TimMcdfan: Eli is a nutcase, in a good way.
17:43waxroseIs the Clojure Conj pretty big?
17:43amacwhere *is* clojureconj?
17:43TimMcMatthias scares all his students. :-P
17:44TimMcamac: NC, I think.
17:44waxroseamac, Says Durham
17:44waxrosehttp://www.clojure-conj.org/
17:44TimMcI might make it down, escpecially if I get a job at Akamai doing Clojure work.
17:44waxroseI wish every thing wasn't so far from Texas.
17:45dfanAt least everything is equally far from Texas
17:45waxroseTrue.
17:45waxroseI'm actually surprised Austin does not have a Clojure conference of some sort. ( not that I know of)
17:45amacI'm in Montreal, getting anywhere in the US costs a fortune.
17:47TimMcwaxrose: The East and West coasts being everything?
17:49waxroseTimMc, Seems like it.
17:49TimMcBoston is amazing. I could see staying here a long time.
17:50dfanI never left :)
17:50waxroseI've lived around the D.C. area before but I've heard that Boston itself is a great place to live.
17:50TimMcI'm from Charlottesville, VA.
17:50TimMcMight combine Clojure Conj with a visit to my folks.
17:50waxroseAnd I imagine there are many Lispish type jobs in that area.
17:51dfanEvery time I travel somewhere warmer during the winter I wonder why I live in Boston
17:51amacI'd go to SF over Boston... I've had enough of winters.
17:51dfanbut then it passes
17:51TimMcdfan: I love the snow. :-)
17:51waxroseI should save up to go to next years Clojure Conj.
17:52waxroseTimMc, I love the snow as well despite living in TX most of my life.
17:52amacTimMc: playing in snow is awesome, living in it sucks ass
17:52TimMcwaxrose: That's probably why you like it. :-)
17:53TimMcWow, you apparently can't get from Austin, TX to Durham, NC by Amtrak.
17:53TimMcThat, or their website is screwed up as usual.
17:54waxroseOuch.
17:54waxroseWould probably have to go to Dallas instead.
17:55gfrlogTimMc: they're pretty bad about connections
17:55TimMcgfrlog: I know they can find two-leg routes.
17:55gfrlogTimMc: they don't
17:55gfrlogTimMc: well sometimes they do.
17:56TimMcI travel from CVS to BOS all the time, and used to transfer at NYP or WAS.
17:57gfrlogthere's a route I would request that involves transferring at WAS, but they won't show it
17:57waxroseHow is the transportation like there? I'd be great to live some where that does not require a car.
17:57TimMcwaxrose: I bike to school, 5.5 miles.
17:57gfrlogI am not a fan of cars.
17:57gfrlogwhen the cars play, I cheer for the other team.
17:57gfrlogunless they are playing trucks
17:57waxrosehaha
17:58dfanPublic transportation in Boston is great in theory
17:58waxroseTimMc, That is awesome. I wish I could do the same here.
17:58waxroseI actually just paid off my car too.
17:58TimMcIf you have an ebook reader, public transit probably isn't so bad.
17:58TimMcYou'll get a lot of reading done.
17:59gfrlogand you probably won't die in a car accident
17:59gfrlogor pay thousands of dollars getting anything fixed
17:59waxroseTimMc, I work at B&N, so I see my fair share of Nooks.
18:00gfrlogBooks&Nooks
18:00TimMchaha
18:00TimMcYou could transfer through... Chicago. -.-
18:00gfrlog,(map #(str % "ooks") ["B" "N"])
18:00clojurebot("Books" "Nooks")
18:02waxroseI'm actually waiting for that new Clojure book, The Joy of Clojure to come out.
18:02waxroseGoing to grab it from the back of the store as soon as I see it too. ( benefits of working there)
18:03TimMcwaxrose: http://i.imgur.com/RfACt.png <-- source and destination are both annoying close to major lines.
18:04waxroseWow
18:04TimMcI hate our stupid, inadequate ground transit system.
18:04waxroseSA is not that far way though thankfully.
18:05TimMcYou could drive 40 miles to San Antonio, use Amtrak to get to Greensboro, and maybe catch a ride 40 miles to Durham.
18:05spewnwaxrose: Loving the wallpaper. Could we get a non-JPEG version? And is the background based on anything? It looks familiar.
18:06gfrlogGreyhound compared to Amtrak is much better about coverage and routing; much worse about experience
18:06gfrlogalso cheaper usually
18:06waxrosespewn, 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:06TimMcgfrlog: No power outlets, no room to walk around.
18:06waxrosespewn, Would you like the actual background as well?
18:07spewnNo, I think your composition of the two is great.
18:07TimMcwaxrose: 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:08TimMc(longer distance anyway, of course)
18:08waxroseTimMc, Yeah I would much rather go through the southern most route merely because of familiarity.
18:10gfrlogTimMc: their newer buses have outlets
18:10TimMcgfrlog: That would almost make it bearable.
18:10waxrosespewn, http://dl.dropbox.com/u/21959941/clojure-flower-1920_1080.png
18:10gfrlogI personally can bear it. But that's only because I have weird ideals.
18:11gfrlogI don't think less of people who choose not to
18:11TimMcgfrlog: It's not a matter of ideals so much as I can't stand being cooped up.
18:12TimMcI get super fidgety.
18:12waxroseI think if I can catch a plane, I would just do it that way.
18:12gfrlogTimMc: ah, then you should get the ticket for the fidgety seat
18:13spewnwaxrose: Merci. Much prettier when the lines are crisp.
18:13gfrlogjust kidding their tickets have nothing to do with seats
18:13TimMcgfrlog: The one with straps? :-(
18:13waxrosespewn, You are welcome. :D
18:15TimMcwaxrose: 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:15waxroseOh wow, thanks for the tip.
18:16TimMcYou can get other discounts with it, but that's the only one I've found applicable to me. :-P
18:16waxrosehehe
18:17waxroseHopefully by the time I use it I'll have made some Android apps in Clojure. -_-
18:23waxroseTimMc, About how long do you think it would take to get to Durham via amtrak?
18:24TimMcwaxrose: 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:24TimMcDidn't check the length.
18:25waxroseOkay thanks. So it would be smart to arrive maybe the 8th then.
18:25TimMcSAS -> GRO
18:26TimMcThe fuck...
18:26waxroseHmm I probably could go with it being $193. Just would have to find a hotel.
18:26TimMcThe alternate routes both go through WAS. (DC)
18:26TimMcAnd Chicago!
18:27TimMcNov 8 won't cut it, you have to go back to Nov 7.
18:28TimMcThat's a redeye: 12:00 Nov 7 -> 16:00 Nov 8
18:28waxroseThat would at least give me some time to sight see.
18:28waxrose:)
18:28gfrlogI had a 4 hr amtrak layover in chicago once. That was when I found out the Sears Tower was not called that anymore.
18:30waxrosegfrlog, haha
18:30TimMcWAS 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:31waxroseTimMc, Thanks a lot for the help. This with the added discount really makes me making it to the Clojure Conj a possibility.
18:31TimMcgfrlog: On Greyhound, is there enough seat room to open up a laptop and code?
18:31TimMcwaxrose: Yay! (Now I'll feel bad if I don't make it.)
18:32waxrosehaha
18:32TimMcI pretty much spend my entire Amtrak ride programming, or tagging my photos.
18:32waxroseI went ahead and put my e-mail in for notification because I know I'll forget.
18:33devnhmmm... I'd like to create mock of the twitter stream using clojure. Any suggestions on existing libraries to model a stream like that?
18:34amacTimMc: greyhounds are a tight squeeze but doable, the problem is that there are no trays to put the laptop on
18:34TimMcamac: Tray for height or keeping your lap cool?
18:35amacboth
18:35amacmy laptop gets crazy hot
18:35gfrlogTimMc: it's pushing it for sure
18:35TimMcMine doesn't/
18:35amacand in tight squeezes the height can be a plus
18:35gfrlogTimMc: Another issue is at night you feel like a jerk if the screen is bright
18:35TimMcHmm.
18:35waxroseamac, I've never travel via bus long term. How well is the power management for your laptop?
18:36waxroseI assumed they would provide sockets.
18:36amacfew of the busses have power
18:36gfrlogonly the new buses
18:36amacat least that's the case in canada
18:36gfrlogthose even have wifi
18:36gfrlogI only rode on one once
18:36TimMcdevn: Are you talking about modeling a producer/consumer architecture, or what?
18:36amacI took greyhound from vancouver to ottawa in october last year, and only one bus had power
18:36gfrlogironically that was the same trip that a group of kids brought peeing cats on board
18:37gfrlogso the luxury of the newer bus was lost
18:37devnTimMc: i want to basically make a fake version of the twitter stream to load test an application im working on
18:37devnim wondering how to best achieve that goal
18:37amacgfrlog: hah
18:38amacdevn: the aleph project has a twitter stream api key in their examples
18:38amacuse that to pump out a dataset
18:39devnamac: beautiful
18:39devnthanks
19:17gfrlogwhat's the way you can get a stack overflow when using lazy seqs?
19:21TimMcgfrlog: I know how to use up memory, but not stack.
19:21raekgfrlog: some combinations of reduce and map can cause it
19:22gfrlogTimMc: I think it's when you try to print a real long lazy seq
19:22gfrlogmaybe it's an issue with the c.c.json specifically
19:22TimMcHolding onto the head of a lazy seq as you force the contents will eventually use up arbitrarily much memory.
19:22gfrlogof course
19:23TimMcOh, you are actually getting a stack overflow in existing code?
19:23gfrlog,(take 14 (clojure.contrib.json/json-str (range 100000)))
19:23clojurebotjava.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.contrib.json
19:23gfrlogTimMc: yeah
19:23amachah, I thought you arbitrarily wanted to break your code
19:24gfrlogoh no; not this time
19:24gfrlog[[dishes]]
19:25raek,(nth (iterate #(map inc %) [1 2 3]) 10)
19:25clojurebot(11 12 13)
19:25raek,(nth (iterate #(map inc %) [1 2 3]) 100)
19:25clojurebot(101 102 103)
19:25raek,(nth (iterate #(map inc %) [1 2 3]) 1000)
19:25clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.StackOverflowError>
19:25raek,(nth (iterate #(doall (map inc %)) [1 2 3]) 1000)
19:25clojurebot(1001 1002 1003)
19:25amaclol
19:25raekthere
19:25amacpoor clojurebot
19:25raekyou end up with somthing like (map f (map f (map f (map f ...))))
19:26raekand when the first element out the outermost map is forced, it triggers a cascade of forcings, each one requiring its own stack frame
19:26amacthough I think you can change the stack size in the java vm if you're ligitimately running out
19:27raekgfrlog: so there you have it... that's one way you can get a stack overflow from lazy sequences. :-)
19:27gfrlogI had been doing the dishes for a few minutes
19:27gfrlogand came to the same conclusion
19:27gfrlogand came back to state it
19:28gfrlogthis is what caused my problem before as well as this time
19:28gfrlogI'm hoping (dorun) will make it better
19:28gfrlogapparently not
19:28gfrlogI should call (vec) I guess?
19:29raekgfrlog: doall is sufficient for my example
19:30raekit will have the same effect as vec, except that you don't allocate a new data structure
19:31raekhaving a doall in the loop will "flush out the laziness" at each iteration, so that it doesn't build up
19:32TimMcI find this surprising.
19:32TimMcI'm going to have to sit awhile and think about how those stack frames build up.
19:33raekit's all about where each map step is forced
19:33TimMcI think I get it...
19:33TimMcnth forces iterate, but the maps aren't forced until println
19:34TimMc,((fn [_] nil) (nth (iterate #(map inc %) [1 2 3]) 1000))
19:34clojurebotnil
19:34TimMc\o/
19:37TimMcWhy 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:41TimMc,(loop [l (list)] (recur (conj l 4)))
19:42clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/conj
19:42TimMcInteresting. Anyway, on my own box that gave me an IndexOutOfBoundsException.
19:43TimMc,*clojure-version*
19:43clojurebot{:major 1, :minor 2, :incremental 0, :qualifier ""}
19:45waxroseTimMc, Thanks again for the amtrak info. Time for work so I'll be back on later. See ya!
19:45TimMccheers
19:47pyrhi
19:47pyrI'm having some problems with a specific type of problem in clojure
19:48pyri have a recursive function which exits due to stack overflow
19:48pyrand which would be a good client for loop/recur
19:49pyrbut it calls itselfs more than one through map
19:49spewnpyr: Some example code might help.
19:50TimMcpyr: Would trampoline help?
19:50pyrmight
19:50pyrhold on
19:51pyrhttp://pastie.org/1637834
19:52pyrhere goes, a simple path finder which goes through a 5x5 grid
19:52pyrand finds out unique paths
19:54pyri'll look and try to see if trampoline can help me
19:55TimMcpyr: By the way, assoc on a vector gives you back a vector. No need for into.
19:56pyrtrue
19:58TimMcAre you trying to count the number of unique paths?
19:59pyryep
19:59amalloy,(alter-meta! #'conj assoc :macro false)
19:59clojurebot{: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:59amalloy,(loop [l (list)] (recur (conj l 4)))
19:59clojurebotjava.lang.OutOfMemoryError: Java heap space
20:00amalloyTimMc: someone was messing around with breaking clojurebot earlier today and didn't bother to fix him, apparently
20:00TimMchah!
20:00gfrlogme?
20:00clojurebotyour assessment smacks of bias, thus undermining your credibility further. (http://wondermark.com/560/)
20:01amalloyi 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:01gfrlogI guess I was a little shaken by the experience
20:01gfrlogI remember I only macro'd conj and cons I think
20:02gfrlogand you un-macro'd one of them?
20:02amalloygfrlog: yeah, it's all fixed up now
20:02amaclol
20:02gfrlogoh okay. pardon my childishness. Poor bot.
20:02gfrlog,(doc dorun)
20:02clojurebot"([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:02gfrlog,(doc doall)
20:02amalloythere there
20:02clojurebot"([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:02gfrlogdorun and doall are the same?
20:02amalloy&(doc dorun)
20:03sexpbot⟹ "([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:03amalloy&(doc doall)
20:03sexpbot⟹ "([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:03gfrlogthese dang bots
20:03gfrlogwhere's printslongstringsbot when you need him?
20:03spewngfrlog: doall returns the head, dorun returns nil
20:03amalloygfrlog: the end of the doc is different but clojurebot truncates
20:03gfrlogI'm ignoring the return value
20:03spewnThen use dorun.
20:03gfrlogand (dorun) didn't fix my problem
20:03amalloysexpbot truncates too of course, but he gists to the rest
20:04gfrlogoooh that's what that link is about
20:04gfrloggood job sexpbot
20:04amalloyyeah, anything that's too long for an irc message
20:04gfrlog&(println (vec (range 10000)))
20:04sexpbot⟹ [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:04gfrlog&(println (vec (range 10000)))
20:04sexpbot⟹ [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:04amalloyand that's too long for a gist :P
20:04gfrlogoh
20:04gfrlog&(println (vec (range 1000)))
20:04sexpbot⟹ [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:05amac,(= (doc dorun) (doc doall))
20:05gfrlogbrilliant
20:05clojurebotfalse
20:05TimMc,(doc doc)
20:05clojurebot"([name]); Prints documentation for a var or special form given its name"
20:05amalloythough 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:06spewnInteresting... in my REPL, (= (doc dorun) (doc doall)) evaluates to true.
20:06spewnSince each returns nil.
20:06amalloyspewn: the bots use special versions of doc
20:06TimMcdoc prints, ,doc is a bot command
20:06amalloyTimMc: no
20:06TimMc,(doc ...) I mean
20:06clojurebotPardon?
20:07amalloy,'anything tells the bot to eval that
20:07clojurebotanything
20:07amalloyhe redefines def to be something that returns a string so that he can capture the output, i imagine
20:07amalloyer, doc
20:07spewn,(meta #'doc)
20:07clojurebot{: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:08TimMcIt must intercept it, then.
20:08amalloy&(meta #'doc)
20:08sexpbot⟹ {: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:08amalloysexpbot rebinds it
20:08TimMc,~
20:09clojurebotEOF while reading character
20:09amalloythe 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:10TimMc,(conj [] 5)
20:10clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/conj
20:10TimMc,(alter-meta! #'conj assoc :macro false)
20:10amalloyhuh. i thought we fixed that
20:10clojurebot{: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:10TimMcYou did. I unfixed it in privmgs.
20:10TimMc*privmsg
20:10amalloyokay, that's what i guessed
20:10TimMcTurns out there isn't one sandbox per channel/query. That's good to know.
20:11amalloyyeah. it's expensive to run a lot of sandboxes
20:11gfrloghow does this sandboxing get done? is it a JVM feature?
20:12amalloygfrlog: the jvm sandbox is one facet
20:12amalloyclojail is the library behind sexpbot's sandboxing
20:12gfrlog$google jvm sandbox
20:12sexpbotFirst out of 7900 results is: Java's security architecture - JavaWorld
20:12sexpbothttp://www.javaworld.com/javaworld/jw-08-1997/jw-08-hood.html
20:13gfrlogI might find this useful actually...
20:13amac,(map println "abc")
20:13clojurebota
20:13clojurebotb
20:13clojurebotc
20:13clojurebot(nil nil nil)
20:14amalloy&(map println "abc")
20:14sexpbot⟹ (abnil cnil nil)
20:14TimMchah!
20:14amachmm... my repl mangles the output of the side effect prints and the return nils
20:14amalloyhaha, i knew the result would be different but i didn't think it would be that
20:15amacyay, I broke something!
20:15gfrlogsexpbot: that wasn't very sexp
20:15amacclojurebot actually handles that pretty gracefully
20:16TimMc&(first (doall (map println "abc")))
20:16sexpbot⟹ a b c nil
20:16TimMc&(map println "abc")
20:16sexpbot⟹ (abnil cnil nil)
20:16TimMc&(first (map println "abc"))
20:16sexpbot⟹ a nil
20:16amacsexpbot's output is what I get at my (slime/swank) repl
20:17TimMcamac: That exact string?
20:17amacyeah, but with linebreaks
20:17amaca b nil c nil nil
20:17TimMcah
20:18TimMc&(map println "abcdef")
20:18sexpbot⟹ (abnil cnil dnil enil fnil nil)
20:18TimMcOh, it is actually quite regular.
20:18amacweeeeeird
20:18TimMcI mean, I see what it is doing.
20:18amalloyTimMc: the behavior there is certainly my fault, though i don't know exactly how :P
20:18gfrlogI think it makes sense...
20:18amacactuall, not that weird
20:19amacjust return a's nil last
20:19gfrlog##(println "What's the diff between & and ##?")
20:19gfrlogthat must be the difference
20:19gfrlogone works and the other doesn't
20:19TimMc&((constantly "") (map println "abcdef"))
20:19sexpbot⟹ ""
20:20gfrloglazy
20:20amalloygfrlog: the ## at the end is messing up the regex
20:20amalloy##(println "What's the diff between & and the other thing?")
20:20sexpbot⟹ What's the diff between & and the other thing? nil
20:20gfrlog&((constantly "") (doall (map println "abcdef"))
20:20sexpbotjava.lang.Exception: EOF while reading
20:20TimMcOK, there goes that theory... I figured map would eagerly compute the first value.
20:20gfrlog&((constantly "") (doall (map println "abcdef")))
20:20sexpbot⟹ a b c d e f ""
20:20amalloythe difference is that things like ##((constantly 'this)) work mid-string
20:20sexpbot⟹ this
20:21gfrlogamalloy: so what's ## for?
20:21gfrlogoh
20:21gfrlogyou just told me
20:21amalloyindeed i did
20:21gfrlogyou were sitting there waiting for me to see it weren't you?
20:21amalloyit is an activity i have grown to enjoy
20:21gfrlogwith me or with people?
20:22amalloywell, i meant you
20:22amacamalloy: that's nifty
20:22amalloy## was one of my first contributions to sexpbot
20:22gfrlogwhy does the regex mess up my original string?
20:23amactries to parse the end of the print statement as another expr
20:23amalloyrighto
20:23gfrlogI'd like to see the regex
20:23amalloygfrlog: no you wouldn't :P
20:23amalloyit's horrible
20:23amachahaha
20:23amacthere's no such thing as a nice regex
20:24gfrlogcouldn't you just use (read-string) or some such thing after any "##"?
20:24amalloy"##(([^#]|#(?!#))+)\s*((##)?(?=.*##)|$)"
20:24gfrlog,(doc read-string)
20:24spewnThat's hardly horrible...
20:24clojurebot"([s]); Reads one object from the string s"
20:24amalloygfrlog: that would probably be best
20:24amalloybut i wanted to make it possible to end a ## section with another ## and go back to talking normally
20:25gfrlogthat would take care of the nested parentheses that regular expressions are not powerful enough for...
20:25amalloygfrlog: it does use read-string eventually
20:25gfrlogso that's why it ##'ignores what's after the first ## but before another
20:25sexpbot⟹ ignores
20:26amalloyif you commit an improvement to use read-string more sensible i'll pull it in :P
20:26gfrlogokay, which file was that in?
20:26amalloygfrlog: the regex is in .sexpbot/info.clj
20:26amalloyit gets used in src/sexpbot/plugins/clojure.clj
20:26TimMcHow does git collaboration via pull work anyway? Do I just fork, commit, push, and make a pull request?
20:26amalloyTimMc: yep
20:27amacI'm really curious how clojurebot is getting proper formatting on that ugly map
20:27gfrlogI've done that once and got rebuked for it
20:27amalloyclojurebot: source?
20:27clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
20:27TimMcAnd the recipient chooses which branch to target?
20:27amalloyTimMc: yeah
20:27TimMcThat's not very scary at all!
20:27amalloygfrlog: 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:28gfrlogamalloy: 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:28amalloyeg 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:28amalloygfrlog: he's just dumb. pull requests are mad simple
20:28gfrlogyeah we hate him
20:29amalloyif you want to go egg his house or something, sign me up
20:29gfrlogjust realized he's the owner of a prominent clojure project that I like
20:30amalloyhaha
20:30amalloywell don't tell me who
20:30gfrlognope
20:30gfrlogI'm too grownup for that
20:30gfrlognot grownup enough to have forgotten it by now
20:31gfrlogI'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:33TimMcUrgh, I don't want to print out a form, fill it out, and mail it.
20:33gfrlogTimMc: and that's why I'm not a contributor either
20:33amalloyTimMc: yeah, it's a pain, but c'est la vie. i sent mine in eventually
20:33amaclike... on paper?
20:33amachow passe
20:34TimMcamac: and a stamp and everything!
20:34gfrlogI don't own a printer, a pen, or a postal service
20:34TimMcamac: You even have to write out your email address longhand!
20:34gfrlogin cursive
20:34amacthat just seems so... wrong
20:34gfrlogI've long forgotten how to do a cursive '@'
20:35amalloygfrlog: they probably teach that in elementary schools now
20:35amacwonder why its not an online form, I'm fairly sure its still legally binding
20:35amalloythe internet makes the @ so much more important
20:36gfrlogamalloy: my son ain't lurnin no at-sine
20:36amalloyamac: rich is a closet luddite
20:36amachahahaha
20:37TimMcOr his attorney is. :-)
20:37gfrloghe writes code with a hammock instead of a build tool
20:38gfrlogamalloy: does the ## apply to all of sexpbot, or just the clojure plugin?
20:38amalloyjust clojure
20:38amalloyTimMc: good luck with that
20:39amalloygfrlog: there's an "embed" plugin that's supposed to allow something like $#command#$ but i don't think it works
20:40amac&(battle 'clojurebot)
20:40sexpbotjava.lang.Exception: Unable to resolve symbol: battle in this context
20:40gfrlogI think I'm finding it
20:40gfrlogamalloy: This whole repo has plenty of test coverage, right?
20:40amalloyhahaha
20:40amalloyno not at all
20:41amalloyclojail has decent testing because it might actually be bad if that broke
20:41amac,(kill 'sexpbot)
20:41clojurebotjava.lang.Exception: Unable to resolve symbol: kill in this context
20:41amalloybut i wrote all of those tests, and Raynes is too lazy to write any for sexpbot
20:41gfrlogclojail doesn't have any mechanism for loading code in a sandboxed way does it?
20:41amacone of these days they'll start fighting, I know it
20:41amalloygfrlog: that's practically what clojail *is*
20:42gfrlogamalloy: I don't mean just evalling, I mean vars and namespaces and all
20:42amacTimMc: funny enough, no one would probably notice
20:42amac:)
20:42gfrloge.g., two sandboxed threads with two different root bindings for the same var
20:43amalloygfrlog: no, but you can start another clojail process from the command line :P
20:44gfrlogI wonder if rebinding def would be an effective way of doing it...
20:44amalloydef is a special form
20:44gfrlogdackbutton
20:44gfrlogit's not *that* special
20:45gfrlog,(let [def 12] (+ 5 def 83 3))
20:45clojurebotDENIED
20:45gfrlog&&(let [def 12] (+ 5 def))
20:45sexpbotjava.lang.Exception: Unable to resolve symbol: & in this context
20:45gfrlog&(let [def 12] (+ 5 def))
20:45sexpbotjava.lang.SecurityException: You tripped the alarm! def is bad!
20:45gfrlogI suck at bots
20:45amalloy&(let [if 10 do 20] (do if))
20:45sexpbot⟹ 10
20:46gfrlogyou've done that before
20:47TimMc&(let [a 4 def 5] (+ a def))
20:47sexpbotjava.lang.SecurityException: You tripped the alarm! def is bad!
20:47amalloygfrlog: and yet, every time it's still funny
20:47gfrlogamalloy: that's exactly the point I was making
20:49TimMcI find the patents section of the CCA unreadable.
20:49TimMcAlso, is "Clojure" the project name?
20:49amalloyyeah
20:50TimMcAnd I use my GitHub username?
20:50TimMcMaybe I will remember to print this at school on Monday.
20:51amacI find most legalese unreadable
20:51amalloyi thought the CA was pretty readable
20:51amacmy brain can't be bothered to parse that shit, I just stare at the paper
20:51TimMcI'm pretty good at reading legalese, but I'm unsure of how to interpret "with respect to" in 3.
20:52TimMcNeeds parens.
21:13gfrlog$google polyomino tiler
21:13sexpbotFirst out of 1850 results is: Sandbox: Polyomino Tiler
21:13sexpbothttp://gfredericks.com/sandbox/polyominoes
21:15amacgfrlog: that's pretty neat
21:17amacgfrlog: what algorithm does it use for packing?
21:19gfrlogoh
21:19gfrlogum
21:19gfrloglessee
21:20gfrlogit tries everything by backtracking; just about all of the algorithmic details are how it chooses which square to try to tile next
21:21amacbeen a while since i've looked at knapsack/bin packing algorithms... something I should brush up on
21:21gfrlogevery step of the algorithm is displayed visually
21:21gfrlogI just did it as a bipartite graph, by pre-generating all possible placements
21:22gfrlognot feasible for real big grids, but works for this
21:22gfrlogit's much easier after that too, because I didn't have to think about directions or squares anymore; just graph algorithms
21:23amacdo you memoize some common open paterns to fill?
21:24gfrlogno; I've thought of that; more I've thought of memoizing unfillable spaces
21:24amacwould probably speed things up considerably
21:24gfrlogmaybe
21:25gfrlogthere would be a lot of combinations....
21:25gfrloghave to be careful about memory
21:25amactrue, but easy to address if you keep the common fillable/unfillable spaces small
21:25amacthen just stack those together to get approximate fillings, then backtrace the rest
21:26gfrlogI'm skeptical...I think there's more promise in looking at the parity of different pieces
21:26gfrlogat least in certain situations
21:27gfrloghow would you generate these common fillable spaces?
21:29amacgenerate 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:30gfrlogoh, are you using the "Random Grid" button?
21:30amacI filled mine in by hand
21:31amacbut randomizing the grid would give you a set of commonly occuring patterns
21:31gfrlogI guess I'm thinking that the 'common spaces' wouldn't come up very often
21:31gfrlogand they'd be specific to a set of polyominoes
21:32gfrlogso just by that any kind of pre-generation of the data would be implausible
21:32amacI guess it depends on how big the empty spaces are
21:32gfrlogsince the app allows any arbitrary set of polyominoes
21:32amac...there's a reason this is np-hard ;)
21:32gfrlogis it?
21:32amacyeah, I'm fairly sure
21:33gfrlogof course NP-hard is just worst case
21:33gfrlogthe algorithm works quite well in a lot of cases
21:33amalloyi 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:34gfrlog,clojure.lang.Compiler/specials
21:34clojurebot{deftype* #<DeftypeParser clojure.lang.Compiler$NewInstanceExpr$DeftypeParser@257ce0>, new #<Parser clojure.lang.Compiler$NewExpr$Parser@1bf0f5b>, quote #<Parser clojure.lang.Compiler$ConstantExpr$Pa...
21:34gfrlog,(keys clojure.lang.Compiler./specials)
21:34clojurebotjava.lang.ClassNotFoundException: clojure.lang.Compiler.
21:34amactell me more, clojurebot!
21:34amalloygfrlog: c'mon, remember the gisting
21:34amalloy&clojure.lang.Compiler/specials
21:34sexpbot⟹ {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:35gfrlogamalloy: 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:35amachaha
21:36amacalso, commas are much sexier punctuation
21:36gfrlog,(keys clojure.lang.Compiler/specials)
21:36clojurebot(deftype* new quote & var set! monitor-enter recur . case* ...)
21:36gfrlogaugh
21:36amalloyBAM!
21:36gfrlogYOU SHOT CLOJUREBOT
21:36gfrlogsomebody take his gun
21:38TimMcWhy is one of my sexprs in Emacs suddenly bright red?
21:38clojurebotemacs is best configured for Clojure with instructions at http://technomancy.us/126
21:38amalloyTimMc: it's embarrassed
21:39gfrlogamac: I'm about to rewrite that algorithm in clojure, sorta
21:39amacgfrlog: pastebin it
21:40amac:)
21:40gfrlogamac: in a month or two, sure
21:40TimMcIt compiles, though.
21:41gfrlog,(println "&(println \"Hey clojurebot\")")
21:41clojurebot&(println "Hey clojurebot")
21:41sexpbot⟹ Hey clojurebot nil
21:42gfrlogoh now I need to look up how to do quines in clojure
21:42amalloygfrlog: you won't be able to make it work
21:42amacholy shit they're talking to each other!
21:42gfrlogamalloy: why not?
21:42gfrlogI'll have to invent some kind of trampoline-quine...
21:43TimMcamalloy: Eli got a loop going between several bots in #scheme at one point.
21:43amalloyirc 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:43amacok, we've gotta do this
21:43amacand let them fight to the death
21:44TimMcamalloy: And the bots ignore each other, right? Right?
21:44amalloyTimMc: of course not. didn't you just see the counterexample?
21:44gfrlog&(println ",(println \"Hey sexpboty\")")
21:44sexpbot⟹ ,(println "Hey sexpboty") nil
21:44gfrlogget hiredman to add ## to clojurebot
21:44TimMcamalloy: Oh! Misread.
21:45amalloyheh
21:45gfrlogdoes sexpbot preface for ##(println "as well?")
21:45sexpbot⟹ as well? nil
21:45gfrlogdorn
21:45gfrlogs/o/a
21:45sexpbot<gfrlog> darn
21:46amalloyclojurebot might actually have sexpbot on ignore anyway
21:46amalloy$login
21:46sexpbotYou've been logged in.
21:46amalloy$say #clojure ,1
21:46sexpbot,1
21:46clojurebot1
21:46amalloy$logout
21:46sexpbotYou've been logged out.
21:46gfrlogholy crap it's like he just stepped through a wall or something
21:47amalloy?
21:47gfrlogyour $login trick
21:47gfrlogit was very sexp
21:47amalloy*chuckle*
21:47amac&(println ",(+ 1 2)")
21:47sexpbot⟹ ,(+ 1 2) nil
21:48amacstupid arrow
21:48gfrloglog back in and turn off the arrow
21:48amalloygfrlog: that's actually hardcoded
21:48gfrlogeverything is dynamic at runtime
21:48gfrlogrebind some vars, come on!
21:48TimMcgfrlog: Ha!
21:48TimMc$say $clojure hello
21:48sexpbotTimMc: It is not the case that you don't not unhave insufficient privileges to do this.
21:49TimMcAh, OK.
21:49TimMcAnd I mistyped anyway.
21:49amalloy_$login
21:49amaclol
21:49gfrloghad to try
21:49amalloygfrlog: wouldn't work even if i let you have my nick
21:49amalloyyou'd need my IP too
21:50amacthat can be spoofed, as long as the response isn't necessary
21:50amalloyamac: yeah
21:50gfrlogwhich it isn't...
21:51gfrlogwell
21:51gfrlogmaybe it is who knows
21:51amacprobably not
21:51amalloyprobly not
21:51gfrlogdang layers upon layers of networking protocols
21:51gfrlogdoesn't it use TCP?
21:51gfrlog3-step handshake?
21:52TimMcYou can spoof a single packet, and that's about it.
21:52gfrlogcome 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:53amacyou underestimate my ability to skip class
21:53gfrloghmm
21:53gfrlogI think I was making a joke rather than a point
21:53amalloyyeah, but it sounded like a joke about your inability to get a point across
21:53gfrlogI'm not very good at jokes
21:54gfrlogI take a shotgun approach
21:54TimMcbrb, need to pour alginate on my housemate
21:55amacTimMc: don't we all.
22:07TimMcsexpbot: commands?
22:07TimMcBah, nevermind.
22:07TimMcIt's in my history,
22:08amalloyspeaking of which, if anyone wants to get their feet wet writing for sexpbot, he could use a commands? function :P
22:08amac&(learn 'commands)
22:08sexpbotjava.lang.Exception: Unable to resolve symbol: learn in this context
22:08amacI tried
22:10amalloygood effort
22:11TimMcsexpbot: mail clojurebot ,1
22:11sexpbotMessage saved.
22:11TimMcclojurebot: hi
22:11clojurebotI don't understand.
22:11amalloyTimMc: interesting attack vector
22:11TimMcDoes it use privmsg?
22:11amalloyyeah
22:12TimMcbah
22:12TimMcAlso, switching to visual bell. These speakers are turned up too high. >_<
22:13TimMcamalloy: I've also considering using the title of a dynamic page on a site I control.
22:15TimMcclojurebot: ,(println "s/I/,'")
22:15clojurebot,(println "clojure bot is the best!")
22:15TimMcwhat
22:15amalloy*blink*
22:16amacit's... alive
22:16amalloyoh
22:16TimMcwhat the shit
22:16amalloycomma only triggers eval if it's the very first char
22:16amalloythis was his canned response to some factoid
22:17amacdoesn't he also just respond randomly to a small percentage of messages?
22:18amacclojurebot: ,(println "s/I,'")
22:18clojurebot,(println "clojure is the best")
22:18amacscratch that, its reproducable
22:19amacer, almost
22:20spewnclojurebot: println
22:20clojurebot,(println "clojure bot is the best!")
22:21TimMcclojurebot: setup
22:21clojurebotsimple setup is http://www.thelastcitadel.com/dirt-simple-clojure
22:21TimMc,(println "s/.*/,1")
22:21clojurebots/.*/,1
22:21sexpbot<clojurebot> ,1,1
22:22TimMcOh, right.
22:35amac,(do (println "#*(println \"stuck\"") (println "s/*/#))
22:35clojurebotEOF while reading string
22:38amac,(do (println "#*(println \"stuck\")") (println "s/*/#"))
22:38clojurebot#*(println "stuck")
22:38clojurebots/*/#
22:39spewnTurns out that double replacement there is not a bug in sexpbot.
22:40spewn,(.replaceAll "foobar" ".*" "baz")
22:40clojurebot"bazbaz"
22:40spewnDoes that look weird to anyone else?
22:41johnmn3were you expecting "baz" ?
22:41spewnI was.
22:42spewn,(.replaceAll "foobar" "^.*" "baz")
22:42clojurebot"baz"
22:42mecthats really weird
22:42spewnI would expect .* to match the entire string regardless of the anchor there.
22:42johnmn3I dunno. "All" might seem strange otherwise
22:43spewn,(.replaceFirst "foobar" ".*" "baz")
22:43clojurebot"baz"
22:43spewnWhat's the second?
22:44johnmn3hmm. * grabs the whole string that time
22:44spewnAs it always should.
22:45spewn,(.replaceAll "foobar" ".*?" "baz")
22:45clojurebot"bazfbazobazobazbbazabazrbaz"
22:45spewnNongreedy finds all zero-width spots, I see.
22:51amalloy.* matches the whole string once, and then the zero-width spot after the end of the string
22:52amalloyyoucould use .+
22:54dfanIs there a way to do quot and rem simultaneously?
22:54amalloyjuxt
22:54amalloy&((juxt quot rem) 10 3)
22:54sexpbot⟹ [3 1]
22:55dfanOK, but that doesn't actually save any time, right?
22:55amalloyright
22:55dfanOK, thanks
22:56TimMcThe JVM might not provide a divmod operator.
22:56TimMc(even though it is available on most ISAs)
22:58spewnamalloy: 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:58spewnBut why?
22:59amalloyspewn: huh? ^ would change my imagined behavior too
22:59amalloy&(re-seq #".*" "test")
22:59sexpbot⟹ ("test" "")
22:59spewnOh, silly of me. Of course it would.
22:59TimMcI consider it broken.
22:59amalloyand arguably wouldn't change yours
23:00amalloyTimMc: then you're not thinking hard enough. this is exactly the behavior you can derive from the definition of *
23:00TimMcIsn't * greedy by default?
23:00amalloyuh huh...
23:02TimMcWhat am I missing?
23:02TimMcI use regex *all the time*.
23:03TimMc,(.replaceAll "foobar" ".*" "12")
23:03clojurebot"1212"
23:03spewnTimMc: .* 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:04TimMcThat's...
23:05TimMcOK, I think I can accept that. Maybe.
23:05spewnAssuming 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:05TimMcI suppose the semantics for replace are tricky.
23:05TimMcReplace involves restarting the matching, but match doesn't.
23:06TimMcs/.+/s\/.+\/,1\//
23:07TimMc,(use '[clojure.contrib.bot-quine])
23:07clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/bot_quine__init.class or clojure/contrib/bot_quine.clj on classpath:
23:14TimMcIt does?
23:15TimMcAh, nvm.
23:15amalloyand i even recently went through some gyrations to create an unhygenic macro on purpose. even so, i'm glad it's hard :P
23:17joshua___thunk, your a fellow clojurian! Excellent!
23:17thunkAhoy! I mostly lurk here
23:17amaceveryone mostly lurks here
23:18amac:)
23:19TimMcCan the core collections be safely serialized and restored?
23:21amalloyTimMc: pr, read-string?
23:21TimMcpr... nice
23:23amalloyindeed, it's clever enough that if it were my original idea i'd be proud of it
23:23amac,(doc pr)
23:23clojurebot"([] [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:24amachandy.
23:25TimMcamalloy: ...but it won't work here. There are Java objects in the collection.
23:25amalloyprint-dup
23:25TimMcNo docstring!
23:25amac,(doc print-dup)
23:25clojurebot"; "
23:25amacbooooooo
23:26amac,(source print-dup)
23:26clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
23:26amalloyif the java classes you'll need to deal with are a closed set, you can implement print-dup for them
23:26amalloyit's a multimethod for printing readable strings
23:26TimMcOh, sweet.
23:27TimMcIs there a read-dup?
23:27TimMc(There isn't by that name.)
23:27amalloyTimMc: it's called read-string
23:27amalloy&(print-dup *ns*)
23:27sexpbotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$fn--3893$fn
23:27amalloy&(print-dup *out* *ns*)
23:27sexpbotjava.lang.IllegalArgumentException: No method in multimethod 'print-dup' for dispatch value: class java.io.StringWriter
23:27amalloy&(print-dup *ns* *out*)
23:27sexpbot⟹ #=(find-ns sandbox11264)nil
23:28TimMcSo, I should print the Java objects as calls to their constructors?
23:28amalloyyeah
23:28TimMcNice.
23:28amalloyTimMc: when the compiler sees a #=(...) form it evaluates the code and uses it in place of the original #= form
23:29amalloythe bots don't allow it, but try it in your repl
23:30TimMcI'm entirely sure that is not documented on http://clojure.org/reader
23:30amalloyyeah, it's hard to find
23:30amalloy$google clojure print-dup
23:30sexpbotFirst out of 1150 results is: Serializing Clojure data structures - Lisp - Snipplr Social ...
23:30sexpbothttp://snipplr.com/view/13559/serializing-clojure-data-structures/
23:39TimMcwhee
23:45skelternet(doc print-dup) gave me a bunch o'nils
23:45clojurebot"; "
23:46TimMcskelternet: It's a multimethod you implement. Check the source. :-/
23:47amalloyyou're not a real OSS developer until you tell someone to read the source :P
23:47TimMcI said it with a chagrined emoticon!
23:48amalloyi don't think that makes it unhappen
23:48amalloyi'm sorry TimMc, there's just no avoiding it...you're a nerd now
23:48TimMcHaw, that happened a while ago.
23:49skelternetThe 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:50amalloyskelternet: i'd say structure instead of sequence, just because it's more generic
23:51amalloybut yeah, that's one of lisp's strengths
23:52skelternetit seems under-represented
23:52amalloyskelternet: it's a direct consequence of the syntax being so minimal
23:52skelternetor I'm not googling for the right things
23:52amalloyheh
23:53amalloydang, i have a favorite article about this subject but i can't remember where it is
23:53skelternetI'd love to read it
23:54TimMcamalloy: Happen to know offhand if the Clojure reader supports circular data structures using the sharp syntax?
23:54TimMc#3#, etc.
23:54amalloyTimMc: yes; no
23:55TimMcOK
23:55amalloyaha! skelternet: http://www.defmacro.org/ramblings/lisp.html
23:56amalloyit's only somewhat topical but still interesting
23:57skelternetthank you!
23:57amalloyit's really hard to google for "sexprs are like xml but not awful"
23:57amalloybecause pretty much everyone says that
23:57skelternet:)
23:59pdknah
23:59pdki think they just say the xml is awful part
23:59pdkat least outside of our little circles
23:59amalloypdk: outside our little circles everyone says xml is awesome