#clojure logs

2010-11-15

00:26amalloythere's some kind of reader macro that causes code to be executed even when you're reading it with read-string, right? what is that, and how do i disable it?
00:28dnolenamalloy: ?
00:28dnolen,(read-string "(+ 4 5)")
00:28clojurebot(+ 4 5)
00:29amalloydnolen: i remember hearing in #clojure a while ago that there's some syntax you can put into the string to make it actually execute the code
00:29amalloyor execute some code, anyway
00:30dnolen,(-> "(+ 4 5)" read-string eval)
00:30clojurebotDENIED
00:32cemerick&(read-string "#=(+ 4 5)")
00:32sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
00:32cemerick,(read-string "#=(+ 4 5)")
00:32clojurebotjava.lang.RuntimeException: java.lang.Exception: EvalReader not allowed when *read-eval* is false.
00:32cemerickamalloy: whatever, ^^
00:33amalloyah, thank you, cemerick
00:33cemerickamalloy: Warning, there be dragons. Very limited set of things you can do in that context, and it's all undocumented.
00:33amalloyi note that #= isn't in the clojure page on reader
00:33cemerickyes, all very experimental
00:34amalloycemerick: yes, i want to restrict that to #{}, not actually use it :P
00:34cemerickrelated to the print-dup stuff in core_print.clj and elsewhere
00:35cemerickamalloy: ?
00:35cemerick&(read-string "#{1 2 3}")
00:35sexpbot⟹ #{1 2 3}
00:35amalloyer
00:35cemericki.e. no #= needed?
00:35amalloynono
00:35amalloyi mean, i want the empty set of #= operations :P
00:35amalloyie, none
00:35cemerickoh, oh :-)
00:36amalloywhich just means setting *read-eval* to false, it seems
00:36cemerickthis is sandboxing?
00:36amalloycemerick: yeah, more or less
00:36cemerickhot topic again these days
00:37amalloyi'm not actually eval'ing the code - there's already a sandbox for that - but i want to use read-string to identify what the first node/tree/object is
00:37amalloyand not let someone hack me at that point before the real sandbox takes over
00:37cemericksure
00:52pppaul$8ball more chocolate?
00:52sexpbotpppaul: As I see it, yes.
00:58amalloyis there a convenient function that always returns nil, or do i have to write out (constantly nil)?
01:02cemerickamalloy: #(do %& nil)? :-P
01:02cemerickconstantly is pretty decent
01:02amalloycemerick: sure, i'm not complaining very loudly
01:03amalloybut i wouldn't mind if the language had already implemented everything i can imagine ever wanting
01:03cemerick(make-me-a-sandwich!) :-D
01:03cemerick&(make-me-a-sandwich!)
01:03sexpbotjava.lang.Exception: Unable to resolve symbol: make-me-a-sandwich! in this context
01:03cemerickbummer. :-(
01:09amalloy&(constantly "Delicious sandwiches for cemerick!") ; call this when you get hungry
01:09sexpbot⟹ #<core$constantly$fn__3551 clojure.core$constantly$fn__3551@f49909>
01:10cemerick:-)
01:10RaynesMan.... It's only 12AM. :<
01:10RaynesI thought I'd wake up later than this...
01:11amalloyRaynes: i get the feeling you're drifting farther east every day
01:11RaynesIs github back up? I'm afraid to check.
01:11amalloyit was working fine an hour ago
01:11RaynesHow 'bout clojars? Is it teh fixed?
01:12amalloyRaynes: if every server you know is broken, it's probably just you
01:12Raynesamalloy: No, it was everybody.
01:12Raynesamalloy: lrenn broke clojars, and Github faced a major outage.
01:13Raynesstatus.github.com
01:13Rayneshaskell.org has also been down for two days.
01:13RaynesShit, even reddit went down for a while.
01:13RaynesThe internet is falling apart.
01:13amalloyRaynes: wild. i'm glad i wasn't trying to work
01:15amalloyRaynes: wrapping up a change to make sexpbot not catch the # # syntax if the next token isn't some kind of collection. i assume this is a feature you would like?
01:16RaynesSure. I don't see anybody embedding stuff like ###'print or ##0
01:16sexpbot#'print or ⟹ #'clojure.core/print
01:16sexpbot0 ⟹ 0
01:16RaynesOr...
01:16Raynesamalloy: You could just make it so that it tries to `read` what comes after ##.
01:16sexpbotjava.lang.Exception: Can't take value of a macro: #'sandbox6588/dot
01:17amalloyRaynes: that's how i'm doing it
01:17amalloywell
01:17amalloynot really i guess
01:17amalloythat's my planned next step though
01:17RaynesWell, I guess that wouldn't help in this particular situation.
01:18RaynesWell, I have to go see if that dog is still breathing.
01:29LauJensenMorning all
01:40DeranderLauJensen: good morning sir
01:40zmyrgel`hi, how can I replace digits in a string with E letters?
01:41zmyrgel`like if a string is "pp3pp" it becomes "ppEEEpp"
01:42Mimisbrunnrjava.lang.String.replace( old, new );
01:42zmyrgel`I'd like something easier, as the digits run from 1 to 8
01:43zmyrgel`like use regexp to match the digit and then replace the matching part with that many \E chars
01:44zmyrgel`clojure.contrib.string seems to have some functions but I don't know how to use them to achieve this
01:46Mimisbrunnreh you can probably do it with map and a nice lamdba function
01:48shachafzmyrgel`: Is it just digits from 1 to 8, or possibly-multi-digit numbers made of those digits?
01:49zmyrgel`it's just 1 to 8, a single digit
01:49zmyrgel`http://richhickey.github.com/clojure-contrib/string-api.html#clojure.contrib.string/replace-by
01:49zmyrgel`that seems quite promising
02:03LauJensen&(.replaceAll "abc3def2" "[0-9]" "E")
02:03sexpbot⟹ "abcEdefE"
02:04LauJensenzmyrgel`: looks good enough to me
02:04zmyrgel`"abc3def2" should become "abcEEEdefEE"
02:05LauJensenaha
02:05zmyrgel`the digits tell how many E letters to add
02:06zmyrgel`I was going for something like (replace-by #"\d" #(str (repeat (Integer/parseInt %) \E)) "1ppp3p")
02:10zmyrgel`ha, the above seems to work once I switched to use clojure.contrib.string/repeat instead of core version
02:10RaynesLauJensen: Remember http://blog.raynes.me/?p=37 ? Well, when Github's DB got screwed up, my gists got all mixed up. Before I fixed them, one of the gists that were appearing in the post was CL code. What are the odds, eh?
02:12RaynesOut of all the languages that gist could have been in...
02:13RaynesI almost left it there, but figured people would notice.
02:23yayitsweiwhat's the idiomatic way to write combine numbers using a nested loop? for example, i want to list all the combinations of a^b for 2 <= a,b <= 100
02:23yayitsweicurrently, I have (take 5 (mapcat (fn [n] (map #(pow n %) (range 2 101))) (range 2 101)))
02:23yayitsweierr, ignore the "take 5"
02:26LauJensenRaynes: Terrible :( I hate relying on outside services
02:26RaynesLauJensen: And I understand why now. :)
02:27RaynesThis'll likely be the first and only post using gist.
02:28yayitsweito answer my own question, (for [a (range 2 101) b (range 2 101)] (expt a b)) would work
02:33zmyrgel`is there a functional way to get string index and char at that index while going though a string?
02:34Raynes&(doc keep-indexed)
02:34sexpbot⟹ "([f coll]); Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return values will be included. f must be free of side-effects."
02:35Raynes&(doc clojure.contrib.seq/indexed)
02:35sexpbotjava.lang.Exception: Unable to resolve var: clojure.contrib.seq/indexed in this context
02:35RaynesWell, anyway.
02:35zmyrgel`hmm
02:36zmyrgel`so I'm trying to init my chess board from a string which has the pieces at their index
02:36zmyrgel`the game board is a simple 128-elem vector
02:37zmyrgel`the string is 128 char like "rnbqkbnreeeeeeee...." and I have a function to add pieces to the board
02:38zmyrgel`fill-square [board index piece-value]
02:38zmyrgel`could I use reduce to init my board from the string somehow?
02:43Rayneszmyrgel`: If I'm right about what you're doing, then sure.
02:44zmyrgel`so does the keep-indexed return index and char from the string?
02:44Rayneszmyrgel`: You could reduce the string into the board. If the result of fill-square is a new board, then make the new board the result of the reducing function, and at the end, you'll have your new board. Let me see if I can think of a good example.
02:45Rayneskeep-indexed wont really work here. You need indexed from clojure.contrib.seq
02:47zmyrgel`ok
02:47Raynes(reduce (fn [board [index item]] ..use fill-square to create the new board with the piece attached..) initial-board string)
02:47RaynesSomething like that.
02:48Raynes(indexed string), of course.
02:48zmyrgel`can I refer to indexed's return values with \1 and \2?
02:50Rayneszmyrgel`: If you call indexed on a string, I believe it will return a sequence like ([0 \a] [1 \b] ...)
02:53zmyrgel`Raynes: http://clojure.pastebin.com/QPds9H3J
02:53zmyrgel`here's my current version
02:57zmyrgel`can I replace the board arg with (init-game-board) on that/
02:57zmyrgel`?
02:58RaynesYou can't do \1 and \2 here.
02:58zmyrgel`ok
02:59RaynesYou'll have to make the function (fn [board [index piece]] (fill-square board index (piece-char->value piece)))
03:00zmyrgel`ah
03:01zmyrgel`seems to work now :)
03:01RaynesGreat! :)
03:02zmyrgel`and my code base got 20 lines shorter :)
03:02Rayneszmyrgel`: In shorthand anonymous functions like #(+ % %2), % and %2 refer to the arguments that have been passed to the function. However, since we needed to destructure the second argument, we needed to use (fn [] ..)
03:03zmyrgel`yeah, I haven't used the destructuring that much
03:05zmyrgel`there's still some horrible stuff that would need to be replaced in my chess engine
03:05zmyrgel`though first I should try to spot why some illegal moves still get approved
03:08zmyrgel`btw, is there a way to overload a function?
03:09zmyrgel`I mean, I have two functions to create moves, one takes 3 args and other 1 arg but both return a same move record
03:10talioszmyrgel: yep - just have multiple forms of param/body in defn - http://clojure.org/special_forms shows that in the example
03:11zmyrgeltalios: ok, thanks
03:59fbru02I'm calling a method in a Java library which in turns calls another method, this last method makes an explicit cast from Integer to String, but somehow Clojure gets a ClassCastException, why could this be?
04:08cais2002fbru02: can u provide more details?
04:10fbru02cais2002: yes just a sec
04:12esjmorning
04:12fbru02cais2002: here https://gist.github.com/700192 , this is basically the problem
04:18cais2002fbru02: do you pass an int value as key? maybe you could convert it to string manually before passing it to .sadd
04:21fbru02cais2002: sorry i didn't quite understand you, where am i passing an int?
04:26cais2002fbru02: isn't "key" a parameter passed into the .sadd method call?
04:36fbru02cais2002: sorry, mi connection died, yes key is a a parameter to the .sadd method
04:40cais2002fbru02: do u have an example of the line that invokes (setr (RedisSet. xxx) yyy value) ? I guess xxx is not a String
04:41fbru02cais2002: xxx in your example i'm invoking it with a string, and still i get the same ClassCastException :(
04:46cais2002fbru02: I think protocol.read(inputStream) is returning int? is that where line 121 is? sorry, I am not familiar with redis
04:47fbru02cais2002: yeah my guess is that too... my guess is that (String) part is not casting correctly
04:55cais2002fbru02: is status code by definition an int? could be a bug in jedis. but I could be wrong
05:01fbru02cais2002: in jedis the definition for read is : public Object read(RedisInputStream is) which then getStatusCodeReply converts to String by doing (String)
05:01fbru02cais2002: seems perfectly valid java to me don't know why is not working when called from Clojure
05:05Chousukewhat, java allows you to cast ints to strings? :/
05:05ChousukeThat doesn't sound right.
05:05fbru02Chousuke: nop, but from Object to String yes
05:05fbru02AFAIK
05:06Chousukeright. that's fine.
05:06Chousukeas long as the object is a String, anyway
05:07fbru02Chousuke: the problem as i imagine it, is that Clojure is deciding "oh this is an int" (or any oter numeric type) before I can tell him that it is a String really
05:08Chousukeadd type hints to the method call?
05:08Chousukeare there overloads?
05:08fbru02no overloads, how do i add type hints ?
05:08Chousuke(.sadd #^String key #^String value)
05:08Chousukein the -> form
05:08fbru02oh cool the metadata
05:09Chousukethat'll at least prevent Clojure from picking the wrong method
05:09Chousukeof course, if your key or value is an integer you'll still get the error
05:12fbru02Chousuke: thanks !
05:42octewhat's the best way of defining a unction with an optional argument in clojure?
05:43AWizzArdocte: you can do (defn f ([x] (f x 10)) ([x y] (+ x y)))
05:43AWizzArdThis defines f for two arities. (f 5) will call (f 5 10).
05:44LauJensenAWizzArd: Did you release yet?
05:45octeAWizzArd, thanks, just what i was looking for :)
08:48tonylmorning
09:07mattmitchellis it possible to destructure an argument that is a single value map, so that i can get the key and value without using let?
09:10mfexmattmitchell: can you elaborate on why you might need that and why let is not an acceptable way?
09:10tonylyou can do it like this: (defn foo [{k v}] ...) i think
09:11mattmitchellmfex: well don't know if it's really what i need, just curious
09:11mattmitchelltonyl: cool i'll give that a try
09:13Raynesmattmitchell: The easiest way would be to just call first on the map and pass that to your function.
09:13tonylmy bad, u can destructure, but the key won't be passed
09:13tonyl(defn foo [{k :v}] [k])
09:14tonylthen the passed map should have a key named :v to work
09:16mattmitchelltonyl: ahh right. that makes sense.
09:17mattmitchellRaynes: yeah good idea
09:18mfexthere's also the key and val functions: (key (first {:a 1})) and (val (first {:a 1}))
09:21mattmitchellthanks everybody!
10:01hsuhanyone used ring's wrap-session ?
10:42pairBest textmate bundle for clojure, anyone?
10:46pairOther than "uninstall it and use Emacs".
10:48fogus_pair: are there multiple options?
10:50tonylI've heard textmate with the lisp bundle works fine with clojure
10:50pairGoogle found three, all on github. But github's search only found two. Figured there'd be opinions on here...
10:51pairThanks tonyl.
11:22rpgI have been trying to use swank-clojure from leiningen, but find that the slime connection keeps crashing with "unreadable message" errors. Is there an easy solution to this?
11:23clojurebotthe leiningen screencast is on full disclojure: http://vimeo.com/8934942
11:23raekrpg: which versions of slime and swank are you using?
11:23rpgslime from CVS a couple of days ago. swank-clojure pulled by leiningen
11:24rpgtwo days ago
11:24rpgLIME 2010-11-07
11:24rpgs/LIME/SLIME/
11:24sexpbot<rpg> SLIME 2010-11-07
11:24raekthe bleeding edge version of slime has been known to break compability
11:25rpgraek: Unfortunately, SLIME has no stable version. It's CVS or nothing...
11:25rpg:-(
11:25raekrpg: the version in ELPA should work
11:25rpgraek: OK, but I have no idea what damage that will do to my accustomed SBCL hacking....
11:26raekthe docs for swank-clojure lists some preferences: https://github.com/technomancy/swank-clojure
11:26rpgraek: Not the fault of swank-clojure --- I wish there was more version discipline in SLIME.
11:29rpgraek: thanks.
11:31raekI'm sorry that I can't give you any better answer than "oh, I use this old version I found here, and it works for me"... :)
11:46raekit's a bit scary that every other line in the TOC is marked with "Don't do this"...
11:47esjthat's funny
11:49raekI think the chapter about the executor framework could be useful for Clojurians too
11:49AWizzArd`(foo ~'object) produces (foo object). I want to type-hint object being a date, so ==> (foo ^Date object). Do I need something like `(foo (with-meta ~'object (assoc (meta ~'object) :tag Date)))? Or is there a better way to achieve this, when the actual type can vary?
11:50rpgraek: as a side note, given the problems with slime/swank compatibility, maybe it would be appropriate to modify swank clojure to simply catch stuff it can't parse, log it, and continue, instead of falling over...
11:50raekAWizzArd: with-meta is not done during compile time
11:50raekAWizzArd: maybe you could do a `(foo ~(with-meta 'object ...))
11:52AWizzArdraek: but the principle idea to use meta & with-meta is correct yes?
11:52tonylI don't get the need for ArrayMaps explained in http://clojure.org/data_structures
11:53tonylI think I am missing something here, are they Java arrays that can be used with maps fns?
11:53raekAWizzArd: do you always have 'object, or do you get that term from a parameter?
11:53raekAWizzArd: you could also do `(foo ~' ^Date object), I think
11:54stuartsierratonyl: no, just a map that happens to be stored as an array of key-value pairs, which is slightly more efficient for very small maps
11:54AWizzArdraek: I will probably enforce it to be always named object. But the type that I want to hint - that will vary.
11:54raekmaybe one should write that as `(foo ~(quote ^Date object)) for clarity...
11:54raek(meta 'foo)
11:54raek,(meta 'foo)
11:54clojurebotnil
11:54tonyloh, wouldn't that make you loose the constant accessibility of values
11:55raekit doesn't seem like symbols have any metadata by default, so a (with-meta 'object {:tag <something>}) would perhaps be sufficient
11:55raek,(doc vary-meta)
11:55clojurebot"([obj f & args]); Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata."
11:58technomancyrpg: that would be nice. a lot of people complain about using swank-clojure and CL simultaneously, but precious few ever do anything about it.
11:59rpgtechnomancy: A challenge is that the two are maintained in divorced revision control systems. Also, I am a novice @ clojure so was pulling swank-clojure from technomancy, rather than using the git copy.
12:00rpgI tried to use the git copy, but didn't understand the instructions (as a novice, "what is this leiningen project of which you speak?")
12:02rpgI have only a binary, and nothing to attempt to cargo-cult fixes into.
12:05amalloytonyl: if the type you want to hint to isn't always the same, i don't think type-hinting will be any better than using a java cast
12:05AWizzArdraek: yes, this vary-meta can be good
12:05amalloy(.cast Date 'obj) ; will return a Date object
12:06amalloyer but without the quote :P
12:07chouserThe video for my Strange Loop talk, "Clojure's Solutions to the Expression Problem" is up: http://bit.ly/9RMQGo
12:07hiredman:D
12:07tonylok mm
12:07amalloytonyl: actually i just tried it in a REPL, and i think i'm wrong
12:08amalloy(defn f [x] (.length (cast String x))) ; reflection
12:08amalloy(defn f [x] (.length ^String x)) ; no reflection
12:08esjchouser: I really did wonder why you had all those photobombers on slide 2.... audio is so useful :)
12:08clojurebotIn Ordnung
12:08amalloywhy can't the compiler figure out the first one?
12:10amalloy(it doesn't do any better with .cast, which surprises me more)
12:11chouseresj: :-)
12:11tonyl(doc cast)
12:11clojurebot"([c x]); Throws a ClassCastException if x is not a c, else returns x."
12:12tonylcast is not much help
12:12amalloytonyl: yes, i figured that out. but .cast should work
12:12tonylwhat class is .cast from?
12:12tonylis not from object
12:13amalloyhm. it should be from Class, but i can't find it now
12:13amalloyoh. i was looking at 1.4 docs :P
12:13rpgtechnomancy: seems like read-swank-message prints a System/err for unreadable message, and then throws it. That takes down the connection (at least the one I have). Any reason to throw this instead of logging it? There's no one to catch it, is there?
12:13tonylthere is a Class named Class?
12:13amalloytonyl: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#cast%28java.lang.Object%29
12:13tonylthat is confusing lol
12:14amalloytonyl: maybe, but it's necessary for a lot of things
12:15tonylwell, I am guessing it doesn't help because maybe the T is also a generic Object
12:15amalloyeg, this.getClass() == other.getClass() tests whether two objects are the same class. it's much harder to do this with instanceOf
12:15amalloytonyl: String.class is of type Class<String>
12:15amalloyso in theory this should work - the java compiler gets it right
12:15tonylbut with clojure it doesn't
12:16amalloywell, the clojure compiler doesn't
12:16tonylok
12:16tonylso metadata in clojure
12:18chouser(doc cast)
12:18clojurebot"([c x]); Throws a ClassCastException if x is not a c, else returns x."
12:19tonyl$source cast
12:19sexpbotcast is http://is.gd/h8LH2
12:21amalloychouser: i realize now that (cast) can't really type-hint the return type effectively since clojure doesn't have generics, but .cast should go straight to java, and the return type will be known, so long as String.class is treated as a constant
12:26chouseramalloy: (defmacro cast* [class obj] `^{:tag ~class} (.cast ~class ~obj))
12:27amalloychouser: ah, well done. yes, it works as a macro, but cast isn't implemented that way
12:27chouserright
12:27amalloyfor good reasons, of course, but it would be nice to have both
12:27chouserI suspect that's intentional -- keeping the type hint and the assertion separate, non-compound.
12:28amalloychouser: more likely it's because you don't always have a class literal
12:28chouseroh, sure
12:28chousergood point
12:33amalloyand i guess whenever you do have a literal, you can use it to type-hint
12:34chouserif the type isn't known at compile time, you'll have to do reflection at runtime anyway.
12:34amalloyright
12:37amalloyi note that ^hinting doesn't throw an exception on mismatched types until you try to use the wrong class; just storing the wrong class is okay
12:38amalloywhich seems reasonable, but tonyl, you may want to use cast as well as hinting
12:38chouserright, a hint is not an assertion
12:39tonyli use both and actually use chouser's cast* for this project, which makes sense since I use class literals
12:39tonylthanks for the help guys
12:43amalloychouser: i don't quite understand the style/idiom for *, still. doesn't foo* usually indicate a "you probably shouldn't use this" internal version of foo? it seems like cast* is the opposite, and i might call it cast+
12:43tonylcast+ seems to me for multiple casts
12:43chouseramalloy: as far as I know, foo* in general just means "like foo"
12:44chouserlike a prime tick mark in math. (x, y), (x', y')
12:44chouserthere are specific cases where the foo* version isn't meant to be used, but I don't think that's always the case.
12:44amalloychouser: mmmm, okay. speaking of which, doesn't 1.3 introduce +', *', and so forth?
12:45chouserbut none of that is really meant to defend the name "cast*" Perhaps I should have used something else. "hint-cast" or something
12:45chouseramalloy: yes
12:45chouserclearly +* ** etc would have been less confusing. :-)
12:45amalloyhm. when i enter +' in my 1.2 repl, it doesn't evaluate as a symbol
12:45amalloychouser: har har. i'm not advocating that :P
12:45chouseramalloy: yeah, the reader changed to support that
12:45amalloyah
12:46hiredmanshould just use the unicode prime mark
12:47hiredmanx′
12:47tonylhow do you get that mark?
12:48amalloytonyl: my advice: don't :P
12:48tonylyeah, can't seem to find it in my keyboard
12:48tonyli like hint-cast for the name though
12:49amalloy&[\u1234 \u2351 \u4351]
12:49sexpbot⟹ [\ሴ \⍑ \䍑]
12:49amalloytonyl: characters selected at random from unicode
12:50tonylyeah my keyboard is not unicode friendly
12:50amalloy&\u2032
12:50sexpbot⟹ \′
12:51tonylthere you go
12:51tonyl:P
12:51amalloy&\u2057 ; extra ridiculous
12:51sexpbot⟹ \⁗
12:51tonylawesome
13:17quizmehow do you walk a social graph like this? {"david" '("sally" "ralph" "mark") "sally" '("ralph" "buddy") "buddy" '("david" "sally")}
13:17quizmei just want to count how big sally's social network is.
13:17amalloyquizme: what do you mean, walk it? you want to get out a series of pairs, like [david sally]. [david ralph]?
13:17quizmeas in friend of a friend of a friend . . . .
13:19quizmeamalloy: i'm thinking there will be separate (disjoint) social networks, and i want to count how many members are in one starting with one person.
13:20amalloyquizme: this is trickier. maybe clojure.walk/prewalk will be useful
13:20quizmebut it's going to be big, so i dont' want to execute a memory-consuming algorithm.
13:20jarpiainquizme: there's lazy-walk in clojure.contrib.graph
13:20quizmethanks.
13:20quizmei'll look at both
13:21amalloyyeah, clojure.walk doesn't look useful for this case actually
13:23amalloyi'm not sure there's a way to do this without using the stack, so memory consumption will be an issue
13:23quizmeamalloy: it can hold N copies of the social network in memory, for small N.
13:24amalloyquizme: but you'll have to hold your place for every branch in the network. when you recur into sally's friend mark, you'll have to remember that you're supposed to look at eva next, for example
13:25amalloy(only for every branch you actually traverse, of course)
13:26quizmeamalloy: yeah that's the kind of problem i'm running into.
13:26amalloyyou can put that memory in the heap or in the stack depending on how you want to do it, but the memory consumption will have to be O(mn) where n is the number of links you traverse to get to a friend, and m is the branching factor
13:27amalloyn will tend to be log-base-m of the size of the input tree, i think
13:29amalloy*disclaimer: i look forward to being proven wrong
13:35Tordmor,(clojure.string/split "1xxxx2xx3xxxxx4" #"x*")
13:35clojurebotjava.lang.ClassNotFoundException: clojure.string
13:36amalloy&(require 'clojure.string)
13:36sexpbot⟹ nil
13:36amalloy&(clojure.string/split "1xxxx2xx3xxxxx4" #"x*")
13:36sexpbot⟹ ["" "1" "" "2" "" "3" "" "4"]
13:36Tordmorthx amalloy
13:37amalloywelcome Tordmor. also, i'm 95% certain you don't mean x*
13:37amalloy&(clojure.string/split "12345" #"x*")
13:37sexpbot⟹ ["" "1" "2" "3" "4" "5"]
13:37amalloy&(clojure.string/split "12345" #"x+")
13:37sexpbot⟹ ["12345"]
13:37Tordmorshouldn't * be greedy?
13:37TordmorAh, Ok, got it. Thanks amalloy
13:37amalloyTordmor: yes, but it allows a match of length 0
13:37qbg&(clojure.string/split "1xxxx2xx3xxxxx4" #"x+")
13:37sexpbot⟹ ["1" "2" "3" "4"]
13:38TordmorIt's obvious once you think about it :)
13:38amalloyindeed. a mistake everyone should make twice, and then never again
13:41amalloyhey rhickey, quick question if you don't mind. i was discussing with chouser earlier why .cast doesn't include a type-hint when you're casting with a class literal. couldn't (.cast String "foo") return a String, since String.class is a Class<String>?
13:41Tordmor&(clojure.string/split "1xx2xx3xx4" 2)
13:41sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.regex.Pattern
13:41Tordmor&(clojure.string/split "1xx2xx3xx4" #"x+" 2)
13:41sexpbot⟹ ["1" "2xx3xx4"]
13:42Tordmorshouldn't that be ["1" "2" "3xx4"] ? split twice?
13:42amalloyTordmor: off by one. it means it will return a vector of at most N
13:42Tordmor&(clojure.string/split "1xx2xx3xx4" #"x+" 3)
13:42sexpbot⟹ ["1" "2" "3xx4"]
13:43TordmorOk, thanks.
13:43Tordmorthe docstring is misleading I think.
13:43amalloyTordmor: it's poorly-phrased, but i wouldn't go so far as misleading
13:44amalloyit's reasonable to call the tokens splits, rather than calling the delimiters splits
13:44TordmorK, I'm not a native english speaker. I trust you there. :)
13:46amalloythe right answer is not to use the word "splits" at all in the docstring :)
13:47jarpiainamalloy: generics don't exist at runtime. clojure sees just that Class.cast() returns Object
13:47amalloyjarpiain: that's why i said class /literal/
13:47amalloy(.cast String foo) can be resolved at compile time, because String is a Class<String>
13:48amalloy(.cast some-class-obj "foo") can't type-hint, i agree
13:49jarpiainit could be done (there's some special code for instance? like that) but i doubt it's worth it
14:34chouserI still think OOP first so often
14:35tonylguilty too, but some FP is creeping on my OOP programming too
14:43amalloybut i bet you both cry when you write a for loop instead of a map, reduce, or filter :)
14:43amalloyand that's what counts
14:44tonylyeah, for loops seem tacky now
14:50rickmoderegarding OOP vs FP in Clojure, I find I use protocols frequently, as I all this OO experience let's me think polymorphically. I worry I overuse them.
14:51rickmodeprior to Clojure, I had the opinion that inheritance hierarchies should be as flat as possible to avoid the object-orgy problem, so moving to protocols is a natural transition for me
15:06cemerickSurely list comprehensions (for …) are still ok… ;-)
15:07jcromartierickmode: the "object orgy problem" is new to me :) hah
15:11jcromartiehttp://c2.com/cgi/wiki?ObjectOrgy
15:11rickmodejcromartie: it's something I kept seeing even before the clever name. The other insidious variant is the break in encapsulation happening with inheritance leading to rigid inheritance structures.
15:21rickmodejcromartie: also humans are fairly good at decomposing things in taxonomies (like Human, Mammal, Animal, Reptile, Snake, etc.). and so we do this in OO design, but forgetting that in reality, humans "map" taxonomies to reality, and change those taxonomies rather easily. So we end up with OO designs that calcify on an early understanding of a system that is increasingly incorrect. Sometimes we can "refactor" to fix thing, but often it
15:21rickmodeslightly wrong and gets worse over time.
15:24jcromartiebasically, yes
15:24jcromartieseems like protocols are much better
15:46rickmodejcromartie: I like the Clojure approach of avoiding inheritance. Basically says: "we're human, we'll get it wrong anyway, so don't bother in the first place." ;)
16:05jjidorickmode: do you think inheritance is a good thing+
16:06rickmodejjindo: sure, but only in moderation. I think deep inheritance is fraught with danger. We rapidly pass that magic 7 +/- 2 limit in the brain.
16:09jjidoProtocols are nice
16:09rickmodejjindo: that's my opinion anyway. The only cases where I've seen good deep inheritance are in general frameworks like java collections and cocoa touch where the domain is well known and the developers had lots of prior experience. even then it seems inconsistencies appear (I'm pretty sure java collections has some warts)
16:10jjidoyes
16:10jjidoit took time to establish current interface of Java collections
16:11dnolenrickmode: Cocoa is anti-deep inheritance as well. At least for points which are to be extended by users. Protocols are *extremely* important in Objective-C. Concrete derivation not so much. The main classes which are meant to be subclasses are views, and they don't generally come with much behavior.
16:13rickmodednolen: ah.. it's been a few months since I looked... I just recall it being "clean"
16:13dnolenbehavior + subclassing disastrous. I'm experiencing that right now with Django and Python.
16:14dnolenI'm curious if there are any other dynamically typed languages that have something analagous to Clojur's Protocols ... none come to mind.
16:15Chousukednolen: a lot is done with delegates in Cocoa, right?
16:15slyrusso is the name of *clojure-version* going to change for 1.3?
16:15dnolenChousuke: a *ton* yes.
16:16dnolenChousuke: it also seems to make it difficult for newbies to grasp - I've had difficulty teaching the beauty of writing extension points around protocols.
16:16jcromartieOK so let's talk... I'm pretty sold on building web apps in Seaside. But at the same time, I love object-less functional code in Clojure.
16:16jcromartieWhat about something like Seaside in Clojure?
16:17Chousukednolen: that might just be because subclassing is so prominently taught in schools :p
16:17Chousukeor just about everywhere
16:18Chousukegiven a tutorial on extensible software, there's probably a greater than 50% probability it focuses on subclassing :D
16:19jcromartieI just hit a subclassing limit in OOP design today. Let's say you are building a web app and want to add tagging to certain model objects.
16:19jcromartieIt doesn't make any sense to have some model objects be subclasses of TaggedObject
16:19jcromartieand if you just have an interface, then you're spreading a lot of copy/pasted code around
16:19jjidojcromartie: that is why AOP was "invented"
16:19jcromartieah, hmm
16:19jcromartieseems like that should be easy in Smalltalk eh?
16:19quilejcromartie: that's also what categories are for in objective-c
16:19rickmodejcromartie: or mixins
16:19jcromartieyeah
16:21rickmodejcromartie: I know obj-c (not smalltalk) but can't you do slick delegation, adding in the specific behavior to the object (not classes) that need it?
16:21jcromartieyeah you can
16:21jcromartieI mean you can do whatever you want
16:25rickmodejcromartie: it's just this issue that kills me with OO. The taxonomy is subtly wrong. It sounds like what you have is an orthogonal concern and no idiomatic way to express it.
16:25jcromartiepretty much
16:25rickmodetime to break out the GoF Design Pattern book... lol
16:25jcromartiealthough open classes and duck typing go a long way
16:25jcromartieheh
16:26jcromartiebut with protocols in Clojure, it would be no problem at all
16:26jcromartiealthough really, I guess having an informal interface in OOP is close enough
16:26jcromartieit just breaks when you have rigid type systems
16:26jjidoI am writing my own language. At first I thought I could use Clojure protocols to implement its object system, but it was too alien after all
16:26rickmodeif you can get the effect of a mixin at runtime, then perhaps you have a good solution. Especially if this a common thing in smalltalk, and so you wont surprise other developers (or yourself in a few months)
16:27jcromartiethere's no "runtime" in Smalltalk rickmode :)
16:27jcromartiethere's only real time :)
16:28jcromartiethat and the debugger are enough for me to toss out everything nice about Clojure for front-end/web apps
16:28jcromartieClojure for the data layer
16:29jcromartieweb services, things like that
16:29rickmodejcromartie: huh.. well I'm trying to use clojure for a web-tier. I feel like I'm reinventing a lot though.
16:31dnolenrickmode: like missing libraries?
16:31rickmodednolen: like form validation... like authentication and authorization. I could use sandbar, i guess, but I'm really trying not to use dynamic vars (they feel like a cheat to me)
16:33rickmodeI'm trying to build on top of compojure / hiccup / ring
16:33rickmodeso that's still pretty raw compared to Rails or Django
16:37dnolenrickmode: sure but you could write a killer formset/validation library with protocols
16:38dnolenrickmode: the django ones stink to high heaven when you need to specialize it
16:39rickmodednolen: ya - i'm heading that way. at the moment i'm spinning my wheels with monads to see if that's a better approach. I already have something basic with protocols. The trick is to keep the validation logic separate enough from presentation so it isn't a ball of mud.
16:39dnolenrickmode: the only way to sanely simulate/extend the behavior django form/formset is dig through a lot of classes and worse metaclasses
16:40dnolenand then you're still not sure if you have the complete set of functionality - there's no way to verify.
16:40dnolenwell besides trial and error
16:40rickmodednolen: bummer. But then that makes sense. The more the framework does, the more specific it ends up being. Clojure's web building blocks are still nicely mix and match. It'll be nice if/when there are blocks for string localizable string resources, authentication and authrozating, form validation, form building, AJAX.
16:41rickmodeat some point the pieces probably end up specific, like sandbar and conjure though
16:42dnolenrickmode: untrue, the problem is not how much the framework does. i.e. Django is a toy compared to Cocoa. It's all about taking the time to decide the sane points of extension. But the Python language doesn't really support you there. Clojure nicely Protocols do IMO.
16:44rickmodednolen: i see what you mean. that said, it is far easier to build a specific framework of any sort than a generalized and flexible one.
16:44dnolenrickmode: no argument there :)
16:45rickmodednolen: couple that with "not-invented here" and over-engineering, and one can easily spend too much time in the wrong direction. *sigh*
17:01jcromartieyay/boo (strike as appropriate) for framworks
17:03amalloyis there a less ugly way to read a single character from *in* than (.read *in*)? it seems like it would be in clojure.java.io, but i don't see it
17:04tonyl(first *in*) maybe?
17:04amalloytonyl: no, readers aren't seqable
17:05tonylyeah, just tested it.
17:05tonylshould've done that before opening my mouth
17:06amalloytonyl: i have that problem a lot
17:06tonyl(first (read-line))
17:06amalloythat consumes a whole line. definitely no good
17:07amalloyanyway .read isn't that bad, i was just hoping i could do it without . or earmuffs
17:07chouserClojure doesn't fully absract IO
17:07tonylhttp://clojuredocs.org/clojure_contrib/clojure.contrib.monadic-io-streams/read-char
17:08bhenryring users in the house?
17:08chouserclojure.java.io (as hinted by the name) provides helpers for common tasks, but doesn't let you forget you're on Java.
17:08amalloyhah
17:09SergeyDbehnry: Ring newbie
17:09SergeyDsorry, bhenry
17:10jjidodamn, my IRC client died (again). Is this channel archived?
17:10tonylclojure-log.n01se.net
17:10bhenryi want to wrap a ring handler so that exceptions lead to a custom 500 page. i have a wrapper for 404, but when there is a server error i just get a blank white browser window.
17:10bhenryi think i'll take a look at wrap-stacktrace in ring-devel
17:11bhenryit just came to me while typing that
17:12amalloyjjido: have a bouncer you can use, maybe?
17:12rickmodebhenry: check out Mark's own writeup on the subject: http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html
17:13bhenryrickmode. thanks
17:13rickmodebhenry: np. that was enough for me to create my own logging and nice, site specific 500 page
17:15jjidotonyl: thanks, I saw the part of the conversation I missed :)
17:15tonylnp
17:15jjidoamalloy: a bouncer???
17:16amalloy$google znc
17:16sexpbotFirst out of 77600 results is: ZNC
17:16sexpbothttp://en.znc.in/
17:16amalloyjjido: ^^
17:16amalloyif you have an external server you can run daemons on...
17:17jjidoallright. I think a less crashy IRC client will do for me :D
17:25arohneris there a way to get clojure paredit functionality in the slime buffer?
17:25arohnerclojure+paredit works great on my source files, but in the slime repl, I don't get highlighting across { }, etc
17:56nickik@arohner there is but I don't have it either. You should be able to google it.
18:02pppaulparedit is a pain in the ass
18:02pppaulreally hard to delete parens when i want to
18:02pppauli guess it's a bit similar to parents
18:03pppaul$8ball paredit mode?
18:03sexpbotpppaul: My reply is no.
18:03pppaulit has spoken!
18:04nickik@pppaul why do you have parans do delete?
18:05pppaulif i make mistakes in the structure of my code, there are usually lots of parents to delete
18:06pppaul"(((" wont be deletable until everything inside of them is deleted... totally crappy most of the time
18:06joegalloM-r
18:06pppaulM-r?
18:06pppaul$8ball M-r?
18:06sexpbotpppaul: Outlook not so good.
18:07joegallo(((foo bar baz))) -- cursor before the last (
18:07joegalloM-r
18:07pppaulok
18:07joegallo((foo bar baz)
18:07joegalloM-r
18:07pppauli'll try that
18:07joegallo(foo bar baz)
18:07joegallo"raise a sexp"
18:07pppaulnice
18:07joegalloQuite. :D
18:08pppaulwell, maybe paredit mode will be more sexy from now on
18:08pppauli'm still a total emacs noob
18:08joegalloI'm only ahead of you by a few months, so never fear. You'll get there!
18:10iveyparedit is awesome once you learn the extra commands
18:10iveyyou can knock sexps around
18:12pppaulenlighten me
18:12pppaulhow do i find the help file for paredit mode in emacs?
18:14iveyC-h a
18:14iveyis apropos
18:14iveyand then you can type anything there, like 'paredit'
18:14joegalloC-h m
18:14iveyand see a list of related funs
18:14joegallowill give you help for the currently enabled modes in the buffer you are in.
18:15joegalloIn a clj file, one of those modes will be paredit, and you can navigate there.
18:22amalloypppaul: i usually end up using M-<up> or M-<down> cause i have trouble understanding M-r
18:30pppaul:D
19:29Derander... and that takes care of work for today
19:33amalloyDerander: now, time to do more work, eh?
19:34Deranderyep
19:34Deranderinteresting. apparently w/ those new amazon gpu instances you can crack any sha passwowrd hash < 6 characters in 45 minutes
19:34Derander<= *
19:50clizzinAnyone know what the difference is between lein compile and lein javac?
19:54pppaulanyone think that implicit indexing (used in newlisp) will make it's way into clojure?
19:54lancepantzclizzin: i think lein compile compiles clojure, vs javac which compiles java code
19:55clizzinlancepantz: ah i see. do you know if javac also happens to compile any clojure code in the project?
19:57_ato`pppaul: it already has it
19:57lancepantzclizzin: the correct way to compile clojure code is to put it's namespace in the :aot key in project.clj
19:57_ato`if I understand correctly what you mean by implicit indexing...
19:57lancepantzclizzin: ie) :aot [foo bar]
19:57pppaul$(1 [4 5 6])
19:57pppaul&(1 [4 5 6])
19:57sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
19:57_ato`,(["a" "b" "c"] 1)
19:57clojurebot"b"
19:58pppauloh
19:58pppaul&( [4 5 6] 5)
19:58sexpbotjava.lang.IndexOutOfBoundsException
19:58pppaul&( [4 5 6] 2)
19:58sexpbot⟹ 6
19:58pppaulcool, didn't know that
19:58amalloywell, it doesn't work for non-vectors
19:58amalloyjust sets, vectors, and maps, i think
19:59amalloy&((range) 2)
19:59sexpbotjava.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn
19:59clizzinlancepantz: oh weird, i never used :aot in project.clj before. how is using that different from the usual lein compiling/jarring process?
19:59technomancyclizzin: :aot used to be called :namespaces
20:01lancepantzclizzin: as i understand it, no clojure code will get compiled in the compile or jar tasks if they are not in the :aot or :namespaces key
20:01clizzintechnomancy: i didn't use that either…maybe i misunderstand something here, but the projects i've worked on haven't defined either :namespaces or :aot, but i can still run all the usual lein commands on them. am i doing something different?
20:02technomancyclizzin: no, most projects don't require AOT. it's only needed for a few special cases
20:02technomancyoh :main can also trigger AOT.
20:04clizzintechnomancy: oh i see it's only for ahead-of-time compilation (hence the name "aot"…) great, thanks!
20:05clizzinon an unrelated note, does anyone know why an attempt to include a dependency from clojars would fail? i'm trying to grab http://clojars.org/org.clojars.bmabey/clj-ml
20:08Deranderdoes anyone know how to get something like this: http://www.youtube.com/watch?v=lf_xI3fZdIg (the arg list highlighting/persistence) up and running?
20:10amalloyclizzin: works for me. what's your project.clj look like?
20:24clizzinamalloy: yeah, just tried to pull it from inside a clean project.clj and it works fine. it actually looks like one of my original project's repositories is down, and the error there leads leiningen to quit early and then report clj-mj as missing, which misled me into thinking it was a clojars issue. thanks for checking!
21:20defnhola
21:23tonylhello
22:21dmiles_afkgood idea
22:40bhenryhttp://bearassbear.blogspot.com/2010/11/clojure-report-generation.html looking for constructive criticism.
22:49jimdueyA few months back, I saw a blog post about analyzing stock charts using Clojure.
22:49jimdueyI've lost the link. Anyone know where that was?
22:52dnolenbhenry: w/o diving too deep that looks like pretty idiomatic Clojure code to me. only thing that stands out is going over report-items twice
22:59bhenrydnolen: thanks. do you see a way to avoid that? not that i personally can think of any report that would have over 100 columns.
23:25dnolenbhenry: maybe something like this? https://gist.github.com/701413. Not very efficient, may or may not matter your case. Might make sense to break out into a helper function for readability.
23:28dnolen,(map (juxt inc dec) [1 2])
23:28clojurebot([2 0] [3 1])
23:28dnolenthat's fun.