#clojure logs

2011-01-08

00:28joshua__What web hosts do you like for Clojure w/ MongoDB as the database?
00:31tomojthe same ones I like for anything else
00:31tomojif you find a host that supports clojure w/ mongo without supporting everything else, let me know
00:33amalloyi'm sure there's an easy way to do this, but i'm not sure what it is: how do i test whether something is specifically (), the empty list, and not eg [] or {}?
00:34amalloyi don't need to worry about lazy seqs here because this is an unevaluated macro parameter
00:37qbg,(= () ())
00:37clojurebottrue
00:37qbg,(= () [])
00:37clojurebottrue
00:38qbgHmm
00:38amalloy&(identical? () ())
00:38sexpbot⟹ true
00:38qbgidentical? is almost certainly the wrong thing
00:38amalloyqbg: agreed
00:38qbgExplicit type check?
00:39qbg(and (= () ()) (list? ()))
00:39qbg,(and (= () ()) (list? ()))
00:39clojurebottrue
00:39amalloyqbg: yeah, i think i'll have to do something like that. thanks
00:39qbgseq? would probably be better
00:40qbgI think lazy seqs might be able to get into your code
00:40amalloyqbg: yeah, i'm actually using seq? already for something else; i'm just going to reorder the checks so that i do seq? first
00:41amalloyalthough i'd be interested in how a lazy-seq could sneak in
00:41qbgMacro produces lazy seq which is passed to your macro
00:41qbgI think that has happened to me before and it bit me
00:41amalloyqbg: my macro expands first
00:41qbgWhat if another macro expands into a usage of your macro?
00:42amalloy*squint* maybe you're right...that makes my head hurt
00:42amalloyyeah, i think so. jeez, good catch
00:43tomojthe fact that I have no idea what problem you're talking about scares me
00:43qbg,(list? (lazy-seq nil))
00:43clojurebotfalse
00:44qbg,(list? (lazy-seq ()))
00:44clojurebotfalse
00:44qbgThe use of syntax-quote is a big cause of the problem
00:44amalloy&(macroexpand '(-> x ()))
00:44sexpbot⟹ (nil x)
00:44qbg,'`(foo ~1 ~2)
00:44clojurebot(clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo)) (clojure.core/list 1) (clojure.core/list 2)))
00:44amalloyfwiw, this is the amusing problem i'm fixing
00:45tomojso the problem is that sometimes you wish you had () when you actually have an empty lazyseq?
00:46qbgSometimes things that look like lists aren't list?
00:48tomojso the real problem is finding things that look like (), not finding ()?
00:50tomojexcept that [] looks awfully like ()..
00:52amalloytomoj: tbh i don't think it matters much how i treat [] and {}, but i'm choosing to duplicate the existing functionality just in case someone is depending on it
01:01tomojthe existing functionality picks out ()?
01:03amalloytomoj: i'm looking at rewriting ->
01:03amalloy&(macroexpand '(-> foo ()))
01:03sexpbot⟹ (nil foo)
01:03amalloythat's known to be ridiculous code, and (foo) might occasionally be useful
01:04amalloyso i want to pick out (), but preserve existing behavior: ##(macroexpand '(-> foo [])) ##(macroexpand '(-> foo {}))
01:04sexpbot(macroexpand (quote (-> foo []))) ⟹ ([] foo)
01:04sexpbot(macroexpand (quote (-> foo {}))) ⟹ ({} foo)
01:07tomojwow that is one long character
01:08amalloytomoj: sexpbot's arrow?
01:08tomojyeah
01:48cheezeyhow can i reference a jar library in clojure? o_o
01:49cheezeyspecifically, just importing some class
01:49amalloycheezey: how are you starting your repl? you need to make sure the jar is on your classpath, and how to do that depends
01:50cheezeyamalloy: im pretty sure the jar is in my class path when i start the repl
01:50amalloycheezey: okay. then you just (import com.mydomain.MyClass)
01:51amalloyor (import (com.mydomain Class1 Class2)) if you have lots in the same package
01:52cheezeyamalloy: oh thanks. i forgot to reset my global variable :x
01:52amalloy*chuckle*
01:53cheezeyamalloy: thnx got it working :D
04:29bartjI am just starting out with Clojure web dev
04:29bartjand would like to know which I should start out with:
04:29bartjenlive+moustache or compojure
05:16midsbartj: there is also #clojure-web if you are interested
05:16midsbartj: are you familiar with any web framework in other languages?
05:17bartjmids, I haven't used any framework till date. :)
05:18bartjmids, I have just written a compojure small app in the time I posted the question here
05:18bartjand you answering it, so my guess is that it is great :)
05:18midsyeah compojure seems to be getting the most traction
05:19midsbut all of them are very leight weight
05:19midsplus you could swap out hiccup for enlive easly
05:19midsI am trying to find a nice diagram showing the clojure web ecosystem.. but not much luck yet :(
05:20midsfound it! http://www.glenstampoultzis.net/blog/clojure-web-infrastructure/
05:21clgvhello, is there any core or contrib macro doing the following: check if an expression is not null and in this case applying a given function on it or else returning nil?
05:23clgvif not, I guess I need to write it - but I dont want to reinvent the wheel every time ;)
05:25mids(when-not (nil? exp) (f exp))
05:25midsI am not aware of anything shorter
05:25clgvthats correct, but it needs the expr written twice ;)
05:26clgv(apply-when nil? expr f) or something like this would be nice. but I guess it's not written yet ;)
05:26clgvor better apply-when-not ;)
05:27midsjust go ahead and make a function or macro for that :)
05:27bartjmids, much thanks
05:28clgvI'll do. just wanted to check if anyone knew an existing one.
05:59raekclgv: (and expr (f expr))
06:00raekclgv: 'fnil' is worth checking out too
06:01clgvI defined this now: (defmacro apply-not-nil [func expr] `(let [expr-result# ~expr] (when expr-result# (~func expr-result#) ) ) )
06:01raek,(macroexpand-1 '(and expr (f expr)))
06:01clojurebot(clojure.core/let [and__3468__auto__ expr] (if and__3468__auto__ (clojure.core/and (f expr)) and__3468__auto__))
06:02raek,(macroexpand '(and expr (f expr)))
06:02clojurebot(let* [and__3468__auto__ expr] (if and__3468__auto__ (clojure.core/and (f expr)) and__3468__auto__))
06:02mduerksenclgv: that's not exactly correct, since expr could become false. in that, func wouldn't be invoked as well
06:03clgvok then I have to use nil? - just got use to simply use when from reading clojure source ;)
06:03raekclgv: there's also -?> in contrib. it works like ->, but returns nil as soon as some function in the chain return nil
06:03clgvraek: that might be what I was looking for
06:03mduerksenraek: didn't know of that one, nice
06:04raek,-?>
06:04clojurebotjava.lang.Exception: Unable to resolve symbol: -?> in this context
06:04raek,(use '[clojure.contrib.core :only (-?>)])
06:04clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/core__init.class or clojure/contrib/core.clj on classpath:
06:04clgv,(use 'clojure.contrib.core) (doc -?>)
06:04clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/core__init.class or clojure/contrib/core.clj on classpath:
06:05raek&(use '[clojure.contrib.core :only (-?>)])
06:05sexpbot⟹ nil
06:06raek&(let [f (constantly false), a (constantly :a)] (-?> :foo f a))
06:06sexpbot⟹ :a
06:06raek&(let [f (constantly nil), a (constantly :a)] (-?> :foo f a))
06:06sexpbot⟹ nil
06:07raekok. -?> checks for nil rather than falseness
06:07clgvit's what the api documentation says too ;)
06:08clgvbut it's exactly what I was looking for. I thought that might be a common use case that is already implemented in contrib ;)
06:11fliebelraek: What would you do if you want to drop out with false? Sortof reverse fnil ;)
06:13raekfalse but not nil?
06:13raekthat feels a bit unusual
06:16raekI guess I'd put together something like and, fnil or -?>, but with 'false?' as the predicate
06:18clgvI just played a bit with macros and learned how to get to the function that was passed as a parameter.
06:18clgvif I call the macro with (test-macro func-name) it is a symbol within the macro which I have to "resolve" to get a "var" which I can pass to "var-get" to get the function.
06:18clgvis that the usual way or is there a shortcut?
06:19clgvthats what I did with: (-?> func resolve var-get)
06:19clgvand checked if it really is a function with fn?
06:21raekit's not certain that you can get the function of the argument, since that's a run-time value and macros are applied at compile-time
06:21raekare you sure you need a macro in this case?
06:22raekmacros receive _code_ and return new code
06:23raek(if the symbol happens to refer to a var (global variable), then you can actually look at the var the way you did, but this does not work if the user passes a symbol introduced by let or fn)
06:24bortrebis there any way to get a file object representing the jar file in which a java class resides?
06:24raekyou can do a lot of magic with higher order fucntions
06:24clgvit's going to return code but therefor I want to pass a function (for brevity) that is used within the macro
06:25clgvI could also put that functions code directly into the macro at that position
06:25clgvbut I think that would look really complicated
06:25raekyou can put it in a separate defn
06:26clgvyes, that is what I plan to do
06:26raekjust use it outside any syntax-quote blocks
06:27raekyou could split the functionality into two parts:
06:27clgvdefine function: (defn funcname [...] ...)
06:27clgvcall macro: (testmacro funcname ...)
06:27raekone function that does the job, and one macro that uses that function and passes another function as an argument
06:28clgvhm ok. that is another possibility.
06:28raek(defmacro testmacro-f1 [x] (testmacro-core f1 x))
06:28raek(defn testmacro-core [f x] ...)
06:29bortrebfigured it out
06:29raek(defn f1 [...] ...)
06:29bortrebyou use getProtectionDomain and go from there
06:29clgvoh, you meant the same idea. thats exactly the layout.
06:29clgvsince the testmacro-cor in my case can't now f1
06:30clgvbut testmacro-f1 knows it
06:31raekmacros are a bit contageous and hard to compose (cannot be applied). best to do as little as possible in them
06:31raekhttp://vrac.cgrand.net/DSL.pdf
06:33clgvthats true, but I am doing some generic function definition interception that shall be transparent
06:33clgvI did it for two purposes in a copy, paste & adjust manner and now want to generalize it to a core that is used for both purposes to avoid the copy&paste
06:36clgvraek: are these your slides on the DSL topic?
06:36raekno, not mine
06:37raekthey are from Cristophe Grand's talk at the Conj
06:38clgvah ok. thats what the bottom line says. but I didn't know if "he might be you" ;)
06:43clgvis there any place (news page) where progress on development on clojure 1.3 is reported in more detail? so that one gets a feeling when it might be finished as stable release?
07:12LeonidasWhat is the best way to iterate over a dict like {"Leonidas" #{#"Leonidas\S*"}} and terminate on the first item that matches a predicate and returning its key?
07:12Leonidasreduce does a bit too much
07:14raekLeonidas: that looks like a job for 'some'
07:14raekit steps through a colleciton and runs a function on each element
07:14raekif the function returns non-nil, it stops and returns that
07:15raekif the function returns nil, it continues with the next thing
07:15clgv(first (filter pred map)) would work to I guess - this way the predicate does not have to return the entry
07:16clgvand shouldnt be much overhead either due to lazy
07:17Leonidasoh, filter is a good idea
07:17Leonidasraek: I'm already using some
07:17Leonidas(some #(re-matches % nick) the-set)
07:17raek,(let [s "Leonidas ", f (fn [[key re]] (when (re-find re s) key))] (some f {"found!" #"Leonidas\S*"}))
07:17clojurebot"found!"
07:17raekok
07:18Leonidashmm? some returns a value?
07:18raekyes
07:18Leonidasin my repl, I get true and false
07:18raekit returns the value of the function
07:19raekwhich does not have to be a predicate
07:19Leonidasoh, I see. odd? returns true and false, apparently :)
07:22raek,(let [s "Leonidas ", f1 (fn [s res] (some #(re-find % s) res)), f2 (fn [[key res]] (when (f1 s res) key))] (some f2 {"found leonidas" #{#"Leonidas\S*"}}))
07:22clojurebot"found leonidas"
07:24Leonidasraek: that looks good. my tries with filter weren't as successful
07:25raeksome and first+filter should both be able to solve the problem, I think
07:26clgvI guess you should prefer filter if you want to have exactly whats in the map. otherwise you have to make the function you pass to some returning it's parameter at the end
07:26Leonidasyeah, I suppose. i just got tangled up in nested functions.
07:26clgvotherwise if you even want to alter the found data, some should be better
07:38Leonidashttp://paste.pocoo.org/show/317060/ <- I suppose at this point I should have used for?
07:39clgvyou could definitely skip the map
07:40clgv(just-nicks (first (filter criterion mapping)))))
07:40clgvand I guess "just-nicks" is superfluous too
07:41clgvit can be replaced by "first" or if it is a map entry by "key"
07:43clgvit looks a bit odd using some within a predicate of filter - but it might totaly make sense depending on your taks and data structure - I cant tell without knowing both ;)
07:46Leonidasclgv: ok, you're right. as I just want the first element's key, there's no need for the complete map
08:05fliebelIs there a way I can typehint like #{interface1 interface2}, without specifying a specific class?
08:11AWizzArdClojures type hints allow you to work on the first level, that is: the set. This you can type hint.
08:12AWizzArdBut type hinting that it contains instances of a specific interface is not possible.
08:12AWizzArdHowever, the functions that work with the elements from this set can type-hint them, in doseq or map for example.
08:14fliebelRight. Well, since it's not for Java interop, I guess I can also do (assert (clojure.set/subset? (ancestors class) #{interfaces}))
08:15fliebelBut actually I don't need t at all. I'm just trying to understand generic programming.
08:19fliebelBut so far it seems generics are mainly a static typed feature. And besides that, iSeq is pretty generic and versatile.
08:22fliebelAWizzArd: You know anything about that? ^
08:23AWizzArdGenerics are a tool for static typing.
08:24AWizzArdThey are not required in dynamically type languages.
08:25fliebelAWizzArd: I met a Haskell guy yesterday, who had a generic function that created a GUI based on a data structure.
08:26AWizzArdYes, you can build a parser for Clojure too that takes an Object and constructs a GUI out of it.
08:26AWizzArdIn fact, I am implementing something similar in Clojure.
08:27AWizzArdThis is comparable to html + a web browser.
08:27AWizzArdThe browser receives an object, a (html) String here, and constructs an UI.
08:27AWizzArdIn Clojure you can send your client a spec, which then constructs a (swing) UI.
08:28clgvAWizzArd: I just read your comment - what exactly are you implementing?
08:29fliebelAWizzArd: But is this like a DSL, or more like a visualization? In other words, do I need to specify what I want, or do I just pass it mydata, and have it figure out a layout and the right controls?
08:31AWizzArdclgv: my company needs several UIs. I will implement an empty Swing window soon, with some loading functions. This App will have a http client and request UI specs from a server. The server will send specs, corresponding to the authentication level of the requesting user of the app. Then the client paints its gui.
08:32AWizzArdThis way the users can have an updated UI and don't really need much implementatiotn.
08:32clgvAWizzArd: ah ok. interesting idea :)
08:32AWizzArdfliebel: in fact, I just finished developing a helper DSL for swing applications. I am in the process of writing the documentation, before I will publish it in the coming days.
08:33AWizzArdclgv: this way my Swing client is basically similar to a browser that receives html + js.
08:33AWizzArdMy program will download Strings that it an read and eval.
08:34AWizzArdThe client will require access to the network. For my use cases this is fine.
08:34clgvsaves you from repeated update installations for the client applications...
08:34AWizzArdYes. Also I don't need to write html and js, but write Clojure instead :)
08:35clgvthats a big pro - avoiding html+js ;)
08:35AWizzArdEnables me to provide any user with the empty stub, which is basically my "Firefox". Inside it any application can be downloaded.
08:36fliebelAWizzArd: What I was thinking of, and what the Haskell guy had, was more like XSLT. You just send it data, and it transforms it to Swing. So I imagine that every seq becomes a fieldset/JPane, with controlls on it suitable for the type of node.
08:36clgvyou could also describe it with the term "thinclient" or something like that ;)
08:37fliebelMeh, I like the browser metaphor better.
08:37AWizzArdfliebel: in some days I can give you a link and you can check out if my lib is similar in some way to what you want.
08:37fliebelAWizzArd: Cool :)
08:37AWizzArdI basically need to add more doc strings and write up some examples.
08:38fliebelokay
08:39AWizzArdBut then you can construct several UIs. That is: containers that contain ui components. Those UIs can then be seen as new ui components themselves that you can reach around and put anywhere you want them to be. That allows for easy reusability.
08:40ChousukeI once read about a pretty cool Haskell UI library. It seemed perfectly composable.
08:42ChousukeI don't remember the exact details of how it worked but you could write a UI for pong that is controlled by the user, then write a generic "mirror" UI transformer, combine the pong UI with the transformer and get two synchronised views, one normal, the other mirrored :P
08:42Chousukeit was pretty cool
08:43AWizzArdIn principle I could do this too. If the function that provides the UI with data has subscribers, then I can simply instantiate another one of my UIs and have it subscribed.
08:43AWizzArdIt could also be a slightly or massively modificated UI.
08:44AWizzArdThis would also work over the network, so that those "mirrors" are not on the same computer.
08:45Chousukehmm, but then keeping the UIs synchronised will be a problem
08:45Chousukedon't try to do too much :)
08:46AWizzArdI won't try too much. What I implemented is a very simple tool that will reduce my LOC, provide better readability, require less scrolling, are easier to maintain and very reusable.
08:47AWizzArdIt's a small lib. But it also brings data binding to swing, which is also nice.
08:50no_mind[OT] can I make my living by writing clojure code ?
08:50clgvdoes anyone know how to do syntax quoting in a nested way?
08:50AWizzArdno_mind: I do :)
08:50no_mindlucky you... where do I find remote clojure jobs ?
08:51clgvI have two nested syntax quotes and in the inner one I want to unquote a symbol thats defined outside
08:51clgv~~symb does not work
08:51AWizzArdclgv: best would be if you could provide a minimal example.
08:51clojurebothttp://clojure.org/data_structures#toc10
08:56clgvhmm I guess I should not nest syntax quotes
08:57fliebelclgv: I think there might be a function counterpart of !, like unquote or whatever.
08:57fliebel*~
08:58clgvunquote it is
08:58clgvhmm perhaps I have to use that one
09:09MrHusGiven the following code:
09:09MrHus(defrecord Monster [x y]
09:09MrHus GameElement
09:09MrHus (paint [this g] (paint-rect g this Color/RED)))
09:09MrHus(defn add-element
09:09MrHus [type x y]
09:09MrHus (dosync
09:09MrHus (alter game-elements conj (type x y))))
09:09MrHusSorry
09:09MrHusill pastebin instead
09:09MrHusI have the following code: http://pastebin.com/7dDQWk3R.
09:10MrHusCan i do this: (add-element Monster. 10 10)
09:12fliebelMrHus: huh? Sure…
09:14fliebelMaybe you'll want to do (new type x y)
09:14MrHusfliebel: I'm getting a class not found error when I try.
09:14MrHusfliebel: ill try new
09:14raekyou cannot do that with normal java constructors, but I don't know about record constructos
09:14raeknew is a special form, and you cannot "apply" it with a run-time value
09:15raekit's easier to call the function like this: (add-element #(Monster. %1 %2) 10 10)
09:16fliebelOr why not (add-element (Monster. 10 10))?
09:17raekit's often recommended to write a constructor function for records
09:17fliebelraek: Why won't new work? Does it need a literal class?
09:17MrHusThanks for the suggestions, I thought it had something to do with my enviorment.
09:17raekyes
09:17raekit needs the class at compile time
09:20raekto summarize: constructors are not first-class values
09:21pdkso functions are still 3/5ths of a person
09:23clgv java.lang.Exception: Can't create defs outside of current ns - whats that supposed to mean if I stay within the same namespace?
09:23Chousukehm
09:24Chousukewhat line is generating that exception?
09:24clgvhm hard to determine since it's a macro
09:24Chousukeif you're doing something like (def foo/bar) that won't work.
09:24Chousukewell look at the macro expansion then
09:25clgvhm that hint is good. I'll see if it shows something like that
09:25ChousukeIf it's your own macro, probably there's a mistake in your use of the syntax-quote
09:25Chousukethat causes the a `(def foo ...) form to become (def blahnamespace/foo ...)
09:26Chousukethough I think that should still work if the namespace is the current one, but I'm not sure.
09:26clgvI guess that could be true
09:27raekI think you'd want something like `(def ~'foo ...)
09:28raekclojure.contrib.def has some macros like that
09:29clgvoh that hit a point I didnt understand until now - whats the difference between `(def ~'foo ...) and `(def foo ...)
09:30raekall symbols inside a syntax-quote are resolved to a namespace
09:30MrHusCan clojure records extend java interfaces?
09:30raek,`(foo)
09:30clojurebot(sandbox/foo)
09:30clgv,`(def ~'foo ...)
09:30clojurebotDENIED
09:31clgv,`(def ~'foo 5)
09:31clojurebotDENIED
09:31raekthis is to avoid symbol capture
09:31raekbut in certain cases you really need the symbol as-is
09:31clgv,`(~foo)
09:31clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
09:31raek&`(~'foo)
09:31sexpbot⟹ (foo)
09:32clgvah ok
09:32raeklike in macros expanding into def forms
09:34clgvyeah it definitely has to do with the fact that the parameter I provide to a macro is resolved too early
09:34raekthe ~ means "insert the result of an expression here" and the expression you insert is the symbol (quoted, to give the symbol itself, rather than the value it stands for)
09:36raekif you want to insert something passed as an argument to the macro into a syntax-quoted expression, you need to add an unquote for it
09:36clgvwow that looks really strange than: ~'~'foo since it's in a nested syntax-quote
09:36raekhuh?
09:37raek&`(a ~'~'foo b)
09:37sexpbot⟹ (clojure.core/a (clojure.core/unquote (quote foo)) clojure.core/b)
09:37clgvyeah I knew the basic part - but I didnt know that the symbol already gets resolved at that point
09:37clgv&`(a `(b ~'~'foo b)
09:37sexpbotjava.lang.Exception: EOF while reading
09:37raeksyntax-quote reslove the symbols at _read-time_.
09:37clgv&`(a `(b ~'~'foo b))
09:38sexpbot⟹ (clojure.core/a (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/b)) (clojure.core/list (quote foo)) (clojure.core/list (quote clojure.core/b)))))
09:38clgvand it doesnt if I quote it with ' - ok
09:38raekclgv: what does ~'~'foo even mean?
09:39raekyou rarely need to use ~' but ~'~' I have never seen
09:39raek~ is only meaningful inside a syntax-quoted expression
09:39clojurebotregular expressions is http://www.regular-expressions.info/tutorial.html
09:40clgvit is within a nested syntax quote
09:40clgvwith only ~' it still gets resolved
09:40raeknested?
09:40raekare you writing a macro that writes macros?
09:40clgvyes
09:41raeki.e. a macro that expands into a defmacro?
09:41clgvand it works now :)
09:45raekin that case, I guess it makes sense :-)
09:45clgvyeah it does. it's kinda meta meta language ;)
09:46clgvwhen does clojurebot post this topic links it read keywords of?
09:49raek~ when the line starts with a tile, I think
09:49clojurebottrampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10
09:50raekclojurebot: thank you. have some botsnack.
09:50clojurebotthanks; that was delicious. (nom nom nom)
09:50clgvlol
09:50clgvclojurebot: take a rest. ;)
09:50clojurebotrest never returns a unicorn
09:50clgvlol
09:51clgvit has an index of the clojure google group?
09:51clgv~ clojure 1.3
09:51clojurebot/Projekt/swank-clojure/ is where I keep the cloned git repo
09:51clgv~ macro
09:51clojurebotmacro are just a game with symbols
09:52raekhuh... that's my path
09:53raekah
09:53raek"~/Projekt/swank-clojure/ is where I keep the cloned git repo"
09:53raek("projekt" is Swedish for "projects")
09:53raekhence, the funky spelling
09:54raekthe bot must have treaded that as an order to add a fact
10:03clgvlol. projekt is also german ;)
10:03clgvyou are involved in swank-clojure?
10:04raekno. I think that line what from when I tried to explain my emacs setup
10:04clgvah ok
10:07clgvclojurebot: help
10:07clojurebothelp is http://clojure.org
10:07clgvlol k. I thought he could tell me what he can do ;)
10:08skelterclojurebot:
10:08clojurebot#<ClassCastException java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;>
10:16clgvskelter: you hurt him badly! ;)
10:25shortlordis there any built-in clojure method to get the position of the first occurence of an item x in a vector?
10:30mrBliss,(.indexOf [1 2 3] 2)
10:30clojurebot1
10:35shortlordmrBliss: thx
11:17raekfogus`away: re Marginalia: is it possible to extract the docstrings of protocols?
11:17rrc7czis there any contrib fn for converting a map to a query string like foo=bar&baz=boo, including urlencoding?
11:29raekrrc7cz: there's functions in Ring for that: http://clojuredocs.org/ring/
11:29raekurl-(en|de)code does the encoding part
11:30rrc7czraek: perfect, thank you
11:30clgvisnt a protocol just a map? I thought you can simply get the docstrings out of this map
11:30raekfound this, but it seems to be private: https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/params.clj#L17
11:32rrc7czraek: I started just building my own - and I'm not sure it's worth a Ring dep - but I'm sure there's some edge cases Ring has accounted for that mine wouldn't
11:32raekit handles multiple occurances of the same key in a, IMHO, complicated way
11:33raekfoo=bar becomes {"foo" "bar"}, but foo=bar&foo=baz becomes {"foo" ["bar" "baz"]}
11:34rrc7czfor now I actually just have to go in the other direction, m->s
11:35rrc7czthe simple way seems to be something like: (apply str (butlast (interleave (map name (keys m)) (repeat "=") (vals m) (repeat "&"))))
11:36raekalso, the URL encoding part is in java too: http://download.oracle.com/javase/6/docs/api/java/net/URLEncoder.html#encode(java.lang.String, java.lang.String)
11:49pevjanhas anybody implemented a CMS in clojure?
11:52BerengalIs there a way to undefine a var?
11:54Berengalns-unmap
11:56BerengalDifferent question: Is it common to use Java exceptions directly in Clojure, or do you use some other form of non-local return?
11:57fliebelpevjan: Not that I know of. LauJensen has a static site generator though. And I and devn where going to write one to, but don't expect that one anytime soon ;)
11:58fliebelBerengal: I don't know, but I was told that try/except is bad as a control structure.
11:58LauJensenpevjan: Ive built a CMS in Clojure, though its not released yet its what I use to build clojureql.org with
12:00cemerickBerengal: Java exceptions are used when appropriate/necessary, but there are other options: error-kit and condition libs in contrib. A holistic solution looks like it's in the oven as well: http://dev.clojure.org/display/design/Error+Handling
12:00fliebelLauJensen: Oooh, will you release it sometime?
12:01LauJensenfliebel: Yea I think it would be a shame not to
12:01cemerickBerengal: the latter is the result of discussions on clojure-dev (and elsewhere); lately, http://groups.google.com/group/clojure-dev/browse_frm/thread/734ee59f6cbc1b55# and http://groups.google.com/group/clojure-dev/browse_frm/thread/c552e06a0e245d74#
12:02Berengalcemerick: Thanks for the links
12:02fliebelLauJensen: Is it ClojureQL-dedicated, like the thing you use for bestinclass, or is it a nicely done, modular and reusable.. thing?
12:02LauJensenfliebel: Totally reusable, its made for general purpose
12:06fliebelLauJensen: Does it have plugins and hooks?
12:35LauJensenfliebel: Not yet. Currently it has a texteditor in which you write the content of your page. Then the backend renders a live preview of your page by knitting together your markdown content with an html template, using enlive. Thats the gist of it. Its as easy as Tubmlr to use
12:45fliebelLauJensen: Cool :)
13:18devnfliebel: :D
13:24BerengalSo I have a list of names, and I want to define a bunch of functions with a generic implementation based on those names. What's the best way to do this?
13:29BerengalRight now I have a function that makes the defn form, and I do (doseq [foo foo-list] (eval (gen-defn foo))) at the top-level
13:31raekBerengal: an alternative could be to use that code in a macro
13:32raek(defmacro define-foo-functions [& names] (cons 'do (for [foo names] (gen-defn foo))))
13:34raek(define-foo-functions x y z) => (do (defn x ...) (defn y ...) (defn z ...))
13:34Berengalraek: And is that better?
13:36raekwell, for top-level stuff, maybe macros and eval are fairly equivalent...
13:37BerengalIt just seems a bit gratuitous to be defining a macro only to use it only once right away
13:39BerengalAlthough it seems this would be general enough to maybe exist already
13:40raeka common pattern seems to be to name such macros as def____ and have one call per name
13:40raek(deffoo x) (deffoo y) (deffoo z)
13:40raekbut I'm a bit uncertain what's considered ideomatic in your case
13:41BerengalIndeed, but that gets a bit old in some cases
13:41raekor whether using eval is something bad in that case
13:42BerengalIs there any difference between (defn foo [bar] baz) and (eval '(defn foo [bar] baz)) at the toplevel anyway?
13:47clgva question that came to my mind while reading an article: is there any tool for autoformatting clojure code according to some settings, e.g. suggested "clojure format" and "personal format"?
13:56LauJensenclgv: Have you seen marginalia?
13:59LauJensenhttp://jaxenter.com/interview-clojureql-overhaul-33262.html
14:05clgvLauJensen: is that a tool for it?
14:05LauJensenclgv: marginalia emits an html page which has all of your code on the left and all of your doc strings / examples on the right. Its a pretty auto-doc you might say. Check out fogus' github repo
14:06raekclgv: emacs can auto-indent your code, if that was what you were asking about
14:07clgvLauJensen: ah ok. I thought more of something like auto-formatting of code like it is done in IDEs e.g. eclipse.
14:07bobo_i know netbeans can format clj code. guess eclipse can aswell?
14:09clgvI ask mainly because I didn't like the usual lisp formatting and found my own style to be able to read my code fast. but considering sharing or releasing code for others this could be an issue.
14:13LauJensenit will be an issue
14:13LauJensen(trust me, we've been over this a few times)
14:13clgvI read some comments about it.
14:13bobo_i dont find it an issue. the reader should be able to autoformat it? unless you are working on something togheter, then it might cause unesecary conflicts and such
14:13LauJensenI also comment on this in my blogpost "Taking uncle bob to school"
14:14clgvI know - I read that one a few hours ago ;)
14:14bobo_although, github is to good at vieweing sourcefiles
14:14bobo_so it might be an issue there =)
14:15clgvso nobody ever bothered to write a configurable formatter since it's not an issue if all stick to the formatting guidelines? ;)
14:16bobo_you want an extyernal tool?
14:16bobo_external from your editor that is
14:16clgvI know that there is none for CCW stable yet - but I dont know what is coming there next. there seems to be a lot in development
14:17bobo_oh, i think i tried that yeasterday. i thought it worked? maybe i remember wrong. that happens alot =)
14:18clgvI have CCW 0.0.64 right now. is there a new release?
14:18clgvmaybe you tried new unstable builds?
14:21bobo_im not sure, dont think my code was much unformated anyway. maybe it can do some simple stuff?
14:25bobo_looks like it can only indent the current line
14:29bartjI am not able to see any syntax highlighting in emacs for clojure files
14:29devndo you have clojure mode?
14:30bartjI have clojure-mode turned on like this in my .emacs:
14:30bartj(add-hook 'clojure-mode-hook 'turn-on-paredit-mode)
14:35tomojthat doesn't look like it should do anything
14:36tomojwhen you are looking at a clojure file and see no syntax highlighting, look down near the bottom of emacs, there should be some text between parens. what is it?
14:37raekbartj: that ativates paredit when clojure-mode is activated.
14:39raekif you install clojure-mode using package.el, I don't think you have to add anything to the .emacs file yourself
14:39bartjI guess I am expecting somewhat of vimclojure (rainbow colors!) effect with clojure-mode; which apparently, just isn't the case
14:40tomojrainbows are not built in
14:41raekbartj: http://dishevelled.net/elisp/rainbow-parens.el
14:42bartjmay I ask, which emacs themes are popular for editing clojure files?
14:45msapplerhey why is this leading to a StackOverFlow : ? - I know that it works if you ` quote it... or is this just bad style?
14:45msappler<msappler> (defmacro testmacro
14:45msappler<msappler> ([a b] (+ a b))
14:45msappler<msappler> ([] (testmacro 1 2)))
14:45msappler<msappler> =>(testmacro)
14:45msappler<msappler> java.lang.StackOverflowError
14:46devnwhat is the technical term for (partial xyz)
15:07raekmsappler: a macro is a function that takes unevaluated code as parameters and return new code
15:07raekmsappler: your macro does not return new code, but evaluates it during compile-time
15:09raek` ("syntax-quote") is just a way of constructing data structures, especially useful as a kind of code templating language
15:09raekso, yes. you are supposed to quote the new code
15:10raek(defmacro testmacro ([a b] `(+ ~a ~b)) ([] `(testmacro 1 2)))
15:10raekthis is eqivalent to:
15:10raek(defmacro testmacro ([a b] (list 'clojure.core/+ a b)) ([] (list 'user/testmacro 1 2)))
15:11raekdevn: partial function application, I would say. "currying" is a related concept, but not exactly the same thing.
15:16msapplerthank you raek
15:26tomojraek: still, why should it overflow the stack?
15:26tomoj(testmacro 1 2) macroexpands to 3 just fine
15:28raekhrm, weird
15:29tomojoh
15:30tomojthe (testmacro 1 2) in the macro definition is inside the macro definition..
15:30tomojnot sure exactly why it overflows the stack, but I wouldn't expect it to work
15:31raekreversing the order of the two arities makes it work
15:31raekwhere "works" = does not cause a stack overflow
15:32tomojhuh, I still get the overflow
15:32tomoj(defmacro testmacro ([] (testmacro 1 2)) ([a b] (+ a b))) you mean?
15:33raekyes
15:33tomojoh, had some weird state left over from the previous definition
15:33tomoj"works" from scratch
15:33tomoj.. no it doesn't. oh well.
15:33raekheh
15:34raekif I restart the repl, that version stops to work as well
15:34raekbut if I eval the same code again, it does
15:37currentBanyone happen to know of a good guide to clojore metadata?
15:43ordnungswidrigcurrentB: besides the doc on with-meta and meta?
15:51ordnungswidrigcurrentB: what do you want to accomplish?
15:53rrc7czhas anyone ever played with haskell-style Either return types for dealing with errors rather than using exceptions?
16:04shortlordin cases where both "partial" and #( ) can be used (e.g. (partial * 100) vs. #(* 100 %) ), which one should be preferred?
16:20replacashortlord: I consider it entirely a mater of taste. I will usually use partial there, but it's a fine line
16:20ordnungswidrigrrc7cz: in my experience this makes only sense with pattern-matching
16:21ordnungswidrigrrc7cz: perhaps together with matchure it might be worth a try. (http://spin.atomicobject.com/2010/04/25/matchure-serious-clojure-pattern-matching)
16:21shortlordreplaca: ok, thx. I guess I'll use partial then, a bit less parenthesis-nesting
16:22replacashortlord: I think that #() has a tiny performance advantage, by I've never noticed a diff in practice
16:23LauJensenshortlord: http://kotka.de/blog/2009/12/Pointfree_vs_Pointless.html
16:27ordnungswidrigLauJensen: very good article.
16:27ordnungswidrigIn general I consider ->> the better style in clojure. For haskell there, e.g. it's a different game because if the $ operator and such
16:27LauJensenyea, he's an interesting guy
16:44clgvso, for performance: is it better to avoid partial and use alternatives?
16:44clgvI mean to avoid partial in cases where it is often called
16:45shortlordis there any short form for (first (filter pred coll))? Some is similar, but instead of the first logical true value of pred, I need the first item of coll for which pred is true
16:50amalloyshortlord: enough people (including me) want that function that it will hopefully be added in future, but currently no
16:51amalloyclgv: if performance is a huge deal, then yeah partial is a little slower
16:52shortlordamalloy: ah ok. I'll stick with first and filter then
16:52clgvamalloy: ok thanks.
17:18BerengalI need some opinions. Which is easier to read and work with: http://hpaste.org/42867/relations
17:19BerengalThe lisp, or the sql?
17:20BerengalAnd ignoring all things meta, like embedding them in programs. Pretend they're both simple query languages
17:21amalloyBerengal: the sql looks better to me, but i have experience with sql and none with the clojure-sql libraries
17:22Chousukethe problem with the sql query is that you gotta read it inside out
17:22Chousukewhereas with the clojure you can just go straight
17:22amalloyChousuke: heh. a funny objection in a lisp channel
17:22ChousukeI guess :)
17:26Berengalamalloy: This isn't part of any existing clojure-sql library. It's just an experiment I'm doing
17:26amalloyah
17:27Chousukereminds me of the new clojureql
17:27Chousukeseems to have a similar idea
17:28BerengalChousuke: Sort of. I think we're solving different, but heavily overlapping problems though. I want to put the relational back in "relational data base"
17:28BerengalBesides, all I'm doing is just an experiment/long-winded, multifaceted kata
17:31BerengalIt's hard to beat sql though. It's an excellent language for what it's made for, but with terrible syntax and a few glaring flaws
17:31LauJensenBerengal: hehe, you're doing the exact same thing as ClojureQL, exactly
17:33AWizzArdLauJensen: btw, I wanted to ask you about the Protocol in ClojureQL. I want to ask a why-question which is by most people understood as criticism. But mine comes from pure curiosity and is not criticism at all :)
17:33LauJensenBerengal: You want to put relational back into relational database, and ClojureQLs motto contributed by chouser is "bringing relational algebra back to relational databases" :)
17:33BerengalLauJensen: Hah, I must've missed that
17:33LauJensenAWizzArd: I like critcism, so dont apologize even before you start flaming
17:34AWizzArdLauJensen: Why did you use a Protocol and had the defrecord extend it? Another approach could have been: you have the mere defrecord and make all the implementations defns.
17:34AWizzArdNote: this is not a suggestion.
17:35LauJensenAWizzArd: Eventually, I think the AST will have more interface than RTable, like Joins, Unions etc. Initially I started with this approach simply for the ease of accessing fields
17:36AWizzArdYes, I thought that there may come other defrecords, and from this moment on the defns would be no real option. Plus with your current strategy you make the code a bit shorter (by not having to type out the “defn”s).
17:37AWizzArdI just did not find any other defrecord so far and that’s why I thought that it could in principle be done without the Proto.
17:37LauJensenIt could
17:37LauJensenBerengal: check out clojureql.org for some examples, I think you'll see the exact same API
17:40AWizzArdLauJensen: btw, ClojureQL looks really nice. I am thinking about using it in one of my projects. Does it use prepared statements under the hood, so that I don’t need to worry about injections?
17:41LauJensenAWizzArd: Yea, one of the features I most happy about is the automated paramaterization of _everything_. Every value you pass will be set as an object on a prepared statement, so it should be completely safe
17:42AWizzArdLauJensen: did you also think about adding cursors? So that one could safely iterate over huge result sets and/or decide to stop processing them at any time?
17:43LauJensenIts already there, just add {:fetch-size 50000} to your connection object and your results will be chunked
17:43devnI have a map {:a :b :c :d}, and I want to check that :a :b and :c all have fuzzy versions of false ["false", false, 0, "0"]
17:43devnmost efficient way to write this function?
17:43AWizzArdLauJensen: hmm, I see. I need to look into that.
17:44devn,(select-keys {:a "false", :b 0 :c 1} [:a :b])
17:44clojurebot{:b 0, :a "false"}
17:44AWizzArddevn you can work with select-keys and with (some #{"false" false 0 "0")
17:44devnah yes that's what i was looking for thanks AWizzArd
17:45Chousukeor every? :P
17:45AWizzArdyes
17:48devn,(every? #(= (val %) #{"false" false 0 "0"}) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d]))
17:48clojurebotfalse
17:48devnerr that's not right
17:51AWizzArddevn: sets can be used as functions
17:52AWizzArdand put a ‘vals’ around select-keys
17:52Chousuke,(every? #(contains? #{"false" false 0 "0"} (val %)) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d])
17:52clojurebotEOF while reading
17:52AWizzArd,(vals (select-keys {:a 1, :b 2, :c 3} [:c]))
17:52clojurebot(3)
17:52Chousukeyou need to use contains? because
17:52Chousuke,(#{false} false)
17:52clojurebotfalse
17:53AWizzArdAh yes, that thing agani.
17:54Chousuke,(every? #(contains? #{"false" false 0 "0"} (val %)) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d]))
17:54clojurebottrue
17:56AWizzArdThough I must still say that I would prefer vals vs. val :)
17:56AWizzArdLauJensen: this :fetch-size looks interesting, thanks for bringing this to my attention.
17:57LauJensenAWizzArd: no problem - just note that its a clojureql specific thing, I dont think anybody else references cursors like that
17:58devnthat seems so verbose for the problem but maybe im just being OCD
17:58devnit seems like you should be able to do the same thing with less but again i think my brain is playing tricks on me
18:05devnanyways, thanks for the help
18:12amalloyChousuke, devn: instead of (contains #{} (val)) you can do (comp #{} val), no?
18:13Chousukeamalloy: not in this case
18:13amalloythus avoiding any anonymous functions
18:13amalloyoh right, cause false isn't true :P
18:13amalloylaaame
18:13Chousukecomp was my first idea too
18:13AWizzArdit would kill every? in this case, but normally it would work.
18:14AWizzArd(every? #{1 2 3} (vals (select-keys map keys)))
20:39devnhere's another question
20:39devnis clojure.string available without a use/require?
20:40devnand the answer is of course no :)
20:41amalloy*chuckle* indeed, that is of course the answer
20:42devn:)
20:42devn,(use 'clojure.string)
20:42clojurebotWARNING: replace already refers to: #'clojure.core/replace in namespace: sandbox, being replaced by: #'clojure.string/replace
20:42clojurebotWARNING: reverse already refers to: #'clojure.core/reverse in namespace: sandbox, being replaced by: #'clojure.string/reverse
20:42clojurebotnil
20:43devn,(join "hello" "world")
20:43clojurebot"whelloohellorhellolhellod"
20:43devninteresting behavior :)
20:43amalloydevn: "world" is a seq of five characters
20:43amalloyyou joined them together with hello
20:43amalloy&(require '[clojure.string :as s]])
20:43sexpbotjava.lang.Exception: Unmatched delimiter: ]
20:43devnyes i know i guess i was just a bit surprised at first
20:44amalloy&(require '[clojure.string :as s])
20:44sexpbot⟹ nil
20:44amalloy&(s/join ["hello" "world"])
20:44sexpbot⟹ "helloworld"
20:45amalloybtw it is kinda rude to (use) stuff in the bots if it's going to override other existing functions
20:45amalloy,(ns-unmap *ns* 'replace)
20:45clojurebotnil
20:45amalloy,(ns-unmap *ns* 'reverse)
20:45devnthe join documentation is weird
20:45clojurebotnil
20:45amalloy,(refer '[clojure.core :only [reverse replace]])
20:45clojurebotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Symbol
20:45devn&(join ["hello" "world"] " ")
20:45sexpbotjava.lang.Exception: Unable to resolve symbol: join in this context
20:46amalloydevn: s/join
20:46amalloy,(use '[clojure.core :only [reverse replace]])
20:46devn,(join ["hello" "world"] " ")
20:46clojurebotnil
20:46clojurebot" "
20:46devn,(join " " ["hello" "world"])
20:46clojurebot"hello world"
20:46devn,(doc join)
20:46clojurebot"([coll] [separator [x & more]]); Returns a string of all elements in coll, separated by an optional separator. Like Perl's join."
20:46devnnow to mean that suggests that you give it a coll followed by a separator
20:47amalloyyou're reading it wrong
20:47devns/mean/me
20:47sexpbot<devn> now to me that suggests that you give it a coll followed by a separator
20:47amalloyit takes either ([coll]) or ([separator [x & more]])
20:47devnbah im such a newb :(
20:47tomojspeaking of that, probably shouldn't be [x & more] there..
20:48amalloytomoj: you could say coll instead, but i don't see much gain
20:48devn,(join " " ["hello", "world"] ["foo" "bar"])
20:48clojurebotjava.lang.IllegalArgumentException: Wrong number of args (3) passed to: string$join
20:49tomojpeople looking at the arglists don't need to know join does its work by destructuring
20:49devntomoj: i agree - if that had said [separator coll], i would have never asked this question in the first place
20:49devnor found it "odd"
20:49tomoj"However, you should only destructure in the arg list if you want to communicate the substructure as part of the caller contract. Otherwise, destructure in a first-line let."
20:53devn,(clojure.repl/apropos #"set")
20:53clojurebot(superset? subset? thread-set-name reset-inspector set-pprint-dispatch set-primary set-env-value set-notnull set-env set-system-properties ...)
20:55amalloydevn: find-doc too
20:55amalloy&(find-doc "set")
20:55sexpbot⟹ ------------------------- clojure-http.resourcefully/with-cookies ([cookie-map & body]) Macro Perform body with *cookies* bound to cookie-map (should be a map; empty if you don't want any initial cookies). Responses that set cookies will have them saved in the *cooki... failed to gist: Broken pipe
20:55Raynessexpbot: wut
20:55amalloyhm. that's...not as pretty as it could be
20:55RaynesBroken pipe? Who broke my pipe?
20:55amalloyRaynes: isn't that the error he gives if the gist is too long?
20:56Raynesamalloy: No. Not unless gist is doing it.
20:56Raynes$(range 1000)
20:56amalloy&(repeat 1e6)
20:56amalloyer whoops
20:56amalloy&(repeat 1e6 1)
20:56sexpbotExecution Timed Out!
20:56sexpbot⟹ (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ... failed to gist: Broken pipe
20:56Raynes&(range 1000)
20:56sexpbot⟹ (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/771336
20:56RaynesYeah, too large.
21:52jimdagemwhat're you guys talking about?
22:53GeoffSKWhen i (-> 10 (fn [x] (+ 1 x))) ; i get an error, any clues why?
22:58amalloyGeoffSK: because (fn 10 [x]) isn't so hot
22:58amalloytry (-> 10 ((fn [x] ...)))
22:59GeoffSKno surprise you are right.
22:59GeoffSKwhat's the difference between inc and (fn [x] (+ 1 x))
23:00RaynesThere isn't one.
23:00GeoffSKi feel i just met a koan.
23:02GeoffSKI am perplexed : (-> 1 inc) is good. (-> 1 (fn [x] ...) is bad, but inc and (fn [x] ... ) is the same.
23:02Raynes&(macroexpand '(-> 10 (fn [x] (+ 1 x))))
23:02sexpbotjava.lang.UnsupportedOperationException: nth not supported on this type: Integer
23:02amalloy&(macroexpand '(-> 1 (fn [x] (+ 1 x))))
23:02sexpbotjava.lang.UnsupportedOperationException: nth not supported on this type: Integer
23:03RaynesSpeaking of bugs.
23:03amalloyum
23:03amalloy,(macroexpand '(-> 1 (fn [x] (+ 1 x))))
23:03clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.UnsupportedOperationException: nth not supported on this type: Integer
23:03amalloyapparently it's so broken it can't macroexpand?
23:03RaynesOr not.
23:03RaynesWow.
23:03amalloyGeoffSK: the difference is -> is modifying your (fn) form before it gets evaluated
23:03amalloyinc is already written; there's nothing to modify
23:04GeoffSKgot it.
23:04GeoffSKmacros and fns are interchangeable
23:04GeoffSKmacros and fns are NOT interchangeable
23:04Raynes(-> 10 (fn [x] (+ 1 x))) = (fn 10 [x] (+ 1 x)); (-> 10 inc) = (inc 10)
23:05amalloyGeoffSK: right, the second one
23:05GeoffSKthanks, don't completely grok, but thats my homework. Thanks.
23:08GeoffSKok i read the source. Is their a reason it should be a macro rather than fold
23:08GeoffSKoops i mean reduce
23:09amalloyGeoffSK: it needs to be applied before its arguments are evaluated
23:09GeoffSKof course.
23:09GeoffSKThanks again.
23:09amalloythe macro could be written using reduce, if it were desired
23:10GeoffSKyes, but like you said, the macro part is critical (code as data)
23:10amalloyright
23:20btw0what's the best way to generate a random subset with specified number of elments from a set?
23:22tomojanybody see what I'm doing wrong? https://gist.github.com/0e6815afb89d1b5b075e I guessed it was a type-hint problem, but I can't think of any other ways to hint it
23:24amalloybtw0: i dunno the best way, but (take n (sort-by (fn [_] (rand)) coll)) would probably work
23:24tonyltomoj: I don't think you would gain much by type hintin void
23:25tomojnot trying to gain anything except an instance of the interface
23:25tomojsince two of the methods share name and arity, I think I have to provide all hints
23:26tonylmethods don't dispatch by method signature in clojure only by arity so you would have to deal with it differently
23:27tomojyou see that I'm reifying?
23:27btw0amalloy: that's a nice solution, thanks!
23:28tonylyeah kf which has a method a that has 2 different signatures
23:28tonylwhich is a predicament I haven't work with before
23:29tomoj&[(.indexOf "foo" 111) (.indexOf "foo" "o")]
23:29sexpbot⟹ [1 1]
23:29tomojdon't think that's the predicament
23:30tomojcould there be problems interoping with classes/interfaces in the default package, maybe?
23:30chouser
23:30chouserpardon me
23:32cemerickbtw0: rand-nth should get you a good way there.
23:32tomojstrange, (.a (reify kf) "foo") gives the expected AbstractMethodError
23:33tomojyet "Can't define method not in interfaces: a"
23:33btw0cemerick: you mean run rand-nth against the collection multiple times?
23:33tomojoh shit
23:34tomojI just left off the 'this' arg
23:35tonyltomoj: I think you can operate with same named methods and different signature, but once you tried to redefined them in clojure, clojure doesn't work by signatures, but just arity. at least that is what i think
23:35tonylbut if you find something else, let me know, that would open some eyes
23:36tomojworks fine with the 'this' param included
23:37tomojtonyl: updated the gist to show
23:38tonylso including it in the methods works the ambiguity? interesting
23:38tonyltomoj: you opened my eyes :) that is always welcome
23:38cemerickbtw0: sure; this is just an example, but should illustrate the idea:
23:38cemerick,(into #{} (take 10 (repeatedly #(rand-nth (seq (set (range 100)))))))
23:38clojurebot#{33 98 67 44 77 15 18 56 91 28}
23:38tomojit's java so we have dispatch by type
23:38tomojjust like my indexOf example above
23:39cemerickbtw0: certainly don't need the other set in there, but you said you were drawing from a set…
23:39cemerick,(into #{} (take 10 (repeatedly #(rand-nth (range 100)))))
23:39clojurebot#{0 98 7 74 11 19 54 55 89 58}
23:41btw0cemerick: isn't the performance really bad if take large number of elements from a relatively small set?
23:43amalloycemerick, btw0: that also includes duplicates
23:45cemerickamalloy: yeah, I've no idea what btw0's real use case is, may or may not matter
23:45cemerickbtw0: not sure what you mean. If it's doing what you need it to do, then perf/optimization is orthogonal.
23:47amalloybtw0: if you want it to be fast and don't care about duplicates, your best bet is probably something like ##(let [elts (vec (range 100))] (take 10 (repeatedly #(rand-nth elts))))
23:47sexpbot⟹ (53 63 45 8 50 23 55 23 29 26)
23:47btw0cemerick: actually what i mean is the performance is bad if we need to get rid of duplicates.
23:49btw0cemerick: since every time there is a dup we need to rand-nth again, this will happen really frequentlly if take a large number from a relatively small set.
23:49cemerickbtw0: then dedupe the source set/seq/collection once, and take randomly from that result.
23:50cemericker, source sets are, of course, "deduped" already
23:51amalloycemerick: i think his issue is he wants the result to have no dupes
23:52btw0amalloy: exactly
23:52amalloy&(into #{} (take 10 (repeatedly #(rand-nth (range 10)))))
23:52sexpbot⟹ #{0 5 6 7 8 9}
23:53amalloyis an example of the problem
23:54btw0no dupes and no less if the source can provide that many elements
23:54cemerickhard to know what to recommend in general -- depends a lot on the data/problem
23:54cemerickdedupe the source collection, shuffle it, and then pop values off?
23:57btw0I am afraid shuffling a large collection is slow
23:58tomojhow large is 'large'? :)
23:58btw0how about 200000?
23:58tomojmore importantly I guess, how many times?
23:58tomoj&(time (when (shuffle (range 200000))))
23:58sexpbot⟹ "Elapsed time: 190.16017 msecs" nil
23:58tomojseems slow to you?
23:58cemericktomoj: beat me to it :-P
23:59tomojhuh
23:59tomoj&(-> 200000 range shuffle when time)
23:59sexpbot⟹ "Elapsed time: 167.677456 msecs" nil
23:59tomoj:)
23:59cemerickbtw0: in any case, you need to pay the price for randomization and avoiding duplicates somewhere.