2011-06-06
| 00:02 | Raynes | I'm going to have to start going door to door and sharing the gospel of cake. |
| 00:03 | Raynes | zakwilson: apache commons-email is fantastic. |
| 00:03 | Raynes | zakwilson: After going through all the Clojure libraries, none are all that satisfactory, and commons-email is fantastic at one thing: sending email. |
| 00:05 | zakwilson | Raynes: five minutes of playing with Postal is starting to convince me of that. I don't have very sophisticated needs, but this seems to be unable to handle encrypted smtp. |
| 00:06 | zakwilson | Why do so many Java libraries make you create an object and use setters instead of passing the values for the fields to the constructor? |
| 00:07 | offby1 | mutation is the Way and the Light™ |
| 00:07 | Raynes | zakwilson: Postal wraps command-line tools for mail stuff, and I'm not convinced that calling out to an external application is a very good thing. |
| 00:07 | lawfulfalafel | I keep seeing people mentioning marmalade on posts about clojure, but I don't really get what it is |
| 00:07 | lawfulfalafel | and googling for it isn't really helping me understand it any better |
| 00:08 | Raynes | zakwilson: However, since it calls out to msmtp and such, chances are you can configure that to do whatever you want. I'd much rather there just be a java-mail wrapper or something though. |
| 00:08 | technomancy | lawfulfalafel: it's clojars for elisp |
| 00:08 | Raynes | lawfulfalafel: Marmalade is an elisp package server. It's just a public place where people can upload their elisp packages for use with ELPA. |
| 00:09 | zakwilson | Raynes: postal claims to be a javamail wrapper, but it seems unable to authenticate with gmail so it sucks. |
| 00:09 | lawfulfalafel | ah, thank you |
| 00:10 | Raynes | zakwilson: I seem to recall needing something that it didn't support on the javamail side. |
| 00:11 | zakwilson | Raynes: then javamail is not very complete. |
| 00:11 | technomancy | lawfulfalafel: while elpa.gnu.org is more like maven central |
| 00:12 | Raynes | zakwilson: Actually, it was the other way around. Postal just didn't support doing whatever it was. It doesn't really seem to wrap javamail very thorougly. |
| 00:13 | zakwilson | Raynes: a brief glance at the source of Postal has me agreeing with you. It looks very bare bones. I'll take your word for it about apache commons. |
| 00:13 | Raynes | zakwilson: I don't know if it supports encrypted stmp, but it's certainly easy to use. |
| 00:15 | zakwilson | Raynes: the docs suggest that it does. |
| 00:16 | lawfulfalafel | okay, I installed cake, but I don't get how to run it |
| 00:16 | lawfulfalafel | I've never used ruby or gems before |
| 00:16 | zakwilson | Raynes: what do I put in my project.clj to make lein or cake download it from wherever they get things? (so far, I'm treating things that interact with Maven as magic) |
| 00:17 | Raynes | zakwilson: [org.apache.commons/commons-email "1.2"] |
| 00:17 | lawfulfalafel | but I know it's at /var/lib/gems/1.8/bin/cake |
| 00:17 | Raynes | lawfulfalafel: The command is 'cake'. |
| 00:17 | zakwilson | Raynes: Thanks. My guess was so close, yet so far. |
| 00:17 | Raynes | If that doesn't work, then put /var/lib/gems/1.8/bin on your PATH |
| 00:18 | lawfulfalafel | uh, could you perhaps remind me how to do that? |
| 00:18 | lawfulfalafel | I know $PATH=/blah/blah/blah sets it |
| 00:18 | lawfulfalafel | but I forget how to append to it |
| 00:18 | Raynes | On Linux? |
| 00:18 | lawfulfalafel | yup |
| 00:18 | Raynes | Do you have a ~/.bashrc file? |
| 00:19 | lawfulfalafel | yes, but it's been automatically generated |
| 00:19 | lawfulfalafel | at least I don't remember touching it |
| 00:19 | Raynes | Put this in it: export PATH=/var/lib/gems/1.8/bin:$PATH |
| 00:20 | Raynes | Then restart your terminal (to restart bash) or run this: . ~/.bashrc |
| 00:22 | lawfulfalafel | Raynes: I tried that and got "bash: /home/kirby/.bashrc: Permission denied" |
| 00:23 | lawfulfalafel | so I just typed "bash" again to just launch another one, but for some reason it still can't find cake |
| 00:23 | Raynes | lawfulfalafel: echo $PATH |
| 00:24 | lawfulfalafel | /var/liv/gems/1.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games |
| 00:24 | devn | /var/liv |
| 00:24 | Raynes | Typo. |
| 00:24 | lawfulfalafel | lol |
| 00:25 | lawfulfalafel | thank you devn |
| 00:25 | lawfulfalafel | thank you Raynes, it works now |
| 00:26 | lawfulfalafel | just out of curiosity, does cake support syntax hilighting? |
| 00:26 | Raynes | No problem. We also have a channel specifically for cake if you have any other problems. #cake.clj |
| 00:26 | devn | now go forth and write clojure with great ferocity |
| 00:27 | Raynes | cake's REPL supports more than most, but it doesn't support syntax highlighting. For that, you want an editor. Emacs or any of the IDEs (Eclipse + Counterclockwise, Netbeans + Enclojure, etc). |
| 00:27 | devn | or you can print your code on paper and get a few colored highlighters |
| 00:27 | Raynes | devn: Or M-x print-buffer |
| 00:28 | devn | 1up |
| 00:28 | lawfulfalafel | well thanks again guys |
| 00:28 | lawfulfalafel | gn |
| 00:28 | devn | im going to bed also |
| 00:28 | devn | good night all |
| 00:58 | korny | anyone know if there's some way to run "lein midje" so it automatically re-runs tests on file changes? |
| 01:00 | korny | - mostly, I'm trying to avoid the startup time; it's a slow process re-running manually |
| 01:06 | technomancy | korny: that's what lein interactive is for |
| 01:07 | technomancy | well, really that's what lein swank is for; lein interactive is just for folks who don't use swank for whatever reason. |
| 01:07 | korny | cool - so "lein interactive" will let you run 'midje' repeatedly. |
| 01:07 | technomancy | yup |
| 01:08 | korny | I'm not using swank for now - I keep meaning to re-learn emacs, but somehow I keep failing. |
| 01:08 | technomancy | sure; one step at a time |
| 01:08 | korny | I was a big emacs used in the '90s, but somehow these days I'm an IDE junky. Especially when jumping from language to language. |
| 01:08 | technomancy | midje should make it easy to run its tests from the repl too |
| 01:08 | korny | s/used/user |
| 01:08 | sexpbot | <korny> I was a big emacs user in the '90s, but somehow these days I'm an IDE junky. Especially when jumping from language to language. |
| 01:09 | technomancy | with clojure.test you can just do (run-tests) in the repl; hopefully midje has an equivalent |
| 01:11 | korny | just running 'midje' in lein interactive is working. thanks! |
| 01:11 | technomancy | cool |
| 01:15 | korny | hmm - nope, 'midje' works the first time, the second time I get "Couldn't connect". |
| 01:16 | technomancy | hm; it could be the midje plugin for leiningen exits |
| 01:17 | technomancy | perhaps the author of midge didn't realize that the task needs to return an integer rather than calling System/exit directly |
| 01:22 | korny | the source is short - I'll ave a look. |
| 01:27 | korny | hmm - got part way there but other stuff is screwing up. This is getting beyond me - might ask the midje author. |
| 01:29 | technomancy | bzzzt--do not want: https://github.com/marick/Midje/blob/master/leiningen/midje.clj#L61 |
| 01:32 | technomancy | actually with subprocesses it's a bit more tricky, but there's a flag you can check to see if you need to exit; I'll open an issue on midje |
| 02:57 | void_ | hi this is my second day with clojure |
| 02:57 | void_ | why does this (.getName String) throw this: #<NoSuchFieldException java.lang.NoSuchFieldException: getName> |
| 03:01 | justinlilly | void_: is it possible that String doesn't refer to what you thought? |
| 03:02 | justinlilly | ,(.getName String) |
| 03:02 | clojurebot | "java.lang.String" |
| 03:02 | justinlilly | should work. |
| 03:02 | justinlilly | ,(.. System (getProperties) (get "os.name")) |
| 03:02 | clojurebot | java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write) |
| 03:19 | xkb | hi |
| 03:20 | void_ | so there's something wrong with my local installation |
| 03:21 | xkb | I'm trying to solve this telephone number mnemonics puzzle in Clojure. Goal is to find a word (or as an extension, words) for a given number. I implemented it like so: https://gist.github.com/1009867 and that works. However loading the whole dictionary into the map takes ages. Any ways to improve this code? |
| 03:47 | fliebel | xkb: Do you have an explaination about the problem? |
| 03:54 | xkb | fliebel: yes |
| 03:54 | xkb | say your telephone number is 111, then the solution would be aaa or aAa |
| 03:55 | xkb | if aaa or aAa would be words |
| 03:55 | xkb | other example: "530189010363" ["adenogenesis"] |
| 03:55 | fliebel | xkb: So basically you try to form words from the chars on the phone keys? |
| 03:56 | xkb | correct |
| 03:56 | xkb | like T9 on the old nokia's |
| 03:56 | fliebel | so, like 1-800-my-apple ;) |
| 03:56 | bpr | then how does 1 => a and 5 => a ? |
| 03:56 | fliebel | xkb: Yea, your table looks weird. |
| 03:57 | fliebel | Why is it like { 0 "e" 1 "jnq" 2 "rwx" 3 "dsy" 4 "ft" 5 "am" 6 "civ" 7 "bku" 8 "lop" 9 "ghz"} and not {1 "abc ...} like normal phones over here do? |
| 03:58 | xkb | fliebel: ah, that was just parameterisation |
| 03:58 | xkb | over here it's a "" 2 "abc" for example |
| 03:58 | bpr | still, on what phone does 1 and 5 both have a? |
| 03:58 | xkb | so app. it's region specific |
| 03:59 | xkb | I meant 1 "" 2 "abc" btw |
| 03:59 | fliebel | xkb: Ah, okay. Have you looked a tries? A nice one using assoc-in: http://stackoverflow.com/questions/1452680/clojure-how-to-generate-a-trie |
| 03:59 | xkb | yup |
| 04:00 | xkb | but as I understand it maps are implemented as trees anyways |
| 04:00 | xkb | so just inserting number word tuples should work just as well |
| 04:00 | xkb | emphasis on the should ;) |
| 04:01 | bpr | trie =/= tree |
| 04:01 | fliebel | xkb: But with a trie you get to take advantage of the alphabet ;) |
| 04:01 | bpr | tries are built from trees, but their a special purpose data structure |
| 04:01 | bpr | they're* |
| 04:01 | bpr | ^ |
| 04:03 | xkb | I started out with something very similar to the SO code, but changed it back to a simple map |
| 04:03 | xkb | I'm wondering why it takes so long to build the {number [word]} map |
| 04:04 | fliebel | xkb: You mean, you are generating all possible words for all possible numbers? :-o |
| 04:05 | xkb | fliebel: other way around |
| 04:05 | xkb | I generate numbers for all words in the dict |
| 04:05 | xkb | that compact it to all words for the numbers generated |
| 04:06 | xkb | and theres 234936 words |
| 04:07 | fliebel | Ah, I see. I'll have some breakfast and have a look at it. |
| 04:07 | xkb | cool :) |
| 04:07 | xkb | maybe I should try the Trie meanwhile ;) |
| 04:40 | fliebel | xkb: How long does yours take? |
| 04:41 | xkb | for the full dict it takes more time then I care to wait for :) |
| 04:42 | xkb | and that's just the convert/compact function |
| 04:42 | xkb | reading the dict and transforming it to number/word pairs is fast |
| 04:43 | xkb | or rather parts of it are lazy oc :) |
| 04:44 | fliebel | xkb: so, all you're doing there is combining word with the same number, right? |
| 04:44 | xkb | correct |
| 04:45 | xkb | I recurse over all the numbers, recombining words if the number is already in the target map |
| 04:46 | xkb | I use get-in to find numbers in the new map, and assoc to update an existing number [word] pair |
| 04:46 | fliebel | xkb: I'd use merge-with |
| 04:47 | xkb | ah |
| 04:48 | fliebel | I run out of memory before I even v=created the full map, btw :( |
| 04:48 | xkb | :( |
| 04:49 | bpr | so, you'll need to store a trie on disk |
| 04:49 | xkb | the problem is you cant even use integers as key: telephonenumbers might start with a 0 |
| 04:56 | xkb | merge-with is quite nice :) |
| 04:59 | xkb | 40k words is still doable |
| 06:05 | fliebel | xkb: I got something trie based, how are you doing? |
| 06:10 | xkb | had to do some real work in the mean-time |
| 06:10 | fliebel | https://gist.github.com/1010027 |
| 06:10 | xkb | rewrote it to just use merge-with |
| 06:10 | xkb | but that doesnt really help |
| 06:11 | fliebel | xkb: Mine is fast enough for me, only it does not include all words for a give number. |
| 06:11 | fliebel | If I did that, I ran out of memory, and it took much longer. |
| 06:11 | xkb | ah, I had the same with my first Trie based attempt |
| 06:12 | xkb | hmm why doesnt your build-trie function blow stack? |
| 06:13 | xkb | with the recursion there |
| 06:17 | fliebel | xkb: because the recursion depth is only max word length. |
| 06:19 | xkb | ah now I see, not that familiar with the use of comp |
| 07:14 | msappler | hello |
| 07:15 | msappler | what is the best way for a macro that does some assertions and then expands to another function call to store the other function? |
| 07:15 | msappler | I mean this function from my blog: http://resatori.com/advanced-keyword-function#comments |
| 07:16 | msappler | when i let the macro expand to the function I get an ExceptionInitializerError |
| 07:17 | msappler | so basically I just want to convert this macro: https://gist.github.com/999256 |
| 07:18 | msappler | so that it runs its checks at compile-time ... |
| 07:46 | hoeck | msappler: checking at compile-time works only in those cases where the arguments are known at compile time |
| 07:46 | hoeck | eg. when you call such a function directly (keyfn :arg1 'value) |
| 07:48 | hoeck | and does not work when you pass the function around: (map keyfn args) |
| 07:50 | msappler | yes i do that always |
| 07:50 | msappler | calling it directly |
| 10:05 | ilyak | hi * |
| 10:06 | ilyak | Suppose I have a class, CSVReader ^^ |
| 10:06 | ilyak | What's the best way to implement seq protocol for it? I can't touch the class itself |
| 10:09 | stuartsierra | Unfortunately, seq is not a protocol. It's just an interface. |
| 10:09 | stuartsierra | All you can do is write a function that takes a CSVReader and returns a seq. |
| 10:11 | ilyak | stuartsierra: How does clojure do it for, e.g., String? |
| 10:11 | stuartsierra | Conditionals for each special case in the implementation of seq. |
| 10:11 | stuartsierra | All that stuff predates the introduction of protocols. |
| 10:12 | stuartsierra | Probably someday it will be replaced by protocols. |
| 10:16 | chouser | so all you need to do is provide a new function that returns a seq for your CSVReader |
| 10:21 | cemerick | ilyak: see iterator-seq and enumerator-seq for examples of fns that return seqs over mutable things |
| 10:21 | cemerick | if your CSVReader is returning rows via an iterator, then you actually have no work to do |
| 10:26 | stuartsierra | I think we lost him, guys. |
| 10:30 | ilyak | cemerick: I just did (repeatedly #(.readNext csv-reader)) |
| 10:30 | ilyak | Yet to actually try |
| 10:30 | ilyak | How would I access enum values of nested enum belonging to some class? |
| 10:31 | ilyak | SqlUtils/Columns/ALL doesn't work |
| 10:31 | ilyak | and no idea how to import it |
| 10:32 | cemerick | that'll work, though you'll need to handle the EOF condition, and use take-while (or some equivalent) to keep only the useful data. |
| 10:33 | cemerick | SqlUtils$Columns/ALL? |
| 10:33 | cemerick | SqlUtils$Columns is the class you'd import |
| 10:34 | ilyak | Okay, figured it out, thanks |
| 11:18 | timvisher | hey all |
| 11:18 | timvisher | what would be the easiest way to compare 2 sequences in a position independent manner |
| 11:18 | timvisher | ? |
| 11:19 | timvisher | so that (= [1 2 3 4] [4 3 2 1]) would return true |
| 11:19 | stuartsierra | Turn them both into sets. |
| 11:19 | manutter | ,(= (into #{} [1 2 3 4]) (into #{} [4 3 2 1]) |
| 11:19 | clojurebot | EOF while reading |
| 11:20 | manutter | ,(= (into #{} [1 2 3 4]) (into #{} [4 3 2 1])) |
| 11:20 | clojurebot | true |
| 11:20 | timvisher | which should only break if there are duplicates |
| 11:20 | timvisher | and if there are never duplicates then maybe they should always be sets... |
| 11:21 | manutter | Maybe you could also map the seqs into hashmaps, with the count as the value |
| 11:21 | manutter | [1 2 3 2 1] => {1 2, 2 2, 3 1} |
| 11:21 | timvisher | it's only a vector because i'm used to the `[` seq literal |
| 11:21 | timvisher | there's really no reason it shouldn't be set |
| 11:21 | timvisher | I don't want duplicate entries |
| 11:22 | manutter | sure, that'll make things easier for you then |
| 11:22 | timvisher | so that's probably a good idea |
| 11:22 | manutter | sure |
| 11:22 | timvisher | ya'll rock :) |
| 11:26 | cemerick | timvisher: just keep in mind that your literals can't have dupes in them already… |
| 11:26 | cemerick | ,#{3 2 3} |
| 11:26 | clojurebot | Duplicate key: 3 |
| 11:26 | timvisher | cemerick: indeed |
| 11:26 | timvisher | none of them do |
| 11:26 | timvisher | i'm really falling victim to what I always do in java |
| 11:26 | cemerick | That wasn't the case a long time ago. |
| 11:26 | timvisher | i default to List there without really thinking about the data structure |
| 11:27 | edw` | Hey, think I found a bug in clojure's swank support: evaling "(keys [0 1 2])" gives an elisp error while evaling "(keys 42)" throws one into the slime debugger. |
| 11:27 | timvisher | or rather, the data that I'm trying to structure |
| 11:27 | cemerick | Each time I get tagged by it (mostly by not paying attention), I wonder why dupe checking is being done at all. |
| 11:27 | timvisher | and then i realize way down the line that it really should have been a map or a set or whatever and i have to got through a huge refactoring exercise |
| 11:30 | stuartsierra | cemerick: It used to be possible to create literal array maps with duplicate keys, rather unexpectedly. |
| 11:32 | cemerick | Yeah, I remember that as well. I can see the utility of both behaviours, especially w/ fns that destructure kw args. |
| 11:33 | chouser | it was possible to have innocent-looking code that produced collections that were internally broken and would behave weiredly at much later times |
| 11:33 | chouser | hard to debug |
| 11:35 | cemerick | Sure, that's bad. |
| 11:58 | cemerick | stuartsierra: that BIGINT notation is…unfortunate |
| 11:58 | stuartsierra | yes |
| 11:58 | stuartsierra | I'm hoping it ends up temporary. |
| 12:01 | cemerick | As in, remove the notation entirely? I don't see the downside to using #<BigInteger 1234>, either. |
| 12:02 | cemerick | All big ops will return BigInts anyway; you really need to try to get a BigInteger. |
| 12:03 | stuartsierra | Either remove 1234BIGINT or replace it with 1234BIGINTEGER |
| 12:03 | cemerick | Besides, two notations for functionally equivalent (ex. interop) concrete types. Bleh. |
| 12:37 | renamecontains | ,(println "Testing 123") |
| 12:37 | clojurebot | Testing 123 |
| 12:38 | renamecontains | &(println "Testing 321") |
| 12:38 | sexpbot | ⟹ Testing 321 nil |
| 12:39 | offby1 | I took Testing 201 but changed my major to English Lit after that |
| 13:15 | `fogus | dnolen: Jekyll sound like a good way to start |
| 13:18 | dnolen | `fogus: cool! I'll try to create the gh-pages branch later today. |
| 13:20 | `fogus | dnolen: Do you know if I have commit rights? |
| 13:20 | dnolen | `fogus: I thought all clojure org devs automatically have commit rights. |
| 13:21 | `fogus | dnolen: I'm sorry, I meant admin rights. It appears I do not... and that's probably not needed anyway |
| 13:22 | dnolen | `fogus: oh yeah, I don't have admin rights either. |
| 13:22 | `fogus | dnolen: I think there is a quick way to create a gh-pages branch, but it requires admin |
| 13:23 | dnolen | `fogus: yeah I'm pretty sure there is, perhaps we can get someone to do that for us? |
| 13:23 | stuartsierra | just branch and push |
| 13:24 | `fogus | stuartsierra: That's it? Cool! |
| 13:24 | stuartsierra | It's an ordinary Git branch like any other. |
| 13:24 | dnolen | `fogus: if you want to setup the branch, that's fine by me. |
| 13:25 | `fogus | stuartsierra: With some special config files I imagine |
| 13:25 | `fogus | (jekyll config files that is) |
| 13:26 | `fogus | Oh I see now. My Potion repo has a gh-pages branch |
| 13:26 | stuartsierra | I don't know much about Jekyll. |
| 13:28 | `fogus | http://fogus.github.com/potion/ |
| 13:28 | `fogus | Jekyll seems pretty nice on 10 minutes of investigation (but what doesnt) |
| 13:29 | stuartsierra | From what I've seen at Relevance, it's good for very small sites (5-10 pages) but gets cumbersome for larger sites. |
| 13:30 | `fogus | Well, we can migrate to Enterprise Jekyll when we cross that threshold :p |
| 13:30 | stuartsierra | ha |
| 13:31 | stuartsierra | You mean Service-Oriented Enterprise JekyllBeans Professional. |
| 13:32 | `fogus | Oh great! Another certification for me! |
| 13:32 | stuartsierra | :) |
| 14:16 | Krato` | imagine I have something like (defn fib [n] (if (< n 2) n (+ (fib (dec n)) (fib (dec (dec n)))))) |
| 14:16 | Krato` | I can speed this up with |
| 14:17 | Krato` | (def fib (memoize (fn [n] (if (< n 2) n (+ (fib (dec n)) (fib (dec (dec n)))))))) |
| 14:17 | Krato` | is there any other way to insert memoize like this |
| 14:18 | Krato` | for instance in this case I don't have metadata like parameter list on the resulting function |
| 14:22 | stuartsierra | Memoize works on any function. You don't need to know the arguments. |
| 14:23 | hiredman | stuartsierra: sure, but he wants to preserve the doc string and args and other metadata you get when using defn |
| 14:23 | hiredman | Krato`: you can define the function using defn and then alter-var-root to memoize |
| 14:24 | hiredman | but memoize doesn't actually work for self calling fns created with defn |
| 14:24 | Krato` | it does |
| 14:25 | Krato` | the one I listed works |
| 14:25 | hiredman | it doesn't |
| 14:25 | Krato` | lol |
| 14:25 | manutter | does it work as memoized, or does it just work as if unmemoized |
| 14:25 | hiredman | becuase (defn foo [x] ...) expands to (def foo (fn foo [x] ...)) |
| 14:26 | hiredman | which means calls to foo in the function body won't go through the var, but use the lexical binding |
| 14:26 | hiredman | so if you memoize the function in var it doesn't matter |
| 14:26 | manutter | but you can explicitly call the var in your function, and then it will work |
| 14:26 | Krato` | the one case I listed works |
| 14:27 | hiredman | Krato`: doesn't |
| 14:27 | manutter | (def fib (memoize (fn [n] (if (< n 2) n (+ (#'fib (dec n)) (#'fib dec (dec n)))))))) |
| 14:27 | Krato` | it does, enter both listed into the repl and time them |
| 14:27 | pjstadig | does too ∞ +1 |
| 14:27 | manutter | Assuming I remembered the correct reader macro for calling a var |
| 14:27 | pjstadig | Krato`: were you entering as (def ...) or (defn ...) |
| 14:28 | hiredman | Krato`: pardon me, I assumed you meant the case you mentioned rewritten using defn |
| 14:28 | hiredman | manutter: that will work |
| 14:28 | Krato` | first one I listed take 13000 msec to calculate fib 38 and second one takes 0.14 msec |
| 14:28 | pjstadig | hiredman is saying that (defn ...) wouldn't work |
| 14:28 | hiredman | this is a particular interaction between defn and memoize |
| 14:28 | hiredman | def and fn is fine |
| 14:28 | hiredman | unfornately defn is the only easy way to get all the cool metadata |
| 14:29 | technomancy | hiredman: do you know if there's a good reason for that? |
| 14:29 | manutter | if you use #'fib in your defn for memoize, that's a workaround, isn't it? |
| 14:29 | hiredman | manutter: it will make your fib slow |
| 14:29 | technomancy | I opened an issue about fn not having arg/docstring meta; no idea if it's by design |
| 14:30 | Krato` | well 2 things bother me with my solution |
| 14:30 | hiredman | the whole metadata on fn situation seems very iffy |
| 14:30 | Krato` | 1. lack of metadata |
| 14:30 | Krato` | 2. I don;t understand why def + fn works |
| 14:30 | Krato` | I mean the variable doesn't exist at the time of function evalution or something? |
| 14:31 | scgilardi | I recall reading that fogus is on the case for a helper to help making defn-like macros easier to write by getting all the metadata, optional-doc-string, etc. right behind an API. |
| 14:32 | Krato` | need to make defmemofn macro :P |
| 14:32 | pjstadig | yeah `fogus_away how's that coming??? :) |
| 14:32 | hiredman | Krato`: the compiler creates #'fib before compiling the function setting the value of the var to the function |
| 14:32 | Krato` | so basically it's (define, then fn then assign to var |
| 14:33 | mrBliss` | http://clojuredocs.org/clojure_contrib/clojure.contrib.def/defn-memo |
| 14:33 | scgilardi | yeah that. :) |
| 14:34 | Krato` | o nice |
| 14:34 | hiredman | mrBliss`: that has the problem I just described |
| 14:34 | Krato` | gotta learn what contrib has to offer |
| 14:34 | hiredman | if you look at the source it expands to defn + alter-var-root |
| 14:34 | mrBliss` | hiredman: sorry, I didn't follow the whole conversation |
| 14:34 | hiredman | which means that self calling functions will not be properly memoized |
| 14:36 | Krato` | memoizing recursive stupid O(2^n) implementations is the best thing to memoize :) |
| 14:38 | Krato` | preserves clarity of the original definition of the problem and evaluates with same speed as iterative implementation :) |
| 14:46 | `fogus_away | scgilardi: You mean this? https://github.com/clojure/tools.macro/blob/master/src/main/clojure/clojure/tools/macro.clj#L273 |
| 14:48 | scgilardi | `fogus_away: looks right. what I saw was an exchange between you and stuart halloway about it. looks like it's done. :) |
| 14:48 | `fogus_away | scgilardi: Recommendations welcomed. :-) |
| 14:49 | hiredman | something should be done about broken memoize+defn |
| 14:49 | scgilardi | hiredman: would a fixed defn-memo do the trick? it seems feasible. |
| 14:50 | hiredman | possibly, I wonder if rich would re-evaluate the need to lexically bind the function now that vars are not dynamic |
| 14:51 | scgilardi | (although the caching policy on a naked memoize is such that I suspect defn-memo has little chance of getting pulled into clojure) |
| 14:52 | pjstadig | hiredman: yeah but i'm not sure how that would work since the var doesn't exist when the fn is compiled |
| 14:52 | pjstadig | perhaps there's a way around it |
| 14:52 | scgilardi | hiredman: is the alternative to compile to var references? maybe only in the case where the fn has no name of its own? |
| 14:52 | hiredman | pjstadig: oh, the comopiler already takes care of that |
| 14:52 | hiredman | defn didn't always expand that way |
| 14:53 | pjstadig | ah |
| 14:53 | hiredman | the way a def is compiled allows the body of the value to refer to the var that is created |
| 14:53 | pjstadig | fixed point combinator? :) |
| 14:54 | hiredman | compilation just generates the code to def the var, it doesn't deref it, so the var can exist and be empty |
| 14:54 | hiredman | which is effectively what the compilation of def does |
| 14:55 | Krato` | btw I did the Euler Project problem 15 with this memoize trick. |
| 14:55 | Krato` | you have to count the number of paths down a 20x20 grid going only down and right |
| 14:56 | Krato` | using naive implementation which forks at each node I couldn't get result even though I ran it 6 hours |
| 14:56 | Krato` | added memoize and it got solved in 0.something ms |
| 14:57 | Krato` | the problem is of size "choose n out of 2n" which is something around squrt(n) * 2^2n-1 |
| 14:58 | Krato` | so around O(4^n) |
| 14:59 | pjstadig | http://en.wikipedia.org/wiki/Dynamic_programming |
| 14:59 | hiredman | you should do it as a grid of agents |
| 15:05 | Krato` | hehe grid of agents |
| 15:07 | Krato` | to be fair I haven't yet grasped how agents and futures work and when I should use one or the other |
| 15:08 | Krato` | also pmap was behaving weirdly, only doubling performance on 8 cores |
| 15:18 | hiredman | Krato`: well, linear performance grow is the dream, but with coordination overhead, etc, it can heardly be expected |
| 15:19 | Krato` | I expected it not to be exactly 8 |
| 15:19 | Krato` | but 2? cmon |
| 15:19 | Krato` | I recall it was only using 25% CPU |
| 15:19 | Krato` | in task manager |
| 15:20 | Krato` | so looks like pmap only utilized 2 cores |
| 15:29 | Krato` | http://clojuredocs.org/clojure_contrib/clojure.contrib.apply-macro/apply-macro |
| 15:29 | Krato` | why is this in contrib if it's evil? |
| 15:30 | technomancy | because contrib doesn't have high standards |
| 15:30 | technomancy | or didn't, I guess |
| 15:30 | hiredman | because contrib is also evil |
| 15:30 | ohpauleez | technomancy: right, I would say old contrib is that way |
| 15:30 | ohpauleez | but I'm sure apply-macro exists for composition |
| 15:34 | Krato` | let's say I have this: I have a function that returns a function that returns a function etc... and I have a vector of arguments which I would like to apply to each of these 1 argument per function |
| 15:34 | Krato` | how would I do that |
| 15:35 | gfrlog | (reduce #(%1 %2) f args) |
| 15:35 | gfrlog | is my guess |
| 15:36 | gfrlog | ,(let [f (partial partial +)] (reduce #(%1 %2) f (range 10))) |
| 15:36 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 15:37 | gfrlog | yeah that didn't do what I wanted it to :( |
| 15:37 | gfrlog | I mean the previous code is probably still fine, but (partial partial +) is not a function like the one you described |
| 15:37 | gfrlog | so I don't have an easy idea for testing it |
| 15:57 | TimMc | ,(((partial partial +) 3) 5) |
| 15:57 | clojurebot | 8 |
| 15:57 | TimMc | ,((((partial partial partial +) 3) 5) 10) |
| 15:57 | clojurebot | 18 |
| 15:58 | TimMc | ,(let [f (nth (iterate partial +) 10)] (reduce #(%1 %2) f (range 10))) |
| 15:58 | clojurebot | java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial |
| 15:59 | TimMc | Ah, not quite. |
| 15:59 | TimMc | Need a comp and apply or something. |
| 16:02 | Krato` | here's why |
| 16:02 | Krato` | vectors maps and sets are also functions |
| 16:02 | TimMc | ,(let [n 10, f ((apply comp (take n (repeat partial))) +)] (reduce #(%1 %2) f (range n))) |
| 16:02 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial |
| 16:02 | TimMc | meh |
| 16:02 | Krato` | so using this and a sequence of indexes and keys would allow one to work with nested collections |
| 16:03 | gfrlog | Krato`: you know about get-in right? |
| 16:04 | gfrlog | surely the functional nature of a set is little help in this situation |
| 16:06 | TimMc | ,(let [n 10, f (apply partial (concat (take (dec n) (repeat partial)) [+]))] (reduce #(%1 %2) f (range n))) |
| 16:06 | clojurebot | 45 |
| 16:06 | TimMc | \o/ |
| 16:07 | gfrlog | TimMc: try writing it where f does not depend on n, and to get the final value you call the last function with no args |
| 16:07 | TimMc | point |
| 16:07 | gfrlog | point? |
| 16:07 | clojurebot | the point of moby dick is "be yourself" |
| 16:08 | TimMc | gfrlog: that is, "you have a good point" |
| 16:08 | gfrlog | ah okay |
| 16:12 | gfrlog | I was thinking maybe you could achieve that with some inherent property of partial (that's what I was going for on my first try), but now I'm thinking you'd need an (if), or two different method bodies :( |
| 16:12 | gfrlog | ,(partial +) |
| 16:12 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial |
| 16:12 | gfrlog | yeah; I was thinking maybe that would return 0 |
| 16:13 | gfrlog | which would be strange. |
| 16:16 | TimMc | Hmm, I don't see why (partial f) should throw. |
| 16:16 | TimMc | It is not ill-defined -- just return f. |
| 16:16 | gfrlog | right |
| 16:17 | gfrlog | I agree that would seem better |
| 16:17 | TimMc | &(source partial) |
| 16:17 | sexpbot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 16:17 | TimMc | $source partial |
| 16:17 | sexpbot | partial is http://is.gd/zZxzDD |
| 16:17 | hiredman | I think you could argue either way, but the sort of person who uses partial is most likely to argue it should not throw |
| 16:18 | TimMc | The case where I see this happening is (apply partial f args) |
| 16:18 | hiredman | args is nil |
| 16:18 | TimMc | yeah |
| 16:32 | gfrlog | ,(map #(-> 10 range % class) [seq sequence]) |
| 16:32 | clojurebot | (clojure.lang.ChunkedCons clojure.lang.LazySeq) |
| 16:41 | TimMc | ,(doc sequence) |
| 16:41 | clojurebot | "([coll]); Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields ()" |
| 16:42 | gfrlog | TimMc: will we ever know all of the clojure.core functions? |
| 16:42 | TimMc | ,(map (juxt seq sequence) [nil () [1]]) |
| 16:42 | clojurebot | ([nil ()] [nil ()] [(1) (1)]) |
| 16:55 | void_ | what database (sql or nosql) do you use for your clojure projects? |
| 16:57 | gfrlog | void_: I have used MySQL and Couch |
| 16:57 | technomancy | lucene |
| 16:57 | void_ | so this REST API of couch, that sounds to me like something annoying |
| 16:57 | technomancy | I've only used couch from elisp, but it was very pleasant there. |
| 16:58 | gfrlog | void_: if you have a good wrapper library then it's fine. It's quite convenient if you're going to call it from client-side JS |
| 16:58 | void_ | well I think I'm gonna compare clojure wrappers and see which one is most popular |
| 16:58 | gfrlog | void_: clutch was good I think. I didn't use it too extensively. |
| 16:59 | void_ | gfrlog: well, I'm not. I want to build a JS app, but use WebSocket instead. (For fun, you know ;)) |
| 16:59 | gfrlog | but the couch API is decently simple, so clutch probably does a good job |
| 17:00 | gfrlog | void_: my opinion is that if you're not planning on ever using couch in a big cluster, then it's probably not worth it. It'll be fine if your data model is real simple, but it sacrifices a lot of functionality to get the scalability |
| 17:00 | void_ | well thanks guys |
| 17:00 | gfrlog | yep |
| 17:01 | void_ | is there any web app example built with clojure? |
| 17:02 | cemerick | gfrlog: The basics of the couch api are simple, but it gets pretty arcane (and ill-documented) as you wade into the more recent stuff. |
| 17:02 | gfrlog | cemerick: I think there are some things it could do better, like url rewrites |
| 17:02 | cemerick | (this coming from a contributor to clutch, FWIW) |
| 17:03 | gfrlog | cemerick: now that I think about it more, I don't mind couch so much as I do couch-apps |
| 17:03 | cemerick | ah |
| 17:03 | cemerick | the couchapp stuff is insane IMO |
| 17:04 | gfrlog | I tried building a couch app or two and there were way too many times where the answer to "how can I do X?" was "nope." |
| 17:04 | Krato` | so insane in what way? |
| 17:05 | cemerick | That's what happens when you nail yourself up with javascript. |
| 17:05 | gfrlog | cemerick: javascript is an orthogonal issue, which is remedied a bit with coffeescript |
| 17:05 | gfrlog | cemerick: if couch ran only clojure, I'd still have the same complaints |
| 17:05 | technomancy | cemerick: I can see a sweet spot there if you got users to run couch locally |
| 17:05 | hiredman | gfrlog: syntax |
| 17:06 | technomancy | which all new ubuntu installs do |
| 17:06 | hiredman | gfrlog: the runtime cannot be fixed by a preprocessor |
| 17:06 | gfrlog | hiredman: right, thus "a bit" |
| 17:06 | cemerick | Krato`: Writing anything besides DOM glue with javascript is pretty tortuous. |
| 17:06 | gfrlog | technomancy: that turns into a security headache |
| 17:07 | technomancy | gfrlog: you could still do plenty of useful stuff only listening on 127.0.0.1 |
| 17:07 | gfrlog | technomancy: At least if you don't have a bijection between users and couch instances |
| 17:07 | technomancy | oh, for multiuser boxes; sure. |
| 17:08 | cemerick | gfrlog: true enough. The app model's quasi-political objectives get in the way of my building useful things. |
| 17:10 | VT_entity | hey all |
| 17:10 | gfrlog | hey |
| 17:10 | VT_entity | I'm having trouble installing Clojure |
| 17:11 | gfrlog | have you tried leiningen? |
| 17:11 | VT_entity | no |
| 17:11 | VT_entity | that was going to be my last resort- I usually don't like running other people's install scripts on my box |
| 17:12 | gfrlog | ah okay then; so what do you mean by "install"? |
| 17:12 | VT_entity | I tried to use counterclockwise from Eclipse |
| 17:12 | VT_entity | it's giving me problems whenever I try to :use a library |
| 17:12 | VT_entity | aaand then I tried to install with git |
| 17:13 | gfrlog | if you want to use Eclipse, I can't help. If you just want to run clojure any way possible, you shouldn't need anything other than the jar (and java installed) |
| 17:13 | VT_entity | but I would also need clojure-contrib.jar, right? |
| 17:13 | gfrlog | if you want to use some of those libraries, yes |
| 17:13 | VT_entity | don't I have to add both to my classpath somehow before I (:use (clojure.contrib...)) |
| 17:14 | gfrlog | yeah |
| 17:14 | VT_entity | see, this is where I'm getting all screwed up |
| 17:14 | cemerick | VT_entity: what was your particular problem with counterclockwise? |
| 17:14 | gfrlog | do you know how to set up the classpath when executing the java command? |
| 17:14 | VT_entity | java -cp |
| 17:14 | gfrlog | so |
| 17:14 | gfrlog | java -cp clojure.jar:clojure-contrib.jar clojure.main |
| 17:14 | gfrlog | should work |
| 17:15 | VT_entity | I can't import libraries while using counterclockwise |
| 17:15 | VT_entity | lol, I did something wrong, I'm just not sure where |
| 17:15 | cemerick | VT_entity: did you add the relevant jars to your project's set of libraries? |
| 17:15 | VT_entity | do any of you install the git way? |
| 17:16 | cemerick | "git way"? |
| 17:16 | VT_entity | how do I do that cemerick? |
| 17:16 | VT_entity | you mean the :use command? |
| 17:17 | cemerick | VT_entity: right-click on your project (usually in the "Project Explorer" view), and choose properties. Select "Java Build Path", and you'll see a listing of the project's libraries, to which you can add jars and such. |
| 17:17 | VT_entity | when I try to download from git, there isn't even a clojure-contrib.jar in the directory, just a series of .clj files |
| 17:17 | cemerick | (that all assumes you're not using maven) |
| 17:17 | VT_entity | I've tried both ways, neither has really worked for me, I screwed something up. |
| 17:17 | VT_entity | oooooooh no way |
| 17:18 | VT_entity | cemerick, I never thought to look under build path |
| 17:18 | VT_entity | I'm going to try that right now |
| 17:19 | cemerick | VT_entity: yeah, it's a snap once you're on the right panel; you probably want "add external jar" — browse, select, then run your REPL, etc. |
| 17:38 | gfrlog | Java doesn't have any nice library for english noun pluralization like ActiveSupport does it? |
| 17:44 | technomancy | jruby =) |
| 17:50 | jmatt | gfrlog: check out inflections - http://r0man.github.com/inflections-clj/ |
| 17:53 | mtrelinsomething | hi there, how do i call this in clojure? public <T extends java.rmi.Remote> T getService(AdWordsService service) ? |
| 17:54 | mtrelinsomething | it's expecting a "T" |
| 17:59 | gfrlog | jmatt: thanks |
| 17:59 | Krato` | hm hm.... I see c.contrib.string/replace-by doesn't allow to replace just certain groups |
| 18:01 | gfrlog | Krato`: maybe something like regex backreferences would do what you want? I'm not too familiar with java's regex support... |
| 18:01 | gfrlog | woah |
| 18:01 | gfrlog | s/backreferences/lookahead-and-lookbehind |
| 18:01 | Krato` | I actually have the needed corde in java |
| 18:01 | Krato` | no those are not useful for replacing |
| 18:02 | gfrlog | I meant for not capturing the part you don't want to replace |
| 18:02 | Krato` | I know what you meant |
| 18:02 | Krato` | when you specify replace string in java |
| 18:02 | Krato` | you can say $1 or something like that |
| 18:02 | Krato` | and the matched group 1 is inserted into replacement string at that position |
| 18:03 | Krato` | however that prevents you from behing able to replace a group with the result of a function |
| 18:04 | gfrlog | doesn't replace-by give you enough info to assemble whatever you need? |
| 18:04 | Krato` | it does in some way |
| 18:04 | Krato` | it would require the user to piece together the replacement string themselves |
| 18:05 | Krato` | especially difficult when groups are nested |
| 18:05 | Krato` | (a(b(c))) |
| 18:05 | Krato` | you wanna replace just c |
| 18:06 | Krato` | you need to append a minus c with the replacement for c |
| 18:06 | Krato` | it can get arbitrarily complicated |
| 18:06 | gfrlog | yep. I think that's when people start building parsers :) |
| 18:09 | Krato` | http://pastebin.com/SSj9JTD9 |
| 18:10 | Krato` | little something I've made that replaces groups with the replacements, null elements meaning group doesn't get replaced |
| 18:11 | Krato` | this is a part of a larger framework for working with java reg exp and the replacements in this case are results of match groups run though a bunch of functions |
| 18:12 | Krato` | when I say functions I mean IFn-like interface instances |
| 18:40 | Krato`` | hmmm |
| 18:40 | Krato`` | (defn string-sum [s] |
| 18:40 | Krato`` | (reduce #(+ %1 (- (.numericValue ^Character %2) (.numericValue \A))) 0 s)) |
| 18:40 | Krato`` | why does this make 2 reflection warnings, both for numericValue |
| 18:41 | Krato`` | I've typehinted one and the constant can't be typehinted |
| 18:42 | Krato`` | oh |
| 18:42 | Krato`` | never mind |