2011-01-08
| 00:28 | joshua__ | What web hosts do you like for Clojure w/ MongoDB as the database? |
| 00:31 | tomoj | the same ones I like for anything else |
| 00:31 | tomoj | if you find a host that supports clojure w/ mongo without supporting everything else, let me know |
| 00:33 | amalloy | i'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:34 | amalloy | i don't need to worry about lazy seqs here because this is an unevaluated macro parameter |
| 00:37 | qbg | ,(= () ()) |
| 00:37 | clojurebot | true |
| 00:37 | qbg | ,(= () []) |
| 00:37 | clojurebot | true |
| 00:38 | qbg | Hmm |
| 00:38 | amalloy | &(identical? () ()) |
| 00:38 | sexpbot | ⟹ true |
| 00:38 | qbg | identical? is almost certainly the wrong thing |
| 00:38 | amalloy | qbg: agreed |
| 00:38 | qbg | Explicit type check? |
| 00:39 | qbg | (and (= () ()) (list? ())) |
| 00:39 | qbg | ,(and (= () ()) (list? ())) |
| 00:39 | clojurebot | true |
| 00:39 | amalloy | qbg: yeah, i think i'll have to do something like that. thanks |
| 00:39 | qbg | seq? would probably be better |
| 00:40 | qbg | I think lazy seqs might be able to get into your code |
| 00:40 | amalloy | qbg: 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:41 | amalloy | although i'd be interested in how a lazy-seq could sneak in |
| 00:41 | qbg | Macro produces lazy seq which is passed to your macro |
| 00:41 | qbg | I think that has happened to me before and it bit me |
| 00:41 | amalloy | qbg: my macro expands first |
| 00:41 | qbg | What if another macro expands into a usage of your macro? |
| 00:42 | amalloy | *squint* maybe you're right...that makes my head hurt |
| 00:42 | amalloy | yeah, i think so. jeez, good catch |
| 00:43 | tomoj | the fact that I have no idea what problem you're talking about scares me |
| 00:43 | qbg | ,(list? (lazy-seq nil)) |
| 00:43 | clojurebot | false |
| 00:44 | qbg | ,(list? (lazy-seq ())) |
| 00:44 | clojurebot | false |
| 00:44 | qbg | The use of syntax-quote is a big cause of the problem |
| 00:44 | amalloy | &(macroexpand '(-> x ())) |
| 00:44 | sexpbot | ⟹ (nil x) |
| 00:44 | qbg | ,'`(foo ~1 ~2) |
| 00:44 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo)) (clojure.core/list 1) (clojure.core/list 2))) |
| 00:44 | amalloy | fwiw, this is the amusing problem i'm fixing |
| 00:45 | tomoj | so the problem is that sometimes you wish you had () when you actually have an empty lazyseq? |
| 00:46 | qbg | Sometimes things that look like lists aren't list? |
| 00:48 | tomoj | so the real problem is finding things that look like (), not finding ()? |
| 00:50 | tomoj | except that [] looks awfully like ().. |
| 00:52 | amalloy | tomoj: 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:01 | tomoj | the existing functionality picks out ()? |
| 01:03 | amalloy | tomoj: i'm looking at rewriting -> |
| 01:03 | amalloy | &(macroexpand '(-> foo ())) |
| 01:03 | sexpbot | ⟹ (nil foo) |
| 01:03 | amalloy | that's known to be ridiculous code, and (foo) might occasionally be useful |
| 01:04 | amalloy | so i want to pick out (), but preserve existing behavior: ##(macroexpand '(-> foo [])) ##(macroexpand '(-> foo {})) |
| 01:04 | sexpbot | (macroexpand (quote (-> foo []))) ⟹ ([] foo) |
| 01:04 | sexpbot | (macroexpand (quote (-> foo {}))) ⟹ ({} foo) |
| 01:07 | tomoj | wow that is one long character |
| 01:08 | amalloy | tomoj: sexpbot's arrow? |
| 01:08 | tomoj | yeah |
| 01:48 | cheezey | how can i reference a jar library in clojure? o_o |
| 01:49 | cheezey | specifically, just importing some class |
| 01:49 | amalloy | cheezey: how are you starting your repl? you need to make sure the jar is on your classpath, and how to do that depends |
| 01:50 | cheezey | amalloy: im pretty sure the jar is in my class path when i start the repl |
| 01:50 | amalloy | cheezey: okay. then you just (import com.mydomain.MyClass) |
| 01:51 | amalloy | or (import (com.mydomain Class1 Class2)) if you have lots in the same package |
| 01:52 | cheezey | amalloy: oh thanks. i forgot to reset my global variable :x |
| 01:52 | amalloy | *chuckle* |
| 01:53 | cheezey | amalloy: thnx got it working :D |
| 04:29 | bartj | I am just starting out with Clojure web dev |
| 04:29 | bartj | and would like to know which I should start out with: |
| 04:29 | bartj | enlive+moustache or compojure |
| 05:16 | mids | bartj: there is also #clojure-web if you are interested |
| 05:16 | mids | bartj: are you familiar with any web framework in other languages? |
| 05:17 | bartj | mids, I haven't used any framework till date. :) |
| 05:18 | bartj | mids, I have just written a compojure small app in the time I posted the question here |
| 05:18 | bartj | and you answering it, so my guess is that it is great :) |
| 05:18 | mids | yeah compojure seems to be getting the most traction |
| 05:19 | mids | but all of them are very leight weight |
| 05:19 | mids | plus you could swap out hiccup for enlive easly |
| 05:19 | mids | I am trying to find a nice diagram showing the clojure web ecosystem.. but not much luck yet :( |
| 05:20 | mids | found it! http://www.glenstampoultzis.net/blog/clojure-web-infrastructure/ |
| 05:21 | clgv | hello, 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:23 | clgv | if not, I guess I need to write it - but I dont want to reinvent the wheel every time ;) |
| 05:25 | mids | (when-not (nil? exp) (f exp)) |
| 05:25 | mids | I am not aware of anything shorter |
| 05:25 | clgv | thats correct, but it needs the expr written twice ;) |
| 05:26 | clgv | (apply-when nil? expr f) or something like this would be nice. but I guess it's not written yet ;) |
| 05:26 | clgv | or better apply-when-not ;) |
| 05:27 | mids | just go ahead and make a function or macro for that :) |
| 05:27 | bartj | mids, much thanks |
| 05:28 | clgv | I'll do. just wanted to check if anyone knew an existing one. |
| 05:59 | raek | clgv: (and expr (f expr)) |
| 06:00 | raek | clgv: 'fnil' is worth checking out too |
| 06:01 | clgv | I defined this now: (defmacro apply-not-nil [func expr] `(let [expr-result# ~expr] (when expr-result# (~func expr-result#) ) ) ) |
| 06:01 | raek | ,(macroexpand-1 '(and expr (f expr))) |
| 06:01 | clojurebot | (clojure.core/let [and__3468__auto__ expr] (if and__3468__auto__ (clojure.core/and (f expr)) and__3468__auto__)) |
| 06:02 | raek | ,(macroexpand '(and expr (f expr))) |
| 06:02 | clojurebot | (let* [and__3468__auto__ expr] (if and__3468__auto__ (clojure.core/and (f expr)) and__3468__auto__)) |
| 06:02 | mduerksen | clgv: that's not exactly correct, since expr could become false. in that, func wouldn't be invoked as well |
| 06:03 | clgv | ok then I have to use nil? - just got use to simply use when from reading clojure source ;) |
| 06:03 | raek | clgv: there's also -?> in contrib. it works like ->, but returns nil as soon as some function in the chain return nil |
| 06:03 | clgv | raek: that might be what I was looking for |
| 06:03 | mduerksen | raek: didn't know of that one, nice |
| 06:04 | raek | ,-?> |
| 06:04 | clojurebot | java.lang.Exception: Unable to resolve symbol: -?> in this context |
| 06:04 | raek | ,(use '[clojure.contrib.core :only (-?>)]) |
| 06:04 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/core__init.class or clojure/contrib/core.clj on classpath: |
| 06:04 | clgv | ,(use 'clojure.contrib.core) (doc -?>) |
| 06:04 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/core__init.class or clojure/contrib/core.clj on classpath: |
| 06:05 | raek | &(use '[clojure.contrib.core :only (-?>)]) |
| 06:05 | sexpbot | ⟹ nil |
| 06:06 | raek | &(let [f (constantly false), a (constantly :a)] (-?> :foo f a)) |
| 06:06 | sexpbot | ⟹ :a |
| 06:06 | raek | &(let [f (constantly nil), a (constantly :a)] (-?> :foo f a)) |
| 06:06 | sexpbot | ⟹ nil |
| 06:07 | raek | ok. -?> checks for nil rather than falseness |
| 06:07 | clgv | it's what the api documentation says too ;) |
| 06:08 | clgv | but it's exactly what I was looking for. I thought that might be a common use case that is already implemented in contrib ;) |
| 06:11 | fliebel | raek: What would you do if you want to drop out with false? Sortof reverse fnil ;) |
| 06:13 | raek | false but not nil? |
| 06:13 | raek | that feels a bit unusual |
| 06:16 | raek | I guess I'd put together something like and, fnil or -?>, but with 'false?' as the predicate |
| 06:18 | clgv | I just played a bit with macros and learned how to get to the function that was passed as a parameter. |
| 06:18 | clgv | if 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:18 | clgv | is that the usual way or is there a shortcut? |
| 06:19 | clgv | thats what I did with: (-?> func resolve var-get) |
| 06:19 | clgv | and checked if it really is a function with fn? |
| 06:21 | raek | it'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:21 | raek | are you sure you need a macro in this case? |
| 06:22 | raek | macros receive _code_ and return new code |
| 06:23 | raek | (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:24 | bortreb | is there any way to get a file object representing the jar file in which a java class resides? |
| 06:24 | raek | you can do a lot of magic with higher order fucntions |
| 06:24 | clgv | it's going to return code but therefor I want to pass a function (for brevity) that is used within the macro |
| 06:25 | clgv | I could also put that functions code directly into the macro at that position |
| 06:25 | clgv | but I think that would look really complicated |
| 06:25 | raek | you can put it in a separate defn |
| 06:26 | clgv | yes, that is what I plan to do |
| 06:26 | raek | just use it outside any syntax-quote blocks |
| 06:27 | raek | you could split the functionality into two parts: |
| 06:27 | clgv | define function: (defn funcname [...] ...) |
| 06:27 | clgv | call macro: (testmacro funcname ...) |
| 06:27 | raek | one function that does the job, and one macro that uses that function and passes another function as an argument |
| 06:28 | clgv | hm ok. that is another possibility. |
| 06:28 | raek | (defmacro testmacro-f1 [x] (testmacro-core f1 x)) |
| 06:28 | raek | (defn testmacro-core [f x] ...) |
| 06:29 | bortreb | figured it out |
| 06:29 | raek | (defn f1 [...] ...) |
| 06:29 | bortreb | you use getProtectionDomain and go from there |
| 06:29 | clgv | oh, you meant the same idea. thats exactly the layout. |
| 06:29 | clgv | since the testmacro-cor in my case can't now f1 |
| 06:30 | clgv | but testmacro-f1 knows it |
| 06:31 | raek | macros are a bit contageous and hard to compose (cannot be applied). best to do as little as possible in them |
| 06:31 | raek | http://vrac.cgrand.net/DSL.pdf |
| 06:33 | clgv | thats true, but I am doing some generic function definition interception that shall be transparent |
| 06:33 | clgv | I 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:36 | clgv | raek: are these your slides on the DSL topic? |
| 06:36 | raek | no, not mine |
| 06:37 | raek | they are from Cristophe Grand's talk at the Conj |
| 06:38 | clgv | ah ok. thats what the bottom line says. but I didn't know if "he might be you" ;) |
| 06:43 | clgv | is 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:12 | Leonidas | What 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:12 | Leonidas | reduce does a bit too much |
| 07:14 | raek | Leonidas: that looks like a job for 'some' |
| 07:14 | raek | it steps through a colleciton and runs a function on each element |
| 07:14 | raek | if the function returns non-nil, it stops and returns that |
| 07:15 | raek | if the function returns nil, it continues with the next thing |
| 07:15 | clgv | (first (filter pred map)) would work to I guess - this way the predicate does not have to return the entry |
| 07:16 | clgv | and shouldnt be much overhead either due to lazy |
| 07:17 | Leonidas | oh, filter is a good idea |
| 07:17 | Leonidas | raek: I'm already using some |
| 07:17 | Leonidas | (some #(re-matches % nick) the-set) |
| 07:17 | raek | ,(let [s "Leonidas ", f (fn [[key re]] (when (re-find re s) key))] (some f {"found!" #"Leonidas\S*"})) |
| 07:17 | clojurebot | "found!" |
| 07:17 | raek | ok |
| 07:18 | Leonidas | hmm? some returns a value? |
| 07:18 | raek | yes |
| 07:18 | Leonidas | in my repl, I get true and false |
| 07:18 | raek | it returns the value of the function |
| 07:19 | raek | which does not have to be a predicate |
| 07:19 | Leonidas | oh, I see. odd? returns true and false, apparently :) |
| 07:22 | raek | ,(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:22 | clojurebot | "found leonidas" |
| 07:24 | Leonidas | raek: that looks good. my tries with filter weren't as successful |
| 07:25 | raek | some and first+filter should both be able to solve the problem, I think |
| 07:26 | clgv | I 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:26 | Leonidas | yeah, I suppose. i just got tangled up in nested functions. |
| 07:26 | clgv | otherwise if you even want to alter the found data, some should be better |
| 07:38 | Leonidas | http://paste.pocoo.org/show/317060/ <- I suppose at this point I should have used for? |
| 07:39 | clgv | you could definitely skip the map |
| 07:40 | clgv | (just-nicks (first (filter criterion mapping))))) |
| 07:40 | clgv | and I guess "just-nicks" is superfluous too |
| 07:41 | clgv | it can be replaced by "first" or if it is a map entry by "key" |
| 07:43 | clgv | it 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:46 | Leonidas | clgv: ok, you're right. as I just want the first element's key, there's no need for the complete map |
| 08:05 | fliebel | Is there a way I can typehint like #{interface1 interface2}, without specifying a specific class? |
| 08:11 | AWizzArd | Clojures type hints allow you to work on the first level, that is: the set. This you can type hint. |
| 08:12 | AWizzArd | But type hinting that it contains instances of a specific interface is not possible. |
| 08:12 | AWizzArd | However, the functions that work with the elements from this set can type-hint them, in doseq or map for example. |
| 08:14 | fliebel | Right. Well, since it's not for Java interop, I guess I can also do (assert (clojure.set/subset? (ancestors class) #{interfaces})) |
| 08:15 | fliebel | But actually I don't need t at all. I'm just trying to understand generic programming. |
| 08:19 | fliebel | But so far it seems generics are mainly a static typed feature. And besides that, iSeq is pretty generic and versatile. |
| 08:22 | fliebel | AWizzArd: You know anything about that? ^ |
| 08:23 | AWizzArd | Generics are a tool for static typing. |
| 08:24 | AWizzArd | They are not required in dynamically type languages. |
| 08:25 | fliebel | AWizzArd: I met a Haskell guy yesterday, who had a generic function that created a GUI based on a data structure. |
| 08:26 | AWizzArd | Yes, you can build a parser for Clojure too that takes an Object and constructs a GUI out of it. |
| 08:26 | AWizzArd | In fact, I am implementing something similar in Clojure. |
| 08:27 | AWizzArd | This is comparable to html + a web browser. |
| 08:27 | AWizzArd | The browser receives an object, a (html) String here, and constructs an UI. |
| 08:27 | AWizzArd | In Clojure you can send your client a spec, which then constructs a (swing) UI. |
| 08:28 | clgv | AWizzArd: I just read your comment - what exactly are you implementing? |
| 08:29 | fliebel | AWizzArd: 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:31 | AWizzArd | clgv: 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:32 | AWizzArd | This way the users can have an updated UI and don't really need much implementatiotn. |
| 08:32 | clgv | AWizzArd: ah ok. interesting idea :) |
| 08:32 | AWizzArd | fliebel: 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:33 | AWizzArd | clgv: this way my Swing client is basically similar to a browser that receives html + js. |
| 08:33 | AWizzArd | My program will download Strings that it an read and eval. |
| 08:34 | AWizzArd | The client will require access to the network. For my use cases this is fine. |
| 08:34 | clgv | saves you from repeated update installations for the client applications... |
| 08:34 | AWizzArd | Yes. Also I don't need to write html and js, but write Clojure instead :) |
| 08:35 | clgv | thats a big pro - avoiding html+js ;) |
| 08:35 | AWizzArd | Enables me to provide any user with the empty stub, which is basically my "Firefox". Inside it any application can be downloaded. |
| 08:36 | fliebel | AWizzArd: 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:36 | clgv | you could also describe it with the term "thinclient" or something like that ;) |
| 08:37 | fliebel | Meh, I like the browser metaphor better. |
| 08:37 | AWizzArd | fliebel: 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:37 | fliebel | AWizzArd: Cool :) |
| 08:37 | AWizzArd | I basically need to add more doc strings and write up some examples. |
| 08:38 | fliebel | okay |
| 08:39 | AWizzArd | But 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:40 | Chousuke | I once read about a pretty cool Haskell UI library. It seemed perfectly composable. |
| 08:42 | Chousuke | I 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:42 | Chousuke | it was pretty cool |
| 08:43 | AWizzArd | In 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:43 | AWizzArd | It could also be a slightly or massively modificated UI. |
| 08:44 | AWizzArd | This would also work over the network, so that those "mirrors" are not on the same computer. |
| 08:45 | Chousuke | hmm, but then keeping the UIs synchronised will be a problem |
| 08:45 | Chousuke | don't try to do too much :) |
| 08:46 | AWizzArd | I 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:47 | AWizzArd | It's a small lib. But it also brings data binding to swing, which is also nice. |
| 08:50 | no_mind | [OT] can I make my living by writing clojure code ? |
| 08:50 | clgv | does anyone know how to do syntax quoting in a nested way? |
| 08:50 | AWizzArd | no_mind: I do :) |
| 08:50 | no_mind | lucky you... where do I find remote clojure jobs ? |
| 08:51 | clgv | I have two nested syntax quotes and in the inner one I want to unquote a symbol thats defined outside |
| 08:51 | clgv | ~~symb does not work |
| 08:51 | AWizzArd | clgv: best would be if you could provide a minimal example. |
| 08:51 | clojurebot | http://clojure.org/data_structures#toc10 |
| 08:56 | clgv | hmm I guess I should not nest syntax quotes |
| 08:57 | fliebel | clgv: I think there might be a function counterpart of !, like unquote or whatever. |
| 08:57 | fliebel | *~ |
| 08:58 | clgv | unquote it is |
| 08:58 | clgv | hmm perhaps I have to use that one |
| 09:09 | MrHus | Given the following code: |
| 09:09 | MrHus | (defrecord Monster [x y] |
| 09:09 | MrHus | GameElement |
| 09:09 | MrHus | (paint [this g] (paint-rect g this Color/RED))) |
| 09:09 | MrHus | (defn add-element |
| 09:09 | MrHus | [type x y] |
| 09:09 | MrHus | (dosync |
| 09:09 | MrHus | (alter game-elements conj (type x y)))) |
| 09:09 | MrHus | Sorry |
| 09:09 | MrHus | ill pastebin instead |
| 09:09 | MrHus | I have the following code: http://pastebin.com/7dDQWk3R. |
| 09:10 | MrHus | Can i do this: (add-element Monster. 10 10) |
| 09:12 | fliebel | MrHus: huh? Sure… |
| 09:14 | fliebel | Maybe you'll want to do (new type x y) |
| 09:14 | MrHus | fliebel: I'm getting a class not found error when I try. |
| 09:14 | MrHus | fliebel: ill try new |
| 09:14 | raek | you cannot do that with normal java constructors, but I don't know about record constructos |
| 09:14 | raek | new is a special form, and you cannot "apply" it with a run-time value |
| 09:15 | raek | it's easier to call the function like this: (add-element #(Monster. %1 %2) 10 10) |
| 09:16 | fliebel | Or why not (add-element (Monster. 10 10))? |
| 09:17 | raek | it's often recommended to write a constructor function for records |
| 09:17 | fliebel | raek: Why won't new work? Does it need a literal class? |
| 09:17 | MrHus | Thanks for the suggestions, I thought it had something to do with my enviorment. |
| 09:17 | raek | yes |
| 09:17 | raek | it needs the class at compile time |
| 09:20 | raek | to summarize: constructors are not first-class values |
| 09:21 | pdk | so functions are still 3/5ths of a person |
| 09:23 | clgv | java.lang.Exception: Can't create defs outside of current ns - whats that supposed to mean if I stay within the same namespace? |
| 09:23 | Chousuke | hm |
| 09:24 | Chousuke | what line is generating that exception? |
| 09:24 | clgv | hm hard to determine since it's a macro |
| 09:24 | Chousuke | if you're doing something like (def foo/bar) that won't work. |
| 09:24 | Chousuke | well look at the macro expansion then |
| 09:25 | clgv | hm that hint is good. I'll see if it shows something like that |
| 09:25 | Chousuke | If it's your own macro, probably there's a mistake in your use of the syntax-quote |
| 09:25 | Chousuke | that causes the a `(def foo ...) form to become (def blahnamespace/foo ...) |
| 09:26 | Chousuke | though I think that should still work if the namespace is the current one, but I'm not sure. |
| 09:26 | clgv | I guess that could be true |
| 09:27 | raek | I think you'd want something like `(def ~'foo ...) |
| 09:28 | raek | clojure.contrib.def has some macros like that |
| 09:29 | clgv | oh that hit a point I didnt understand until now - whats the difference between `(def ~'foo ...) and `(def foo ...) |
| 09:30 | raek | all symbols inside a syntax-quote are resolved to a namespace |
| 09:30 | MrHus | Can clojure records extend java interfaces? |
| 09:30 | raek | ,`(foo) |
| 09:30 | clojurebot | (sandbox/foo) |
| 09:30 | clgv | ,`(def ~'foo ...) |
| 09:30 | clojurebot | DENIED |
| 09:31 | clgv | ,`(def ~'foo 5) |
| 09:31 | clojurebot | DENIED |
| 09:31 | raek | this is to avoid symbol capture |
| 09:31 | raek | but in certain cases you really need the symbol as-is |
| 09:31 | clgv | ,`(~foo) |
| 09:31 | clojurebot | java.lang.Exception: Unable to resolve symbol: foo in this context |
| 09:31 | raek | &`(~'foo) |
| 09:31 | sexpbot | ⟹ (foo) |
| 09:32 | clgv | ah ok |
| 09:32 | raek | like in macros expanding into def forms |
| 09:34 | clgv | yeah it definitely has to do with the fact that the parameter I provide to a macro is resolved too early |
| 09:34 | raek | the ~ 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:36 | raek | if 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:36 | clgv | wow that looks really strange than: ~'~'foo since it's in a nested syntax-quote |
| 09:36 | raek | huh? |
| 09:37 | raek | &`(a ~'~'foo b) |
| 09:37 | sexpbot | ⟹ (clojure.core/a (clojure.core/unquote (quote foo)) clojure.core/b) |
| 09:37 | clgv | yeah I knew the basic part - but I didnt know that the symbol already gets resolved at that point |
| 09:37 | clgv | &`(a `(b ~'~'foo b) |
| 09:37 | sexpbot | java.lang.Exception: EOF while reading |
| 09:37 | raek | syntax-quote reslove the symbols at _read-time_. |
| 09:37 | clgv | &`(a `(b ~'~'foo b)) |
| 09:38 | sexpbot | ⟹ (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:38 | clgv | and it doesnt if I quote it with ' - ok |
| 09:38 | raek | clgv: what does ~'~'foo even mean? |
| 09:39 | raek | you rarely need to use ~' but ~'~' I have never seen |
| 09:39 | raek | ~ is only meaningful inside a syntax-quoted expression |
| 09:39 | clojurebot | regular expressions is http://www.regular-expressions.info/tutorial.html |
| 09:40 | clgv | it is within a nested syntax quote |
| 09:40 | clgv | with only ~' it still gets resolved |
| 09:40 | raek | nested? |
| 09:40 | raek | are you writing a macro that writes macros? |
| 09:40 | clgv | yes |
| 09:41 | raek | i.e. a macro that expands into a defmacro? |
| 09:41 | clgv | and it works now :) |
| 09:45 | raek | in that case, I guess it makes sense :-) |
| 09:45 | clgv | yeah it does. it's kinda meta meta language ;) |
| 09:46 | clgv | when does clojurebot post this topic links it read keywords of? |
| 09:49 | raek | ~ when the line starts with a tile, I think |
| 09:49 | clojurebot | trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10 |
| 09:50 | raek | clojurebot: thank you. have some botsnack. |
| 09:50 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 09:50 | clgv | lol |
| 09:50 | clgv | clojurebot: take a rest. ;) |
| 09:50 | clojurebot | rest never returns a unicorn |
| 09:50 | clgv | lol |
| 09:51 | clgv | it has an index of the clojure google group? |
| 09:51 | clgv | ~ clojure 1.3 |
| 09:51 | clojurebot | /Projekt/swank-clojure/ is where I keep the cloned git repo |
| 09:51 | clgv | ~ macro |
| 09:51 | clojurebot | macro are just a game with symbols |
| 09:52 | raek | huh... that's my path |
| 09:53 | raek | ah |
| 09:53 | raek | "~/Projekt/swank-clojure/ is where I keep the cloned git repo" |
| 09:53 | raek | ("projekt" is Swedish for "projects") |
| 09:53 | raek | hence, the funky spelling |
| 09:54 | raek | the bot must have treaded that as an order to add a fact |
| 10:03 | clgv | lol. projekt is also german ;) |
| 10:03 | clgv | you are involved in swank-clojure? |
| 10:04 | raek | no. I think that line what from when I tried to explain my emacs setup |
| 10:04 | clgv | ah ok |
| 10:07 | clgv | clojurebot: help |
| 10:07 | clojurebot | help is http://clojure.org |
| 10:07 | clgv | lol k. I thought he could tell me what he can do ;) |
| 10:08 | skelter | clojurebot: |
| 10:08 | clojurebot | #<ClassCastException java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;> |
| 10:16 | clgv | skelter: you hurt him badly! ;) |
| 10:25 | shortlord | is there any built-in clojure method to get the position of the first occurence of an item x in a vector? |
| 10:30 | mrBliss | ,(.indexOf [1 2 3] 2) |
| 10:30 | clojurebot | 1 |
| 10:35 | shortlord | mrBliss: thx |
| 11:17 | raek | fogus`away: re Marginalia: is it possible to extract the docstrings of protocols? |
| 11:17 | rrc7cz | is there any contrib fn for converting a map to a query string like foo=bar&baz=boo, including urlencoding? |
| 11:29 | raek | rrc7cz: there's functions in Ring for that: http://clojuredocs.org/ring/ |
| 11:29 | raek | url-(en|de)code does the encoding part |
| 11:30 | rrc7cz | raek: perfect, thank you |
| 11:30 | clgv | isnt a protocol just a map? I thought you can simply get the docstrings out of this map |
| 11:30 | raek | found this, but it seems to be private: https://github.com/mmcgrana/ring/blob/master/ring-core/src/ring/middleware/params.clj#L17 |
| 11:32 | rrc7cz | raek: 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:32 | raek | it handles multiple occurances of the same key in a, IMHO, complicated way |
| 11:33 | raek | foo=bar becomes {"foo" "bar"}, but foo=bar&foo=baz becomes {"foo" ["bar" "baz"]} |
| 11:34 | rrc7cz | for now I actually just have to go in the other direction, m->s |
| 11:35 | rrc7cz | the simple way seems to be something like: (apply str (butlast (interleave (map name (keys m)) (repeat "=") (vals m) (repeat "&")))) |
| 11:36 | raek | also, 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:49 | pevjan | has anybody implemented a CMS in clojure? |
| 11:52 | Berengal | Is there a way to undefine a var? |
| 11:54 | Berengal | ns-unmap |
| 11:56 | Berengal | Different question: Is it common to use Java exceptions directly in Clojure, or do you use some other form of non-local return? |
| 11:57 | fliebel | pevjan: 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:58 | fliebel | Berengal: I don't know, but I was told that try/except is bad as a control structure. |
| 11:58 | LauJensen | pevjan: Ive built a CMS in Clojure, though its not released yet its what I use to build clojureql.org with |
| 12:00 | cemerick | Berengal: 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:00 | fliebel | LauJensen: Oooh, will you release it sometime? |
| 12:01 | LauJensen | fliebel: Yea I think it would be a shame not to |
| 12:01 | cemerick | Berengal: 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:02 | Berengal | cemerick: Thanks for the links |
| 12:02 | fliebel | LauJensen: Is it ClojureQL-dedicated, like the thing you use for bestinclass, or is it a nicely done, modular and reusable.. thing? |
| 12:02 | LauJensen | fliebel: Totally reusable, its made for general purpose |
| 12:06 | fliebel | LauJensen: Does it have plugins and hooks? |
| 12:35 | LauJensen | fliebel: 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:45 | fliebel | LauJensen: Cool :) |
| 13:18 | devn | fliebel: :D |
| 13:24 | Berengal | So 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:29 | Berengal | Right 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:31 | raek | Berengal: an alternative could be to use that code in a macro |
| 13:32 | raek | (defmacro define-foo-functions [& names] (cons 'do (for [foo names] (gen-defn foo)))) |
| 13:34 | raek | (define-foo-functions x y z) => (do (defn x ...) (defn y ...) (defn z ...)) |
| 13:34 | Berengal | raek: And is that better? |
| 13:36 | raek | well, for top-level stuff, maybe macros and eval are fairly equivalent... |
| 13:37 | Berengal | It just seems a bit gratuitous to be defining a macro only to use it only once right away |
| 13:39 | Berengal | Although it seems this would be general enough to maybe exist already |
| 13:40 | raek | a common pattern seems to be to name such macros as def____ and have one call per name |
| 13:40 | raek | (deffoo x) (deffoo y) (deffoo z) |
| 13:40 | raek | but I'm a bit uncertain what's considered ideomatic in your case |
| 13:41 | Berengal | Indeed, but that gets a bit old in some cases |
| 13:41 | raek | or whether using eval is something bad in that case |
| 13:42 | Berengal | Is there any difference between (defn foo [bar] baz) and (eval '(defn foo [bar] baz)) at the toplevel anyway? |
| 13:47 | clgv | a 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:56 | LauJensen | clgv: Have you seen marginalia? |
| 13:59 | LauJensen | http://jaxenter.com/interview-clojureql-overhaul-33262.html |
| 14:05 | clgv | LauJensen: is that a tool for it? |
| 14:05 | LauJensen | clgv: 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:06 | raek | clgv: emacs can auto-indent your code, if that was what you were asking about |
| 14:07 | clgv | LauJensen: ah ok. I thought more of something like auto-formatting of code like it is done in IDEs e.g. eclipse. |
| 14:07 | bobo_ | i know netbeans can format clj code. guess eclipse can aswell? |
| 14:09 | clgv | I 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:13 | LauJensen | it will be an issue |
| 14:13 | LauJensen | (trust me, we've been over this a few times) |
| 14:13 | clgv | I read some comments about it. |
| 14:13 | bobo_ | 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:13 | LauJensen | I also comment on this in my blogpost "Taking uncle bob to school" |
| 14:14 | clgv | I know - I read that one a few hours ago ;) |
| 14:14 | bobo_ | although, github is to good at vieweing sourcefiles |
| 14:14 | bobo_ | so it might be an issue there =) |
| 14:15 | clgv | so nobody ever bothered to write a configurable formatter since it's not an issue if all stick to the formatting guidelines? ;) |
| 14:16 | bobo_ | you want an extyernal tool? |
| 14:16 | bobo_ | external from your editor that is |
| 14:16 | clgv | I 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:17 | bobo_ | oh, i think i tried that yeasterday. i thought it worked? maybe i remember wrong. that happens alot =) |
| 14:18 | clgv | I have CCW 0.0.64 right now. is there a new release? |
| 14:18 | clgv | maybe you tried new unstable builds? |
| 14:21 | bobo_ | im not sure, dont think my code was much unformated anyway. maybe it can do some simple stuff? |
| 14:25 | bobo_ | looks like it can only indent the current line |
| 14:29 | bartj | I am not able to see any syntax highlighting in emacs for clojure files |
| 14:29 | devn | do you have clojure mode? |
| 14:30 | bartj | I have clojure-mode turned on like this in my .emacs: |
| 14:30 | bartj | (add-hook 'clojure-mode-hook 'turn-on-paredit-mode) |
| 14:35 | tomoj | that doesn't look like it should do anything |
| 14:36 | tomoj | when 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:37 | raek | bartj: that ativates paredit when clojure-mode is activated. |
| 14:39 | raek | if you install clojure-mode using package.el, I don't think you have to add anything to the .emacs file yourself |
| 14:39 | bartj | I guess I am expecting somewhat of vimclojure (rainbow colors!) effect with clojure-mode; which apparently, just isn't the case |
| 14:40 | tomoj | rainbows are not built in |
| 14:41 | raek | bartj: http://dishevelled.net/elisp/rainbow-parens.el |
| 14:42 | bartj | may I ask, which emacs themes are popular for editing clojure files? |
| 14:45 | msappler | hey why is this leading to a StackOverFlow : ? - I know that it works if you ` quote it... or is this just bad style? |
| 14:45 | msappler | <msappler> (defmacro testmacro |
| 14:45 | msappler | <msappler> ([a b] (+ a b)) |
| 14:45 | msappler | <msappler> ([] (testmacro 1 2))) |
| 14:45 | msappler | <msappler> =>(testmacro) |
| 14:45 | msappler | <msappler> java.lang.StackOverflowError |
| 14:46 | devn | what is the technical term for (partial xyz) |
| 15:07 | raek | msappler: a macro is a function that takes unevaluated code as parameters and return new code |
| 15:07 | raek | msappler: your macro does not return new code, but evaluates it during compile-time |
| 15:09 | raek | ` ("syntax-quote") is just a way of constructing data structures, especially useful as a kind of code templating language |
| 15:09 | raek | so, yes. you are supposed to quote the new code |
| 15:10 | raek | (defmacro testmacro ([a b] `(+ ~a ~b)) ([] `(testmacro 1 2))) |
| 15:10 | raek | this is eqivalent to: |
| 15:10 | raek | (defmacro testmacro ([a b] (list 'clojure.core/+ a b)) ([] (list 'user/testmacro 1 2))) |
| 15:11 | raek | devn: partial function application, I would say. "currying" is a related concept, but not exactly the same thing. |
| 15:16 | msappler | thank you raek |
| 15:26 | tomoj | raek: still, why should it overflow the stack? |
| 15:26 | tomoj | (testmacro 1 2) macroexpands to 3 just fine |
| 15:28 | raek | hrm, weird |
| 15:29 | tomoj | oh |
| 15:30 | tomoj | the (testmacro 1 2) in the macro definition is inside the macro definition.. |
| 15:30 | tomoj | not sure exactly why it overflows the stack, but I wouldn't expect it to work |
| 15:31 | raek | reversing the order of the two arities makes it work |
| 15:31 | raek | where "works" = does not cause a stack overflow |
| 15:32 | tomoj | huh, I still get the overflow |
| 15:32 | tomoj | (defmacro testmacro ([] (testmacro 1 2)) ([a b] (+ a b))) you mean? |
| 15:33 | raek | yes |
| 15:33 | tomoj | oh, had some weird state left over from the previous definition |
| 15:33 | tomoj | "works" from scratch |
| 15:33 | tomoj | .. no it doesn't. oh well. |
| 15:33 | raek | heh |
| 15:34 | raek | if I restart the repl, that version stops to work as well |
| 15:34 | raek | but if I eval the same code again, it does |
| 15:37 | currentB | anyone happen to know of a good guide to clojore metadata? |
| 15:43 | ordnungswidrig | currentB: besides the doc on with-meta and meta? |
| 15:51 | ordnungswidrig | currentB: what do you want to accomplish? |
| 15:53 | rrc7cz | has anyone ever played with haskell-style Either return types for dealing with errors rather than using exceptions? |
| 16:04 | shortlord | in cases where both "partial" and #( ) can be used (e.g. (partial * 100) vs. #(* 100 %) ), which one should be preferred? |
| 16:20 | replaca | shortlord: I consider it entirely a mater of taste. I will usually use partial there, but it's a fine line |
| 16:20 | ordnungswidrig | rrc7cz: in my experience this makes only sense with pattern-matching |
| 16:21 | ordnungswidrig | rrc7cz: perhaps together with matchure it might be worth a try. (http://spin.atomicobject.com/2010/04/25/matchure-serious-clojure-pattern-matching) |
| 16:21 | shortlord | replaca: ok, thx. I guess I'll use partial then, a bit less parenthesis-nesting |
| 16:22 | replaca | shortlord: I think that #() has a tiny performance advantage, by I've never noticed a diff in practice |
| 16:23 | LauJensen | shortlord: http://kotka.de/blog/2009/12/Pointfree_vs_Pointless.html |
| 16:27 | ordnungswidrig | LauJensen: very good article. |
| 16:27 | ordnungswidrig | In 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:27 | LauJensen | yea, he's an interesting guy |
| 16:44 | clgv | so, for performance: is it better to avoid partial and use alternatives? |
| 16:44 | clgv | I mean to avoid partial in cases where it is often called |
| 16:45 | shortlord | is 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:50 | amalloy | shortlord: enough people (including me) want that function that it will hopefully be added in future, but currently no |
| 16:51 | amalloy | clgv: if performance is a huge deal, then yeah partial is a little slower |
| 16:52 | shortlord | amalloy: ah ok. I'll stick with first and filter then |
| 16:52 | clgv | amalloy: ok thanks. |
| 17:18 | Berengal | I need some opinions. Which is easier to read and work with: http://hpaste.org/42867/relations |
| 17:19 | Berengal | The lisp, or the sql? |
| 17:20 | Berengal | And ignoring all things meta, like embedding them in programs. Pretend they're both simple query languages |
| 17:21 | amalloy | Berengal: the sql looks better to me, but i have experience with sql and none with the clojure-sql libraries |
| 17:22 | Chousuke | the problem with the sql query is that you gotta read it inside out |
| 17:22 | Chousuke | whereas with the clojure you can just go straight |
| 17:22 | amalloy | Chousuke: heh. a funny objection in a lisp channel |
| 17:22 | Chousuke | I guess :) |
| 17:26 | Berengal | amalloy: This isn't part of any existing clojure-sql library. It's just an experiment I'm doing |
| 17:26 | amalloy | ah |
| 17:27 | Chousuke | reminds me of the new clojureql |
| 17:27 | Chousuke | seems to have a similar idea |
| 17:28 | Berengal | Chousuke: 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:28 | Berengal | Besides, all I'm doing is just an experiment/long-winded, multifaceted kata |
| 17:31 | Berengal | It'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:31 | LauJensen | Berengal: hehe, you're doing the exact same thing as ClojureQL, exactly |
| 17:33 | AWizzArd | LauJensen: 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:33 | LauJensen | Berengal: You want to put relational back into relational database, and ClojureQLs motto contributed by chouser is "bringing relational algebra back to relational databases" :) |
| 17:33 | Berengal | LauJensen: Hah, I must've missed that |
| 17:33 | LauJensen | AWizzArd: I like critcism, so dont apologize even before you start flaming |
| 17:34 | AWizzArd | LauJensen: 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:34 | AWizzArd | Note: this is not a suggestion. |
| 17:35 | LauJensen | AWizzArd: 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:36 | AWizzArd | Yes, 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:37 | AWizzArd | I 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:37 | LauJensen | It could |
| 17:37 | LauJensen | Berengal: check out clojureql.org for some examples, I think you'll see the exact same API |
| 17:40 | AWizzArd | LauJensen: 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:41 | LauJensen | AWizzArd: 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:42 | AWizzArd | LauJensen: 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:43 | LauJensen | Its already there, just add {:fetch-size 50000} to your connection object and your results will be chunked |
| 17:43 | devn | I 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:43 | devn | most efficient way to write this function? |
| 17:43 | AWizzArd | LauJensen: hmm, I see. I need to look into that. |
| 17:44 | devn | ,(select-keys {:a "false", :b 0 :c 1} [:a :b]) |
| 17:44 | clojurebot | {:b 0, :a "false"} |
| 17:44 | AWizzArd | devn you can work with select-keys and with (some #{"false" false 0 "0") |
| 17:44 | devn | ah yes that's what i was looking for thanks AWizzArd |
| 17:45 | Chousuke | or every? :P |
| 17:45 | AWizzArd | yes |
| 17:48 | devn | ,(every? #(= (val %) #{"false" false 0 "0"}) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d])) |
| 17:48 | clojurebot | false |
| 17:48 | devn | err that's not right |
| 17:51 | AWizzArd | devn: sets can be used as functions |
| 17:52 | AWizzArd | and put a ‘vals’ around select-keys |
| 17:52 | Chousuke | ,(every? #(contains? #{"false" false 0 "0"} (val %)) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d]) |
| 17:52 | clojurebot | EOF while reading |
| 17:52 | AWizzArd | ,(vals (select-keys {:a 1, :b 2, :c 3} [:c])) |
| 17:52 | clojurebot | (3) |
| 17:52 | Chousuke | you need to use contains? because |
| 17:52 | Chousuke | ,(#{false} false) |
| 17:52 | clojurebot | false |
| 17:53 | AWizzArd | Ah yes, that thing agani. |
| 17:54 | Chousuke | ,(every? #(contains? #{"false" false 0 "0"} (val %)) (select-keys {:a false :b "false" :c 0 :d "0" :e 1} [:a :b :c :d])) |
| 17:54 | clojurebot | true |
| 17:56 | AWizzArd | Though I must still say that I would prefer vals vs. val :) |
| 17:56 | AWizzArd | LauJensen: this :fetch-size looks interesting, thanks for bringing this to my attention. |
| 17:57 | LauJensen | AWizzArd: no problem - just note that its a clojureql specific thing, I dont think anybody else references cursors like that |
| 17:58 | devn | that seems so verbose for the problem but maybe im just being OCD |
| 17:58 | devn | it 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:05 | devn | anyways, thanks for the help |
| 18:12 | amalloy | Chousuke, devn: instead of (contains #{} (val)) you can do (comp #{} val), no? |
| 18:13 | Chousuke | amalloy: not in this case |
| 18:13 | amalloy | thus avoiding any anonymous functions |
| 18:13 | amalloy | oh right, cause false isn't true :P |
| 18:13 | amalloy | laaame |
| 18:13 | Chousuke | comp was my first idea too |
| 18:13 | AWizzArd | it would kill every? in this case, but normally it would work. |
| 18:14 | AWizzArd | (every? #{1 2 3} (vals (select-keys map keys))) |
| 20:39 | devn | here's another question |
| 20:39 | devn | is clojure.string available without a use/require? |
| 20:40 | devn | and the answer is of course no :) |
| 20:41 | amalloy | *chuckle* indeed, that is of course the answer |
| 20:42 | devn | :) |
| 20:42 | devn | ,(use 'clojure.string) |
| 20:42 | clojurebot | WARNING: replace already refers to: #'clojure.core/replace in namespace: sandbox, being replaced by: #'clojure.string/replace |
| 20:42 | clojurebot | WARNING: reverse already refers to: #'clojure.core/reverse in namespace: sandbox, being replaced by: #'clojure.string/reverse |
| 20:42 | clojurebot | nil |
| 20:43 | devn | ,(join "hello" "world") |
| 20:43 | clojurebot | "whelloohellorhellolhellod" |
| 20:43 | devn | interesting behavior :) |
| 20:43 | amalloy | devn: "world" is a seq of five characters |
| 20:43 | amalloy | you joined them together with hello |
| 20:43 | amalloy | &(require '[clojure.string :as s]]) |
| 20:43 | sexpbot | java.lang.Exception: Unmatched delimiter: ] |
| 20:43 | devn | yes i know i guess i was just a bit surprised at first |
| 20:44 | amalloy | &(require '[clojure.string :as s]) |
| 20:44 | sexpbot | ⟹ nil |
| 20:44 | amalloy | &(s/join ["hello" "world"]) |
| 20:44 | sexpbot | ⟹ "helloworld" |
| 20:45 | amalloy | btw it is kinda rude to (use) stuff in the bots if it's going to override other existing functions |
| 20:45 | amalloy | ,(ns-unmap *ns* 'replace) |
| 20:45 | clojurebot | nil |
| 20:45 | amalloy | ,(ns-unmap *ns* 'reverse) |
| 20:45 | devn | the join documentation is weird |
| 20:45 | clojurebot | nil |
| 20:45 | amalloy | ,(refer '[clojure.core :only [reverse replace]]) |
| 20:45 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Symbol |
| 20:45 | devn | &(join ["hello" "world"] " ") |
| 20:45 | sexpbot | java.lang.Exception: Unable to resolve symbol: join in this context |
| 20:46 | amalloy | devn: s/join |
| 20:46 | amalloy | ,(use '[clojure.core :only [reverse replace]]) |
| 20:46 | devn | ,(join ["hello" "world"] " ") |
| 20:46 | clojurebot | nil |
| 20:46 | clojurebot | " " |
| 20:46 | devn | ,(join " " ["hello" "world"]) |
| 20:46 | clojurebot | "hello world" |
| 20:46 | devn | ,(doc join) |
| 20:46 | clojurebot | "([coll] [separator [x & more]]); Returns a string of all elements in coll, separated by an optional separator. Like Perl's join." |
| 20:46 | devn | now to mean that suggests that you give it a coll followed by a separator |
| 20:47 | amalloy | you're reading it wrong |
| 20:47 | devn | s/mean/me |
| 20:47 | sexpbot | <devn> now to me that suggests that you give it a coll followed by a separator |
| 20:47 | amalloy | it takes either ([coll]) or ([separator [x & more]]) |
| 20:47 | devn | bah im such a newb :( |
| 20:47 | tomoj | speaking of that, probably shouldn't be [x & more] there.. |
| 20:48 | amalloy | tomoj: you could say coll instead, but i don't see much gain |
| 20:48 | devn | ,(join " " ["hello", "world"] ["foo" "bar"]) |
| 20:48 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (3) passed to: string$join |
| 20:49 | tomoj | people looking at the arglists don't need to know join does its work by destructuring |
| 20:49 | devn | tomoj: i agree - if that had said [separator coll], i would have never asked this question in the first place |
| 20:49 | devn | or found it "odd" |
| 20:49 | tomoj | "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:53 | devn | ,(clojure.repl/apropos #"set") |
| 20:53 | clojurebot | (superset? subset? thread-set-name reset-inspector set-pprint-dispatch set-primary set-env-value set-notnull set-env set-system-properties ...) |
| 20:55 | amalloy | devn: find-doc too |
| 20:55 | amalloy | &(find-doc "set") |
| 20:55 | sexpbot | ⟹ ------------------------- 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:55 | Raynes | sexpbot: wut |
| 20:55 | amalloy | hm. that's...not as pretty as it could be |
| 20:55 | Raynes | Broken pipe? Who broke my pipe? |
| 20:55 | amalloy | Raynes: isn't that the error he gives if the gist is too long? |
| 20:56 | Raynes | amalloy: No. Not unless gist is doing it. |
| 20:56 | Raynes | $(range 1000) |
| 20:56 | amalloy | &(repeat 1e6) |
| 20:56 | amalloy | er whoops |
| 20:56 | amalloy | &(repeat 1e6 1) |
| 20:56 | sexpbot | Execution Timed Out! |
| 20:56 | sexpbot | ⟹ (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:56 | Raynes | &(range 1000) |
| 20:56 | sexpbot | ⟹ (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 ... http://gist.github.com/771336 |
| 20:56 | Raynes | Yeah, too large. |
| 21:52 | jimdagem | what're you guys talking about? |
| 22:53 | GeoffSK | When i (-> 10 (fn [x] (+ 1 x))) ; i get an error, any clues why? |
| 22:58 | amalloy | GeoffSK: because (fn 10 [x]) isn't so hot |
| 22:58 | amalloy | try (-> 10 ((fn [x] ...))) |
| 22:59 | GeoffSK | no surprise you are right. |
| 22:59 | GeoffSK | what's the difference between inc and (fn [x] (+ 1 x)) |
| 23:00 | Raynes | There isn't one. |
| 23:00 | GeoffSK | i feel i just met a koan. |
| 23:02 | GeoffSK | I am perplexed : (-> 1 inc) is good. (-> 1 (fn [x] ...) is bad, but inc and (fn [x] ... ) is the same. |
| 23:02 | Raynes | &(macroexpand '(-> 10 (fn [x] (+ 1 x)))) |
| 23:02 | sexpbot | java.lang.UnsupportedOperationException: nth not supported on this type: Integer |
| 23:02 | amalloy | &(macroexpand '(-> 1 (fn [x] (+ 1 x)))) |
| 23:02 | sexpbot | java.lang.UnsupportedOperationException: nth not supported on this type: Integer |
| 23:03 | Raynes | Speaking of bugs. |
| 23:03 | amalloy | um |
| 23:03 | amalloy | ,(macroexpand '(-> 1 (fn [x] (+ 1 x)))) |
| 23:03 | clojurebot | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.UnsupportedOperationException: nth not supported on this type: Integer |
| 23:03 | amalloy | apparently it's so broken it can't macroexpand? |
| 23:03 | Raynes | Or not. |
| 23:03 | Raynes | Wow. |
| 23:03 | amalloy | GeoffSK: the difference is -> is modifying your (fn) form before it gets evaluated |
| 23:03 | amalloy | inc is already written; there's nothing to modify |
| 23:04 | GeoffSK | got it. |
| 23:04 | GeoffSK | macros and fns are interchangeable |
| 23:04 | GeoffSK | macros and fns are NOT interchangeable |
| 23:04 | Raynes | (-> 10 (fn [x] (+ 1 x))) = (fn 10 [x] (+ 1 x)); (-> 10 inc) = (inc 10) |
| 23:05 | amalloy | GeoffSK: right, the second one |
| 23:05 | GeoffSK | thanks, don't completely grok, but thats my homework. Thanks. |
| 23:08 | GeoffSK | ok i read the source. Is their a reason it should be a macro rather than fold |
| 23:08 | GeoffSK | oops i mean reduce |
| 23:09 | amalloy | GeoffSK: it needs to be applied before its arguments are evaluated |
| 23:09 | GeoffSK | of course. |
| 23:09 | GeoffSK | Thanks again. |
| 23:09 | amalloy | the macro could be written using reduce, if it were desired |
| 23:10 | GeoffSK | yes, but like you said, the macro part is critical (code as data) |
| 23:10 | amalloy | right |
| 23:20 | btw0 | what's the best way to generate a random subset with specified number of elments from a set? |
| 23:22 | tomoj | anybody 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:24 | amalloy | btw0: i dunno the best way, but (take n (sort-by (fn [_] (rand)) coll)) would probably work |
| 23:24 | tonyl | tomoj: I don't think you would gain much by type hintin void |
| 23:25 | tomoj | not trying to gain anything except an instance of the interface |
| 23:25 | tomoj | since two of the methods share name and arity, I think I have to provide all hints |
| 23:26 | tonyl | methods don't dispatch by method signature in clojure only by arity so you would have to deal with it differently |
| 23:27 | tomoj | you see that I'm reifying? |
| 23:27 | btw0 | amalloy: that's a nice solution, thanks! |
| 23:28 | tonyl | yeah kf which has a method a that has 2 different signatures |
| 23:28 | tonyl | which is a predicament I haven't work with before |
| 23:29 | tomoj | &[(.indexOf "foo" 111) (.indexOf "foo" "o")] |
| 23:29 | sexpbot | ⟹ [1 1] |
| 23:29 | tomoj | don't think that's the predicament |
| 23:30 | tomoj | could there be problems interoping with classes/interfaces in the default package, maybe? |
| 23:30 | chouser | |
| 23:30 | chouser | pardon me |
| 23:32 | cemerick | btw0: rand-nth should get you a good way there. |
| 23:32 | tomoj | strange, (.a (reify kf) "foo") gives the expected AbstractMethodError |
| 23:33 | tomoj | yet "Can't define method not in interfaces: a" |
| 23:33 | btw0 | cemerick: you mean run rand-nth against the collection multiple times? |
| 23:33 | tomoj | oh shit |
| 23:34 | tomoj | I just left off the 'this' arg |
| 23:35 | tonyl | tomoj: 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:35 | tonyl | but if you find something else, let me know, that would open some eyes |
| 23:36 | tomoj | works fine with the 'this' param included |
| 23:37 | tomoj | tonyl: updated the gist to show |
| 23:38 | tonyl | so including it in the methods works the ambiguity? interesting |
| 23:38 | tonyl | tomoj: you opened my eyes :) that is always welcome |
| 23:38 | cemerick | btw0: sure; this is just an example, but should illustrate the idea: |
| 23:38 | cemerick | ,(into #{} (take 10 (repeatedly #(rand-nth (seq (set (range 100))))))) |
| 23:38 | clojurebot | #{33 98 67 44 77 15 18 56 91 28} |
| 23:38 | tomoj | it's java so we have dispatch by type |
| 23:38 | tomoj | just like my indexOf example above |
| 23:39 | cemerick | btw0: certainly don't need the other set in there, but you said you were drawing from a set… |
| 23:39 | cemerick | ,(into #{} (take 10 (repeatedly #(rand-nth (range 100))))) |
| 23:39 | clojurebot | #{0 98 7 74 11 19 54 55 89 58} |
| 23:41 | btw0 | cemerick: isn't the performance really bad if take large number of elements from a relatively small set? |
| 23:43 | amalloy | cemerick, btw0: that also includes duplicates |
| 23:45 | cemerick | amalloy: yeah, I've no idea what btw0's real use case is, may or may not matter |
| 23:45 | cemerick | btw0: not sure what you mean. If it's doing what you need it to do, then perf/optimization is orthogonal. |
| 23:47 | amalloy | btw0: 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:47 | sexpbot | ⟹ (53 63 45 8 50 23 55 23 29 26) |
| 23:47 | btw0 | cemerick: actually what i mean is the performance is bad if we need to get rid of duplicates. |
| 23:49 | btw0 | cemerick: 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:49 | cemerick | btw0: then dedupe the source set/seq/collection once, and take randomly from that result. |
| 23:50 | cemerick | er, source sets are, of course, "deduped" already |
| 23:51 | amalloy | cemerick: i think his issue is he wants the result to have no dupes |
| 23:52 | btw0 | amalloy: exactly |
| 23:52 | amalloy | &(into #{} (take 10 (repeatedly #(rand-nth (range 10))))) |
| 23:52 | sexpbot | ⟹ #{0 5 6 7 8 9} |
| 23:53 | amalloy | is an example of the problem |
| 23:54 | btw0 | no dupes and no less if the source can provide that many elements |
| 23:54 | cemerick | hard to know what to recommend in general -- depends a lot on the data/problem |
| 23:54 | cemerick | dedupe the source collection, shuffle it, and then pop values off? |
| 23:57 | btw0 | I am afraid shuffling a large collection is slow |
| 23:58 | tomoj | how large is 'large'? :) |
| 23:58 | btw0 | how about 200000? |
| 23:58 | tomoj | more importantly I guess, how many times? |
| 23:58 | tomoj | &(time (when (shuffle (range 200000)))) |
| 23:58 | sexpbot | ⟹ "Elapsed time: 190.16017 msecs" nil |
| 23:58 | tomoj | seems slow to you? |
| 23:58 | cemerick | tomoj: beat me to it :-P |
| 23:59 | tomoj | huh |
| 23:59 | tomoj | &(-> 200000 range shuffle when time) |
| 23:59 | sexpbot | ⟹ "Elapsed time: 167.677456 msecs" nil |
| 23:59 | tomoj | :) |
| 23:59 | cemerick | btw0: in any case, you need to pay the price for randomization and avoiding duplicates somewhere. |