#clojure log - Nov 11 2012

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:23 akr: Hi! How can I add extra jars in java classpath?

0:23 I am using leiningen

0:24 A SO thread mentioned that if I should create a lib/ directory and put my jars there they will be automatically available

0:28 akhudek: akr: did you try that? I suspect it's correct, though I was under the impression that the lib directory was cleared out when you do a lein clean. Perhaps that's changed with lein2 though.

0:29 I usually just install jars into my local maven repository.

0:29 with this http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

0:30 akr: I will try to put them in local m2 repo

3:33 Inst: does anyone use haskell here?

3:33 how does clojure compare to haskell?

5:07 doomlord: does clojure have a predicate to tell if 2 variables are of the same type; and possibly by extention to tell if a collection is homogeneous

5:10 dspp: ,(instance? clojure.lang.Sequential [])

5:10 clojurebot: true

5:10 wingy: i dont think that was what he wanted

5:11 he wanna look if "a" and "b" is of the same type

5:15 dspp: yeah, i know

5:15 ,(instance? clojure.lang.Sequential [] [] [])

5:15 clojurebot: true

5:15 dspp: ,(instance? clojure.lang.Sequential [] [] \t)

5:15 clojurebot: true

5:15 dspp: (type [])

5:15 ,(type [])

5:15 clojurebot: clojure.lang.PersistentVector

5:16 dspp: ,(every? #(instance? clojure.lang.PersistentVector %) '([] [] [] [] \c))

5:16 clojurebot: false

5:16 dspp: ,(every? #(instance? clojure.lang.PersistentVector %) '([] [] [] [] []))

5:16 clojurebot: true

5:16 dspp: tadaaa

5:37 pyr: hi

5:37 Is the process for submitting to sub-projects the same than for clojure ? (i.e: JIRA + contributor agreement ?)

5:38 I have a PR for tools.cli

5:55 doomlord: ,(typeof "foo")

5:55 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: typeof in this context, compiling:(NO_SOURCE_PATH:0)>

5:55 doomlord: ok instance and type do it

6:19 sunkencityryleh: is there some way I can filter for not nil without writing (filter #(not (nil? %)) arr)

6:20 shachaf: What don't you like about writing that?

6:20 (comp not nil?) == #(not (nil? %))

6:21 edlothiol: (remove nil? arr)

6:21 (filter (complement nil?) arr)

6:21 sunkencityryleh: ah, that's better

6:21 shachaf: That works.

6:21 jakubH: nil is interpreted as false so also this would work

6:21 ,(filter identity [1 nil 3])

6:21 clojurebot: (1 3)

6:22 jakubH: though there are certainly nicer ways

6:22 remove is nicer

6:22 sunkencityryleh: remove makes it as simple as it should be

6:23 thanks

6:30 I want to find the smallest thing in a list with a function. I can do this with apply (apply min-key #(Math/abs %) [-3 1 4]), but how can I transform the code so that it doesn't bork on an empty list? I could use if of course, but is there some other way?

6:33 raek: sunkencityryleh: what is the smallest value of the empty list? :)

6:33 sunkencityryleh: one way could be to add a smallest possible value to the collection

6:35 another way could be to make a check for the empty list and return a special value

6:35 sunkencityryleh: raek: yep, i'm checking for empty list now, because I have to handle it specially anyway I just realized

6:36 raek: (defn smallest-number [coll] (if-not (seq coll) :no-such-value (apply min-key #(Math/abs %) coll)))

6:36 (defn smallest-number [coll] (apply min-key #(Math/abs %) (cons 0 coll)))

6:37 sunkencityryleh: yep, Im going with the if-not thing

6:37 raek: "(if (empty? coll) ..." looks slightly better...

6:37 sunkencityryleh: writing a textile -> hiccup tool so I need to find next closest token

6:37 clojurebot: hiccup is http://tinyurl.com/426og7n

7:05 Netfeed: hi, i have these two macros: http://pastebin.com/avf6zz4W and i have a "problem", i'd like to define a function (defn select-first [sql & binds] (first (select sql binds))), but it doesn't work, this works though (defmacro select-first [sql & binds] `(first (select ~sql ~@binds))) but it feels overkill, how can i get the first case to work?

7:12 hcumberdale: cemerick not here ;(

7:14 joegallo: Netfeed: Since you've defined it as sql & binds, you'd want to (apply select sql binds) so that the binds would be carried through correctly.

7:14 However.

7:14 You can't do that with a macro since apply works on functions, no macros.

7:15 Netfeed: oh, so i have to stick with the latter?

7:16 joegallo: It works, it's not wrong to do it that way. I'd recommend you carry on with writing useful software and not worry about it. ;)

7:16 Netfeed: heh, ok, thanks

7:16 joegallo: That said, it's a fine demonstration of the infectious nature of macros, so maybe make a note of that.

7:18 Netfeed: but it's so handy :)

7:19 hcumberdale: I can't catch slingshot exceptions, don't know why

7:19 tried a lot,... (try+ (catch Exception e _ ...

7:19 (try (catch Exception e _

7:19 ...

7:21 https://www.refheap.com/paste/6538

7:21 any ideas?

7:28 joegallo: i think they're throwables, not exceptions?

7:32 hcumberdale: joegallo how to catch them?

7:32 joegallo: (catch Throwable t ...)

7:33 That said, that would be hugely overkill.

7:33 hcumberdale: Lets try

7:34 joegallo: Maybe peek around cemerick's library and see what he does? Catching Throwable is almost certainly not what he intends, and it's certainly not what Steve G intended with slingshot.

7:34 You're supposed to catch it based on the contents of the thrown map, per the documentation on slingshot.

7:34 hcumberdale: Yes joegallo! But friend does not behave as expected

7:34 When I browse a route like /user and I am not logged in the exception/throwable is fired

7:35 But it does not get caught

7:35 no ":unauthorized-handler" is called

7:36 it seems it does not care if there is such a handler or not

7:36 (catch Throwable e (print "NOT AUTH!"))) << also throws the exception

7:37 It does not get caught

7:38 joegallo: I'm guessing your catch expression isn't in the right location, then.

7:48 ro_st: is there a way to get a seq of all a fn's args from inside the fn body without using :as in the arg vector?

8:17 ambrosebs: ,(instance? clojure.lang.Sequential [] [] [])

8:17 clojurebot: true

8:17 ambrosebs: wtf?

8:18 Why doesn't this throw an arity error?

8:19 There's probably some inlining deep in the Compiler for instanceof optimisation.

8:20 Well, there is, but not sure if that's the issue.

8:21 Seems like a known issue http://stackoverflow.com/questions/13176400/clojure-instance-single-argument

8:24 joegallo: appears to me that instance? is defined in terms of the relatively primitive fn at line 42 of core.clj, rather than the more featureful fn defined at line 3989

8:24 so yeah, no arity checking

8:24 at least, that's my quick read of it

8:28 hcumberdale: mhh

8:29 (defroutes ring-app

8:29 ;; requires user role

8:29 (compojure/context "/user" request

8:29 (try (friend/wrap-authorize user-routes #{::user})

8:29 (catch Throwable e (print "NOT AUTH!"))))

8:29 The exception should be thrown by wrap-authorize?

8:29 right

8:30 ?!

8:30 https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj#L302

8:30 joegallo: or does wrap authorize return a fn that will later do the checking?

8:30 that appears to be what it does, based on what you linked me to

8:30 sooo... yeah, wrong spot.

8:31 hcumberdale: why wrong spot?

8:31 it calls throw-unauthorized

8:31 joegallo: no it doesn't.

8:31 it returns a fn that will do so later.

8:31 well outside of the context of your try/catch.

8:31 hcumberdale: where exactly does that happen

8:31 ambrosebs: joegallo: I think the stackoverflow answer has the right idea. The compiler emits an InstanceOfExpr without checking the number of arguments to instance?

8:31 joegallo: line 299

8:32 a defn that return a fn

8:32 hcumberdale: yeah, i've seen that. But where is it evaluated?

8:32 joegallo: hcumberdale: i'm sure i don't know, somewhere else in the bowels or your app

8:32 s/or/of/

8:33 ambrosebs: sure, sounds reasonable.

8:34 hcumberdale: joegallo, but then it seems like a bug in friend

8:34 joegallo: no, that's how ring works

8:35 hcumberdale: but why is default-unauthorized-handler not called

8:35 since it is build to catch unauthorized requests

8:36 https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj#L196

8:36 Why must a user be auth'ed to call the unauthorized-handler ?

8:37 Also redirect-unauthorized does not work

8:37 The exception bubbles up, no handling by friend as it is expected

8:37 flying_rhino: hello guys

8:37 hcumberdale: hi flying_rhino ;)

8:38 joegallo: hcumberdale: i think you need to also be calling authenticate somewhere -- which i'm not sure you are. you keep pointing to parts of it, but it doesn't appear that it's ever called as a result of wrap-authorize (i think).

8:39 it seems like your pretty lost here, and i've never read or worked with friend before, so my suggestion is that you look for some existing code elsewhere that uses friend that you can use as an example

8:39 hcumberdale: I'll refheap the whole program, sek

8:40 joegallo: or that you wait for cemerick to come on and see if he can give you a hand

8:40 hcumberdale: https://www.refheap.com/paste/6540

8:40 joegallo, i searched for existing applications. Can't find any

8:41 that work with compojure as in the examples and with wrap-auth...

8:41 joegallo: i think wrap-authorize is only for when you've already used authenticate as earlier middleware

8:41 which you haven't

8:41 hcumberdale: https://www.refheap.com/paste/6540#L-42

8:41 joegallo: but again, this is my very first read of this library, which i've never used, so yeah...

8:41 hcumberdale: I've

8:42 joegallo: okay, missed that. anyway, best of luck, but i've got nothing.

8:42 hcumberdale: ./ping cemerick << yesterday he said bbl. Haven't seen him since then

8:44 flying_rhino: anyone ever tried to implement immutable entity systems in clojure?

8:44 hcumberdale: flying_rhino like datomic ?

8:47 flying_rhino: I don't know what is datomic, but Component Entity System is, in short, extremely data driven method of developing games. You have bunch of structs (components) that you manipulate using Systems. It looks a little like relational database and separates data from code.

8:48 It is usually done in mutable languages

8:48 *imperative languages

8:49 this link explains the whole thing http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/

8:49 hcumberdale: Is there such an existing sytem for LISP?

8:50 flying_rhino: it is popular for mmorpgs, but can be used for other games as well.

8:50 dunno

8:50 I could implement one but I am asking around first.

8:51 on the face of it it does look like immutability could help a lot but I am far from experienced functional programmer.

8:53 hcumberdale: joegallo, got it working

8:53 ;)

8:53 what is a mmorpg for example?ß

8:53 wow?

8:53 joegallo: hcumberdale: what was it?

8:54 also, nice work!

8:54 hcumberdale: joegallo, i am not sure ;(

8:54 joegallo: argh

8:54 hcumberdale: done lein2 clean and lein2 run

8:54 and the code I posted runs 1:1

8:54 crazy ;(

8:55 joegallo: i feel totally unsatisfied :)

8:57 hcumberdale: had the same problems before with another lein2 project

8:58 but it was not the auth that lagged

8:58 joegallo: oh, maybe you're getting killed by aot?

8:58 and that classes you're aoting are stale and out of date wrt the clj files you're editing?

8:59 hcumberdale: http://stackoverflow.com/questions/8291910/noclassdeffounderror-with-clojure-tools-logging

8:59 Had the same issue, lein clean, and then lein deps, and then lein compile fixed it

9:00 This whole AOT thing sucks

9:00 wink: classic: writing (> 0 x) instead of (> x 0) and then reading up on the clojure type system for 30min, questioning sanity

9:01 callen: hcumberdale: remember, you *could* be wrangling with cabal.

9:01 wingy: datomic supports couchbase!

9:01 callen: wingy: I won't use it until it supports kyoto cabinet.

9:02 wingy: sounds exotic

9:02 callen: thats_the_joke.jpg

9:03 wingy: i just know one thing

9:03 no aws!

9:03 hcumberdale: Why wingy?

9:03 Because of the big aws fallout ;)

9:04 callen: you say that as if there was only one.

9:04 hcumberdale: I've seen only one callen

9:04 callen: AWS US-East has gone down many times.

9:04 wingy: because they do everything

9:04 hcumberdale: my blog was down, hosted on heroku

9:04 wingy: but nothing innovative

9:04 callen: The real trick is to just let US-East continue to vanguard the scalability issues

9:04 and just use US-West or something other AZ

9:05 hcumberdale: But it's not possible to choose with heroku

9:05 + mongohq, they are also using aws

9:05 callen: hcumberdale: your choice of master for your sharecropping isn't my problem.

9:05 ferd: Is there something similar to "tree-seq" but parallelizable? (therefore, non-lazy)?

9:05 ...that is, I want it to call my "children" function in parallel to keep expanding the tree concurrently

9:05 callen: I'm just making it explicit that it isn't the entirety of AWS that goes down, it's usually just US-East which is a detail that can be exploited.

9:06 hcumberdale: callen, thx for the info

9:06 US-West = same price as US-East ?

9:07 callen: hcumberdale: mostly yes, if you mean Oregon

9:08 Northern California is slightly more expensive.

9:08 hcumberdale: Have you production applications running on aws?

9:08 callen: If you're using AWS, caring about expense is a bit like caring about getting wet while swimming across the channel.

9:08 hcumberdale: ;)

9:08 callen: hcumberdale: I've built more than one production system on AWS, although I try to use it as little as possible these days.

9:09 hcumberdale: callen: what's the best alternative?

9:09 callen: that's like asking what's the best car.

9:09 Depends entirely on what you're doing. There are still some use-cases that AWS is superior at.

9:10 for my part, I favor a mix of VPSs and renting dedicated hardware.

9:11 hcumberdale: yes callen, I think that's a good idea and you might reach less outtakes

9:11 But you have to worry about to OS/Updates/Maintenance

9:11 Evil bad hackers ;)

9:11 callen: what you just said makes no sense.

9:11 nothing about that changes when you're using AWS.

9:12 you do understand that EC2 is just a VPS, right?

9:12 evil bad hackers. *snorts*

9:12 hcumberdale: But when you use heroku and services over EC2, they care for you

9:13 cmn: but that's something different; you were asking about AWS, not heroku

9:13 IIRC engineyard provide a similar service and are based on rackspace

9:13 hcumberdale: Heroku is based on AWS so server failure effects both

9:14 cmn: yes

9:14 but that wasn't the conversation

9:14 callen: that also means that if AWS goes down, you're fucked anyway, heroku or no.

9:14 hcumberdale: ;) yes.

9:14 http://www.engineyard.com/ << no clojure

9:14 callen: it was with extreme pleasure that I was one of the few startup people I knew that didn't experience any downtime during the AWS blip.

9:15 cmn: heroku are starting to roll out some servers on the west coast

9:15 callen: hcumberdale: ...and? Nobody's trying to sell you on anything in particular.

9:15 hcumberdale: own servers cmn?

9:15 cmn: no

9:15 callen: heroku isn't going to stop using EC2.

9:15 Their devops infrastructure is heavily tied into it.

9:15 they're stuck with Amazon.

9:16 incidentally this is why I refused to use AMIs when I used AWS more heavily. It meant that switching away was just a matter of repointing scripts, instead of having to rebuild the automation stack.

9:18 hcumberdale: mhh..

9:18 Is there any real competitor to EC2/AWS?

9:18 callen: bits and pieces.

9:19 Rackspace, Azure in the large. In the small, Linode et al.

9:19 cmn: but it all depends on what you need

9:19 callen: There are plenty of companies that offer one-off things like MongoHQ that are analogous to AWS RDS.

9:19 hcumberdale: Rackspace cloud is really new, isn't it?

9:20 cmn: and what if it isn't?

9:20 AWS isn't new

9:20 callen: hcumberdale: do you have something in particular you are aiming for?

9:22 hcumberdale: callen, just want to hear about your experience with the solutions/providers. I've discovered the problems with heroku/mongohq and AWS a few weeks ago

9:22 callen: your needs seem pretty low level. You could truck along with "whatever" for hosting a blog.

9:22 Licenser: hcumberdale joyent

9:22 wink: I've been bitten by AWS performance once, badly. Still a bit cautious to see the positive aspecs :(

9:25 hcumberdale: Yes the requierements for a blog are really low-level. I'm interested in big applications running on EC2

9:25 Seems to most hosting companies tend to sell vservers now as 'cloud'

9:25 Licenser: should take a look http://joyent.com/ :) they are pretty awesome

9:25 callen: I've built big clusters, but I need something specific to really be able to tell you what's up and down.

9:26 I'm not going to exposit aimlessly in IRC about what I do and do not like about AWS.

9:28 hcumberdale: Never heard about joyent, website looks interesting. Licenser, have you any clojure applications running there?

9:29 Licenser: hcumberdale nope but I am using the underlying hypervisor for my stuff - where I also run java applications (just no clojure)

9:29 but java works great and so should clojure then

9:35 jonasen: I'm trying to release a new version of Kibit but I seem to have messed up. Could someone try the new [lein-kibit "0.0.5"] and see if it works?

9:38 wink: jonasen: $ lein kibit Check :dependencies and :repositories for typos. It's possible the specified jar is not in any repository. If so, see "Free-floating Jars" under http://j.mp/repeatability Could not resolve dependencies

9:39 $ cat ~/.lein/profiles.clj

9:39 {:user {:plugins [[lein-kibit "0.0.5"]]}}

9:55 pyr: wouldn't it be cool to have a ns construct that would let you pull in a standard config (require's, use's, import's etc)

10:02 joegallo: pyr: http://code.google.com/p/clj-nstools/

10:03 pyr: ah, nice

10:04 jonasen: wink: I think I got it working now, could you try [lein-kibit "0.0.7"] instead?

10:05 wink: jonasen: yes, and the results hurt my feelings! :)

10:05 good reminder to use it on this project

10:05 jonasen: wink: Thanks alot!

10:07 pyr: joegallo: for that type of functionality I would be hesitant to bring in a new dep

10:08 joegallo: then i guess you don't get that functionality. :(

10:08 pyr: yup

10:12 _ulises: ,(doc list*)

10:12 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

10:12 _ulises: ,(doc list)

10:12 clojurebot: "([& items]); Creates a new list containing the items."

10:13 _ulises: ,(list? (list* (set '(a b c))))

10:13 clojurebot: false

10:13 _ulises: hum

10:13 ,(list? (list (set '(a b c))))

10:13 clojurebot: true

10:13 _ulises: ,(list (set '(a b c)))

10:13 clojurebot: (#{a c b})

10:13 _ulises: (set '(a b c))

10:14 ,(set '(a b c))

10:14 clojurebot: #{a c b}

10:14 _ulises: ,(list* (set '(a b c)))

10:14 clojurebot: (a c b)

10:14 _ulises: sorry for spam

10:14 raek: the name for list* is a bit misleading. it produces an ISeq, not an IPersistentList

10:15 _ulises: oh!

10:15 raek: thanks!

10:15 raek: (list* x y z some-seq) is like (cons x (cons y (cons z some-seq)))

11:31 si14: hi, guys. Is there any example of Java usage from Leiningen repl?

11:32 Licenser: si14 I think it's the same as in all clojure

11:32 a simple example would be (System/exit 0)

11:33 si14: Licenser: I don't understand the thing with Classpath and such.

11:33 Licenser: ah okay, that kind of stuff, to be honest - I've no clue :(

11:34 ChongLi: si14: what don't you get about classpath?

11:34 si14: ok, I've added project.clj; added java-source-paths to it; I have foobar.java in that path and when I do something like (import Foobar) I get "no such file"

11:35 ChongLi: I think you need to compile your java first

11:35 into a jar

11:40 _ulises: si14: not just that, you have to import packagename.othername.ClassName

11:42 si14: oh, I've managed to make it work! :) updated Lein and lein javac did the work.

11:43 _ulises: well, what if have just a simple class in my java-source-paths (no packages there)? it seems to work as (import 'TOTP) and (TOTP/main (into-array String [])) , am I missing something?

11:44 _ulises: si14: that should work too, but remember that the default package in Java is discouraged

11:44 augustl: is it possible to create a map where the values are eval-ed when read?

11:45 si14: _ulises: so I should create some directory structure, rename my class and import it under that name?

11:45 augustl: perhaps something that implements IPersistentMap

11:46 _ulises: si14: I'm not saying you *should* do anything :)

11:46 si14: just regurgitating what I know and have read

11:47 augustl: you could have closures as values? and then just call them as fns?

11:47 ,((:foo {:foo (fn [] "foo")}))

11:47 si14: _ulises: you definitely have more knowledge than me in this field, so your advices counts as something I should do :)

11:47 clojurebot: "foo"

11:48 _ulises: si14: well, the default package name is discouraged in java (standard practise) but this doesn't mean you shouldn't do it; I'd probably advise you to organise your code using packages and namespaces mainly because you'll be reading that code later on and will thank your former-self

11:50 si14: _ulises: got it, thanks :)

11:52 _ulises: si14: sure

12:06 konr_trab: What's that function that is like comp but from left to right?

12:07 jackdanger: konr_trab: are you looking for `partial`?

12:07 konr_trab: jackdanger: hmm, I think not...

12:10 _ulises: konr_trab: what are you trying to achieve?

12:11 konr_trab: _ulises: I'm just writing a composite function to be used in a map; it's more convenient to append its posterior functions to the right

12:12 augustl: _ulises: ended up using delays, based on your suggestion, thanks :)

12:13 _ulises: augustl: cool!

12:13 konr_trab: so you'd need to reverse the flow to use comp?

12:13 augustl: _ulises: I'll hopefully get to present this to the unconference, if you're going to the conj ;)

12:13 _ulises: augustl: neat! I can't make it this year though :(

12:14 augustl: aww

12:14 konr_trab: _ulises: yes, and I thought there was already a function for it

12:14 _ulises: konr_trab: not sure there is unfortunately

12:46 erwagasore: I am doing koans and I am stuck on multimethod, need help to understand?

12:47 Anybody!

12:47 tomoj: anyone?

12:47 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

12:48 gauravag: could someone help me in understanding this >> "(iterate f[x] :foo)"

12:48 erwagasore: Here is the function

12:49 (defmulti diet (fn [x] (:eater x)))

12:49 (defmethod diet :herbivore [a] (str "$1 eats veggies." a))

12:49 (defmethod diet :carnivore [a] (str "$1 eats animals." a))

12:49 (defmethod diet :default [a] (str "I don't know what $1 eats." a))

12:49 and this is how I am calling it (diet {:species "lion" :name "Simba" :eater :carnivore})

12:50 what would be the enswer?

12:50 gauravag: erwagasore: isn't this from clojure koan

12:50 s*

12:50 am doing that just now..

12:50 erwagasore: gauravag yes it is!

12:50 Great, can u share?

12:51 tomoj: the dispatch value is (:eater {:species "lion" :name "Simba" :eater :carnivore})

12:51 erwagasore: Just want to understand. Everything I am putting is not passing the test.

12:51 tomoj: :carnivore

12:52 but str doesn't do interpolation like that

12:52 gauravag: (diet {:species "lion" :name "Simba" :age 1 :eater :carnivore})

12:52 "Simba eats animals."

12:52 tomoj: also, the argument to the methods, a, is the map

12:53 erwagasore: gauravag does it work?

12:53 tomoj: you need to get the :name out

12:53 gauravag: it worked for me..

12:53 I am on

12:53 **ex 14 by the way

12:54 tomoj: use str like this: (str "foo's value is:" foo)

12:54 erwagasore: No it is the example 09

12:54 tomoj: no $ interpolation

12:54 gauravag: (defmethod diet :carnivore [a] (str (get a :name) " eats animals."))

12:55 erwagasore: That is not what I have

12:55 (str "$1 eats animals.")

12:56 tomoj: you gave him the answer :(

12:56 erwagasore: What do u mean?

12:57 Oh!

12:57 Hahahahahaha!

12:57 tomoj: note (= (:name a) (get a :name))

12:58 gauravag: tomoj: oops..

12:58 tomoj: well, only part of the answer

13:00 gauravag: but I think this is the part where the power of defining dsl's is most prominent in clojure

13:09 rodnaph_: with enlive is it possible to do multiple transformations in a single match? ie. [:div.foo] [(content "this) (set-attr "that")] (but that doesn't work obv)

13:11 tomoj: gauravag: (iterate f[x] :foo) looks like an error

13:12 gauravag: tomoj: what would be the correct way?

13:12 tomoj: dunno what it's trying to do

13:12 gauravag: (take 100 (iterate (fn [x] :foo) :foo))

13:12 tomoj: oh

13:13 raek: rodnaph_: well, you could repeat the selector like this: [:div.foo] (content "this) [:div.foo] (set-attr "that")

13:13 gauravag: which prints a set of 100 :foo

13:13 tomoj: i.e. (repeat 100 :foo)

13:13 ebaxt: rodnaph_: You can use the do-> macro

13:13 gauravag: yup.. but I wanted to try it using iterate..

13:13 raek: if the transformation functions always return a single new node maybe you can use 'comp': [:div.foo] (comp (content "this") (set-attr "that"))

13:14 gauravag: but the redundant mention of :foo din't seem right to me..

13:14 tomoj: (fn [x] :foo) is also (constantly :foo)

13:14 well (iterate identity :foo) works too

13:14 * raek has a feeling that he's not using enlive in a typical way

13:15 gauravag: tomoj: awesome.. so what is identity?

13:15 tomoj: (fn [x] x)

13:15 gauravag: in that context am I passing identity procedure with a parameter :foo inside iterate?

13:16 tomoj: yeah

13:16 (iterate identity :foo) is a seq (:foo (identity :foo) (identity (identity :foo)) ...)

13:16 rodnaph_: ebaxt: will try that thanks.

13:17 gauravag: tomoj: cool.. many thanks.. :)

13:36 dissipate: hi

13:39 gauravag: what is the clojure way of solving this?

13:39 (= "Rich Hickey aka The Clojurer aka Go Time aka Macro Killah"

13:39 (let [[first-name last-name & aliases]

13:39 (list "Rich" "Hickey" "The Clojurer" "Go Time" "Macro Killah")]

13:39 (str first-name " " last-name (for [alias aliases] (" aka " alias)))))

13:46 erwagasore: (iterate __ :foo)

13:51 ivan: how do I nrepl-load-current-buffer when I have a new nREPL connection?

13:51 it always says "Namespace not found" until I close and reopen the .clj file

13:56 Sgeo: How do I make a .DLL visible to my Leiningen project?

13:59 ivan: hm, why is it that when I do (ns otherns) and then (ns user) in nREPL, I lose everything I've added to user?

14:00 oh, I think it's just spitting old exceptions at me now

14:00 oh, duh. never mind.

14:01 debugging lack of pst by calling (pst)...

14:05 in other news I've been so braindamaged by Python that I thought I'd be able to do (user/pst) from another namespace after (use)ing it in user

14:25 sjl: Is slurp supposed to add a trailing newline even if the file doesn't contain one, or is that a bug?

14:27 AimHere: It doesn't do it for me

14:27 Clojure 1.4

14:28 sjl: hm

14:28 maybe Vim is messing with me then

14:43 Sgeo: http://clojuredocs.org/clojure_core/clojure.core/locking

14:43 What is the "monitor" of a thing, and how do I know if an object has one?

14:45 mudge: anybody here know how to use fs.compression/zip ?

14:46 or how do I zip compress files using clojure? is there an existing clojure library for this?

15:04 augustl: mudge: I'd just use a java lib for that

15:08 joro: I've repeatedly end up constructing maps like ... (if (is-good e) (assoc m :e e) m). Is there better way to do this?

15:08 callen: joro: well you could make a predicate assoc function that passes a predicate checker and automatically returns the assoc'd map if the predicate returns true

15:09 joro: in a less abstract fashion, if it's a common pattern for specific data, you can just abstract the concrete form of this.

15:09 joro: some specifics about how frequent this is, how much the patterns have in common, etc would be helpful.

15:13 joro: I'm transforming stuff in mongodb on a wire. There is lot of stuff that resembles like this: (if (> new-comments 0) (assoc bare-ex :newComments new-comments) bare-ex)))

15:14 I was wondering that if there is a binding form (like map destructuring) that would make this easier

15:20 tomoj: (test-> bare-ex (> new-comments 0) (assoc :newComments new-comments))

15:20 in 1.5.0-beta1

15:23 callen: joro: are you looking for something like what tomoj demonstrated, or something else? please be specific.

15:26 bbloom: test-> is extremely useful!

15:27 saw cond-> in codeq, which i think is basically the same thing. said to myself: "why the hell didn't i think of that?" :-)

15:29 joro: what is the third argument of test->?

15:34 sunkencityryleh: mmmm… multimethods. cleaning up some code with multi methods. this is good stuff.

15:35 callen: sunkencityryleh: example? :D

15:35 sunkencityryleh: also, love the name.

15:36 Sgeo: Suppose I'm writing an event-based library

15:36 Would it make sense to expose to event handlers a *stop-handling* function that they can call to remove itself from the list of event handlers?

15:37 sunkencityryleh: callen: I had an array of hashes and a fn as one of the keys, now I have the methods separate and just switch on a key. I send in the same hash but I have added some match data to it. This is beginning to look like pythons OO.

15:41 callen: Sgeo: I hate to punt the ball like this, but this is something you'd really want to look into by examining Lamina.

15:42 my initial instinct is "no" unless a specific use-case cries out for it.

15:43 Sgeo: Pretty sure that some use cases cry out for a nice way to have an event handler remove itself, but not sure if that's the best way to do it

15:43 ivan: Sgeo: well, what else could you do?

15:44 Sgeo: I could pass the function into the handler like an argument, or I could just have the function I call to set up the handler return the function to stop handling, and whenever I want a handler to remove itself, use promises to make it accessible to the handler

15:45 Last one's inconvenient to use raw but could be a building block'

15:45 raek: Sgeo: I think so. some network protocols have commands that form temporary "dialogs". in those cases you might want to use a state machine that listens for certain commands, but only for a limited lifetime

15:46 one example is the IRC login process

15:46 Sgeo: I'm thinking more ... IRC-bot-like thing except for a particular 3d world

15:47 ivan: this could become a mess with code reloading

15:47 Sgeo: Ah, hmm

15:47 raek: I like how IObservable does it in .net: when you subscribe you get an instance of IDisposable back. when you call dispose on it, it deregisters the callback

15:48 no need to carry around ids/keys like in Clojure's add-watch/remove-watch

15:49 Sgeo: What sees the IDisposable?

15:50 raek: the code that registers the callback

15:50 Sgeo: Ah

15:50 Well, the question is how to make the callback itself be able to deregister itself

15:50 It's easy enough to return to the registrating code a function that will deregister the callback

15:50 raek: ah

15:51 in Haskell, you could let the callback close on the result of the subscribe operation :)

15:52 but in Clojure variable bindings have to be causal...

15:54 Sgeo: what is your library like compared to Lamina, Cljque, and RX in .Net?

15:55 Sgeo: Haven't looked at Cljque

15:56 There's an event for when someone says something, an event for when someone joins, someone leaves, etc. etc.

15:56 Someone clicks something

15:58 raek: I wonder if anyone has made a Clojure library for Functional Reactive Programming...

15:59 mudge: how do a load a file from disk into a lazy byte array?

16:00 raek: mudge: Clojure (and Java) does not have any type for lazy byte arrays. you could make a lazy sequence of bytes, though...

16:01 mudge: raek: thanks

16:01 callen: mudge: why does it need to be lazy?

16:01 mudge: callen: well I need to read a file into a byte array --- if the file is large then I need to load the entire file into memory, but if it is lazy then I don't

16:02 callen: that's my theory anyway

16:02 Sgeo: Even Haskell discourages lazy I/O

16:02 mudge: Sgeo: why?

16:03 raek: mudge: how will you process the bytes?

16:03 mudge: anyway, if you need a lazy byte seq, you can do it like this: https://gist.github.com/661631

16:03 Sgeo: mudge, because the time of closing the file might be unknown, what if you close it too early, or never close it, etc.'

16:03 mudge: reak: I'm making one zip file of various files.

16:03 raek: pass it an input stream, for example one created by clojure.java.io/input-stream

16:04 in Clojure you can wrap the whole code that will potentially touch the seq in a with-open form

16:05 the problem lies in the "that will potentially touch the seq" of course...

16:08 Sgeo: does Haskell discourage lazy I/O in general or only "lazy resource management"?

16:08 Sgeo: raek, hmm, not sure

16:09 mudge: what's the best way to read a binary file into a byte array?

16:10 raek: mudge: use the methods of the java.io.InputStream class

16:10 mudge: Raek: okay, thanks

16:13 raek: mudge: you can use the gist I linked previously as an example. just replace the (lazy-cat ...) part with whatever you need to do with the bytes

16:13 tomoj: (let [out (java.io.ByteArrayOutputStream.)] (io/copy in out) (.toByteArray out))

16:13 ??

16:13 lazybot: tomoj: Definitely not.

16:14 augustl: any suggestions for a in-process database that stores to a specified path in a local file system?

16:14 datomic free fits that description, right?

16:14 mudge: raek: can you send me the URL again?

16:14 tomoj: datomic free is not exactly in-process

16:14 augustl: new to the JVM so not sure what's available

16:14 tomoj: the free transactor is a separate process

16:14 raek: mudge: sure: https://gist.github.com/661631

16:14 augustl: tomoj: hmm, I thought the transactor local storage was in-process

16:14 ah I see

16:15 tomoj: in process you only get memory 'storage'

16:15 raek: tomoj's version does the same thing, but reads the whole file into one big array

16:15 mudge: are you using the java classes for the zipping?

16:15 augustl: tomoj: I see

16:16 mudge: raek: I am via this library: https://github.com/Raynes/fs/blob/master/src/fs/compression.clj

16:16 tomoj: theoretically you should be able to run the free transactor in the same process, I think

16:16 but it is not supported yet

16:16 mudge: raek: i'm using the file system clojure library

16:16 tomoj: you don't get a pom for the free transactor

16:17 mudge: reak: for zipping I have to get the bytes of each file and associate it with a file name

16:17 augustl: tomoj: hmm I see

16:17 tomoj: I'll be shipping uberjars/uberwars so a pom isn't that important actually

16:17 raek: mudge: wait, there's a better example in the clojure source: https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/io.clj#L296

16:17 augustl: it's a standalone application that you just start with java -jar ...

16:17 Somelauw: I just installed leiningen through package manager, but what does it need a lot of dependencies?

16:18 mudge: thanks raek

16:18 Somelauw: also it needs clojure as a dependency, whereas its goal is to install leiningen

16:18 tomoj: augustl: well, you could try adding all the jars in the transactor lib/ (manually - no pom), and then you'd have to figure out how to start it

16:18 raek: mudge: using the java api (which fs uses) you can do this by looping and reading/writing fixed sized arrays

16:18 augustl: tomoj: I'll investigate, thanks

16:19 mudge: raek: so that the entire file doesn't have to be read into memory?

16:19 at the same time

16:19 raek: mudge: yes

16:19 mudge: raek: that sounds good

16:20 tomoj: looks like there is a transactor pom hidden in datomic pro

16:20 raek: mudge: I'm not sure if/how 'fs' can do this. Raynes (the author) is frequently in this channel, so maybe you can ask him directly

16:21 mudge: raek: okay, thanks

16:21 Raynes: you around?

16:21 raek: mudge: you can probably find an example that does what you want written in Java somewhere and then translate it into Clojure

16:22 mudge: raek: that is a good idea, I'll search for that now

16:23 raek: mudge: the approach would basically look like this:

16:23 amalloy: man, java.util.zip. what a mess

16:23 raek: yeah...

16:24 open output zip file. for each file: open input stream from file, open output stream to zip entry, copy data in chunks (clojure.java.io/copy does this)

16:24 mudge: raek: amalloy: seems like the best zip function would be a function that takes a filename and a directory name and zips everything in the directory to the file name

16:24 amalloy: mudge: why bother if you want something that generic? just shell out to tar+gzip, or zip, or whatever

16:25 zipping directories is a solved problem :P

16:25 raek: mudge: if you can rely on certain executables being available where you run the progeam, perhaps it's simpler to just use an external program

16:25 amalloy: (but i bet you apache commons io has a decent java solution)

16:25 mudge: raek, amalloy, yea sounds good

16:27 amalloy: is apache commons in the maven website repository?

16:27 sorry if I sound silly, i'm just getting into all this

16:27 amalloy: certainly

16:28 most reasonable java libs are, and especially those run by the people who run maven

16:31 raek: mudge: an example of how to use the zip classes (in Java): https://gist.github.com/4056327

16:31 Somelauw: When doing % lein run

16:31 raek: it only writes a single file, but I think you get the idea

16:31 Somelauw: "No :main namespace specified in project.clj" is what I get.

16:32 mudge: raek: i get the idea, thanks

16:34 Somelauw: nvm, I think I got it to work

16:35 Well I added to project.clj ":main myproject.core", so that should work?

16:36 But I get Exception in thread "main" java.lang.RuntimeException: java.lang.ClassNotFoundException: myproject.core

16:38 fixed it

16:38 raek: Somelauw: and you have a file called src/myproject/core.clj ?

16:39 callen: is anyone here familiar with the template inheritance structure Refheap uses with Stencil?

16:39 I'm finding it a little difficult to track everything that's going on.

16:39 Somelauw: raek: yes, i only forgot to create a -main method in that file

16:39 or actually I named it main- instead

16:40 sunkencityryleh: Just finished a little clojure project for converting textile to hiccup. It *seems* to work, but I'll have to test it out for real.

16:40 callen: sunkencityryleh: write a fuzzer.

16:40 sunkencityryleh: I'd love to get some feedback on what I could do better in the code

16:40 https://github.com/sunkencity/dr-textile-and-mr-hiccup/blob/master/src/dr_textile_and_mr_hiccup/core.clj

16:40 callen: sunkencityryleh: oh that explains the multimethods. But seriously, write a fuzzer that generates valid textfile.

16:41 textile*

16:41 sunkencityryleh: what's a fuzzier?

16:41 callen: sunkencityryleh: http://en.wikipedia.org/wiki/Fuzz_testing

16:41 I use it all the time in my unit-testing. It bares a measure of resemblance to how QuickCheck works, although it's a lot more specific.

16:42 sunkencityryleh: ah, like the test quickcheck

16:42 callen: 'ish.

16:51 augustl: is there a public version of this around? https://github.com/ring-clojure/ring/blob/860fbdd825b4fbe83ec67dad4009ce7bc0b0117a/ring-jetty-adapter/src/ring/adapter/jetty.clj#L12

16:51 want to create a servlet for my ring handler, without actually starting a server in the same step

17:00 dissipate: what's the quickest and easiest way to get started learning clojure?

17:02 joro: dissipate: I bought Emerick's "P in C", and started writing a mid-sized clojure program.

17:03 dissipate: joro, link to book?

17:04 joro: there might be other good books also around, I chose that by reviews and pragmatism

17:04 Bronsa: dissipate: http://www.clojurebook.com/

17:05 dissipate: Bronsa, are you sure that isn't a reference book?

17:05 Bronsa: yeah.

17:06 joro: the most difficulties I've had in error handling, debuggin, and lately, debugging stm stuff.

17:07 maybe tooling is an issue, if you are not used to emacs?

17:07 callen: dissipate: it's not a reference book.

17:08 The main issue I've been having with Clojure, and yeah, I know this is silly...HTML templating

17:08 Stencil, Enlive, and Hiccup all make me deeply unhappy.

17:10 dissipate: clojure doesn't seem to have many web frameworks available for it. that could be a bonus actually. :D

17:10 joro: I'm quite happy with ring, compojure, and pure REST

17:11 Raynes: dissipate: There are no 'reference' books for Clojure.

17:11 dissipate: Raynes, that's strange

17:12 rodnaph_: callen: that's surprising to hear. i really liked hiccup, but have fallen for enlive over it now.

17:12 Raynes: I'm not sure how.

17:12 dissipate: rodnaph_, are you doing web programming with clojure?

17:13 rodnaph_: yeah, pretty much everything i've done with clojure is web focused (or at least has a web frontend)

17:13 dissipate: rodnaph_, interesting

17:14 rodnaph_: dissipate: i'm finding compojure + enlive a really great combination. for UI and API stuff

17:14 Raynes: Enlive gives me hives. I'm partial to mustache.

17:14 dissipate: rodnaph_, what are the benefits of web programming in clojure vs. say a python framework like django?

17:14 callen: rodnaph_: I've only been able to make progress thanks to Raynes' refheap as a reference for how to do the mixture of partials in Stencil.

17:15 rodnaph_: I still find mustache to be pretty freakin' weak compared to Jinja though.

17:15 Raynes: <3

17:15 I think the fact that it is weak is why I like it. Simple is nice.

17:15 callen: Raynes: no seriously, playing "follow along" with refheap has been a MASSIVE boon to making a web app in Clojure. I've not had any serious breakage since I started simply because I was able to learn from your code.

17:16 dissipate: what are the benefits of doing web apps in clojure?

17:16 Raynes: Happy to hear it.

17:16 tomoj: enlive seems simpler

17:16 callen: well the weakness means falling back to defining partials in terms of Clojure code. The iterable behavior is questionable too. That's more coupling between HTTP runtime/template-side than I like to see.

17:16 Raynes: dissipate: The benefits are that you get to use Clojure instead of Python.

17:16 callen: dissipate: for me? Almost none. Purely pedagogical. Web apps are what I know.

17:16 rodnaph_: dissipate: i've never used django, but have lots of other frameworks in various languages, and the benefit i find is purely clojure. if you feel more comfortable with frameworks then maybe it's not right for you.

17:16 callen: dissipate: I'm 1000% more productive in Python/Flask/Jinja than I am in Clojure right now. Might change eventually.

17:16 Raynes: And if you ask "what are the benefits of Clojure over Python", I'm going to find you and cause you harm.

17:17 callen: my python stack isn't more productive because of Python, it's more productive because of Flask and Jinja.

17:17 dissipate: Raynes, yikes!

17:17 Raynes: :p

17:17 callen: Noir sorta'ish covers the Flask use-case, but Jinja still isn't really provided for yet.

17:17 Monger is a perfectly acceptable replacement for MongoEngine (better, even)

17:17 dissipate: Raynes, i'm coming from Python, but i'm very interested in the benefits of pure functions and transactional state memory

17:17 callen: so the biggest hits to my productivity come from unfamiliarity and the lack of a jinja equivalent.

17:17 Raynes: I want a driver for rethinkdb.

17:18 callen: dissipate: I'm only here for the Lisp.

17:18 rodnaph_: when you're comfortable with clojure, i think the simplicity is refreshing. i've found what i thought made me productive in other frameworks, i simply don't need in clojure.

17:18 callen: Raynes: writing a driver for rethinkdb could be interesting, since it has like 3 different query langs.

17:18 I'm an ex-CL'er trying to get back on the horse, so to speak.

17:18 dissipate: rodnaph_, how easy is it to become 'comfortable' with clojure? :O

17:18 Raynes: callen: I've got taking a shot at it on my TODO list.

17:18 wink: anyone seen any clues how to do it? I wondered if they're even open to 3rd-party-drivers

17:19 Raynes: wink: It looks like it is done over sockets. You can look at the implementations in the repo.

17:19 callen: Raynes: I use MongoDB as well, I see you're as excited as I am about replacing MongoDB? :P

17:19 Raynes: callen: I'm excited about not having to hear people bitch because I use mongodb.

17:19 That's about it.

17:19 dissipate: callen, what's wrong with MongoDB?

17:19 rodnaph_: dissipate: i won't lie, i found moving to FP a bit of a struggle. but mostly because i was overcomplicating things in my mind i think. use it 100% on a project and i reckon within a week you'll be flowing.

17:20 callen: Raynes: who complains?

17:20 Raynes: Lots of people.

17:20 wink: Raynes: ok, I failed to find a repo. *very* cursory glance it seems. thanks :)

17:20 callen: Raynes: you made a free pastebin designed for Clojure users. Is that what they bitch about? refheap using it?

17:20 rodnaph_: dissipate: (but then throwing out everything you did a week later, hehe)

17:20 callen: dissipate: a lot of stuff that matters about 10% of the time.

17:20 Raynes: callen: Mostly long discussions about how terrible mongodb is whenever I've ever mentioned how refheap uses it.

17:20 dissipate: i'm using mongodb for a small project

17:21 i like the flexibility

17:21 callen: Raynes: Refheap is the sort of thing MongoDB is perfect for, thugh.

17:21 Raynes: Which I am completely and utterly uninterested in, given that mongo works fine for this project.

17:21 callen: dissipate: it's great for that. Just don't suggest using it at work.

17:21 dissipate: callen, someone is already using it at work. :P

17:21 wink: refheap isn't supposed to be a consistent transactional DB though :P

17:21 callen: I use it at my startup, but that's due to 1. Legacy code 2. I know the trade-offs and it doesn't matter for us.

17:22 dissipate: someone is using MongoLabs at work actually

17:22 callen: you know of all the trade-offs that bother me with MongoDB, I have to say that transactions has come up for me approximately zero times.

17:22 Raynes: callen: https://github.com/weavejester/comb An old templating lib.

17:22 dissipate: are the complaints with mongodb related to scalability or what?

17:22 unnali: callen: it's come up for us about a hundred times. I think it really just depends on your domain/what you're doing.

17:23 callen: Raynes: I managed to get things working with stencil, thanks to you refheap/views folder, but it feels a bit creaky. As if I'm going to run into pain later if I need to spread out my template inheritance or something.

17:23 unnali: yeah I work in consumer web apps, so for me it just rarely if ever matters.

17:23 unnali: knowing that the option isn't available is...disconcerting to say the least.

17:23 Raynes: callen: Admittedly, refheap's templates are a mess that could probably be cleaned up.

17:23 callen: the thought of having to implement a lock-batch-unlock mechanism makes me weep.

17:24 Raynes: callen: Jinja looks interesting. Has a built in sandboxed execution environment. Why is that useful?

17:24 callen: Raynes: they were a little hard to follow until I understood that you were implementing a partials system on top of Mustache's pseudo-partials system.

17:24 Raynes: Do people not sanitize user input?

17:24 callen: Raynes: having it baked into the templating system does a lot to prevent issues.

17:25 Raynes: Mustache partials are less useful than doing it in the Clojure code itself.

17:25 callen: Raynes: the best way to explain Jinja is to realize that I am rarely writing templates except as an initial "example" showing what the name of the data getting injected looks like, then handing it off to the frontend guy.

17:25 Raynes: the blocks/template inheritance system in Jinja is something the frontend guy can understand and work with without bugging me

17:25 Raynes: Right, makes sense. I don't have a frontend guy for my personal projects.

17:25 callen: Raynes: having to reach into my Clojure code is highly sub-optimal.

17:26 Raynes: right, but that's a common issue in clojure projects. No accommodation/thought for division of labor.

17:26 Raynes: I had to work with a frontend guy for the first time a while back.

17:26 I was like an encyclopedia answering questions.

17:27 akhudek: In an ideal world, the frontend and backend would both be clojure. ;-)

17:27 callen: Raynes: how do you mean?

17:27 akhudek: not really, people specialize their knowledge into HTML/CSS/JS because those are subjects that often merit their own hooman in larger projects.

17:27 learning clojure is, frankly, out of the question.

17:27 Raynes: I mean he asked me lots of questions. Lots and lots of questions. It wasn't actually a website, but an API that he had to implement a frontend for.

17:28 akhudek: callen: HTML/CSS/CLJS. Just replace Javascript with ClojureScript. I don't see why learning clojure is out of the question for a javascript programmer, but not for a java programmer.

17:28 Raynes: Anyways, Jinja looks cool. I might argue with the "Jinja is Beautiful" tagline, but nonetheless..

17:30 callen: akhudek: you know what, give it a whirl. See how the JS dev reacts.

17:31 Raynes: Jinja is something that came out of the post-PHP/JSP era. In that context, it's heaven itself.

17:31 Raynes: ClojureScript seems like a tiny bit of a pain in the ass to use. Unless those js devs really hate js and really would rather use Clojure, I don't think you'll have much luck.

17:32 dissipate: what is clojurescript used for?

17:32 rodnaph_: i've only started using enlive today, but it really feels like an improvements on templating "languages"

17:32 Raynes: dissipate: It's a Clojure implementation that compiles to Javascript.

17:33 dissipate: interesting

17:33 sounds like coffeescript

17:33 akhudek: callen: I've taught two student javascript programmers clojure. It wasn't too hard. And Raynes, JS devs seem to really like Coffeescript. I don't think they are opposed to new languages in general.

17:33 callen: akhudek: I'm talking about working with experienced professionals who have a lot invested in their skillset

17:33 akhudek: not undergrand randos with time to burn.

17:35 akhudek: callen: the argument is still the same as any other experienced developer. You may as well advocate the same thing about Java and thus people shouldn't learn clojure.

17:35 callen: erm, no.

17:35 Backend is different. You can use anything you want there.

17:35 You will never ever ever escape HTML/CSS/JS on the frontend in web.

17:35 clojurebot: Huh?

17:35 callen: you can try to hide it with coffeescript, cljs, or whatever, but you'll never fully escape it.

17:35 Not even close.

17:36 akhudek: you're just grasping at straws now. Let it go.

17:36 dissipate: callen, how did google escape it? JS is not an official google language. :P

17:36 matt444: I have a deeply nested vector that I would like to "reach into" and modify. What functions should I be using?

17:36 callen: dissipate: they didn't, JS is a large component of their work.

17:37 dissipate: I know a Google employee who's one of the principals on AngularJS.

17:37 dissipate: callen, did they not 'escape' via GWT?

17:37 callen: no, that failed horribly.

17:37 amalloy: matt444: update-in and assoc-in

17:37 callen: they still use it in bits and pieces, especially on older properties.

17:37 They abandoned it for newer projects.

17:37 dissipate: google is using pure JS on new projects?

17:37 yikes

17:37 matt444: amalloy, assoc-in is the one I was thinking, thanks!

17:37 callen: the Google Closure ecosystem is a more accurate representation of how they do things.

17:37 dissipate: here comes Dart!

17:37 akhudek: callen: if your argument is that compiling to JS is bad in general, I suspect there are many that would disagree.

17:37 callen: akhudek: no, that's not my argument.

17:38 akhudek: jesus, stop making shit up just to try to make an argument you don't have the experience to be making.

17:38 Raynes: Eh

17:38 You don't really have to be so harsh.

17:38 callen: I don't like having words put in my mouth just so people can make themselves look less stupid at my expense.

17:39 Raynes: I'm pretty sure the channel is here for discussion.

17:39 dissipate: akhudek, it is bad. JS is the bain of web programming.

17:39 callen: Especially on IRC when it's textual and there's really no excuse. You can take your time to read what I said before tossing random stabs at getting the advantage.

17:39 dissipate: bane.

17:39 dissipate: bain is a name.

17:39 dissipate: callen, you are right, bane. :P

17:40 callen: Raynes: you're right, that was too harsh, but I lost interest in the argument several lines prior. Despite that, I get dragged back in because I have to fend off obviously ridiculous assertions as to what I meant so I don't look like the complete ass he was trying to make me into.

17:40 Raynes: I'll attempt to fend off the ridiculousness with a more polite and cheerful tone in future.

17:40 Raynes: Sounds good.

17:40 dissipate: has anyone 'big player' in web considered using a browser virtual machine that can run byte code compiled from many different languages? e.g. the Parrot VM

17:41 callen: dissipate: impractical.

17:41 dissipate: callen, how so?

17:41 callen: dissipate: well for one thing, a browser VM runtime has been done, it was called Flash.

17:42 amalloy: callen: nobody could put words in your mouth if you weren't constantly starting arguments unrelated to clojure in here

17:42 callen: dissipate: for another, you'd be introducing an immense amount of complexity for little gain. Performance is another concern.

17:42 dissipate: callen, so what is the solution? javascript is clearly a problem.

17:43 callen: amalloy: to my credit, I was originally talking about stencil, hiccup, and enlive. The general subject of front-end work eventually nose-dived into what you saw.

17:43 dissipate: I don't agree with the premise.

17:43 dissipate: callen, JS is perfectly fine? :O

17:43 callen: that's not the way I'd put it.

17:44 I think JS is fine for what it's meant to do and that compiling into it from things like cljs is a fine way to ameliorate the pain if you don't like JS.

17:44 or coffeescript, or roy, fay, etc.

17:44 dissipate: callen, the problem with JS is that it sucks for building larger apps

17:45 callen: dissipate: what large apps have you built?

17:45 Raynes: This is why I never argue about javascript.

17:46 dissipate: callen, i'm currently working on electrosim.com, a browser based schematic capture and simulator for electrical engineers.

17:46 callen: Whether or not JS scales up to a large project depends a great deal on factors that have little do with JS. Like testing, linting, code standards, libraries, etc. That's true of any programming language and any project.

17:46 dissipate: the Google Closure ecosystem shows some good ways to scale JS up for larger projects.

17:47 tomoj: what a coincidence

17:47 callen: tomoj: ?

18:05 cshell_: Is lein 2.0 backwards compatible with 1.7.x projects?

18:22 akhudek: cshell_: no, but there is some package that will try to auto-update a project to some extent

18:24 Raynes: cshell_: No, but every project you'll ever care about (except your own, I guess) has updated.

18:25 akhudek: cshell_: https://github.com/technomancy/leiningen/wiki/Upgrading

18:26 cshell_: thanks guys - I'm trying to work on the IDEA Leiningen Plugin and trying to figure out if I should support both 1.7+ and 2.0

18:26 or if I should just support 2.0

18:26 Raynes: I'd just support 2.0.

18:27 cshell_: Yeah, that would make my life easier - and I could just tell people how to update their current projects from 1.7 to 2.0

18:27 Raynes: Supporting 1.7 encourages continued using 1.7 which we shouldn't do, and opens up a huge can of annoying worms for you.

18:27 cshell_: good point

18:27 Raynes: But really, pretty much nobody is still using 1.7, so I think you're safe.

18:27 akhudek: Also, as Raynes said, there are very very few 1.7 projects still around.

18:27 Raynes: Eclipse, for example, uses lein2 I think.

18:28 amalloy: Raynes: spinning laziness as community activism since 2011

18:28 Raynes: Damn right.

18:29 cshell_: Okay great, I'll go with 2.0 then - the leiningen-core library makes my life a lot easier as well

18:29 Raynes: My life skills include landscaping and making people feel like their laziness is beneficial in the end.

18:35 cshell: I guess the only people using 1.7 are those who are still using the leiningen plugin in IDEA :)

18:36 Sgeo: Ugh, the C wrapper I'm wrapping takes callbacks as functions, and any sane Clojurey API, which I intend to make, would take the callback as a function, but the JNAerated Java, of course, doesn't.

18:49 Hodapp: wellll, I had to go all the way to Emacs to get Clojure support that would (1) give me syntax highlighting in the editor, (2) let me send expressions in the editor buffer to a REPL, and (3) let me type things in the REPL

18:49 but I'm finally there

18:49 * Hodapp glares in the direction of vim and Eclipse

18:51 Raynes: You could get that from Light Table too.

18:51 Pretty sure Eclipse makes it easy as well.

18:51 And there is catnip.

18:51 mudge: Raynes: hi!! I've been using your file system clojure library today

18:51 Hodapp: Raynes: Eclipse & Counterclockwise gave me a bunch of crashy bullshit.

18:52 Raynes: mudge: Yo.

18:52 Hodapp: Raynes: It worked okay for a bit, and then it didn't.

18:52 Raynes: Hodapp: That's okay, I don't like Eclipse either.

18:52 Hodapp: Raynes: It's nice for Java stuff. At least as far as Java stuff goes.

18:52 Raynes: But if you don't dig Emacs, give light table a shot. It isn't perfect, but it's making excellent progress.

18:52 Hodapp: I'm liking Emacs, actually. But I did watch the video on Light Table months and months back and it looks like some very cool software.

18:53 Raynes: Catnip looks pretty neat too, if you just want a Clojure editor.

18:53 mudge: Ryanes: I was looking at using the zip function in fs.compression but it looks like I need to load the entire files into byte arrays for use by make-zip-stream, does this sound right?

18:53 akhudek: Hodapp: I'm one of the few here who like IDEA + La Clojure.

18:53 Hodapp: akhudek: I had mixed luck with IDEA.

18:54 Raynes: akhudek: The file contents have to be either strings or byte arrays.

18:54 Er.

18:54 mudge: ^

18:55 But having to load the entire file into memory sounds bad.

18:55 mudge: I would expect that your byte array could be lazy. At least, I hope that's the case. I didn't actually write those functions.

18:56 Having to load entire files into memory is a bug, so open an issue about it if it turns out to be the case.

18:56 mudge: Raynes: I see

19:01 Raynes: okay thanks. Well make-zip-stream expects arguments like this: [[filename1 content1][filename2 content2]...] and the content1 variable is passed to ZipOutputStream.write() which expects a Java byte array, which I'm thinking can't be lazy because Java byte arrays are not lazy

19:01 Raynes: Ugh, an actual byte array.

19:01 Yeah, this is the devil.

19:08 mudge: Raynes:, raek: I wrote my own implementation of zip that makes a zip file of all files in a directory: https://gist.github.com/4056821

19:16 gfredericks: has clojure.java.jdbc had major breaking changes since the contrib days?

19:31 wink: gfredericks: hm, it's definitely different, can't say how different

19:37 gfredericks: is it possible to tell lein not to do anything with the internet even though my project has snapshots?

19:48 TheShellfishMeme: I'm trying to learn clojure at the moment. To understand macros better I decided to make one that makes all calls to '*' return x times the result. I first wrote the code that does this directly with a fixed

19:48 hit wrong button :/

19:50 … with a fixed multiplier. then I tried to convert it into a macro, but I keep getting a IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:494) error no matter how much I simplify it. Can someone help me and point me in the right direction? Code: http://pastebin.com/2VApsqnp

19:52 tmciver: TheShellfishMeme: Well, you forgot a name for the macro.

19:52 TheShellfishMeme: yeah I just realized that as well

19:53 *facepalm*

19:54 thanks :)

19:54 * gfredericks wonders how (def *facepalm* ...) should be completed

19:54 tmciver: np. It happens to the best of us.

19:55 gfredericks: (defn println [& args] (apply clojure.core/println (if *facepalm* (concat args ["duh."]) args)))

20:02 mattis: what is the preferred way to talk to a socket from Clojure? I see quite a few using the Java classes directly, but clojure.java.io looks more functional

20:17 TheShellfishMeme: now I have the problem that it says "Can't let qualified name" http://pastebin.com/kQbq0Ac0. I tried to do some research into what causes this, but I don't think I quite got it yet. Ignoring that this is nothing one would actually want to do in a real program, what is it that causes this error and how can I get around it?

20:18 cshell: change * in the binding to *#

20:19 (defmacro moretimes [times body] `(let[*# #(apply * (conj %& ~times))] ~body))

20:20 TheShellfishMeme: but then it doesn't seem to do anything. something else I missed there?

20:20 cshell: what do you expect (moretimes 2 (* 1 2)) to expand to?

20:22 TheShellfishMeme: actually it does what I want but it's getting late and I didn't notice the "1" in there.

20:22 or does it?

20:23 actually I wanted (moretimes 2 (* 2 2)) to expand to (let[* #(apply * (conj %& 2))] (* 2 2))

20:23 which should evaluate to 8

20:24 but (moretimes 2 (* 2 2)) evaluates to 4, so I guess something isn't working there

20:24 cshell: why are you shadowing the clojure/core/* operator?

20:25 gfredericks: he's messin with macros

20:25 you either want to shadow with (let [~'* ...] ...) or you want to use with-redefs, depending on your exact goal

20:25 TheShellfishMeme: because I have no idea what I am doing :) needed to find some kind of example use for them, so I came up with this

20:26 gfredericks: TheShellfishMeme: did you want the effect to be just in the code that's lexically inside of moretimes?

20:26 or all code executed even indirectly?

20:26 TheShellfishMeme: yes exactly

20:26 just inside moretimes

20:26 gfredericks: then you want to shadow with (let [~'* ...] ...)

20:26 that causes any * inside the macro to refer to your local function instead of the clojure.core var

20:27 TheShellfishMeme: hah, perfect. thanks a lot

20:27 gfredericks: it's syntactically ornery because that sort of thing is rarely what you want to do in a macro

20:27 (shadowing)

20:29 TheShellfishMeme: yes, I thought so. felt weird writing this code, but I needed some kind of thing to implement. just reading about macros didn't really help the understanding

20:30 cshell: Just think of macros as functions that return Clojure code

20:30 tmciver: TheShellfishMeme: you realize that you don't need to shadow * here; you could replace it with something like my-sym# everywhere.

20:31 or my-times#, say.

20:31 TheShellfishMeme: yes I do understand that. but I learned a lot more doing it the ugly way :)

20:34 I swear I'll never use this kind of thing in real code

20:35 Iceland_jack: Only in imaginary code

20:38 gfredericks: or at worst complex code

20:41 TheShellfishMeme: complex code is an integral part of lambda calculus

20:42 *I'll show myself out*

20:43 anyway, thanks for your help.

20:43 penryu: I've seen both (cons foo (lazy-seq ....)) and (lazy-seq (cons foo ...)) forms; which is better/best? or what are the caveats of each?

20:44 gfredericks: the latter won't evaluate foo until needed

20:45 if foo already exists I don't know any reason to use the latter

20:45 penryu: so not even the head of the returned seq will be eval'd until needed?

20:45 gfredericks: there's probably something though. I always don't think of something.

20:45 right

20:45 lazy-seq just thunks everything and does nothing until you need it to

20:46 penryu: okay. that makes sense.

20:46 so the latter is closer to haskell, iiuc

20:47 gfredericks: I spose

20:47 penryu: hrm. that comparison seems less and less useful the more I think about it.

20:48 gfredericks: :)

20:49 clojure: it's like haskell but only for lists some of the time

20:51 amalloy: gfredericks: ##(realized? (iterate inc 1)) is one reason you might prefer the latter

20:51 lazybot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPending

20:51 gfredericks: I was half considering mentioning that 85% of the time that I miss something amalloy or hiredman will point it out

20:51 rafb3: would like feedback on this content about functional programming I've been working on for a talk...

20:52 https://github.com/rafaelbandeira3/The_Stateless_Server_pt-BR/blob/master/the_stateless_server_en.markdown

20:52 feel invited to comment on it there

20:54 penryu: amalloy: are you referring to the change in behavior of (realized? (iterate inc 1)) and (realized? (rest (iterate inc 1)))?

20:54 amalloy: yeah

20:55 penryu: good point

20:55 so that's two points in favor of the lazy-seq-over-cons routine

20:57 gfredericks: well it's a conceivable reason to use that; I don't think it's a reason to prefer it generally

20:59 penryu: in the case of iterate, it's not really important either way, I believe. if the seeding of the sequence were expensive, you might choose one or the other to try to perform/delay the operation as desired

20:59 and indeed, all the docs use cons->lazy-seq

21:00 but the argument for consistency is a strong one, but maybe not very important in practice?

21:01 gfredericks: consistent with what? most sequences don't respond to realized?

21:01 e.g., lists

21:01 penryu: good point

21:02 gfredericks: it only makes sense in a context where laziness is expected for some odd reason

22:21 cshell: Can anyone tell me why (drop-while #(not= % "--to-dir") '("myprj" "--to-dir" "c:/temp/yyy11")) returns ("--to-dir" "c:/temp/yyy11")?

22:22 ,(drop-while #(not= % "--to-dir") '("myprj" "--to-dir" "c:/temp/yyy11"))

22:22 clojurebot: ("--to-dir" "c:/temp/yyy11")

22:24 cshell: ,(take-while #(not= % "--to-dir") '("myprj" "--to-dir" "c:/temp/yyy11"))

22:24 clojurebot: ("myprj")

22:25 cshell: ,#(not= "c:/temp/yyy11" "--to-dir")

22:25 clojurebot: #<sandbox$eval85$fn__86 sandbox$eval85$fn__86@6fc1049d>

22:25 cshell: ,(#(not= "c:/temp/yyy11" "--to-dir"))

22:25 clojurebot: true

22:29 cshell: ohhh.starting from the first item

22:29 oops

Logging service provided by n01se.net