#clojure logs

2011-06-06

00:02RaynesI'm going to have to start going door to door and sharing the gospel of cake.
00:03Rayneszakwilson: apache commons-email is fantastic.
00:03Rayneszakwilson: After going through all the Clojure libraries, none are all that satisfactory, and commons-email is fantastic at one thing: sending email.
00:05zakwilsonRaynes: 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:06zakwilsonWhy 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:07offby1mutation is the Way and the Light™
00:07Rayneszakwilson: 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:07lawfulfalafelI keep seeing people mentioning marmalade on posts about clojure, but I don't really get what it is
00:07lawfulfalafeland googling for it isn't really helping me understand it any better
00:08Rayneszakwilson: 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:08technomancylawfulfalafel: it's clojars for elisp
00:08Rayneslawfulfalafel: Marmalade is an elisp package server. It's just a public place where people can upload their elisp packages for use with ELPA.
00:09zakwilsonRaynes: postal claims to be a javamail wrapper, but it seems unable to authenticate with gmail so it sucks.
00:09lawfulfalafelah, thank you
00:10Rayneszakwilson: I seem to recall needing something that it didn't support on the javamail side.
00:11zakwilsonRaynes: then javamail is not very complete.
00:11technomancylawfulfalafel: while elpa.gnu.org is more like maven central
00:12Rayneszakwilson: 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:13zakwilsonRaynes: 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:13Rayneszakwilson: I don't know if it supports encrypted stmp, but it's certainly easy to use.
00:15zakwilsonRaynes: the docs suggest that it does.
00:16lawfulfalafelokay, I installed cake, but I don't get how to run it
00:16lawfulfalafelI've never used ruby or gems before
00:16zakwilsonRaynes: 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:17Rayneszakwilson: [org.apache.commons/commons-email "1.2"]
00:17lawfulfalafelbut I know it's at /var/lib/gems/1.8/bin/cake
00:17Rayneslawfulfalafel: The command is 'cake'.
00:17zakwilsonRaynes: Thanks. My guess was so close, yet so far.
00:17RaynesIf that doesn't work, then put /var/lib/gems/1.8/bin on your PATH
00:18lawfulfalafeluh, could you perhaps remind me how to do that?
00:18lawfulfalafelI know $PATH=/blah/blah/blah sets it
00:18lawfulfalafelbut I forget how to append to it
00:18RaynesOn Linux?
00:18lawfulfalafelyup
00:18RaynesDo you have a ~/.bashrc file?
00:19lawfulfalafelyes, but it's been automatically generated
00:19lawfulfalafelat least I don't remember touching it
00:19RaynesPut this in it: export PATH=/var/lib/gems/1.8/bin:$PATH
00:20RaynesThen restart your terminal (to restart bash) or run this: . ~/.bashrc
00:22lawfulfalafelRaynes: I tried that and got "bash: /home/kirby/.bashrc: Permission denied"
00:23lawfulfalafelso I just typed "bash" again to just launch another one, but for some reason it still can't find cake
00:23Rayneslawfulfalafel: echo $PATH
00:24lawfulfalafel/var/liv/gems/1.8/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
00:24devn /var/liv
00:24RaynesTypo.
00:24lawfulfalafellol
00:25lawfulfalafelthank you devn
00:25lawfulfalafelthank you Raynes, it works now
00:26lawfulfalafeljust out of curiosity, does cake support syntax hilighting?
00:26RaynesNo problem. We also have a channel specifically for cake if you have any other problems. #cake.clj
00:26devnnow go forth and write clojure with great ferocity
00:27Raynescake'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:27devnor you can print your code on paper and get a few colored highlighters
00:27Raynesdevn: Or M-x print-buffer
00:28devn1up
00:28lawfulfalafelwell thanks again guys
00:28lawfulfalafelgn
00:28devnim going to bed also
00:28devngood night all
00:58kornyanyone know if there's some way to run "lein midje" so it automatically re-runs tests on file changes?
01:00korny- mostly, I'm trying to avoid the startup time; it's a slow process re-running manually
01:06technomancykorny: that's what lein interactive is for
01:07technomancywell, really that's what lein swank is for; lein interactive is just for folks who don't use swank for whatever reason.
01:07kornycool - so "lein interactive" will let you run 'midje' repeatedly.
01:07technomancyyup
01:08kornyI'm not using swank for now - I keep meaning to re-learn emacs, but somehow I keep failing.
01:08technomancysure; one step at a time
01:08kornyI 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:08technomancymidje should make it easy to run its tests from the repl too
01:08kornys/used/user
01:08sexpbot<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:09technomancywith clojure.test you can just do (run-tests) in the repl; hopefully midje has an equivalent
01:11kornyjust running 'midje' in lein interactive is working. thanks!
01:11technomancycool
01:15kornyhmm - nope, 'midje' works the first time, the second time I get "Couldn't connect".
01:16technomancyhm; it could be the midje plugin for leiningen exits
01:17technomancyperhaps the author of midge didn't realize that the task needs to return an integer rather than calling System/exit directly
01:22kornythe source is short - I'll ave a look.
01:27kornyhmm - got part way there but other stuff is screwing up. This is getting beyond me - might ask the midje author.
01:29technomancybzzzt--do not want: https://github.com/marick/Midje/blob/master/leiningen/midje.clj#L61
01:32technomancyactually 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:57void_hi this is my second day with clojure
02:57void_why does this (.getName String) throw this: #<NoSuchFieldException java.lang.NoSuchFieldException: getName>
03:01justinlillyvoid_: is it possible that String doesn't refer to what you thought?
03:02justinlilly,(.getName String)
03:02clojurebot"java.lang.String"
03:02justinlillyshould work.
03:02justinlilly,(.. System (getProperties) (get "os.name"))
03:02clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)
03:19xkbhi
03:20void_so there's something wrong with my local installation
03:21xkbI'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:47fliebelxkb: Do you have an explaination about the problem?
03:54xkbfliebel: yes
03:54xkbsay your telephone number is 111, then the solution would be aaa or aAa
03:55xkbif aaa or aAa would be words
03:55xkbother example: "530189010363" ["adenogenesis"]
03:55fliebelxkb: So basically you try to form words from the chars on the phone keys?
03:56xkbcorrect
03:56xkblike T9 on the old nokia's
03:56fliebelso, like 1-800-my-apple ;)
03:56bprthen how does 1 => a and 5 => a ?
03:56fliebelxkb: Yea, your table looks weird.
03:57fliebelWhy 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:58xkbfliebel: ah, that was just parameterisation
03:58xkbover here it's a "" 2 "abc" for example
03:58bprstill, on what phone does 1 and 5 both have a?
03:58xkbso app. it's region specific
03:59xkbI meant 1 "" 2 "abc" btw
03:59fliebelxkb: 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:59xkbyup
04:00xkbbut as I understand it maps are implemented as trees anyways
04:00xkbso just inserting number word tuples should work just as well
04:00xkbemphasis on the should ;)
04:01bprtrie =/= tree
04:01fliebelxkb: But with a trie you get to take advantage of the alphabet ;)
04:01bprtries are built from trees, but their a special purpose data structure
04:01bprthey're*
04:01bpr^
04:03xkbI started out with something very similar to the SO code, but changed it back to a simple map
04:03xkbI'm wondering why it takes so long to build the {number [word]} map
04:04fliebelxkb: You mean, you are generating all possible words for all possible numbers? :-o
04:05xkbfliebel: other way around
04:05xkbI generate numbers for all words in the dict
04:05xkbthat compact it to all words for the numbers generated
04:06xkband theres 234936 words
04:07fliebelAh, I see. I'll have some breakfast and have a look at it.
04:07xkbcool :)
04:07xkbmaybe I should try the Trie meanwhile ;)
04:40fliebelxkb: How long does yours take?
04:41xkbfor the full dict it takes more time then I care to wait for :)
04:42xkband that's just the convert/compact function
04:42xkbreading the dict and transforming it to number/word pairs is fast
04:43xkbor rather parts of it are lazy oc :)
04:44fliebelxkb: so, all you're doing there is combining word with the same number, right?
04:44xkbcorrect
04:45xkbI recurse over all the numbers, recombining words if the number is already in the target map
04:46xkbI use get-in to find numbers in the new map, and assoc to update an existing number [word] pair
04:46fliebelxkb: I'd use merge-with
04:47xkbah
04:48fliebelI run out of memory before I even v=created the full map, btw :(
04:48xkb:(
04:49bprso, you'll need to store a trie on disk
04:49xkbthe problem is you cant even use integers as key: telephonenumbers might start with a 0
04:56xkbmerge-with is quite nice :)
04:59xkb40k words is still doable
06:05fliebelxkb: I got something trie based, how are you doing?
06:10xkbhad to do some real work in the mean-time
06:10fliebelhttps://gist.github.com/1010027
06:10xkbrewrote it to just use merge-with
06:10xkbbut that doesnt really help
06:11fliebelxkb: Mine is fast enough for me, only it does not include all words for a give number.
06:11fliebelIf I did that, I ran out of memory, and it took much longer.
06:11xkbah, I had the same with my first Trie based attempt
06:12xkbhmm why doesnt your build-trie function blow stack?
06:13xkbwith the recursion there
06:17fliebelxkb: because the recursion depth is only max word length.
06:19xkbah now I see, not that familiar with the use of comp
07:14msapplerhello
07:15msapplerwhat is the best way for a macro that does some assertions and then expands to another function call to store the other function?
07:15msapplerI mean this function from my blog: http://resatori.com/advanced-keyword-function#comments
07:16msapplerwhen i let the macro expand to the function I get an ExceptionInitializerError
07:17msapplerso basically I just want to convert this macro: https://gist.github.com/999256
07:18msapplerso that it runs its checks at compile-time ...
07:46hoeckmsappler: checking at compile-time works only in those cases where the arguments are known at compile time
07:46hoeckeg. when you call such a function directly (keyfn :arg1 'value)
07:48hoeckand does not work when you pass the function around: (map keyfn args)
07:50msappleryes i do that always
07:50msapplercalling it directly
10:05ilyakhi *
10:06ilyakSuppose I have a class, CSVReader ^^
10:06ilyakWhat's the best way to implement seq protocol for it? I can't touch the class itself
10:09stuartsierraUnfortunately, seq is not a protocol. It's just an interface.
10:09stuartsierraAll you can do is write a function that takes a CSVReader and returns a seq.
10:11ilyakstuartsierra: How does clojure do it for, e.g., String?
10:11stuartsierraConditionals for each special case in the implementation of seq.
10:11stuartsierraAll that stuff predates the introduction of protocols.
10:12stuartsierraProbably someday it will be replaced by protocols.
10:16chouserso all you need to do is provide a new function that returns a seq for your CSVReader
10:21cemerickilyak: see iterator-seq and enumerator-seq for examples of fns that return seqs over mutable things
10:21cemerickif your CSVReader is returning rows via an iterator, then you actually have no work to do
10:26stuartsierraI think we lost him, guys.
10:30ilyakcemerick: I just did (repeatedly #(.readNext csv-reader))
10:30ilyakYet to actually try
10:30ilyakHow would I access enum values of nested enum belonging to some class?
10:31ilyakSqlUtils/Columns/ALL doesn't work
10:31ilyakand no idea how to import it
10:32cemerickthat'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:33cemerickSqlUtils$Columns/ALL?
10:33cemerickSqlUtils$Columns is the class you'd import
10:34ilyakOkay, figured it out, thanks
11:18timvisherhey all
11:18timvisherwhat would be the easiest way to compare 2 sequences in a position independent manner
11:18timvisher?
11:19timvisherso that (= [1 2 3 4] [4 3 2 1]) would return true
11:19stuartsierraTurn them both into sets.
11:19manutter,(= (into #{} [1 2 3 4]) (into #{} [4 3 2 1])
11:19clojurebotEOF while reading
11:20manutter,(= (into #{} [1 2 3 4]) (into #{} [4 3 2 1]))
11:20clojurebottrue
11:20timvisherwhich should only break if there are duplicates
11:20timvisherand if there are never duplicates then maybe they should always be sets...
11:21manutterMaybe you could also map the seqs into hashmaps, with the count as the value
11:21manutter[1 2 3 2 1] => {1 2, 2 2, 3 1}
11:21timvisherit's only a vector because i'm used to the `[` seq literal
11:21timvisherthere's really no reason it shouldn't be set
11:21timvisherI don't want duplicate entries
11:22manuttersure, that'll make things easier for you then
11:22timvisherso that's probably a good idea
11:22manuttersure
11:22timvisherya'll rock :)
11:26cemericktimvisher: just keep in mind that your literals can't have dupes in them already…
11:26cemerick,#{3 2 3}
11:26clojurebotDuplicate key: 3
11:26timvishercemerick: indeed
11:26timvishernone of them do
11:26timvisheri'm really falling victim to what I always do in java
11:26cemerickThat wasn't the case a long time ago.
11:26timvisheri default to List there without really thinking about the data structure
11:27edw`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:27timvisheror rather, the data that I'm trying to structure
11:27cemerickEach time I get tagged by it (mostly by not paying attention), I wonder why dupe checking is being done at all.
11:27timvisherand 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:30stuartsierracemerick: It used to be possible to create literal array maps with duplicate keys, rather unexpectedly.
11:32cemerickYeah, I remember that as well. I can see the utility of both behaviours, especially w/ fns that destructure kw args.
11:33chouserit was possible to have innocent-looking code that produced collections that were internally broken and would behave weiredly at much later times
11:33chouserhard to debug
11:35cemerickSure, that's bad.
11:58cemerickstuartsierra: that BIGINT notation is…unfortunate
11:58stuartsierrayes
11:58stuartsierraI'm hoping it ends up temporary.
12:01cemerickAs in, remove the notation entirely? I don't see the downside to using #<BigInteger 1234>, either.
12:02cemerickAll big ops will return BigInts anyway; you really need to try to get a BigInteger.
12:03stuartsierraEither remove 1234BIGINT or replace it with 1234BIGINTEGER
12:03cemerickBesides, two notations for functionally equivalent (ex. interop) concrete types. Bleh.
12:37renamecontains,(println "Testing 123")
12:37clojurebotTesting 123
12:38renamecontains&(println "Testing 321")
12:38sexpbot⟹ Testing 321 nil
12:39offby1I took Testing 201 but changed my major to English Lit after that
13:15`fogusdnolen: Jekyll sound like a good way to start
13:18dnolen`fogus: cool! I'll try to create the gh-pages branch later today.
13:20`fogusdnolen: Do you know if I have commit rights?
13:20dnolen`fogus: I thought all clojure org devs automatically have commit rights.
13:21`fogusdnolen: I'm sorry, I meant admin rights. It appears I do not... and that's probably not needed anyway
13:22dnolen`fogus: oh yeah, I don't have admin rights either.
13:22`fogusdnolen: I think there is a quick way to create a gh-pages branch, but it requires admin
13:23dnolen`fogus: yeah I'm pretty sure there is, perhaps we can get someone to do that for us?
13:23stuartsierrajust branch and push
13:24`fogusstuartsierra: That's it? Cool!
13:24stuartsierraIt's an ordinary Git branch like any other.
13:24dnolen`fogus: if you want to setup the branch, that's fine by me.
13:25`fogusstuartsierra: With some special config files I imagine
13:25`fogus(jekyll config files that is)
13:26`fogusOh I see now. My Potion repo has a gh-pages branch
13:26stuartsierraI don't know much about Jekyll.
13:28`fogushttp://fogus.github.com/potion/
13:28`fogusJekyll seems pretty nice on 10 minutes of investigation (but what doesnt)
13:29stuartsierraFrom what I've seen at Relevance, it's good for very small sites (5-10 pages) but gets cumbersome for larger sites.
13:30`fogusWell, we can migrate to Enterprise Jekyll when we cross that threshold :p
13:30stuartsierraha
13:31stuartsierraYou mean Service-Oriented Enterprise JekyllBeans Professional.
13:32`fogusOh great! Another certification for me!
13:32stuartsierra:)
14:16Krato`imagine I have something like (defn fib [n] (if (< n 2) n (+ (fib (dec n)) (fib (dec (dec n))))))
14:16Krato`I can speed this up with
14:17Krato`(def fib (memoize (fn [n] (if (< n 2) n (+ (fib (dec n)) (fib (dec (dec n))))))))
14:17Krato`is there any other way to insert memoize like this
14:18Krato`for instance in this case I don't have metadata like parameter list on the resulting function
14:22stuartsierraMemoize works on any function. You don't need to know the arguments.
14:23hiredmanstuartsierra: sure, but he wants to preserve the doc string and args and other metadata you get when using defn
14:23hiredmanKrato`: you can define the function using defn and then alter-var-root to memoize
14:24hiredmanbut memoize doesn't actually work for self calling fns created with defn
14:24Krato`it does
14:25Krato`the one I listed works
14:25hiredmanit doesn't
14:25Krato`lol
14:25manutterdoes it work as memoized, or does it just work as if unmemoized
14:25hiredmanbecuase (defn foo [x] ...) expands to (def foo (fn foo [x] ...))
14:26hiredmanwhich means calls to foo in the function body won't go through the var, but use the lexical binding
14:26hiredmanso if you memoize the function in var it doesn't matter
14:26manutterbut you can explicitly call the var in your function, and then it will work
14:26Krato`the one case I listed works
14:27hiredmanKrato`: doesn't
14:27manutter(def fib (memoize (fn [n] (if (< n 2) n (+ (#'fib (dec n)) (#'fib dec (dec n))))))))
14:27Krato`it does, enter both listed into the repl and time them
14:27pjstadigdoes too ∞ +1
14:27manutterAssuming I remembered the correct reader macro for calling a var
14:27pjstadigKrato`: were you entering as (def ...) or (defn ...)
14:28hiredmanKrato`: pardon me, I assumed you meant the case you mentioned rewritten using defn
14:28hiredmanmanutter: that will work
14:28Krato`first one I listed take 13000 msec to calculate fib 38 and second one takes 0.14 msec
14:28pjstadighiredman is saying that (defn ...) wouldn't work
14:28hiredmanthis is a particular interaction between defn and memoize
14:28hiredmandef and fn is fine
14:28hiredmanunfornately defn is the only easy way to get all the cool metadata
14:29technomancyhiredman: do you know if there's a good reason for that?
14:29manutterif you use #'fib in your defn for memoize, that's a workaround, isn't it?
14:29hiredmanmanutter: it will make your fib slow
14:29technomancyI opened an issue about fn not having arg/docstring meta; no idea if it's by design
14:30Krato`well 2 things bother me with my solution
14:30hiredmanthe whole metadata on fn situation seems very iffy
14:30Krato`1. lack of metadata
14:30Krato`2. I don;t understand why def + fn works
14:30Krato`I mean the variable doesn't exist at the time of function evalution or something?
14:31scgilardiI 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:32Krato`need to make defmemofn macro :P
14:32pjstadigyeah `fogus_away how's that coming??? :)
14:32hiredmanKrato`: the compiler creates #'fib before compiling the function setting the value of the var to the function
14:32Krato`so basically it's (define, then fn then assign to var
14:33mrBliss`http://clojuredocs.org/clojure_contrib/clojure.contrib.def/defn-memo
14:33scgilardiyeah that. :)
14:34Krato`o nice
14:34hiredmanmrBliss`: that has the problem I just described
14:34Krato`gotta learn what contrib has to offer
14:34hiredmanif you look at the source it expands to defn + alter-var-root
14:34mrBliss`hiredman: sorry, I didn't follow the whole conversation
14:34hiredmanwhich means that self calling functions will not be properly memoized
14:36Krato`memoizing recursive stupid O(2^n) implementations is the best thing to memoize :)
14:38Krato`preserves clarity of the original definition of the problem and evaluates with same speed as iterative implementation :)
14:46`fogus_awayscgilardi: You mean this? https://github.com/clojure/tools.macro/blob/master/src/main/clojure/clojure/tools/macro.clj#L273
14:48scgilardi`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_awayscgilardi: Recommendations welcomed. :-)
14:49hiredmansomething should be done about broken memoize+defn
14:49scgilardihiredman: would a fixed defn-memo do the trick? it seems feasible.
14:50hiredmanpossibly, I wonder if rich would re-evaluate the need to lexically bind the function now that vars are not dynamic
14:51scgilardi(although the caching policy on a naked memoize is such that I suspect defn-memo has little chance of getting pulled into clojure)
14:52pjstadighiredman: yeah but i'm not sure how that would work since the var doesn't exist when the fn is compiled
14:52pjstadigperhaps there's a way around it
14:52scgilardihiredman: is the alternative to compile to var references? maybe only in the case where the fn has no name of its own?
14:52hiredmanpjstadig: oh, the comopiler already takes care of that
14:52hiredmandefn didn't always expand that way
14:53pjstadigah
14:53hiredmanthe way a def is compiled allows the body of the value to refer to the var that is created
14:53pjstadigfixed point combinator? :)
14:54hiredmancompilation just generates the code to def the var, it doesn't deref it, so the var can exist and be empty
14:54hiredmanwhich is effectively what the compilation of def does
14:55Krato`btw I did the Euler Project problem 15 with this memoize trick.
14:55Krato`you have to count the number of paths down a 20x20 grid going only down and right
14:56Krato`using naive implementation which forks at each node I couldn't get result even though I ran it 6 hours
14:56Krato`added memoize and it got solved in 0.something ms
14:57Krato`the problem is of size "choose n out of 2n" which is something around squrt(n) * 2^2n-1
14:58Krato`so around O(4^n)
14:59pjstadighttp://en.wikipedia.org/wiki/Dynamic_programming
14:59hiredmanyou should do it as a grid of agents
15:05Krato`hehe grid of agents
15:07Krato`to be fair I haven't yet grasped how agents and futures work and when I should use one or the other
15:08Krato`also pmap was behaving weirdly, only doubling performance on 8 cores
15:18hiredmanKrato`: well, linear performance grow is the dream, but with coordination overhead, etc, it can heardly be expected
15:19Krato`I expected it not to be exactly 8
15:19Krato`but 2? cmon
15:19Krato`I recall it was only using 25% CPU
15:19Krato`in task manager
15:20Krato`so looks like pmap only utilized 2 cores
15:29Krato`http://clojuredocs.org/clojure_contrib/clojure.contrib.apply-macro/apply-macro
15:29Krato`why is this in contrib if it's evil?
15:30technomancybecause contrib doesn't have high standards
15:30technomancyor didn't, I guess
15:30hiredmanbecause contrib is also evil
15:30ohpauleeztechnomancy: right, I would say old contrib is that way
15:30ohpauleezbut I'm sure apply-macro exists for composition
15:34Krato`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:34Krato`how would I do that
15:35gfrlog(reduce #(%1 %2) f args)
15:35gfrlogis my guess
15:36gfrlog,(let [f (partial partial +)] (reduce #(%1 %2) f (range 10)))
15:36clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
15:37gfrlogyeah that didn't do what I wanted it to :(
15:37gfrlogI mean the previous code is probably still fine, but (partial partial +) is not a function like the one you described
15:37gfrlogso I don't have an easy idea for testing it
15:57TimMc,(((partial partial +) 3) 5)
15:57clojurebot8
15:57TimMc,((((partial partial partial +) 3) 5) 10)
15:57clojurebot18
15:58TimMc,(let [f (nth (iterate partial +) 10)] (reduce #(%1 %2) f (range 10)))
15:58clojurebotjava.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial
15:59TimMcAh, not quite.
15:59TimMcNeed a comp and apply or something.
16:02Krato`here's why
16:02Krato`vectors maps and sets are also functions
16:02TimMc,(let [n 10, f ((apply comp (take n (repeat partial))) +)] (reduce #(%1 %2) f (range n)))
16:02clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial
16:02TimMcmeh
16:02Krato`so using this and a sequence of indexes and keys would allow one to work with nested collections
16:03gfrlogKrato`: you know about get-in right?
16:04gfrlogsurely the functional nature of a set is little help in this situation
16:06TimMc,(let [n 10, f (apply partial (concat (take (dec n) (repeat partial)) [+]))] (reduce #(%1 %2) f (range n)))
16:06clojurebot45
16:06TimMc\o/
16:07gfrlogTimMc: 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:07TimMcpoint
16:07gfrlogpoint?
16:07clojurebotthe point of moby dick is "be yourself"
16:08TimMcgfrlog: that is, "you have a good point"
16:08gfrlogah okay
16:12gfrlogI 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:12gfrlog,(partial +)
16:12clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial
16:12gfrlogyeah; I was thinking maybe that would return 0
16:13gfrlogwhich would be strange.
16:16TimMcHmm, I don't see why (partial f) should throw.
16:16TimMcIt is not ill-defined -- just return f.
16:16gfrlogright
16:17gfrlogI agree that would seem better
16:17TimMc&(source partial)
16:17sexpbotjava.lang.Exception: Unable to resolve symbol: source in this context
16:17TimMc$source partial
16:17sexpbotpartial is http://is.gd/zZxzDD
16:17hiredmanI think you could argue either way, but the sort of person who uses partial is most likely to argue it should not throw
16:18TimMcThe case where I see this happening is (apply partial f args)
16:18hiredmanargs is nil
16:18TimMcyeah
16:32gfrlog,(map #(-> 10 range % class) [seq sequence])
16:32clojurebot(clojure.lang.ChunkedCons clojure.lang.LazySeq)
16:41TimMc,(doc sequence)
16:41clojurebot"([coll]); Coerces coll to a (possibly empty) sequence, if it is not already one. Will not force a lazy seq. (sequence nil) yields ()"
16:42gfrlogTimMc: will we ever know all of the clojure.core functions?
16:42TimMc,(map (juxt seq sequence) [nil () [1]])
16:42clojurebot([nil ()] [nil ()] [(1) (1)])
16:55void_what database (sql or nosql) do you use for your clojure projects?
16:57gfrlogvoid_: I have used MySQL and Couch
16:57technomancylucene
16:57void_so this REST API of couch, that sounds to me like something annoying
16:57technomancyI've only used couch from elisp, but it was very pleasant there.
16:58gfrlogvoid_: 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:58void_well I think I'm gonna compare clojure wrappers and see which one is most popular
16:58gfrlogvoid_: clutch was good I think. I didn't use it too extensively.
16:59void_gfrlog: well, I'm not. I want to build a JS app, but use WebSocket instead. (For fun, you know ;))
16:59gfrlogbut the couch API is decently simple, so clutch probably does a good job
17:00gfrlogvoid_: 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:00void_well thanks guys
17:00gfrlogyep
17:01void_is there any web app example built with clojure?
17:02cemerickgfrlog: 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:02gfrlogcemerick: I think there are some things it could do better, like url rewrites
17:02cemerick(this coming from a contributor to clutch, FWIW)
17:03gfrlogcemerick: now that I think about it more, I don't mind couch so much as I do couch-apps
17:03cemerickah
17:03cemerickthe couchapp stuff is insane IMO
17:04gfrlogI 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:04Krato`so insane in what way?
17:05cemerickThat's what happens when you nail yourself up with javascript.
17:05gfrlogcemerick: javascript is an orthogonal issue, which is remedied a bit with coffeescript
17:05gfrlogcemerick: if couch ran only clojure, I'd still have the same complaints
17:05technomancycemerick: I can see a sweet spot there if you got users to run couch locally
17:05hiredmangfrlog: syntax
17:06technomancywhich all new ubuntu installs do
17:06hiredmangfrlog: the runtime cannot be fixed by a preprocessor
17:06gfrloghiredman: right, thus "a bit"
17:06cemerickKrato`: Writing anything besides DOM glue with javascript is pretty tortuous.
17:06gfrlogtechnomancy: that turns into a security headache
17:07technomancygfrlog: you could still do plenty of useful stuff only listening on 127.0.0.1
17:07gfrlogtechnomancy: At least if you don't have a bijection between users and couch instances
17:07technomancyoh, for multiuser boxes; sure.
17:08cemerickgfrlog: true enough. The app model's quasi-political objectives get in the way of my building useful things.
17:10VT_entityhey all
17:10gfrloghey
17:10VT_entityI'm having trouble installing Clojure
17:11gfrloghave you tried leiningen?
17:11VT_entityno
17:11VT_entitythat was going to be my last resort- I usually don't like running other people's install scripts on my box
17:12gfrlogah okay then; so what do you mean by "install"?
17:12VT_entityI tried to use counterclockwise from Eclipse
17:12VT_entityit's giving me problems whenever I try to :use a library
17:12VT_entityaaand then I tried to install with git
17:13gfrlogif 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:13VT_entitybut I would also need clojure-contrib.jar, right?
17:13gfrlogif you want to use some of those libraries, yes
17:13VT_entitydon't I have to add both to my classpath somehow before I (:use (clojure.contrib...))
17:14gfrlogyeah
17:14VT_entitysee, this is where I'm getting all screwed up
17:14cemerickVT_entity: what was your particular problem with counterclockwise?
17:14gfrlogdo you know how to set up the classpath when executing the java command?
17:14VT_entityjava -cp
17:14gfrlogso
17:14gfrlogjava -cp clojure.jar:clojure-contrib.jar clojure.main
17:14gfrlogshould work
17:15VT_entityI can't import libraries while using counterclockwise
17:15VT_entitylol, I did something wrong, I'm just not sure where
17:15cemerickVT_entity: did you add the relevant jars to your project's set of libraries?
17:15VT_entitydo any of you install the git way?
17:16cemerick"git way"?
17:16VT_entityhow do I do that cemerick?
17:16VT_entityyou mean the :use command?
17:17cemerickVT_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:17VT_entitywhen I try to download from git, there isn't even a clojure-contrib.jar in the directory, just a series of .clj files
17:17cemerick(that all assumes you're not using maven)
17:17VT_entityI've tried both ways, neither has really worked for me, I screwed something up.
17:17VT_entityoooooooh no way
17:18VT_entitycemerick, I never thought to look under build path
17:18VT_entityI'm going to try that right now
17:19cemerickVT_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:38gfrlogJava doesn't have any nice library for english noun pluralization like ActiveSupport does it?
17:44technomancyjruby =)
17:50jmattgfrlog: check out inflections - http://r0man.github.com/inflections-clj/
17:53mtrelinsomethinghi there, how do i call this in clojure? public <T extends java.rmi.Remote> T getService(AdWordsService service) ?
17:54mtrelinsomethingit's expecting a "T"
17:59gfrlogjmatt: thanks
17:59Krato`hm hm.... I see c.contrib.string/replace-by doesn't allow to replace just certain groups
18:01gfrlogKrato`: maybe something like regex backreferences would do what you want? I'm not too familiar with java's regex support...
18:01gfrlogwoah
18:01gfrlogs/backreferences/lookahead-and-lookbehind
18:01Krato`I actually have the needed corde in java
18:01Krato`no those are not useful for replacing
18:02gfrlogI meant for not capturing the part you don't want to replace
18:02Krato`I know what you meant
18:02Krato`when you specify replace string in java
18:02Krato`you can say $1 or something like that
18:02Krato`and the matched group 1 is inserted into replacement string at that position
18:03Krato`however that prevents you from behing able to replace a group with the result of a function
18:04gfrlogdoesn't replace-by give you enough info to assemble whatever you need?
18:04Krato`it does in some way
18:04Krato`it would require the user to piece together the replacement string themselves
18:05Krato`especially difficult when groups are nested
18:05Krato`(a(b(c)))
18:05Krato`you wanna replace just c
18:06Krato`you need to append a minus c with the replacement for c
18:06Krato`it can get arbitrarily complicated
18:06gfrlogyep. I think that's when people start building parsers :)
18:09Krato`http://pastebin.com/SSj9JTD9
18:10Krato`little something I've made that replaces groups with the replacements, null elements meaning group doesn't get replaced
18:11Krato`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:12Krato`when I say functions I mean IFn-like interface instances
18:40Krato``hmmm
18:40Krato``(defn string-sum [s]
18:40Krato`` (reduce #(+ %1 (- (.numericValue ^Character %2) (.numericValue \A))) 0 s))
18:40Krato``why does this make 2 reflection warnings, both for numericValue
18:41Krato``I've typehinted one and the constant can't be typehinted
18:42Krato``oh
18:42Krato``never mind