2010-11-21
| 00:17 | danlarkin | java crypto is enough to drive a person nuts |
| 01:32 | livingston | creating protocols and attaching them to classes / records is far easier than creating a ton of defmulti's but is there a way to put a default on a protocol function like I can for a defmulti, for something that doesn't have the specified behavior to return the default? |
| 01:33 | technomancy | livingston: you can extend Object. |
| 01:33 | livingston | yeah i was thinking about that, but then I won't get all the native types? or will it autobox an int into an Integer to get the behavior? |
| 01:34 | technomancy | I think calls from Clojure would get autoboxed; I don't know about calls from Java |
| 01:35 | technomancy | ISTR some discussion about the Conj re: reservations about extending Object, but I don't remember the details |
| 01:36 | livingston | I think i'm ok with that... and the dispatch on protocols always picks the more specific type, if there are several applicable, I'm sure, right? |
| 01:36 | livingston | oops I mean ok with clj code and java maybe maybe-not |
| 01:37 | livingston | hmm maybe I should just keep this particular function as a defmulti instead of fighting with the protocol, since I pretty much want in to work for about anything |
| 01:38 | technomancy | personally I find the semantics of defmulti to be much more straightforward |
| 01:38 | technomancy | defrecord attempts to straddle AOT and JIT worlds in ways that are still unpredictable to me. |
| 01:40 | livingston | yes me too, but when you have a handful of functions that naturally fall in a group, then protocols seems pretty useful (I came from lisp, there was nothing like protocol it was all dispatch so I think that way) |
| 01:40 | technomancy | for my purposes namespaces have served just fine as a way of grouping defmultis |
| 01:41 | livingston | the docs seem to imply if you can use protocols/records it's more efficient, but that's not exactly clear to me when there's still dispatch I would assume? |
| 01:41 | technomancy | but I could see the appear of the way protocols do it |
| 01:41 | technomancy | it's very rare for that level of optimization to be justified. |
| 01:41 | technomancy | unless you're writing clojure-in-clojure |
| 01:41 | talios | 'lo technomancy |
| 01:41 | technomancy | talios: hi |
| 01:43 | livingston | technomancy: i don't have a problem grouping them or whatever, that's fine. some of what I'm working on will end up in pretty tight loops, if there's a bit to eek out of that, I'll take it now - why not, doesn't seem that much harder with protocols. but I hear you on defmulti just making sense |
| 01:43 | talios | turns out spilling lemonade thru a macbooks keyboard isn't healthy for said macbook :( |
| 01:43 | technomancy | talios: time to get a thinkpad--built-in drainage in the keyboard =) |
| 01:44 | livingston | talios: bummer. yeah and they don't have drains, because I'm sure Steve Jobs thinks things like drains and vents are ugly |
| 01:44 | talios | livingston: yeh - hopefully the insurance will come thru and pay for a replacement ( which I could then upgrade to something more decent as well ). |
| 01:44 | talios | draintrays would be a wonderful thing. I see the new HPs have them too. |
| 01:45 | livingston | I like my mac book. some things like that just make sense. like the mac power connector. there should just be basic things always included. |
| 01:46 | technomancy | they are nice, but I also like the fact that I can buy three thinkpad power supplies for the price of one apple power supply =P |
| 01:46 | talios | thankfully I have 98% of everything backed up, and thankfully co-podcaster richard loaned me his old macbook pro. so at least I can continue to do stuff |
| 01:47 | technomancy | surely liquids can't damage the drive? |
| 01:47 | livingston | it's not the power supply it's your laptop that goes flying when someone trips over the cord |
| 01:47 | talios | I should be able to get the data off it. will find out when I get the machine back from the store where I was getting a repair/insurance quote |
| 01:48 | livingston | yeah I would think last resort you could pull the drive. even if it had a drain there'd be some disassembly involved anyway to clean something like lemonade. |
| 01:48 | technomancy | livingston: I guess that would be a bummer if your laptop wasn't indestructible =) |
| 01:49 | livingston | technomancy: I've seen it happen more times than it should at conferences, sucks every time |
| 01:49 | technomancy | I have a 6-ft standing desk; I've pulled my laptop off it twice (from the ethernet cord, ironically) without a scratch. |
| 01:50 | talios | impressive |
| 01:50 | livingston | lucky. hopefully your drive readheads parked themselves in time - you won't see the scratches there ;) |
| 01:56 | technomancy | talios: I was up really late last week and couldn't help being struck by how quiet things are on freenode in your timezone. |
| 01:58 | talios | mmm, most of the people I know on IRC pride themselves with their idle times anyway :) |
| 01:58 | talios | undernet seems to get more NZ users ( or used to at least ). |
| 01:59 | livingston | talios: that's funny. I can't run idle we have it blocked at work, and this web client will crap out sooner or later. |
| 01:59 | talios | I find it depends on the channel. Trying to get anyone from the codehaus servers to respond during my "awake" is impossible |
| 02:00 | talios | livingston: ssh+irssi ;-) |
| 02:00 | technomancy | even better: ssh+free EC2 micro instance |
| 02:01 | talios | altho now you've made me think about the time I realise it's past dinner time - no wonder i'm hungry :) |
| 02:01 | livingston | I was just going to say I don't have anywhere to ssh to, but that's an interesting option |
| 02:02 | technomancy | free for a year |
| 02:02 | technomancy | check out http://github.com/dysinger/nanosat |
| 02:02 | livingston | a better client would be better, but running idle offers no major advantage, I mean it's all archived on the net |
| 02:02 | technomancy | you can even get the machine provisioned using clojure |
| 02:02 | technomancy | ERC works great on EC2 |
| 02:03 | livingston | technomancy: what's ERC? |
| 02:04 | trybeingarun | Emacs Relay Chat |
| 02:05 | livingston | oh right, yeah I started off looking into using that, and then found out about the silly firewall - "only "hackers" and bots use IRC, can't possibly be useful" -- I said, "I know, I'm a hacker - you've hired one, now help me out." |
| 02:06 | technomancy | well if they allow SSH then it's game over |
| 02:06 | technomancy | no point in blocking anything |
| 02:07 | hiredman | ssh even has a built in socks proxy |
| 02:07 | technomancy | heck; you can run an SSH server on the HTTPS port and get around anything |
| 02:08 | talios | tcp/ip over dns works as well :-) slow as all hell, but works. |
| 02:08 | talios | http://analogbit.com/tcp-over-dns_howto |
| 02:08 | livingston | yeah, their avg. user doesn't know that here though. I don't know how smart their firewall is though, it may look for odd traffic like that. |
| 02:08 | hiredman | it sure is slow |
| 02:08 | technomancy | or ICMP |
| 02:10 | livingston | if it's something that's needed you can file paperwork and get it eventually - you should have seen what was involved for a skype exemption -- meanwhile I can just use webchat |
| 02:10 | technomancy | grumble... still no paredit 22 in elpa. |
| 02:10 | technomancy | I really need to get my own package server working. |
| 02:10 | talios | bbl - going to find some dinner. I'm thinking Thai. |
| 02:11 | hiredman | technomancy: I built the latest emacs and the paredit from the starter kit stopped working (looked like a conflict with a paredit that came with emacs) |
| 02:11 | technomancy | paredit comes with emacs now... ! |
| 02:11 | technomancy | wat |
| 02:12 | hiredman | maybe, I did look that into it, I uninstalled the elpa paredit, stopped getting warnings, and still have paredit |
| 02:12 | hiredman | I did not look |
| 02:12 | hiredman | or something |
| 02:12 | technomancy | I'm not seeing it; must have been an older manual install |
| 02:13 | technomancy | the one in elpa is so old it doesn't really work with {} =( |
| 02:13 | hiredman | right |
| 02:13 | hiredman | and whatever I have now does |
| 02:14 | technomancy | the latest one has a new feature where you can configure it to sorta even work in JS without inserting those annoying spaces |
| 02:16 | hiredman | weird, I cannot find a predit file in the emacs src, or in my .emacs.d, but I have predit |
| 02:18 | technomancy | M-x locate-lib |
| 02:20 | hiredman | ugh, it is in my .emacs.d, but I was running find $PWD, and $PWD was a symlink, so fail |
| 02:36 | livingston | i hate having to either forward declare things or write code that seems upside-down. |
| 02:43 | livingston | records will behave just like maps when it comes to accessors and keys, right? |
| 02:44 | hiredman | records don't extend IFn if I recall |
| 02:45 | livingston | hiredman: ok so you just have to make sure to do (:keyword record) instead of the other way around, right? |
| 04:10 | fbru02 | Hi anyone around ? |
| 04:11 | kumarshantanu | hi, can somebody tell me if this is the right way to pass type hints? -- (fn [^java.util.Map m k] (.contains m k)) |
| 04:12 | kumarshantanu | I am getting warning though |
| 04:20 | livingston | you can try putting the hint in the (.contains call |
| 04:21 | livingston | (.contains ^hint m k) |
| 04:24 | kumarshantanu | livingston: still not working :( |
| 04:24 | kumarshantanu | (fn [^java.util.Map m ^String k] |
| 04:24 | kumarshantanu | (.contains ^java.util.Map m ^String k)) |
| 04:37 | notsonerdysunny | can somebody help me understand clojure.zip/seq-zip with an example? |
| 04:40 | _ato | kumarshantanu: java.util.Map has no .contains method |
| 04:40 | _ato | http://download.oracle.com/javase/6/docs/api/java/util/Map.html |
| 04:44 | kumarshantanu | _ato: you are right! (wondering why .contains works nevertheless) |
| 04:45 | kumarshantanu | _ato: I changed it to .containsKey and it no more gives a warning |
| 04:46 | _ato | must be whatever concrete class is being passed in does have a .contains and Clojure is finding it via reflection at runtime |
| 04:47 | kumarshantanu | _ato: right |
| 05:02 | fbru02 | hey can somebody try this and see if this is also failing for you? |
| 05:03 | fbru02 | https://github.com/alexott/clojure-libs/blob/9a6bbe7b7cd1c299d05863d8c82ef2468cf0e706/mahout/project.clj |
| 05:26 | Vinzent | fbru02: yes |
| 05:27 | fbru02 | Vinzent: cool , I thought i was the only one that got that failing , thanks |
| 05:32 | Vinzent | np |
| 06:44 | LauJensen | I justed released a new jar on clojars in which ClojureQL now supports joins on multiple tables |
| 06:44 | LauJensen | s/justed/just/ |
| 06:44 | sexpbot | <LauJensen> I just released a new jar on clojars in which ClojureQL now supports joins on multiple tables |
| 06:46 | _ulises | morning all |
| 06:55 | fbru02 | LauJensen: Cool |
| 07:04 | fbru02 | i have a mvn question, i'm using lein, and i have a project that needs some other project. This second project has a pom with dependencies etc. Do i have to specify all the deps for the second project in my first project or is there a way of mvn/lein knowing how to resolve those? |
| 07:06 | _ato | maven/lein will do transitive dependency resolution. So if project A depends on B and B depends on C, then A will pull in C as well without you having to specify it explicitlyfff |
| 08:01 | raek | hrm, why do I get "Can only recur from tail position" when I do (when-let [y (f x)] (recur ...) (...))? |
| 08:02 | raek | ah, nevermind... |
| 08:02 | raek | *if-let* |
| 08:37 | joeyd81 | Hi, there has to be a better way to do AOT compilation than what I do : echo "(compile 'explore.perm)" | clj_compiler |
| 08:38 | raek | what is clj_compiler? |
| 08:39 | raek | I would use one of the build tools (Leiningen or Cake) |
| 08:39 | raek | with Leiningen, it would be "lein compile", I think |
| 08:40 | joeyd81 | exec java -server -d64 -cp ${JAR}/clojure-contrib.jar:${JAR}/clojure.jar:${JAR}/ |
| 08:40 | joeyd81 | jline-0.9.94.jar:/opt/clojure jline.ConsoleRunner cloj |
| 08:40 | joeyd81 | ure.main $* |
| 08:41 | joeyd81 | I am calling this stuff from within a Makefile |
| 08:45 | kumarshantanu | can anybody tell me if it's possible to type hint object arrays (non-primitive arrays)? |
| 08:49 | edbond | how to println in -main? |
| 08:55 | raek | edbond: (defn -main [] (println "hello")) ? |
| 08:58 | edbond | raek, ha this doesn't print anything |
| 08:59 | raek | it will only print when -main is called. in what situation do you want it to be called? |
| 08:59 | edbond | raek, oops I use printf not println |
| 09:00 | raek | -main is usually for when you AOT compile your project into a jar |
| 09:00 | joeyd81 | how do you test for 2 things being identical vs. equal in clojure? |
| 09:01 | raek | joeyd81: identical? is for object identity |
| 09:01 | joeyd81 | in Ocaml you have physical equality (==) vs. structural equality (=) |
| 09:01 | raek | joeyd81: = means value-based equality for immutable types and identity-based equality for mutable types |
| 09:02 | raek | (this is the semantics for types introduced by clojure. for java types, = means java .equals and identical? means java ==) |
| 09:02 | joeyd81 | I definite identical thus - the 2 things have the same address in memory and are equal, vs. equal - different addresses in memory |
| 09:03 | raek | joeyd81: then clojure.core/identical? fits your definition of identical |
| 09:03 | joeyd81 | ok, cool is there sugar for it? |
| 09:04 | raek | oh, sorry. I misinterpreted you statement. identical? is only same address in memory |
| 09:05 | raek | but how could they not be equal if they are the same object? |
| 09:05 | raek | ,(= [1 2 3] [1 2 3]) |
| 09:05 | clojurebot | true |
| 09:05 | raek | ,(= [1 2 3] '(1 2 3)) |
| 09:05 | clojurebot | true |
| 09:05 | raek | ,(= (atom [1 2 3]) (atom [1 2 3])) |
| 09:05 | clojurebot | false |
| 09:06 | raek | ,(identical? [1 2 3] [1 2 3]) |
| 09:06 | clojurebot | false |
| 09:06 | raek | you could see = as sugar for identical? if you are comparing reference types |
| 09:07 | joeyd81 | so when I store an object into a collection the address of it is stored, not the object itself, seems to me |
| 09:07 | raek | yes |
| 09:07 | raek | on the JVM, only primitives are stored themselves |
| 09:07 | joeyd81 | good, thanks a lot raek |
| 09:07 | raek | objects and arrays are reference types |
| 09:09 | raek | two sequential collections are = if they are = element-wise and of the same size |
| 09:09 | raek | ,(let [a (atom 1)] (= [0 a 0] [0 a 0])) |
| 09:09 | clojurebot | true |
| 09:10 | raek | 0 = 0, because they are the same value, a = a because they are the same object |
| 09:10 | joeyd81 | then what is == used for |
| 09:11 | joeyd81 | in clojure? |
| 09:13 | joeyd81 | it seems to me that == is used solely for numerical comparisons in clojure |
| 09:13 | edbond | joeyd81, read http://clojuredocs.org/clojure_core/clojure.core/== |
| 09:14 | raek | ,(= 1 1.0M) |
| 09:14 | clojurebot | false |
| 09:14 | raek | ,(== 1 1.0M) |
| 09:14 | clojurebot | false |
| 09:15 | raek | I have never used == |
| 09:15 | joeyd81 | ok, enough dumb questions for today, thanks everyone |
| 09:15 | jarpiain | ,(== 1.0M 1.00M) |
| 09:15 | clojurebot | false |
| 09:17 | raek | ~source == |
| 09:27 | joeyd81 | actually 1 more question and no more - how can I unify the repl definitions of -main and the AOT compiled version of same? Here is what I mean, in the repl the definition is (defn -main [args] .....) and it gets called (-main *command-line-args*) VERSUS compiled code the definition is (defn - main [& args] ......) . As you see args are passed in differently, hence I can't have the same -main code |
| 09:28 | raek | what code calls (-main *command-line-args*)? |
| 09:28 | raek | 'cause that should indeed be (apply -main *command-line-args*) |
| 09:28 | joeyd81 | The repl calls it |
| 09:28 | raek | leiningen? |
| 09:28 | clojurebot | http://github.com/technomancy/leiningen |
| 09:28 | joeyd81 | no, I don't use leinigen just yet |
| 09:28 | raek | hrm |
| 09:29 | raek | how do you launch clojure? |
| 09:29 | joeyd81 | java -server -d64 -cp ${JAR}/clojure-contrib.jar:${JAR}/clojure.jar:${JAR}/jline-0.9.94.jar:/opt/clojure jline.ConsoleRunner clojure.main $* |
| 09:29 | raek | so clojure.main calls the -main function? |
| 09:30 | joeyd81 | yes I think |
| 09:30 | raek | that's odd |
| 09:30 | raek | how does it now in which namespace it should look for the -main var...= |
| 09:31 | joeyd81 | I don't know but it looks like the answer is to call (apply -main *command-line-args*), I will give this a try |
| 09:31 | raek | what is in the $* variable? |
| 09:31 | joeyd81 | represents the args to the -main |
| 09:32 | raek | yes, but what args do you pass it? |
| 09:32 | joeyd81 | the argv[] array from the C world |
| 09:34 | raek | joeyd81: is there any (-main *command-line-args*) call in your code? |
| 09:34 | jarpiain | ,(doc clojure.main/main) |
| 09:34 | clojurebot | "([& args]); Usage: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*] With no options or args, runs an interactive Read-Eval-Print Loop init options: -i, --init path Load a file or reso... |
| 09:35 | joeyd81 | I paste that code into the repl after the -main definition: (-main *command-line-args*) |
| 09:35 | raek | ah. |
| 09:36 | joeyd81 | but you said it should be (apply -main *command-line-args*) if -main takes [args] instead of [& args] |
| 09:36 | raek | you should probably do something like ... clojure.main -e "(use 'the-namespace) (apply -main *command-line-args*)" ... |
| 09:36 | raek | if you have a call to -main in the source file, that will be run at *compile time* when you AOT compile your source |
| 09:37 | joeyd81 | ok, let me give it a try, this chat room is awesome |
| 09:37 | raek | :) |
| 09:38 | raek | there is a lein-run plugin for this (will be a part of leiningen itself in the next release, I think), if you happen to start using leiningen later on |
| 09:43 | fbru02 | _ato: thanks for your answer I just came back to the computer |
| 10:11 | cljbie | hi everyone. |
| 10:12 | cljbie | anyone here also using python? |
| 10:12 | cljbie | python has dir() method which lets me see what methods and attributes an object has, does clojure have anything like that? |
| 10:15 | yacin | cljbie: maybe show in clojure.contrib-repl-utils? |
| 10:16 | cljbie | yacin: i only have clojure and don't know what that is |
| 10:17 | yacin | how did you install clojure? |
| 10:17 | yacin | but i'm sure show is what you want |
| 10:17 | yacin | ,(show "str") |
| 10:17 | clojurebot | java.lang.Exception: Unable to resolve symbol: show in this context |
| 10:18 | yacin | ,(use 'clojure.contrib-repl-utils) |
| 10:18 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib_repl_utils__init.class or clojure/contrib_repl_utils.clj on classpath: |
| 10:18 | yacin | hmm |
| 10:19 | yacin | ,(use 'clojure.contrib.repl-utils) |
| 10:19 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath: |
| 10:19 | cljbie | there is "inspect" |
| 10:19 | cljbie | i found that hmm |
| 10:21 | yacin | ,(use 'clojure.contrib.shell) |
| 10:21 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/shell__init.class or clojure/contrib/shell.clj on classpath: |
| 10:21 | yacin | hmm, guess you can't import contrib |
| 10:21 | yacin | anyway, repl-utils' show is what you want |
| 10:21 | yacin | user=> (show "str") |
| 10:21 | yacin | === public final java.lang.String === |
| 10:21 | yacin | [ 0] static CASE_INSENSITIVE_ORDER : Comparator |
| 10:21 | yacin | [ 1] static copyValueOf : String (char[]) |
| 10:21 | yacin | [ 2] static copyValueOf : String (char[],int,int) |
| 10:21 | yacin | [ 3] static format : String (Locale,String,Object[]) |
| 10:21 | yacin | ... |
| 10:23 | raek | $(use '[clojure.contrib.repl-utils :only (show)]) |
| 10:23 | raek | &(use '[clojure.contrib.repl-utils :only (show)]) |
| 10:23 | sexpbot | java.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath: |
| 10:23 | raek | well, the bot's are limited... :) |
| 10:25 | SergeyD | Hi! Is there a better way to translate [[3 4 5]] into [3 4 5] than "(apply map identity [[3 4 5]])" ? |
| 10:25 | yacin | ,(flatten [[3 4 5]]) |
| 10:25 | clojurebot | (3 4 5) |
| 10:25 | cljbie | thanks yacin |
| 10:25 | yacin | np |
| 10:25 | SergeyD | oh, thanks :) |
| 10:25 | yacin | np :) |
| 10:26 | yacin | or i guess you could just use first |
| 10:26 | SergeyD | ,(first [[345]]) |
| 10:26 | clojurebot | [345] |
| 10:41 | cljbie | yacin: i have a list. how can i loop through all of the elements and sum them all up? |
| 10:43 | trybeingarun | (defn sum-list [lst] |
| 10:43 | yacin | ,(reduce + [1 2 3 4 5 6]) |
| 10:43 | clojurebot | 21 |
| 10:43 | trybeingarun | (reduce + l)) |
| 10:45 | yacin | there's no reason to make a separate function |
| 10:45 | yacin | reduce is clear enough, imho |
| 10:46 | trybeingarun | yep. my bad :) |
| 10:59 | cljbie | alright :) |
| 10:59 | cljbie | i've written my first clojure function |
| 10:59 | kumarshantanu | is a type hint in a macro passed to ~@body ? |
| 11:01 | cljbie | yacin: http://paste.pocoo.org/show/294246/ |
| 11:01 | cljbie | :) |
| 11:02 | cljbie | a question here. if i wanted to store "(+ 1 (count others))" part in a variable, how should i have done it and how could i use it in the calculation? |
| 11:03 | raek | (let [c (inc (count others))] ...calculations...) |
| 11:05 | raek | another slight variation would be to let the function take a sequence rathern than multiple arguments |
| 11:05 | trybeingarun | There is a version of reduce function which takes 3 args, [fn val coll] which is also useful |
| 11:05 | raek | (defn avg [coll] (/ (reduce + coll) (count coll))) |
| 11:07 | raek | cljbie: also, you usually indent like this: http://pastebin.com/dzTYsevH |
| 11:07 | trybeingarun | make sure that you handle the case of empty collection, where (count coll) is 0 |
| 11:08 | raek | two spaces for def* forms and closing parens not on separate lines |
| 11:09 | bhenry | raek: (defn avg [& args] (/ (reduce + args) (count args))) would look nicer when calling imo |
| 11:09 | silveen | I'm trying to get ClojureQL running, but I'm getting SQLExceptions, "no suitable driver found". Any know anything about this if there's anything I've missed? |
| 11:09 | bhenry | i'm just coming in, so maybe i missed an important part of the discussion |
| 11:09 | raek | depends on whether you make the call manually or get a sequence of values from somewhere else |
| 11:10 | cljbie | thanks raek |
| 11:10 | trybeingarun | Or trust your ide for indentation :) |
| 11:11 | raek | yes, you shouln't have to indent your code manually... |
| 11:11 | raek | i emacs: select the code and press tab |
| 11:11 | cljbie | i have not setup my vim for clojure yet |
| 11:11 | trybeingarun | Me 2 emacs! |
| 11:11 | trybeingarun | how is vim's clojure support? |
| 11:11 | bhenry | M-q for the win. |
| 11:11 | silveen | trybeingarun: it's terrible |
| 11:12 | cljbie | there is vim-clojure which i have not tried yet |
| 11:12 | silveen | I got slimv running last night. But it causes the entire window to flash like a disco lamp. |
| 11:12 | trybeingarun | I find emacs' clojure support very good |
| 11:12 | trybeingarun | I, however am facing a huge pain point |
| 11:12 | silveen | vim-clojure requires that dreadfull Nailgun server running |
| 11:12 | trybeingarun | (read-line) is not working in emacs |
| 11:13 | trybeingarun | Anybody managed to fix that (read-line) problem in emacs? |
| 11:15 | trybeingarun | raek: Dude, do you have any suggestions for (read-line) issue? |
| 11:15 | kumarshantanu | asking again...is a type hint in a macro passed to ~@body ? |
| 11:16 | trybeingarun | At least in my setup (read-line) is not taking any user input |
| 11:16 | raek | yes, I never got that to work. but then, I haven't needed it yet |
| 11:16 | trybeingarun | can you please share how you got that to work? |
| 11:17 | trybeingarun | I am sorry. Din't read ur reply properly. OOPS!! |
| 11:19 | raek | maybe you could do something like (binding [*in* System/in] (read-line)) and type it in the swank terminal |
| 11:19 | raek | it's too bad that the swank protocol is mostly undocumented... |
| 11:20 | trybeingarun | let me see if it works... |
| 11:21 | trybeingarun | what is the advantage of nRepl? |
| 11:21 | raek | hrm... how does one get the root binding of a var when it has a thread-local binding... |
| 11:21 | raek | it is a replacement for swank |
| 11:22 | trybeingarun | hm |
| 11:22 | raek | one of its goals is that it should be usable from any IDE |
| 11:22 | raek | and built for clojure |
| 11:22 | trybeingarun | then that should be awesome!! |
| 11:22 | raek | (future (def in *in*)) ;; ouch! |
| 11:23 | raek | (binding [*in* in] (read-line)) |
| 11:23 | raek | hrm... that didn't work |
| 11:24 | trybeingarun | I am getting an error saying "in" is not defined |
| 11:24 | trybeingarun | System/in is also not working for me |
| 11:25 | raek | bbl |
| 11:25 | trybeingarun | (future) What is that call? Never heard of that... |
| 11:28 | bhenry | ,(doc future) |
| 11:28 | clojurebot | "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the com... |
| 11:28 | bhenry | &(doc future) |
| 11:28 | sexpbot | ⟹ "Macro ([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block." |
| 11:31 | trybeingarun | Thanks |
| 11:44 | hiredman | http://byteworm.com/2010/11/21/the-fastest-vm-bytecode-interpreter/ cute |
| 12:25 | mrroman | hi, i'm here first time. |
| 12:26 | mrroman | i've got problem with using clojure.string |
| 12:26 | tonyl | welcome |
| 12:26 | mrroman | i've got clojure 1.2 and i tried to start example of clojure.string/split from clojuredocs |
| 12:27 | mrroman | and i've got error message java.lang.ClassNotFoundException: clojure.string (NO_SOURCE_FILE:0) |
| 12:28 | tonyl | did you (use 'clojure.string) before calling it |
| 12:28 | tonyl | since it is in another namespace |
| 12:29 | mrroman | yes, but i used full path to function, clojure.string/split |
| 12:29 | tonyl | or better use require since some functions' names would collide |
| 12:29 | mrroman | ok |
| 12:29 | hiredman | mrroman: clojure namespaces have to be explicitly loaded |
| 12:30 | mrroman | ou |
| 12:30 | mrroman | ok, thanks for help |
| 12:30 | tonyl | hiredman: I never understood why is that, do you know? |
| 12:32 | hiredman | tonyl: I imagine the ultimate answer is it makes distinguishing between vars and classes easier for the compiler |
| 12:32 | mrroman | BTW, great number of members, 256 |
| 12:33 | mengu_ | what is the difference between (use 'clojure.inspector) and (:use 'clojure.inspector)? |
| 12:33 | kumarshantanu | is it possible to type hint non-primitive arrays? |
| 12:33 | hiredman | (:use 'clojure.inspector) is incorrect in all cases |
| 12:33 | hiredman | (use 'clojure.inspector) may or may not be |
| 12:34 | hiredman | kumarshantanu: yes but it is rarely useful |
| 12:34 | kotarak | kumarshantanu: ^"[Lyou.custom.Class;" the-array |
| 12:34 | kumarshantanu | kotarak: I am trying the same technique, but it still warns me for reflection |
| 12:35 | kotarak | mengu_: use is a standalone function, :use is only used in the ns clause, :use is without ' |
| 12:35 | kumarshantanu | hiredman: I am calling a Java method that accepts arrays |
| 12:35 | hiredman | kumarshantanu: ah |
| 12:35 | mengu_ | kotarak: thats why :use did not work when i tried it then |
| 12:35 | kotarak | kumarshantanu: might depend on other arguments? |
| 12:36 | kumarshantanu | kotarak: certainly not -- but curiously (1) that technique works for ^"[Ljava.util.Map;" but not for ^"[Ljava.lang.Object;" and (2) I am doing this inside a macro |
| 12:38 | kotarak | kumarshantanu: because you hint (unquote x). the list. Not x itself. You have to do ~(with-meta x {:tag 'String}) .... |
| 12:39 | kotarak | kumarshantanu: shameless self-promotion (although a little out-dated by now): http://bit.ly/a51mbM |
| 12:41 | kumarshantanu | kotarak: what is {:tag 'String} for? |
| 12:42 | kotarak | kumarshantanu: This is was ^String does. |
| 12:42 | kumarshantanu | ah |
| 12:42 | kotarak | kumarshantanu: ^String is short for ^{:tag String} |
| 12:43 | kotarak | kumarshantanu: Uh. I even had your problem as an example at the end. :) |
| 12:44 | kumarshantanu | so, for ^"[Ljava.lang.Object;" it should be {:tag '"[Ljava.lang.String;"} ? |
| 12:44 | kumarshantanu | kotarak: it's working !! |
| 12:44 | kotarak | yup |
| 12:44 | kotarak | \o/ |
| 12:45 | kotarak | Actually without ' |
| 12:45 | kotarak | '"bla" and "bla" are the same |
| 12:46 | kumarshantanu | kotarak: thanks! I was struggling for the past two hours and finished watching a movie meanwhile due to frustration :) |
| 12:46 | kotarak | kumarshantanu: hehe :) That's a good approach. I do the same from time to time. :) |
| 13:17 | rdeshpande | howdy |
| 13:23 | mengu_ | hi rdeshpande |
| 14:33 | LauJensen | Im looking for a simple solid introduction to log4j logging on Tomcat - Got link? |
| 14:37 | nickik | does anybody know when the clojure conj videos will be available? |
| 14:41 | raek | nickik: here. have a strange loop talk by chouser while you wait. :-) http://www.infoq.com/presentations/Clojure-Expression-Problem |
| 14:42 | nickik | i allready watched that. |
| 16:52 | joeyd81 | I still can't get my simple permutations program to work, http://pastebin.com/UrRfi124 |
| 17:00 | tufflax | joeyd81 btw normally people don't have spaces between '(' and the operator, as on you line 4, and not newlines after ( and [ as in your line 12 and 13. And they normally just stack up ) behind each other, not using newlines for each like you have on lines 24-26. And I don't think it's a good idea to use defn within another function, use let or letfn instead. |
| 17:01 | tufflax | I'll try to see what's wrong with your program but your style confuses me :P |
| 17:01 | joeyd81 | ok, thanks for the feedback, I will rework it soon, I am just a newbie and the syntax betrays that |
| 17:03 | tufflax | using defn within a function doesn't work as you think, probably. I think it "creates" the function in the namespace just as if you had written it outside the function, but only when you run the function that contains the inner defn. So it's a side effect of running the outer function. |
| 17:04 | joeyd81 | ok, so you're saying that I should replace it with letfn? Earlier I put it inside the let binding but the compiler complained that 'permute' is undefined |
| 17:05 | _ato | put all your functions at the top-level and use (declare permute) before (defn gen-perms ...) so that gen-perms knows permute exists |
| 17:05 | tufflax | Yes... It should work fine. Paste the code again if you change it and then get errors |
| 17:06 | joeyd81 | ok, I will change it soon as you suggested but the stylistic issue aside, it would still yield the wrong answer |
| 17:08 | ossareh | joeyd81: also, I think your recursion is done incorrectly. If the JVM had TCO then you can recurse as you are on line 23, however since it doesn't then in theory you could overflow the stack - this is what loop / recur is for, and given that you could in fact have your permute fn in the let before it. |
| 17:09 | ossareh | I guess, said a little more concisely, the assertion in the comment on line 10 is incorrect; your recursion is implemented in correctly. |
| 17:10 | joeyd81 | ok, give me 5 minutes to move it in a letfn declaration and repost |
| 17:11 | tufflax | joeyd81 or do what _ato said, move the functions out completely |
| 17:12 | ossareh | tufflax: assuming there is a benefit to having a global var for that fn, then yes that is a good idea too. |
| 17:12 | joeyd81 | but I like inner functions that refer to the closure in which they are defined |
| 17:12 | tufflax | joeyd81 also, why do you have a function called main? It should be easy to test the individual functions in a REPL |
| 17:13 | joeyd81 | I have used the repl repeatedly to test the smaller functions |
| 17:14 | tufflax | ok good |
| 17:18 | Raynes | _ato: It speaks! |
| 17:18 | Raynes | _ato: Haven't seen you in a while. :< |
| 17:18 | joeyd81 | ok, I made the changes that you guys suggested and I still get the wrong answer, http://pastebin.com/qbztx8LE |
| 17:20 | _ato | Raynes: hi |
| 17:21 | _ato | joeyd81: hmm, the first thing I notice is that gen-subsets' base case is inconsistent: |
| 17:21 | _ato | (gen-subsets #{1 2}) ;; => ((1 (2)) (2 (1))) |
| 17:21 | _ato | (gen-subsets #{1}) ;; => (1 ()) |
| 17:21 | _ato | shouldn't (gen-subsets #{1}) be ((1 ())) ? |
| 17:23 | joeyd81 | ok, I am thinking about it, not ignoring you |
| 17:26 | joeyd81 | added (list ....) to the base case (1 el in set) and still got the same result |
| 17:33 | _ato | joeyd81: http://pastebin.com/ph73mKC0 |
| 17:35 | joeyd81 | great, your program works! How could you print each permutation on a separate line (i.e. vertically instead of horizontally) |
| 17:37 | _ato | joeyd81: just call println on each permutation? |
| 17:37 | _ato | eg: (dorun (map println (permute (range 1 4)))) |
| 17:38 | joeyd81 | ok, you're great, I am going away now to study your code, thanks and see you guys later |
| 17:52 | tufflax | I'm using vimclojure with the nailgun server to get a repl. And then I try to eval "(ns pe)" by sending with <leader>et and it gives me the following error: java.io.FileNotFoundException: Could not locate pe__init.class or pe.clj on classpath... Writing it in the REPL works though. Does anyone know what's wrong? |
| 17:54 | kotarak | tufflax: you have to have the appropriate files set up on your classpath |
| 17:55 | kotarak | tufflax: vc reads the namespace to provide things like omnicompletion and such. |
| 17:55 | tufflax | But what's the difference between writing in into the repl by hand and sending it with <leader>et |
| 17:55 | tufflax | ok |
| 17:55 | tufflax | hm |
| 17:56 | kotarak | tufflax: exactly that: writing in the repl does nothing but the command. Sending \et loads the namespace. Because vc can't know what you send, it has to set up everything so that all required functions are in place. |
| 17:57 | tufflax | ok, thank you |
| 18:10 | jimduey | joeyd81: I'm stepping into the middle of your conversation, but do you know about clojure.contrib.combinatorics? |
| 18:10 | jimduey | (use 'clojure.contrib.combinatorics) |
| 18:11 | jimduey | (println (interpose \newline (permutations (range 1 4)))) |
| 18:11 | joeyd81 | no, thanks for the link. I was just in the process of learning clojure by way of writing simple programs, that's all |
| 18:11 | jimduey | excellent. good way to start. |
| 18:17 | CaseyS | hello all |
| 18:51 | rata_ | hi |
| 19:07 | ossareh | I wonder why so many people use macro's where a fn would suffice. |
| 19:07 | ossareh | Is there some fundamental misunderstanding about macros? |
| 19:09 | zakwilson | I think the misunderstandings are usually related to what can be accomplished with an ordinary function. |
| 19:09 | joeyd81 | hey guys, does clojure support eta reduction, example of something I want to reduce is this: (my-map [f colls] |
| 19:09 | joeyd81 | (if (> (count colls) 8) (pmap f colls) (map f colls))) |
| 19:09 | Raynes | zakwilson: Indeed. You can be *really* creative with functions to accomplish things that you might assume are only possible with macros. |
| 19:10 | Raynes | chouser: Demonstrated this on the hotel shuttle at the Conj that I happened to be on when he and a group were off to the car rental place. He pointed out how 'or' and 'and' could be implemented using normal functions. |
| 19:10 | Raynes | <3 chouser |
| 19:11 | zakwilson | I think the Right Thing is to do whatever is easiest to understand. Usually, that's a normal function, not a macro, but if lots of trickery is required for the function to work, go with the macro. |
| 19:12 | _ato | Raynes: they're implemented as macros so that they can short circuit. eg (or (foo) (bar)) doesn't need to execute (bar) if (foo) returns true. You can't do that with a function (unless you changed 'or' to take functions instead of values) |
| 19:13 | Raynes | _ato: I know. That's what I just said. |
| 19:13 | Raynes | Well, I didn't explain myself, but that's what I was talking about. |
| 19:13 | _ato | ah, I see |
| 19:13 | rata_ | is there anything like Python's "template %s" % ("strings") ? |
| 19:13 | Raynes | He was talking about how and and or could be written as functions that take functions. |
| 19:14 | _ato | ,(format "I %s food" "food") |
| 19:14 | clojurebot | "I food food" |
| 19:14 | _ato | Raynes: ^ |
| 19:15 | Raynes | _ato: I'm not rata_ |
| 19:15 | rata_ | hahahaha thanks =) |
| 19:15 | zakwilson | A lot of things we do with macros require macros because macros let you evaluate some or all arguments lazily. Haskell can do them without macros because it's lazy by default. It is also possible to do similar things with ugly syntax in any language that lets you pass something resembling a thunk. |
| 19:15 | _ato | damn.. channel is getting too crowded (ra<tab>) ;-) |
| 19:16 | joeyd81 | Hey guys, what is a better way to write this function, so that repetition is reduced (defn my-map [f colls] (if (> (count colls) 8) (pmap f colls) (map f colls))) |
| 19:17 | zakwilson | That's pretty succinct as it is. What would you like to not repeat? |
| 19:18 | joeyd81 | the args f coll |
| 19:18 | ossareh | agreed, only thing I see is potentially providing the map function - but then you start to introduce ambiguity |
| 19:20 | _ato | (defn my-map [f colls] ((if (> (count colls) 8) pmap map) f colls)) |
| 19:20 | _ato | I prefer the original though |
| 19:21 | joeyd81 | yes, you nailed it _ato, that's what I was looking for |
| 19:21 | zakwilson | You could write a macro somewhat resembling ->, which I'll call -:/ for purposes of this discussion that would allow you to write (defn my-map (-:/ [f colls] (count colls) pmap map)), but that would be pathological. |
| 19:23 | joeyd81 | :), macros are too advanced for me, I'll study them in the context of a DSL implementation in clojure of a non-lisp language, if there is one such implementation pls feel free to provide a link |
| 19:25 | dnolen | ,(let [x 5 y 4] `(+ ~x ~y)) |
| 19:25 | clojurebot | (clojure.core/+ 5 4) |
| 19:26 | joeyd81 | example: the DSL is the syntax in which you write Makefiles, input is a makefile, output is the interpretation of the actions in it |
| 19:26 | dnolen | joeyd81: think of macros as "HTML templating" for code. DSLs are not the only usecase. |
| 19:28 | zakwilson | joeyd81: a macro would let you write a shorter version of the function you gave as an example, but it would be a mistake to write one for that situation because it would make the overall system more complicated and longer. If you had to write 10 functions that looked almost identical, macros might make short work of it. |
| 19:29 | joeyd81 | yes, I understand that application of macros but to be really impressed I want to see them used to implement a DSL for a simple non-lisp language, I just don't know of any such implementations though I'm sure they exist |
| 19:32 | zakwilson | If you're going to make a non-lisp language, you really need a parser, not macros. |
| 19:35 | joeyd81 | I thought you could write something like this http://www.venge.net/graydon/talks/mkc/html/index.html in lisp/clojure easier than in any other language |
| 19:35 | joeyd81 | with macros alone |
| 19:38 | zakwilson | Well, you probably *could* write a DSL that has to be wrapped in (eval-my-dsl ...) without writing a parser, but it's probably not a good way to go about it. |
| 19:40 | zakwilson | The most common use of macros is to delay evaluation of an argument so you can write control structures like if and when. Other common uses include making a Lisp-like DSL that outputs a non-Lisp language and making a template for often-repeated code that can't be optimized away by other means. |
| 19:41 | joeyd81 | camlp4 macros are not any more powerful than lisp/clojure macros, it seems, the reason I mention it is because I want to explore the depths of what is possible with lisp/clojure macros |
| 19:42 | zakwilson | I have minimal experience with ML, but I suspect an ML macro system is more limited than Lisp macros. |
| 19:42 | zakwilson | Furthermore, Clojure macros are more limited than Common Lisp macros. |
| 19:42 | joeyd81 | Yes, that's my point too. So if that guy in the link can write a DSL with camlp4 macros, the same should be possible with clojure |
| 19:43 | joeyd81 | I just want to see a common lisp or clojure example of something like that |
| 19:44 | zakwilson | I just picked a random slide and he was talking about writing a recursive-descent parser, which suggests that he DID use a parser. |
| 19:46 | joeyd81 | he is not, camlp4 is the macro facility employed by the ocaml system, he is using a lexer but no parser |
| 19:53 | zakwilson | http://www.venge.net/graydon/talks/mkc/html/mgp00021.html <-- here, he says he's using a recursive-descent parser. He uses pa_extend to write the parser, and while pa_extend comes with camlp4, it's not inherently part of a macro system; it's a parser library. |
| 19:56 | joeyd81 | Just like in clojure macros have a narrower scope of application that you pointed out above, so does camlp4 primarily defined syntax extensions to the core language and is rarely if ever used for anything else. The guy who wrote the slides points out that it could be used for more than just staying within the confines of ocaml.... So I am not yet convinced that clojure macros may not be used to go outside the confines of the core langua |
| 19:58 | joeyd81 | but I am not an expert on these matters, I just wish that an example would be provided in lisp or clojure of how you could do that, if it's possible |
| 20:09 | zakwilson | joeyd81: Clojure macros can't replace the entire syntax of the language directly. It looks like camlp4 can, but what it's doing is essentially the same as (eval-my-dsl (read some-file)) |
| 20:17 | joeyd81 | @zakwilson, so are you implying then that it's possible to write macros in clojure that implement a DSL, where neither the input is clojure nor the output is clojure? In the slides the input is a makefile, the output is an executable a.out program |
| 20:20 | zakwilson | joeyd81: it's possible, but the only reason to base the design of such a system around macros is to demonstrate that you can. The Right Thing is to write a parser and a code generator. Both will probably make use of macros to some degree. |
| 20:22 | joeyd81 | I tend to agree that it's not the Right Thing to do but if there is such an example in Lisp or Clojure I'd love to study it because it pushes the limits of what is possible to achieve with macros |
| 20:26 | jweiss_ | is there doc somewhere on how to get gen-class to add annotations? i saw some old mailing list posts, but I'm not sure if that was the proposed solution or the real deal |
| 20:27 | jweiss_ | perhaps it works just like this? https://gist.github.com/377213 |
| 20:28 | zakwilson | joeyd81: See an implementation of the Common Lisp loop macro for an idea of how to evaluate non-lisp inside a macro body. After that, it's just a matter of calling your macro on a list of the results of calling read on your non-lisp file until you hit EOF, though there are some limitations. |
| 20:31 | joeyd81 | thanks zak, will definitely study it |
| 20:33 | zakwilson | joeyd81: another thing that's important to understand is that camlp4 seems to be a preprocessor, which is a bit different from Lisp macros. You could certainly write a Clojure program (with or without macros) that reads a file containing code written in a DSL, compiles that code to Clojure and uses that Clojure to spit out another language (though your OCaml example really only does the latter because the OCaml compiler can output C natively) |
| 20:36 | joeyd81 | ok |
| 21:17 | livingston | I have a multi method, lets call it foo for select user defined / 3rd party classes foo needs to do something but for all clojure native types foo can be the identity function. I can make that the default behavior but then I lose the fail-fast checking on when foo isn't implemented for a 3rd party type -- thoughts? |
| 21:23 | livingston | do all the clojure native types implement any particular protocol/interface that I could dispatch on? |
| 21:24 | tonyl | var maybe |
| 21:25 | tonyl | IVar |
| 21:26 | livingston | i would assume that's only for vars? I'm more looking for the clojure-only equivalent of Object. |
| 21:27 | jarpiain | livingston: http://tinyurl.com/clojure-classes |
| 21:27 | jweiss_ | i cannot figure out how to get annotations onto the class i'm generating with gen-class. the classes always end up without them. is this supported? |
| 21:29 | livingston | jarpiain: wow there's a lot of detail in there thanks. |
| 21:30 | livingston | iObj may be what I want... although I still have to stare at that for a long time to be sure that java classes don't implement that too. |
| 22:08 | ossareh | other than java interop is there much benefit to a record over a structmap ? |
| 22:08 | livingston | ossareh: compiled in type information |
| 22:09 | dnolen | ossareh: java interop is not the main benefit of records |
| 22:09 | livingston | ossareh: see the discussion here: http://clojure.org/datatypes |
| 22:10 | dnolen | ossareh: consider structmap a legacy feature, you should just records here on out. |
| 22:10 | dnolen | s/just/just use |
| 22:12 | ossareh | dnolen: thanks, so it turns out it is a performance thing too it seems? |
| 22:12 | livingston | is there a way from the repl to see what interfaces/protocols an object instance is implementing? |
| 22:12 | ossareh | "one need not leave Clojure to get the highest-performing data structures possible on the platform." |
| 22:12 | joshua__ | What is the best way to deal with forms when using appengine/compojure/enlive? |
| 22:12 | dnolen | ossareh: yes that's another benefit |
| 22:12 | rata_ | livingston: (supers (class thing)) |
| 22:13 | livingston | that's not showing me any protocols there should be at least two in this guys list |
| 22:14 | rata_ | livingston: well, I don't know what are you looking at, but (supers (class [])) shows every interface vectors implement |
| 22:15 | dnolen | ,(supers (class [])) |
| 22:15 | clojurebot | #{java.util.List clojure.lang.Seqable clojure.lang.Reversible clojure.lang.IEditableCollection clojure.lang.Sequential java.io.Serializable clojure.lang.Associative clojure.lang.IPersistentStack cloj... |
| 22:16 | livingston | I have an instance of a Record, (show _) reports the correct type, (supers (class _)) doesn't give me the protocols I have attached to it, and I have extended two onto it at least |
| 22:19 | _ato | I don't think there's an efficient way to do it, since :impls is stored with the protocol, not the other way around |
| 22:20 | livingston | so it's the protocols that know who implement themselves but no way to get from an object to a list of protocols (kinda makes sense since protocols don't monkey patch) |
| 22:21 | _ato | yeah, if you look at the source for extends? for example: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L444 |
| 22:21 | hiredman | protocols don't create an is-a relationship |
| 22:22 | livingston | makes sense I suppose, I was just layering up a few of them on a thing, and I just want to make sure I was getting what I thought I was getting, and was hoping for some debugability even if ineffecient - oh well |
| 22:27 | livingston | interesting as a further oddity, if package foo has protocol P and record R it's foo/P and foo.R which is another differentiator between protocols behaving like classes/interfaces... |
| 22:27 | hiredman | package? |
| 22:27 | clojurebot | amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 22:27 | hiredman | surely you mean namespaces |
| 22:28 | livingston | hiredman: yes |
| 22:28 | hiredman | well then why didn't you use the word "package"? |
| 22:30 | hiredman | did |
| 22:31 | livingston | so if the protocol implementation isn't with the record, why is this more efficient, there's still dispatch right? or can the compiler find it ahead of time with type hints? |
| 22:31 | livingston | or is the efficiency of protocols/records only in that the records can have accessors etc. compiled in? |
| 22:33 | livingston | hiredman: I still think in common-lisp, the word is package over there -- force of habit |
| 22:34 | _ato | livingston: there's some discussion about it here: http://groups.google.com/group/clojure-dev/browse_thread/thread/59d2f3a1703cc09 |
| 22:35 | livingston | _ato: thanks for the pointer, I'll look that over |
| 22:37 | _ato | kind of cryptic, but basically, yes you're right that you get maximum performance from a inline definition (like a class implementing the protocol's interface, which presumably deftype does). But the protocol also caches the last used implentation, which should help the common case for extending after definition |
| 22:41 | livingston | interesting. so if I put the protocol implementation on with a defrecord I'll get better performance than if I do it with an extend? |
| 22:54 | _ato | looks like it |
| 22:56 | livingston | I would not have expected find to do what find does, I was expecting more of a common-lisp find, although clj find happens to do exactly what I need |
| 22:57 | livingston | multiple return values would be really useful right about now too.. |
| 23:03 | livingston | what's the preferred idiom for mapping a function that could produce nil and removing the nils? (remove nil? (map fcn data)) |
| 23:05 | _ato | ,(doc keep) |
| 23:05 | clojurebot | "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects." |
| 23:05 | _ato | livingston: ^ |
| 23:06 | livingston | that's an extremely non-intuitive name, but ok. |
| 23:06 | livingston | _ato: thanks |
| 23:06 | _ato | heh, I agree about the name |
| 23:07 | livingston | keep sounds like it should be the opposite of remove and shouldn't inherently accumulate/map too |
| 23:08 | tomoj | keep? since when? |
| 23:08 | tomoj | ,(:added ^keep) |
| 23:08 | clojurebot | Unmatched delimiter: ) |
| 23:08 | livingston | tomoj: apparently 1.2 |
| 23:08 | tomoj | shucks |
| 23:08 | tomoj | ,(:added (meta keep)) ;? |
| 23:08 | clojurebot | "1.2" |
| 23:09 | tomoj | cool |
| 23:09 | livingston | my version of slime doesn't even recognize it as a reserve word (I probably need to update) |
| 23:09 | tomoj | eh |
| 23:10 | tomoj | I've come to accept that random colors will show up inexplicably |
| 23:10 | livingston | there have been a lot of weird names added with stuff like that, I was following the discussion and gave up (the intent was to be intuitive but many are not: find, keep, etc.) |
| 23:10 | tomoj | find too/ |
| 23:10 | tomoj | ? |
| 23:10 | tomoj | ,(doc find) |
| 23:10 | clojurebot | "([map key]); Returns the map entry for key, or nil if key not present." |
| 23:10 | tomoj | oh |
| 23:11 | livingston | yeah that's the function I wanted, but I went looking for a "find" expecting to have to wrap it myself around a map |
| 23:11 | tomoj | naming is hard :( |
| 23:14 | livingston | yeah, there's some stuff that's really confusing to me (lisp people?) in there, but it is what it is |
| 23:15 | _ato | 'keep' needs a succinct name or you may as well just do (remove nil? (map ...)). I can't think of anything intuitive that's succinct |
| 23:15 | livingston | _ato "mapcon" ;) |
| 23:16 | livingston | er mapcan I meant |
| 23:18 | livingston | I wonder if the compiler is smart enough / produces equally efficient code for keep and (remove nil? (map ... ? |
| 23:18 | _ato | hehe, intuitive for a common lisper maybe, but not for me |
| 23:19 | _ato | nah I don't think the compiler's clever enough to avoid the intermediate lazyseq objects |
| 23:19 | livingston | I'm not actually lobbying for that but it's not bad, it's basically "map" + "concatenate" |
| 23:19 | _ato | ,(doc mapcat) |
| 23:19 | clojurebot | "([f & colls]); Returns the result of applying concat to the result of applying map to f and colls. Thus function f should return a collection." |
| 23:19 | livingston | and it has parity with mapcar (map through the car (first) elements of a list) which is clojure's map |
| 23:21 | livingston | yes mapcat is cl:mapcan - the 'n' was also used as a flag for being destructive in lisp, I don't know why. |
| 23:27 | livingston | I wished the compiler would warn at least on non-local non-special variable being present in a function - dumb me just lost 30 min because I cut and paste some code that used a different variable name |
| 23:51 | Derander | livingston: does seem like that should be possible to statically check |
| 23:52 | livingston | It's possible I've corrupted my repl enough too that it hallucinated a bound symbol there too, but yeah |