#clojure log - Dec 11 2011

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

0:56 georgek: I have an array map of rss feeds, I then got a sequence by mapping :entries over the values of the map. Now I want to get the :title of each entry, but I can't figure out how to map :title over each item of :entries; the sequence I have is a sequence of sequences basically

0:56 tomoj: you want a seq of all the titles of all the entries, or a seq of seqs of titles for each feed?

0:58 georgek: a sequence of all the titles for all the entries; basically the result of combining (map :title (first seq)) and (map :title (second seq)), etc.

0:58 tomoj: where combining = concatenating?

0:58 georgek: when I (map :title seq) I get nil nil returned

0:58 yes tomoj

0:58 tomoj: first off, why an array map? just curious..

0:59 I think maybe you're looking for (map :title (mapcat :entries (vals feeds))) though?

0:59 georgek: no reason, it's just what I got back when I zipmapped a vector of strings as keys over a bunch of structmaps (the feeds)

1:00 tomoj: that will actually return a hash map if you have enough feeds - does order matter?

1:00 georgek: nope

1:01 tomoj: (mapcat :entries seq-of-structmaps) will give you one seq of all the entries (mapcat = map+concat)

1:02 georgek: ahh cool, thanks tomoj that's it

1:20 alexbaranosky: duck1123, are you around?

1:32 duck1123: yes

1:38 alexbaranosky: duck1123, care to add your thoughts to this issue?: https://github.com/marick/Midje/issues/72

1:39 duck1123: sure, I'll add it to the ticket

1:46 done

1:51 alexbaranosky: thx

2:00 duck1123: just realized I didn't have Midje cloned on this machine. Go long download time. :)

2:17 amalloy: duck1123, alexbaranosky: as i understand it, you can put facts inside of deftests, and then the usual clojure.test mechanisms work

2:17 cake certainly has the option to run just a single test (eg, cake test my.ns/test-name), and i wouldn't be surprised if lein does too

2:18 i guess that belongs as a comment on the issue. all right, all right, no need to hassle me

2:20 alexbaranosky: hey amalloy, glad to have your input

2:30 pierre-renaux: Hi, my first time here, I'm playing around with Clojure, I have a "test" problem for which I build a binary tree. It works fine, but... I'm wondering if anyone would be willing to check out the implementation to see if there's a way to make it faster, its quite a bit recursive (not 'recur' recursive :s)

2:37 amalloy: trees generally are

2:40 pierre-renaux: the main issue I have is that each node as a min/max value (an integer)

2:41 and every time I insert a value in the tree each parent node "before" the leaf have to update their min/max

2:41 amalloy: yep. that's pretty much how it has to work

2:42 pierre-renaux: one way I can think of is to index those min/max in an external (mutable) array... but well, I suppose its pretty obvious that it isnt pretty :P

2:42 ... since the min/max is the only thing that really change when I insert... and of course the leaf node added every time...

2:43 ... I'm looking at this because its by far the most time consuming part of the test...

2:43 amalloy: pierre-renaux: if you're interested in data-structure stuff, you might like okasaki's Purely Functional Data Structures. or you can read some bloggy things online

2:43 pierre-renaux: an implementation in C++, using mutable structure, doesn't even register the tree building part...

2:44 (I mean its almost free, looking at profiling data)

2:44 in the Clojure implementation its ~70-80% of the time spent...

2:45 I've read quite a bit of stuff, its not that I dont understand how it works, is just that I'm not sure if there's a better way...

2:45 amalloy: pierre-renaux: you're trying out a new language, and the first thing you're doing is comparing the speed of your back-of-the-envelope implementations against a C++ impl you're comfortable with? what's the point?

2:45 pierre-renaux: I have 4 different implementations :P

2:46 well, that's not my point

2:46 I'm pretty sure that if I use the Java - mutable structures in Clojure

2:46 I'll get the same perf as the C++ implementation...

2:46 I'm trying to figure out how to build the immutable tree efficiently

2:47 amalloy: why?

2:47 clojurebot: amalloy: because you can't handle the truth!

2:47 pierre-renaux: :P

2:55 amalloy: seriously this seems like a complete waste of your time. learn how to use the language, get comfortable with how to write expressive code. if what you really want is to write code that looks like C++ and performs exactly as well, then just write C++

2:57 pierre-renaux: right, point well taken

2:58 but I can't really think of a "better" way for this particular case, which is why I'm asking

2:58 I have a tree A[min,max] -> B[min,max] -> Leaf[value,index]

2:58 min/max are min/max of the index in the Leaf

2:58 so if I add another value in the tree, I have to update the min/max at each node...

2:59 amalloy: if you add another value to the tree, you have to update all the nodes on its path to the root whether you're tracking min/max at all

2:59 pierre-renaux: mmm

2:59 right indeed

3:00 amalloy: $google clojure persistenthashmap higher-order

3:00 lazybot: [Assoc and Clojure's PersistentHashMap: part ii | Higher-Order] http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii/

3:00 amalloy: you might find that useful if you want to read about trees

3:00 pierre-renaux: right I have read that

3:00 devn: great article

3:00 pierre-renaux: I've reimplemented those in C++... so I do know how it works fairly well

3:01 I'm wondering if there's some idiomatic way to build that type of trees with immutable datastructure that could be more efficient than the "naive" way...

3:05 amalloy: mutably or immutably in c++? it seems like immutability is what's giving you pause, so having implemented a mutable version in c++ isn't necessarily a very useful exercise

3:05 seriously though, if you've implemented those in c++ you probably know your stuff, data-structure wise, so okasaki would be a great book to dive into

3:07 for me it's a bit too heavy but it sounds like it's targeted at exactly what you want to learn

3:07 pierre-renaux: right, its about immutability, the PersistentHashMap in C++ as the same "issue" as the one in Clojure, I mentioned the C++ implementation as an example of what I'm seeing with a "mutable" implementation... not really anything particualr to the language

3:08 my main "pause" is about how to efficiently initialize those immutable structure

3:08 using a transient version helps a bit (about 50%) better, but I'm wondering if there isn't even a better way to do it :P

3:09 what I didn't try yet, is to build the tree concurrently, I'm concerned "merging" it at the end could be quite painfull...

3:12 tomoj: pierre-renaux: do you mean like this? http://www.sitepoint.com/hierarchical-data-database-2/ ...not to suggest I can help you, just trying to understand what you mean :)

3:13 ..or is it min/max of the values on the nodes?

3:15 pierre-renaux: well, the min/max isn't really the main issue - as amaolly pointed out - I guess it just boils down to "what is the most efficient way to build an immutable binary tree whith a fairly deep hierarchy when each new insert starts at the root node"

3:16 the efficiency issue comes - I'm supposing - from the fact that the "whole path" the leaf inserted has to be rebuilt

3:17 amalloy: pierre-renaux: well, the efficient way is not not build deep trees :P

3:17 which is why clojure's built-in trees have a branching factor of 32

3:17 pierre-renaux: yes :P

3:17 tomoj: hmm.. zippers don't solve that?

3:17 pierre-renaux: zippers is good to mod in the "middle" of the tree

3:18 but when I build a deep tree and insert from the root for each new value

3:18 it doesnt really help :P

3:22 amalloy: pierre-renaux: zippers do solve some cases of this problem

3:22 pierre-renaux: do you know of any article that explains what happens when a large XML file is loaded ?

3:22 its essentially the same issue I believe...

3:22 amalloy: haha. here's my article: "you run out of memory"

3:22 pierre-renaux: :D

3:22 I meant something that might explain how to do it efficiently ;)

3:23 amalloy: zippers let you "queue up" a number of sorta "local" changes to the tree, and apply them all at once when you walk back up to the root

3:24 pierre-renaux: mmm

3:24 oki, so it kinds of "buffer" the build, and "commits" it when you ask for the root back ?

3:24 amalloy: doesn't help if you have a bunch of random changes all over the tree, but if you're working on one area for a while...

3:25 pierre-renaux: right, that was my understanding

3:25 amalloy: yes, that is one effect it has

3:26 devn: The more I use noir the more I enjoy it.

3:39 tomoj: huh.. is the idea that you only have one app?

3:40 i.e. defpage anywhere in the code defines a page in that one web app?

3:41 oh, or just one per namespace passed to noir.server/start..?

3:42 no, wow, there is one global route table? is it just me or is that odd?

3:46 amalloy: tomoj: i mean, i guess it seems a little short-sighted, but it's pretty normal to have one jvm per app?

3:50 duck1123: I wonder, what are the performance differences between checking every route in your app, vs splitting of into sub-matches based on url path components

3:51 I'm sure it's highly dependant on the number of routes

3:51 tomoj: yeah.. I'm not thinking "man I really want to have two apps at once" but "man defpage -> swap! noir-routes.. weird"

3:51 I mean, it's religious :)

3:53 duck1123: you could use binding on the var that holds the ref to run each site within it's own binding

3:54 not that I'm actually sugesting that

3:54 amalloy: duck1123: only if you want each site to have only one thread...?

3:55 duck1123: amalloy: I'm sure if you're masochistic enough to do something like this, you could find a way around that

3:56 I've been wanting to find a more efficient way to do the routes in my framework

3:56 tomoj: (defn foo-handler [req] ..) is so beautiful

3:56 duck1123: I run a series of checkers over the route data and the request. and it's a bit wasteful

4:08 tomoj: hmm.. so if e.g. storm's web UI were written with noir instead of compojure, just having storm as a dep might infect my noir app and break everything

4:18 amalloy: oh. wow, yeah, that's a good point

4:18 tomoj: or maybe the :ns option to server/start helps

9:46 cmiles74: I'm moving some code from Clojure 1.2 to 1.3, does anyone know if 'clojure.contrib.mmap' was migrated to one of the modular contrib libraries?

9:48 It's not a lot of code if it wasn't. Handy though :)

9:52 capotribu: hi, don't see any comment for nmap here http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

9:53 cmiles74: Yeah, me neither.

9:54 I work with some big files, I think for now I'm just going to just build a little JAR just for these functions. It's not much code, really.

10:12 ambrosebs: here an example of using the ClojureScript analyzer (with modifications) on Clojure code to detect misplaced docstrings

10:12 https://github.com/frenchy64/typed-clojure/blob/master/src/clojure_analyzer/docstrings.clj

10:12 work in progress, but you get the idea

10:53 Borkdude: this might be a dangerous question, but has anyone tried (just for fun) to make a Common Lisp lib for Clojure (so you can just write defun and cond with extra parens etc)?

10:57 ,(defmacro defun [name arg-list body] `(defn ~name [~@arg-list] ~body))

10:57 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

11:07 kzar: Does anyone else get that "Debugger entered--Lisp error: (end-of-file)" error using slime, emacs and clojure? I always get it after I evaluate something that returns a lot of data, like if I'm testing a scrape function interactively

11:08 and then once I get that error I have to disconnect and reconnect slime before I can evaluate anything, it's really annoying

11:20 Also I'm trying to figure out, what should I use for XML generation? It seems that clojure.xml isn't recommended and lazy-xml is being superseded by data.xml but that's not ready yet.

11:24 Borkdude: kzar I've had this and I had to change some encoding setting, let me find it

11:24 kzar: Borkdude: sweet thanks

11:25 Borkdude: kzar: put this in your init.el or whatever: (setq slime-net-coding-system 'utf-8-unix)


11:29 kzar: Borkdude: Ah now I'm getting that "error in process filter: Variable binding depth exceeds max-specpdl-size", brb going to restart emacs

11:31 Borkdude: Yea, that fixed the end-of-file thing, thanks!

11:31 Borkdude: :)

11:31 kzar: Borkdude: Do you know how to fix the max-specpdl-size problem? I always have to just restart emacs

11:31 Borkdude: kzar: can't remember to have seen it

11:34 kzar: shucks OK, still I'm stoked about the end-of-file fix

11:35 mrb_bk: sup, anyone around use gloss at all?

11:35 seems to not work well with clojure 1.3?

11:36 Borkdude: kzar: tried this? http://stackoverflow.com/questions/1322591/tracking-down-max-specpdl-size-errors-in-emacs

11:37 kzar: Borkdude: Ah I'll give that a try later, cheers

11:45 Bronsa: scgilardi: why is it slingshot.slingshot and not slingshot.core or just slingshot?

11:47 ambrosebs: how can you call a macro from apply?

11:47 ,(apply #'-> {} {} [:a :b])

11:47 Bronsa: you cant

11:47 clojurebot: (:b :a)

11:48 ambrosebs: the ClojureScript compiler does, I'm trying to work out how

11:48 Bronsa: there was apply-macro in old contrib

11:48 https://github.com/richhickey/clojure-contrib/blob/2ede388a9267d175bfaa7781ee9d57532eb4f20f/src/main/clojure/clojure/contrib/apply_macro.clj#L32

11:49 ambrosebs: any idea how the above code that I entered works?

11:53 Bronsa: hm

11:55 no idea

11:55 ambrosebs: this is the line in question https://github.com/frenchy64/typed-clojure/blob/master/src/clojure_analyzer/compiler.clj#L578

11:56 looks like &form and &env become explicit

11:58 duck1123: Borkdude, thanks for that fix to kzar's problem. (I've had that same one myself)

11:58 ambrosebs: ,(apply #'-> 'a {} [#'-> {:a :b} :b])

11:58 clojurebot: (clojure.core/-> (clojure.core/-> #'clojure.core/-> {:a :b}) :b)

11:59 duck1123: mrb_bk: which version of gloss are you using? I know that gloss works because it's used in aleph

11:59 mrb_bk: duck1123: aleph with clojure 1.3?

12:00 duck1123: yeah, I did the patches that made it work, but ztellman merged them in

12:00 mrb_bk: oh yeah i saw that

12:00 duck1123: 0.2.0

12:00 duck1123: you need 0.2.1-SNAPSHOT for 1.3

12:00 mrb_bk: oh okay cool

12:00 thanks!

12:02 duck1123: perfect!

12:06 Bronsa: ambrosebs: i think i got it

12:06 when using a macro as a function, the first two parameters get binded as &form and &env

12:06 oh, you said it too

12:07 ambrosebs: do you know what the "rest" args are for?

12:08 Bronsa: im not sure i understood your question

12:09 ambrosebs: oh I see, the first 2 args are special, then the rest are as normal

12:09 Bronsa: yes

12:09 ambrosebs: awesome thanks :)

12:16 is there a difference between using `in-ns` and binding *ns* to change namespace?

12:19 wiseen: is there a way to start lein test as a "server" so I don't have to restart JVM all the time with lein test ?

12:22 Bronsa: ambrosebs: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L204 it seems this is actually what in-ns does :P

12:23 ambrosebs: Bronsa: I'm glad you found it, I figured the impl would be deep down :P

12:38 ,(.startWith "asdf" "asd")

12:38 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: startWith for class java.lang.String>

12:38 ambrosebs: ,(.startsWith "asdf" "asd")

12:38 clojurebot: true

12:39 ambrosebs: ,(.startsWith (str "asdf") "asd")

12:39 clojurebot: true

12:39 ambrosebs: :) nvm, typo

12:52 devn: Never forget that it is a waste of energy to do the same thing twice, and that if you know precisely what is to be done, you need not do it at all. -- E. E. "Doc" Smith (1930)

13:13 cemerick: So, just how evil would it be to define a type that implements e.g. IPersistentMap, but proxies database state?

13:15 lnostdal: with a cache that would be evil cool, cemerick

13:16 cemerick: what would the cache get you?

13:16 ambrosebs: what's the function to print a Java class's fields and methods?

13:16 lnostdal: hm, yeah, i guess the map would "be" the "cache" actually

13:17 cemerick: ambrosebs: see clojure.reflect/reflect

13:17 lnostdal: There wouldn't be any storage; assoc would put, get would get, dissoc would delete, etc.

13:17 It strikes me as a really bad idea. :-P

13:18 Bronsa: wouldn't this be mutable state?

13:18 ambrosebs: cemerick: cheers

13:18 cemerick: yeah

13:19 Bronsa: and mutable state is bad right?

13:19 cemerick: All databases are mutable state.

13:19 Bronsa: that's a good point

13:20 cemerick: Part of me wants to be able to utilize the vocabulary provided by assoc/dissoc/into/update-in, etc.

13:36 TimMc: cemerick: ORM!

13:36 It would be pretty evil, since the DB is not... persistent.

13:38 cemerick: OR... "Duh, what did you *think* 'persistent" meant."

13:39 technomancy_: devn: is that the same doc smith as the guy who pioneered the space opera?

13:41 Borkdude: I have always disliked working with databases because of their mutability

13:43 TimMc: At least they have a good concurrency story...

13:44 Borkdude: Why does everyone use the word "story" in Clojure world

13:44 Bronsa: also "to complect"

13:44 Borkdude: just wondering where that came from ;)

13:44 TimMc: Borkdude: I think it's an enterprisey thing.

13:44 Borkdude: and "mitigate"

13:45 TimMc: I don't like enterprisey things

13:45 TimMc: "complect" comes from Rich's talk "Simple Made Easy", which is worht a watch

13:45 Bronsa: yeah, i watched it

13:45 Borkdude: is it like Scrum "user stories"?

13:45 TimMc: Borkdude: That's my guess.

13:46 A lot of Clojurians (conj-urers?) come from the Java world, which is pretty enterprisey.

13:47 Borkdude: TimMc: I get critized for using Clojure because it is too immature (un-enterprisey), this guy believes you cannot do "big" projects with it

13:48 TimMc: because in OO world there are a lot of tools, methods, notation (UML) and documentation, unlike in the functional/Clojure realm.

13:49 mbac: (ns foo (:require clojure.contrib.json))

13:49 (read-json "{}")

13:49 java.lang.Exception: Unable to resolve symbol: read-json in this context (NO_SOURCE_

13:49 say what?

13:49 Bronsa: s/require/use/

13:49 Borkdude: mbac: you have to prefix it with the namespace name you required

13:49 mbac: or "use" it like Bronsa suggests

13:49 mbac: oh, is that the difference between require and use?

13:49 Borkdude: mbac: yup

13:49 cgray: just curious: why is last not implemented as (nth coll (dec (count coll))) ? wouldn't that at least make it constant-time for vectors?

13:50 Borkdude: ,(source last)

13:50 mbac: why does require exist at all then?

13:50 clojurebot: Source not found

13:50 Borkdude: mbac: so your namespace does't get polluted with vars you don't need

13:51 cgray: Borkdude: http://clojuredocs.org/clojure_core/clojure.core/last#source

13:51 TimMc: mbac: Use :require with :as.

13:51 Borkdude: mbac: or to distinguish clearly, for example you can do : require :as json and then every json function you can call like: (json/function ...)

13:52 TimMc: http://blog.8thlight.com/articles/2010/12/6/clojure-libs-and-namespaces-require-use-import-and-ns

13:52 Borkdude: cgray: hmmm, I didn't know that it walked the entire seq in case it is a vector

13:53 cgray: Borkdude: yeah, I was surprised too... I bet there's a good reason that I'm not seeing though

13:53 Borkdude: cgray: maybe there is some trickery going on with protocols or smth, I don't know

13:54 TimMc: Huh, that's an ugly surprise.

13:54 mbac: what i mean is if you still have to fully qualify the package even after you say require, what's the point of require

13:54 TimMc: mbac: :as

13:54 you don't

13:55 Borkdude: mbac: if you don't do require at all, it doesn't even know it I guess?

13:56 TimMc: mbac: Are you asking why you have to require at all if you just use a FQNS?

13:56 mbac: yeah

13:56 TimMc: Ah, I see. That's a good question.

13:57 It doesn't have parity with import, does it.

13:57 I can do java.io.File without importing.

14:00 Borkdude: ,(loaded-libs)

14:00 clojurebot: #{clojure.java.io clojure.repl}

14:00 Borkdude: ,(clojure-version)

14:00 clojurebot: "1.3.0"

14:05 Borkdude: mbac: https://gist.github.com/1462160

14:07 Scriptor: where did Hiccup get its name from?

14:08 * kumarshantanu likes Scriptor's question

14:08 chessguy: howdy ya'all

14:08 * Raynes tips his hat

14:09 Raynes: ... partner.

14:09 mbac: Borkdude, what's this? :)

14:09 Scriptor: wait, better question, is james reeves on irc?

14:10 TimMc: &(keyword "-)")

14:10 lazybot: ⇒ :-)

14:10 Borkdude: mbac: an answer to your question about require?

14:10 mbac: just checking

14:10 :)

14:12 chessguy: so i'm a bit confused about how to use clojure.test. can i just feed a file with tests to clojure from the command-line?

14:13 mbac: why are def and defn different?

14:13 can't clojure just treat defs with more than 2 atoms as a function definition?

14:14 kumarshantanu: mbac: that sounds leaky; what do you mean?

14:14 Borkdude: mbac: defn is a special case of def

14:15 mbac: it is shorthand for (def my-var (fn ....))

14:15 ,(source defn)

14:15 clojurebot: Source not found

14:15 Borkdude: this doesn't work right?

14:15 mbac: sometimes i say (def base_url "http://example.com/&quot;) but then i go oh wait it's a function of your session-id so i change it to (def base_url [session_id] (str "http://example.com/&quot; session_id))

14:15 and then clojure's like fuck you you forgot to say defn

14:15 and i'm like damnit you can figure it out

14:16 :(

14:16 Borkdude: mbac: you should just write defn if you want to define a function

14:16 mbac: or (def my-var (fn [session-id ...)))

14:16 mbac: i'm simply asking if there's a reason clojure can't overload the meaning of def

14:16 flashingpumpkin: hey guys. how would I access a hash-map value when I've got the key in a variable?

14:17 Borkdude: mbac: such cleverness will only lead to more confusion

14:17 ssideris: flashingpumpkin: (get map key)

14:17 Bronsa: mbac: since 1.3 def supports an optional doc argoument for def

14:17 Scriptor: yea, (def base-url [session-id]) would be assigning a one-element list to base-url

14:17 Bronsa: so you can (def a [] "doc")

14:17 mbac: borkdude, disagree. i have this expectation from using ocaml

14:17 Bronsa: and this means a has value [] and as doc "doc"

14:17 kumarshantanu: defn also adorns the var with metadata (type hints, documentation etc)

14:17 Bronsa: but (defn a [] "doc") is different

14:17 Borkdude: mbac: ocaml isn't a lisp

14:18 Bronsa: it's a function that returns the string "doc"

14:18 mbac: where let base_url = "http://example.com" can extend smoothyl to let base_url session_id ("http://example.com/&quot; ^ session_id)

14:18 flashingpumpkin: ssideris, https://gist.github.com/889a2535b84ef1d3b996

14:18 mbac: borkdude, no, but it aspires to functional platitudes :)

14:18 (clojure does)

14:18 i think?

14:18 Borkdude: mbac: clojure doesn't have currying

14:18 mbac: and I think what you are showing has to do with currying

14:18 mbac: anyway, i was wondering if there was a reason why this wouldn't work and bronsa had a good answer

14:18 doc strings

14:19 borkdude, this has nothing to do with currying

14:19 Scriptor: mbac: you're asking why (def base-url [session-id]) isn't detected as being a function definition?

14:19 mbac: scriptor, yeah

14:19 wiseen: can anyone help me figure out how to run clojure tests with lein so that I don't have to reload JVM every time I run lein ?

14:19 Scriptor: mbac: because that's also valid as assigning a list to base-url

14:19 mbac: yeah, i see the error of my ways now

14:19 Scriptor: namely, a one-element list containing session-id

14:19 flashingpumpkin: ah. ssideris if the key is actually a string it works :)

14:19 ssideris: flashingpumpkin: yeah, :foo is not the same as "foo"

14:20 flashingpumpkin: yep

14:20 ssideris: if you have the string, you have to convert it to a keyword first

14:20 kumarshantanu: wiseen: you should pester @icylisper to release Jark with Lein integration

14:20 ssideris: (get map (keyword s))

14:20 where s is the string

14:22 wiseen: kumarshantanu, what's Jark ? google isn't helpful

14:22 cemerick: TimMc: I'd never suggest an ORM ;-)

14:22 kumarshantanu: wiseen: http://icylisper.in/jark/

14:23 wiseen: kumarshantanu, tnx will look in to it

14:24 Borkdude: mbac: you're right; let in ocaml can be used for simple values or functions, it is just clever syntax, whereas clojure is more like other lisps: if you want to write things more clever, write a macro (like defn)

14:25 daniel___: (def conn mongo/make-connection "iskine" :host "" :port 27017)

14:25 mbac: i was more curious if there was a reason wasn't feasible

14:25 than anything

14:25 daniel___: Caused by: java.lang.RuntimeException: Too many arguments to def

14:25 im trying to use congomongo, getting this error

14:26 Bronsa: should be (def conn (mongo/make-connection ..))

14:26 Borkdude: daniel___: you are forgetting parens before mongo/... and after 27017

14:26 ssideris: daniel___: (def conn (mongo/make-...))

14:26 daniel___: i see, github readme is wrong then

14:26 should have realised anyway

14:30 docs also tell you to use mongo/make-connection but on the import line they dont create the mongo namespace

14:31 Borkdude: mbac: you might also want to read this SO question http://stackoverflow.com/questions/2570628/difference-in-f-and-clojure-when-calling-redefined-functions

14:31 mbac: I was confused when I just started clojure after doing some F# (derived from Ocaml)

14:33 mbac: borkdude, yikes

14:33 that's good to know

14:34 Bronsa: mbac: if you defined g as (defn g [x] (#'f x))

14:34 mbac: what's the term for this behavior? the top-level defs are dynamically scoped?

14:34 Bronsa: the resoul would be the same as in f#

14:34 omni5cience:

14:34 ops

14:35 Borkdude: vars have a root binding and you can give them a thread local binding, but I'm always confused about vars, so maybe someone else can explain this better

14:36 mbac: http://clojure.org/vars

14:37 mbac: I guess the example in F# you can read as nested lets right

14:38 mbac: yeah

14:47 chessguy: i'm a bit confused about how to use clojure.test. can i just feed a file with tests to clojure from the command-line?

14:48 Borkdude: chessguy: I guess you can do (run-tests) and then it runs all tests from all referenced namespaces

14:48 chessguy: Borkdude: i've tried doing a (load-file ...) at the repl, and then doing (run-all-tests), but it's not working

14:49 it doesn't recognize the run-all-tests symbol

14:50 Borkdude: chessguy: hmm..

14:50 chessguy: let me show the code

14:50 Borkdude: chessguy: what clojure version?

14:50 chessguy: Borkdude: umm, i cloned github and built that, so whatever that is

14:50 Borkdude: chessguy: http://clojuredocs.org/clojure_core/clojure.test/run-all-tests < 1.3.0

14:51 chessguy: do you have a repl? type: (clojure-version)

14:51 chessguy: ah, nice

14:51 1.4.0-master-SNAPSHOT"

14:52 it's unable to resolve (run-tests) too

14:52 Borkdude: chessguy: did you use clojure.test?

14:52 chessguy: or require

14:53 chessguy: Borkdude: here's the code: https://gist.github.com/1462396

14:54 Borkdude: i did a use

14:55 Borkdude: chessguy: from where are you calling run-tests then

14:56 chessguy: Borkdude: from a repl, i did a (load-file "unify_test.clj")

14:56 and (run-all-tests)

14:56 Borkdude: chessguy: you typed all of this into a repl?

14:56 chessguy: Borkdude: the code in the gist is in two files. i put comments with the filenames

14:57 Borkdude: chessguy: right. you need to use clojure.test also from the repl

14:57 chessguy: Borkdude: oh really? why?

14:57 ah, you're right, that worked.

14:57 Borkdude: chessguy: because then the test lib gets loaded and run-tests will become available from your namespace

14:58 chessguy: Borkdude: does it not get loaded when i specfy ":use clojure.test" in the namespace?

14:58 Borkdude: chessguy: now it is only available from building-problem-solvers, not from your repl namespace, unless you do (in-ns 'building-problem-solvers)

14:58 chessguy: ah. which is probably notn what i want anyway

14:59 daniel___: in noir, how can i pass content through to the general layout from a defpage? i have some links that are in the layout but they depend on attributes like :id from each page

14:59 Borkdude: chessguy: use doesn't work transitively, it would mean a cluttered namespace

15:00 daniel___: in other words i need some kind of placeholder in the layout that i later define in the defpage

15:00 chessguy: hmm. it looks like i still need to use clojure.test from within the namespace, to be able to define the test

15:00 Borkdude: daniel___: sounds like a perfect use for Enlive

15:01 TimMc: chessguy: I just use `lein test`. -.-

15:01 Borkdude: chessguy: yes, you need to 'use' it everywhere you 'use' it ;)

15:01 chessguy: Borkdude: thanks for your help

15:01 daniel___: Borkdude: dunno what that is but ill have a search

15:01 chessguy: TimMc: i haven't gotten around to lein yet

15:01 TimMc: How is that possible? :-P

15:02 Borkdude: daniel___: Enlive is a templating library

15:02 daniel___: so you don't have to construct html from clojure, but just plain html file which you can use as a template with selectors etc

15:03 daniel___: I bet you can also use html contructed with hiccup but I haven't used it like that

15:04 TimMc: daniel___: Enlive's documentation is terrible, but it is a pretty useful lib.

15:05 daniel___: TimMc: most clojure libs seem to have terrible documentation, at least for beginners

15:05 noir/korma are quite good

15:13 Borkdude: daniel___: I guess this is an argument for the immaturity of Clojure libs for enterprise

15:14 daniel___: missing docs, things are still moving fast

15:15 chessguy: TimMc: ok, i've almost got it turned into a lein project. it still complains when i try to 'lein test', though

15:15 TimMc: says it can't find the .class or .clj file on the classpath

15:19 Borkdude: chessguy: move your .clj into a dir named project/src/name and make the name of the dir and the namespace of your .clj file the same

15:19 chessguy: but you might have figured this out already

15:24 chessguy: Borkdude: i'm almost there, but something's still not quit lining up right: https://github.com/arwagner/bps-clojure

15:26 i'm guessing it's because i was inconsistent about sometimes abbreviating bps and sometimes not

15:31 Borkdude: chessguy: normally, when you have a project and a src dir with a clj file directly in it called core, you have to refe it like: projectname.core

15:32 chessguy: but when you use an extra subsir you have to refer it like: projectname.subsir.core and also declare it like this

15:32 chessguy: Borkdude: i just pushed a change to make some stuff more consistent. lein created a projectname subdir under src

15:33 Borkdude: ok

15:33 and did it also create the core.clj?

15:33 chessguy: yes

15:35 Borkdude: chessguy: my advise, just make a new project with "lein new" and move in your code gradually

15:35 chessguy: also _ and - can be tricky

15:35 chessguy: Borkdude: that's what i tried to do

15:35 i guess i'll start over again...

15:38 mbac: i don't quite grok how to deal with the 1.3 contrib world

15:39 am i supposed to download the modules i need and somehow tell clj where to find them?

15:39 Borkdude: mbac: http://dev.clojure.org/display/doc/Clojure+Contrib

15:39 mbac: are you using leiningen?

15:40 flashingpumpkin: mbac, Borkdude, same puzzling here - and yep using leiningen

15:40 mbac: i do for quick development, but i'm also using a ~/bin/clj script which doesn't seem to line up with whatever leiningen does

15:42 borkdude, i don't know how to use the information on that page

15:42 Borkdude: mbac: from project.clj just [org.clojure/core.logic "0.6.8-SNAPSHOT"]

15:42 mbac: i want to usea standalone script without leiningen

15:43 or, better yet, put leiningen into my #! line

15:44 Borkdude: mbac: I only did it the leiningen way so far, sorry

15:44 mbac: yeah, i guess i'll give up and use leiningen

15:48 gfredericks: There are 7 times more google results for "vim to emacs" than "emacs to vim"

15:49 companion_cube: that must mean that more people use vim :]

15:49 gfredericks: I had not thought of it that way.

15:52 duck1123: more people want to leave vim

15:54 gfredericks: maybe the switch to emacs is much more painful and so more likely to be blogged about.

15:54 * gfredericks is just sayin, it's theoretically possible

15:54 companion_cube: yeah, the amount of blogging does not reflect the popularuty

15:54 popularity*

15:55 duck1123: I guess if you know emacs, then vim is just one big annoying piece of cake. Not so the other way

15:56 daniel___: Borkdude: i realised by reading the noir tutorial that i can achieve what i wanted by just passing extra variables through to defpartial

15:57 gfredericks: is there an argument to emacs that makes it open in a terminal?

15:57 daniel___: i thought you could only do it on defpage, but it works with something like (defpartial layout [id name & content] ...

15:57 gfredericks: -nw

15:57 gfredericks: daniel___: thx

15:58 duck1123: gfredericks: if you already have emacs running somewhere else: emacsclient -ct

16:01 Borkdude: daniel___: ah good

16:01 gfredericks: duck1123: man I don't even know what that means. emacs is/can-be client-server?

16:02 Borkdude: duck1123: emacsclient -nw or emacsclient -ct does exactly the same thing for me when I have emacs running

16:02 duck1123: gfredericks: put (start-server) at the bottom of your init file, then you can open multiple connections to the same emacs session

16:03 I have two computers here, so I'll open a x11 forwarded ssh session and have them both work on the same emacs instance

16:03 gfredericks: I think I will have to learn some basics first.

16:03 Borkdude: duck1123: I think -t just means -nw

16:03 gfredericks: I just looked up how to move the cursor up/down/left/right.

16:03 Borkdude: duck1123: -c is only useful if you want to use it from a window

16:04 duck1123: Borkdude: are you sure client takes the -nw flag, i thought that was only for emacs

16:04 Borkdude: duck1123: according to emacsclient --help it does

16:04 gfredericks: I was hoping C-h would backspace like it does everywhere else. Unfortunately it helped.

16:04 daniel___: gfredericks: what editor are you more used to?

16:04 gfredericks: daniel___: the other one

16:04 daniel___: me too, tried vimclojure?

16:05 gfredericks: yep

16:05 couldn't get it to do anything fancy

16:05 duck1123: Borkdude: hmm, looks like you're right. I seem to remember at one time that not working

16:05 gfredericks: mostly it just indented exactly the way I didn't want

16:05 daniel___: i like it for syntax-highlighting, paren matching, and indenting

16:06 gfredericks: I probably didn't learn it well enough

16:06 duck1123: gfredericks: C-h is for help-related options. You can rebind it (as with everything) but I wouldn't recommend it

16:06 daniel___: i am also trying to learn emacs because lein-nailgun doesnt seem to be as good or easy to use as swank

16:06 gfredericks: I've tried to learn emacs maybe twice before.

16:07 daniel___: still wishing there was a better option for vim though

16:08 * gfredericks is learning org-mode at the same time

16:08 daniel___: i find myself trying to make emacs as much like vim as i can

16:10 gfredericks: I will learn emacs and org-mode and xmonad in parallel. Maybe.

16:10 daniel___: had never even heard of org-mode tbh, isnt it just an extension of emacs?

16:11 duck1123: org-mode is concentrated awesome

16:11 gfredericks: I'm trying to get off of tomboy

16:12 daniel___: org-mode looks interesting, tbh i just use a textfile or something like notepad.cc

16:15 duck1123: I need to revise my use of org-mode. I used to be really into, but I fell out of practice

16:15 daniel___: do people have any preferences when working with javascript with a clojure web framework? are there any worthwhile advantage si can get from using something like clojurescript? just write plain javascript/jquery? any good libraries for coffeescript?

16:16 amalloy: daniel___: my experience is that the clojure community mostly scoffs at coffeescript; some see an advantage in using clojurescript; others stick with javascript

16:17 scoffeescript?

16:19 daniel___: tbh i think coffeescript has nice syntax but doesnt seem to provide any real advantages and it's just one-more thing to learn

16:19 gfredericks: amalloy: really? I'm curious why somebody would prefer javascript over coffeescript.

16:19 daniel___: im worried clojurescript is a bit immature

16:19 lnostdal: this doesn't apply for 1.3 anymore (or i'm testing with 1.4-SNAPSHOT really)? http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/

16:20 Scriptor: coffeescript fixes a bunch of things that irked js developers for years, there's definitely a point to using it

16:20 gfredericks: I've used coffeescript in a big project at work the last few months, and have never regretted it. Wished clojurescript had been around sooner, but certainly didn't want to use JS

16:21 Scriptor: yea, you can scoff at it all you want, but it grew *extremely* quickly after it was released

16:22 * gfredericks just swapped ctrl and caps and has not recovered yet

16:22 Scriptor: I'm still debating on that, I like having it set to esc for now

16:22 duck1123: gfredericks: you actually have a reason to retain caps?

16:23 gfredericks: Yeah I was just thinking there wasn't much of a point to that.

16:23 but this forces me to retrain

16:23 Any recommended alt uses for the LCtrl?

16:24 it's so far away I can't imagine anything being all that compelling...

16:24 Scriptor: caps lock :p

16:24 duck1123: bind it to hyper, then program a whole new level of commands

16:24 gfredericks: duck1123: is that a real thing?

16:24 amalloy: gfredericks: i leave it as another ctrl; in a few combinations it's easier to use than caps

16:24 JaegerBar: hi

16:25 duck1123: gfredericks: yes

16:25 amalloy: eg, for ctl-shift-tab it seems better. and i already have a super key i don't use; not much value in hyper :P

16:26 gfredericks: I've been wanting to map from C-Space to Tab, but google doesn't produce any magic xmodmap code for it, and the whole subject seems too complex to learn easily

16:26 TimMc: daniel___: ClojureScript *is* immature.

16:26 gfredericks: TimMc: does it have rationals yet?

16:26 TimMc: No idea.

16:27 amalloy: gfredericks: i don't think xmodmap lets you do that. i'm not sure it's a good idea either; c-spc is pretty handy in emacs

16:27 * gfredericks likes him some rationals

16:27 gfredericks: amalloy: what's it do?

16:27 amalloy: set the mark

16:27 gfredericks: my pinkie gets tired during tab-completions

16:27 amalloy: gfredericks: M-/

16:28 (and in C-u C-spc it pops the mark)

16:28 gfredericks: amalloy: is that supposed to work with bash, or just in emacs?

16:28 duck1123: gfredericks: setting the mark allows you to start selecting text. (for cutting or whatever)

16:28 there's something similar in screen

16:28 amalloy: gfredericks: probably just emacs, since i think it's supposed to be "dynamic completion", whatever that means

16:29 btw, on a barely-related note, C-/ is undo in bash

16:29 gfredericks: I'm always tab-completing stuff at the command line. Maybe I'll do that less w/ emacs? :/

16:29 companion_cube: amalloy: wow, didn't know that

16:30 amalloy: companion_cube: a huge percentage of things you do in emacs work at the command-line, because bash uses readline

16:30 mbac: is there a zip function? (zip [1 2 3] ["a" "b" "c"]) evaluates to [[1 "a"] [2 "b"] [3 "c"]] ?

16:31 companion_cube: but i thought C-/ was 'search' in emacs

16:31 amalloy: ~zip

16:31 clojurebot: zip is not necessary in clojure, because map can walk over multiple sequences, acting as a zipWith. For example, (map list '(1 2 3) '(a b c)) yields ((1 a) (2 b) (3 c))

16:31 Chousuke: mbac: map vector

16:31 mbac: neat

16:31 gfredericks: clojurebot: that is handy

16:31 clojurebot: In Ordnung

16:31 gfredericks: ha

16:31 clojurebot: that?

16:31 clojurebot: that is handy

16:32 gfredericks: very nice.

16:32 weavejester: companion_cube: Isn't C-/ undo?

16:33 companion_cube: never mind, i don't know much emacs commands

16:33 JaegerBar: i'm trying to get started in Clojure, which compiler do i need

16:34 weavejester: JaegerBar: You can download the jar from the main site, or use Leiningen, which is a build tool and dependency manager for Clojure.

16:34 duck1123: JaegerBar: you need Java, and while you don't need it, you need leiningen

16:35 JaegerBar: ok

16:35 does this compile like normal java

16:35 like do i have to say something similar to "javac ....java"

16:35 weavejester: Not usually. It's more like Python or Ruby

16:36 JaegerBar: so it's a scriptable language

16:36 gtrak```: JaegerBar, it's kinda hard to explain it all over IRC, let me find you a good tutorial

16:36 weavejester: In that it's compiled when you execute it.

16:36 duck1123: clojure's kinda a little of both

16:36 JaegerBar: i saw a book at the store called "The Joy of Clojure: Thinking the Clojure Way" should i get it?

16:36 gfredericks: JaegerBar: yes.

16:36 gtrak```: it's good, but pretty advanced

16:36 JaegerBar: i read the part where it tried to explain functional programming

16:37 identity vs. state

16:37 i still am not super sure i understand that but i'm getting there

16:37 gtrak```: http://java.ociweb.com/mark/clojure/article.html#Intro

16:37 amalloy: JoC is the best clojure book. i don't think it's "advanced", it's just "fast"

16:37 JaegerBar: gtrak do you program clojure professionaly

16:38 gtrak```: not so much myself right now, but we have a lot of stuff written in it

16:39 I've read through JoC and done some toy programs, plus some work in an existing large clojure project

16:40 amalloy, I've seen lots of folks say it's a good second book, not first

16:40 JaegerBar: who is "we"

16:40 your company

16:40 gtrak```: Revelytix

16:40 duck1123: Programming Clojure was a good intro book

16:40 JaegerBar: is clojure used exclusively for threaded programming

16:41 gfredericks: nope

16:41 duck1123: who was the guy at Revelytix that came to michigan for CloudDevDay ?

16:41 JaegerBar: Revelytix is a big time company

16:41 gtrak```: probably Alex?

16:42 JaegerBar: how do you pass a function

16:42 gtrak```: ah, Ryan

16:42 JaegerBar: that's a confusing concept

16:42 gtrak```: Ryan Senior, I've worked with him a little, all those guys are really great

16:42 daniel: is Practical Clojure any good? thats the one im reading

16:43 gfredericks: JaegerBar: that's a fundamental concept in functional programming -- functions can be treated as objects

16:43 JaegerBar: is someone gonna hold my hand on this

16:43 gfredericks: JaegerBar: what programming languages are you most familiar with?

16:43 JaegerBar: or am i on my own

16:43 just C

16:43 well C and java i guess

16:43 gfredericks: doesn't C have a bit of that?

16:43 JaegerBar: java i suck at though

16:43 gtrak```: JaegerBar, it's too much for hand-holding, imo :-)

16:44 JaegerBar: i don't know i am not a hardcore C programmer

16:44 amalloy: gfredericks: you can pass functions in c, but you can't return them

16:44 gfredericks: amalloy: C so weird.

16:44 amalloy: well, that's not true

16:44 JaegerBar: i didn't know you could pass a function in C =p

16:44 duck1123: that's what I was thinking

16:44 amalloy: you can't make closures, which is as near as possible as not being able to return them :P

16:44 gtrak```: duck1123, we have a team of 9 in St. Louis doing full clojure, I work mostly on a big java thing, 300k lines :-D

16:45 gfredericks: JaegerBar: one of the things it lets you do is create abstract algorithms. For example I can easily define a function called "do-twice", that takes a function as an argument and calls it twice

16:45 JaegerBar: ha that's really cool

16:45 weavejester: gtrak: Out of interest, how maintainable do you find 300k lines of code?

16:45 duck1123: I'm so happy that I finally got to start using Clojure at work. We've been doing Ruby, but I've re-written a large portion of my app in Clojure

16:45 gfredericks: Not so easily done imperatively

16:46 JaegerBar: is Clojure mainly used now for web programs

16:47 gfredericks: JaegerBar: I think that's a signifiant portion of its uses, but probably not even a majority

16:47 weavejester: JaegerBar: I don't think so... I've seen a lot of data-processing done in Clojure, for instance...

16:47 JaegerBar: duck, what did you write in Ruby/Clojure at work

16:47 gtrak```: weavejester, ha, well, it's my first big project, I'm just out of school 2 years ago so I have no standard to compare against. I find that I have to read every line in whatever subsytem I'm working on before I can make changes confidently. It takes time, but it's doable. Tests help.

16:47 weavejester, honestly, I'm much more scared of other people's clojure code :-)

16:48 weavejester: gtrak: I haven't worked on a software project anywhere near that size before, so I was curious :)

16:48 duck1123: I do data processing, reading streams of blog posts and twitter streams, etc which we process and index for another team

16:48 arkh: it takes 38 seconds for my vm to run cljsc on some simple clojurescript - any recommendations to speed things up? (besides a faster computer)

16:48 gtrak```: weavejester, I'd definitely be lost without the expertise of the senior guys, sometimes they can say in one sentence what would take me days to figure out

16:49 Turtl3boi: show me how to pass a function C

16:49 in the C language........because i've never seen dat b4

16:49 gtrak```: hey there Turtl3boi

16:49 Turtl3boi: hi Gtrakh

16:49 duck1123: http://stackoverflow.com/questions/9410/how-do-you-pass-a-function-as-a-parameter-in-c

16:50 Turtl3boi: oh yea you pass it as a pointer to function

16:50 i don't generally do that very often for whatever reason haha

16:51 gtrak```: well, in C you can't actually have closures since there's no GC

16:51 might be possible with reference counting

16:51 Turtl3boi: what's a closure? haha

16:52 weavejester: CPython ref-counts and has closures, I believe.

16:52 brehaut: weavejester: yes, although its got some stuff in addition to the ref counter for cycles

16:52 gtrak```: ,((let [a 1] (fn [] (inc a)))

16:52 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

16:52 gtrak```: ,((let [a 1] (fn [] (inc a))))

16:52 clojurebot: 2

16:53 bobhope: hello clojuristas, can anyone explain to me what the consequence of disabling occurs-check in a kanren implementation is?

16:53 gtrak```: Turtl3boi, that thing I just wrote calls an anonymous function that closes over the value of a

16:53 weavejester: Turtl3boi: A closure is a function that references the environment in which it was defined.

16:53 I think :)

16:53 There might be a more accurate description.

16:54 Turtl3boi: ooo anonymous functions again

16:54 gtrak```: it's binding a heap-allocated object to a value that was local at one point

16:54 and then invoking it

16:55 duck1123: the point is, you capture the value of a when you define that fn, then you can pass that fn around, do whatever, and it''l return 2 whenever you do call it

16:55 gtrak```: and it's easy to make functions that make functions

16:56 ,((fn [] (fn [] (+ 1 2))))

16:56 clojurebot: #<sandbox$eval79$fn__80$fn__81 sandbox$eval79$fn__80$fn__81@611faa>

16:56 gtrak```: ,(((fn [] (fn [] (+ 1 2)))))

16:56 clojurebot: 3

16:56 Raynes: weavejester: In my experience, the definition of 'closure' is "That's an okay working definition, but it isn't correct."

16:57 Turtl3boi: deconstruct that for me gtrak

16:57 gfredericks: (apply partial (repeat partial)) is a function that makes functions ad infinitum

16:57 Turtl3boi: what does "fn[] (+ 1 2)" do ?

16:57 gfredericks: Turtl3boi: that's a function that adds one and two

16:57 Turtl3boi: does that define a function which adds 1 + 2

16:57 gfredericks: so it returns 3

16:57 weavejester: Turtl3boi: You mean (fn [] (+ 1 2)) ?

16:57 gtrak```: creates a function, the arglist goes in the []

16:57 weavejester: Raynes: Yeah, there's a more accurate computer-sciencey definition

16:58 gtrak```: ,((fn [x] (+ 1 x)) 2)

16:58 clojurebot: 3

16:58 Turtl3boi: why do you put parens around it weavejester?

16:58 duck1123: to call it

16:58 gtrak```: (fn .. defines the function

16:58 weavejester: Turtl3boi: Because that's the syntax

16:58 gtrak```: ((fn .. calls the function that was defined

16:58 Turtl3boi: kk gotcha

16:58 gtrak```: (fn ... actually returns a function

16:58 gfredericks: ,(+)

16:58 clojurebot: 0

16:58 Turtl3boi: what does the outer "fn [] " do?

16:59 gtrak```: that's just defining a function that returns a function :-)

16:59 you call it once to get the inner, then call that to get the value

17:00 ((fn [x] (+ 1 x)) 2) calls the function with 2 as the first parameter, x

17:01 Turtl3boi: ,((fn [] (+ 1 2)))

17:01 clojurebot: 3

17:01 Turtl3boi: if i add another "fn [] " to the left, what does it do in the above statement?

17:01 is that the same as calling it

17:01 gfredericks: ,(fn [] (fn [] (+ 1 2)))

17:01 clojurebot: #<sandbox$eval221$fn__222 sandbox$eval221$fn__222@12aeb08>

17:02 gfredericks: that just returns the outer function

17:02 TimMc: &(((fn [] (fn [] 5))))

17:02 lazybot: ⇒ 5

17:02 TimMc: &((fn [] ((fn [] 5))))

17:02 lazybot: ⇒ 5

17:02 gtrak```: Turtl3boi, (fn calls fn

17:02 TimMc: Turtl3boi: This is more clear when you bind the fns to names and then call them.

17:02 gfredericks: is there an alt keybinding in emacs for backspace?

17:03 gtrak```: (let [add (fn [x] (+ 1 x))] (add 6))

17:03 ,(let [add (fn [x] (+ 1 x))] (add 6))

17:03 clojurebot: 7

17:03 Turtl3boi: ,(fn [] (fn [] (+ 1 2)))

17:03 clojurebot: #<sandbox$eval55$fn__56 sandbox$eval55$fn__56@d7cdf1>

17:03 Turtl3boi: ^ why doesn't athw rok

17:03 lol

17:03 gtrak```: it does, that's how a function shows up

17:03 TimMc: ,(let [boring (fn [x] (+ 2 x))] (boring 3))

17:03 clojurebot: 5

17:03 gfredericks: it does work. what do you want it to do?

17:04 duck1123: gfredericks: If you ever want to get any info about a key sequence: C-h k <sequence>

17:04 TimMc: Oh, gtrak``` beat me to it.

17:04 gtrak```: TimMc, :-D

17:04 daniel: whats the simplest way of password protecting paths with noir? i have a path like /model/:id and this model may or may not have a password attribute set...if it has a password i want to check for the password or redirect

17:04 mindbender: functions are first class objects in clojure just like classes are in java

17:04 TimMc: gtrak```: lazybot was feeding me NPEs on that for some reason

17:04 Raynes: (fn [x] x) <-- returns a new function that returns its argument. Functions are first class in Clojure. You can create this function and then call it immediately like any other function. That's what they did earlier.

17:04 daniel: this is my attempt https://gist.github.com/1463038

17:05 but seems to pass the when-not, even if i dont pass in any password variable

17:05 Turtl3boi: ,(let [bullshit (fn [x] (+ -1 x))] (bullshit 33))

17:05 clojurebot: 32

17:05 amalloy: gfredericks: none built in

17:05 gfredericks: duck1123: that's a useful thing to know, but I don't see how it helps me answer my question? I tried it with backspace, and from what I can tell it displayed unrelated information

17:06 Turtl3boi: are functions first class in python?

17:06 mindbender: Turtl3boi: lmao

17:06 gfredericks: amalloy: so you just reach all the way up there all the time?

17:06 gtrak```: i think so

17:06 amalloy: and duck1123 is right - i got that answer by pressing C-h k BACKSPACE

17:06 Turtl3boi: why are you laughing

17:06 mindbender: your choice of symbol

17:07 gtrak```: Turtl3boi, try dir(len) in your python interpreter

17:07 Turtl3boi: ahh haha ok

17:07 gfredericks: amalloy: all I got was some stuff about org-self-insert-command; didn't really understand it

17:07 weavejester: Functions are first class in Python.

17:07 amalloy: gfredericks: well, it generally shows you what other keys it's bound to if there are any

17:07 Raynes: One-line lambdas ftw!

17:08 amalloy: try C-h k C-/ for comparison

17:08 mindbender: weavejester: as it is in any other functional language

17:08 gfredericks: are functions considered first-class in ruby?

17:08 weavejester: mindbender: Well, Python's not a functional language...

17:08 gfredericks: No, because technically it just has methods, not functions :)

17:08 mindbender: what makes a language functional?

17:08 Raynes: List comprehensions considered harmful.

17:08 gfredericks: weavejester: that's what I figured

17:08 brehaut: Raynes: one expression, not line

17:09 Raynes: A language creator that doesn't abolish the paradigm, probably.

17:09 weavejester: mindbender: A functional language tries to reduce or restrict side effects

17:09 Turtl3boi: (fn [x] x) <-- returns a new function that returns its argument.

17:09 what does that mean

17:09 weavejester: weavejester: So in Clojure, we have atoms and refs for handing state change. We need to be explicit

17:09 gtrak```: ,(fn [x] x)

17:09 clojurebot: #<sandbox$eval169$fn__170 sandbox$eval169$fn__170@b952ad>

17:09 weavejester: mindbender: But in Python, everything's mutable by default

17:10 lucian: weavejester: except when it isn't

17:10 gtrak```: Turtl3boi, that's the .toString() on the function object

17:10 Turtl3boi: hmm

17:10 lucian: (ints, floats, strings and tuples are immutable)

17:10 weavejester: lucian: Well... okay, the core data structures in Python are all mutable

17:10 gfredericks: Turtl3boi: it means that whatever argument you pass to that function is its return value

17:10 Raynes: It is the identity function.

17:10 &(identity 0)

17:10 lazybot: ⇒ 0

17:10 Turtl3boi: hahaha ok that's what i thought

17:10 weavejester: lucian: ... except for those :)

17:10 gfredericks: ,(let [returns-its-arg (fn [x] x)] (returns-its-arg "HAAAA"))

17:10 clojurebot: "HAAAA"

17:11 Turtl3boi: why did the other guy say it "returns a new function that returns its argument"

17:11 why did he say "new function"

17:11 gtrak```: ,(source identity)

17:11 clojurebot: Source not found

17:11 gfredericks: Raynes: you just passed the additive identity to the functional identity

17:11 weavejester: lucian: I wouldn't class Python as functional though. Aside from tuples and maybe strings, it doesn't make much effort to avoid mutability.

17:11 TimMc: Turtl3boi: Well, it's a new function, it's not the same object as `identity`.

17:11 Raynes: Turtl3boi: Because it isn't an old function...?

17:11 Turtl3boi: lol k

17:11 i'm going too far into it as i usually do

17:12 brb

17:12 lucian: weavejester: sure, it makes little effort. i sort of see any language with first-class functions as functional

17:12 TimMc: &(identical? (fn [x] x) (fn [x] x))

17:12 lazybot: ⇒ false

17:12 gfredericks: Turtl3boi: "new" functions can be created just as easily as "new" strings

17:12 TimMc: &(let [boring (fn [x] (+ 2 x))] (boring 3)) ;; let's see if lazybot is still broken...

17:12 lazybot: java.lang.NullPointerException

17:12 TimMc: haha

17:12 gfredericks: rather than only being declared at some kind of higher level

17:12 gtrak```: ,&(= (fn [x] x) (fn [x] x))

17:12 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: & in this context, compiling:(NO_SOURCE_PATH:0)>

17:12 Raynes: $reload

17:12 lazybot: Reloaded successfully.

17:12 lucian: weavejester: so in that sense, python has functional concepts (decorators, properties, object creation, comprehensions, immutable iterators, etc)

17:12 TimMc: &(let [boring (fn [x] (+ 2 x))] (boring 3)) ;; let's see if lazybot is still broken...

17:12 lazybot: java.lang.NullPointerException

17:12 gtrak```: ,(= (fn [x] x) (fn [x] x))

17:12 clojurebot: false

17:13 Raynes: TimMc: Meh, I'll figure that out later.

17:13 TimMc: Raynes: SANBOX DENIED

17:13 gtrak```: &(= (fn [x] x) (fn [x] x))

17:13 lazybot: ⇒ false

17:13 gtrak```: if only :-)

17:13 brehaut: lucian: if you think pythons iterators are immutable, you are sadly mistaken

17:13 weavejester: lucian: Why is object creation functional?

17:13 mindbender: weavejester: a bit of reading up confirms you're right

17:13 bobhope: what's the best way to return multiple values in clojure?

17:13 lucian: brehaut: i meant the original object to be iterated on is not mutated

17:13 gtrak```: bobhope, a vector or a map

17:14 Raynes: &(fn [] [1 2 3])

17:14 lucian: weavejester: because it act like functions (classes are first-class callables)

17:14 lazybot: ⇒ #<sandbox28697$eval30931$fn__30932 sandbox28697$eval30931$fn__30932@3e51ed>

17:14 daniel: whats the simplest way of password protecting paths with noir? i have a path like /model/:id and this model may or may not have a password attribute set...if it has a password i want to check for the password or redirect

17:14 this is my attempt https://gist.github.com/1463038

17:14 but seems to pass the when-not, even if i dont pass in any password variable

17:14 weavejester: lucian: Oh right. I think functional programming is more about avoiding state change, though.

17:15 lucian: At least, that's what wikipedia says ;)

17:15 lucian: weavejester: sure, i guess. but i find the first bit (first-class functions) much more necessary than the latter

17:15 without the first you're fucked. without the second it's just a little uncomfortable

17:16 weavejester: lucian: Yeah, but that makes for a *really* broad definition of functional programming

17:16 brehaut: HoFs with pervasive mutability results in higher order imperative code though, not functional code

17:16 gtrak```: it's all imperative on some level

17:16 weavejester: lucian: Usually when people talk about functional programming, it's all about restricting state change.

17:17 amalloy: the definition of functional programming has evolved over time, as more languages adopted what was originally called "functional"

17:17 weavejester: Yeah...

17:18 licenser: nooo

17:19 amalloy: in the very early days, lisp was functional because it had first-class functions

17:19 gtrak```: clojure's mutability default inverts the control, but it's still imperative

17:20 weavejester: Well, there are places where Clojure is imperative...

17:20 Turtl3boi: Gtrak i believe i talked to you along time ago in the java channel

17:20 weavejester: But most of the code I write in Clojure is very functional.

17:20 gtrak```: Turtl3boi, yea

17:20 I think I told you to look at clojure :-D

17:20 Turtl3boi: i guess i don't know what "first-class"means yet though

17:21 all these computer science terms are coming back to bite me

17:21 because, alas, i was not a comp sci major

17:21 gtrak```: they're not first-class in java, since you can't make one at run-time easily

17:21 Turtl3boi: yeah you did tell me to look at it but i delayed on that

17:21 weavejester: Turtl3boi: It just means you can treat functions the same way you'd treat any other data

17:21 Turtl3boi: ahhh.....i see

17:21 weavejester: Like, they're not second-class citizens, so to speak.

17:21 gtrak```: yea, check it out

17:21 Raynes: Turtl3boi: For the most part, it just means that a function is just a value like anything else. For example, a function and an integer are on the same level in Clojure.

17:22 weavejester: So does this mean Clojure is communist? :)

17:22 gtrak```: ((first [(fn [] (+ 1 x)) (fn [] (- x 1))] 5))

17:22 ,((first [(fn [] (+ 1 x)) (fn [] (- x 1))] 5))

17:22 Turtl3boi: wow that's pretty nifty....so a function can be modified at run time

17:22 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)>

17:22 gtrak```: oh oops

17:22 ,((first [(fn [x] (+ 1 x)) (fn [x] (- x 1))] 5))

17:22 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$first>

17:22 gtrak```: fail!

17:23 weavejester: Turtl3boi: Well... kinda. It's more that you can create functions at runtime.

17:23 daniel: can anyone help me password protect this? https://gist.github.com/1463136 im not supplying a password but it doesnt redirect

17:23 weavejester: Turtl3boi: Once a function has been created, it's pretty much immutable, but every other data structure in Clojure is too.

17:23 gtrak```: ((first [(fn [x] (+ 1 x)) (fn [x] (- x 1))]) 5)

17:23 ,((first [(fn [x] (+ 1 x)) (fn [x] (- x 1))]) 5)

17:23 clojurebot: 6

17:24 gtrak```: Turtl3boi, that picks the first function in that vector and invokes it with 5 as the arg

17:24 weavejester: daniel: Use if-not instead of when-not

17:24 gtrak```: ,((second [(fn [x] (+ 1 x)) (fn [x] (- x 1))]) 5)

17:24 clojurebot: 4

17:24 bobhope: Sorry if my question was already answered, but i'm on a laggy train connection and it may have blown by without my getting a chance to see it: is destructuring let the best way to return multiple values?

17:24 TimMc: bobhope: Pretty standard, yeah.

17:24 gtrak```: bobhope, destructuring is for input not output

17:25 daniel: weavejester: still the same problem :(

17:25 TimMc: bobhope: return a vector or map, capture and dissect it in a let

17:25 bobhope: thanks guys :)

17:25 weavejester: daniel: You want something like... (if (password-protected?) (redirect) (show-page))

17:26 daniel: right?

17:26 daniel: yeah weavejester

17:26 bobhope: has anyone used relations/facts with core.logic?

17:26 weavejester: daniel: Redirect doesn't have side-effects. You need to return it from your function for it to have an effect.

17:26 daniel: i see

17:26 bobhope: I'm trying to understand how to use them with a typechecking system

17:27 should I input the declared types as facts, and see if the relationships can be inferred?

17:27 and how could I report errors in the type verification?

17:27 daniel: weavejester: can i force that somehow in its current form?

17:28 can you issue return statements in clojure? or is it always the last to be eval'ed

17:29 TimMc: daniel: "last to be eval'd" is correct, but misleading

17:30 gtrak```: daniel, all the code is compiled before it's run, to eval something means to read it in, compile it, and run it

17:30 TimMc: daniel: A (do ...) form's value is the value of the last contained form, and let, fn, etc. have an implicit do form around their body.

17:30 weavejester: daniel: https://gist.github.com/1463164

17:30 TimMc: gtrak```: That's nitpicking.

17:30 Turtl3boi: does "immutability" mean the same thing in clojure as it does in java

17:30 gtrak```: ,(eval '(inc 1))

17:31 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

17:31 TimMc: Turtl3boi: And in every other language, yep.

17:31 gtrak```: The SANBOX has DENIED you!

17:31 bobhope: is there a way to evaluate in a new, empty namespace, or a namespace that you explicitly control?

17:31 gtrak```: hmm, why eval bad?

17:32 daniel: weavejester: thanks, that looks good. lets see if it works

17:32 TimMc: ,((resolve (symbol "eval")) `(inc 1))

17:32 clojurebot: 2

17:32 gtrak```: ah, i know why, eval must skip the check Raynes put in on his own eval :-)

17:33 TimMc: I don't think clojurebot uses clojail.

17:33 gtrak```: TimMc, wtf

17:33 TimMc: haha

17:33 weavejester: Well, that's Ring 1.0.0 finally released. Now I can start going through all patches for all the other projects :)

17:33 Raynes: gtrak```: If you allow eval, you've allowed everything.

17:33 And clojurebot definitely does not use clojail.

17:33 weavejester: Oh, except I probably need to write a mailing list post.

17:34 TimMc: weavejester: Congratulations.

17:35 Turtl3boi: ,((first [(fn [x] (+ 1 x)) (fn [x] (- x 1))]) 5)

17:35 clojurebot: 6

17:35 Turtl3boi: ^what's the point of that gtrak?

17:35 gtrak```: Turtl3boi, shows you that functions are data like anything else

17:35 Turtl3boi: oh right you can have an array of functions

17:35 gtrak```: gets the first thing in the vector, invokes it

17:35 Turtl3boi: oh sorry vector not array

17:36 gtrak```: you could probably do array, too

17:36 Raynes: Good thing you apologized. I was about to call the terminology police.

17:36 Turtl3boi: i'm so used to C++ vector vs array being different

17:36 Raynes: &(into-array [(fn [])])

17:36 lazybot: ⇒ #<sandbox6862$eval9045$fn__9046[] [Lsandbox6862$eval9045$fn__9046;@573068>

17:37 gtrak```: wait, is it actually a typed array?

17:37 err, no

17:37 (into-array [(fn [x] (+ 1 x)) (fn [x] (- x 1))])

17:37 ,(into-array [(fn [x] (+ 1 x)) (fn [x] (- x 1))])

17:37 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: array element type mismatch>

17:37 gtrak```: ,(to-array [(fn [x] (+ 1 x)) (fn [x] (- x 1))])

17:37 clojurebot: #<Object[] [Ljava.lang.Object;@177d7db>

17:38 Turtl3boi: what does the ampersand do?

17:38 gtrak```: that's just telling the bot to run it

17:38 there's two bots in here

17:38 weavejester: TimMc: thanks :)

17:38 Turtl3boi: that's the same as using the comma

17:38 gtrak```: ,is lazybot

17:38 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: is in this context, compiling:(NO_SOURCE_PATH:0)>

17:38 gtrak```: rather, clojurebot

17:38 & is lazybot

17:38 lazybot: java.lang.RuntimeException: Unable to resolve symbol: is in this context

17:39 Turtl3boi: awesome

17:39 daniel___: weavejester: unfortunately it doesn't work, but i think it must be that fetch-one is returning something other than false or nil

17:40 weavejester: daniel: I guess that means its time to add in some debug code :)

17:40 gtrak```: ah, it is a typed array

17:41 TimMc: gtrak```: It is base don the first arg, I think.

17:41 &(doc into-array)

17:41 lazybot: ⇒ "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class obj... https://gist.github.com/1463238

17:41 gtrak```: Turtl3boi, you'll notice that each function is its own class

17:42 TimMc: &(class +)

17:42 lazybot: ⇒ clojure.core$_PLUS_

17:42 gtrak```: &(class (fn [] nil))

17:42 lazybot: ⇒ sandbox6862$eval9073$fn__9074

17:43 Wild_Cat: interesting. I'd have thought there'd be a single Function class (or at worst, one per arity).

17:43 gtrak```: nopers

17:43 TimMc: Wild_Cat: Each fn (inline or not) becomes a .class file.

17:43 gtrak```: TimMc, Wild_Cat, only on AOT

17:43 TimMc: This is because of the JVM.

17:44 gtrak```: you can load classes from a byte-array object dynamically

17:44 qbg: Is there something special you need to do to get Counterclockwise's REPL to work with Clojure 1.3?

17:44 TimMc: gtrak```: But that's an in-JVM class, even if it isn't a .class *file*.

17:44 gtrak```: yes

17:44 TimMc: CLOSE ENOUGH o\__/o

17:44 gtrak```: nevar!

17:45 Turtl3boi: so one set of parens around a funcion defines it

17:45 two around it actually calls it

17:45 TimMc: Turtl3boi: The parens in (fn [x] x) are a call as well, to fn.

17:45 cgray: where is unquote defined?

17:45 gtrak```: (..) calls the first item in the list

17:45 Wild_Cat: yeah, I should have guessed it was due to a JVM implementation issue.

17:45 gtrak```: with the rest as parameters

17:46 it's all just lists

17:46 TimMc: It's calls all the way down.

17:46 &`unquote

17:46 lazybot: ⇒ clojure.core/unquote

17:46 TimMc: cgray: ^

17:46 cgray: nope

17:46 at least not in my clojure.core

17:46 TimMc: Oh, right -- Compiler special.

17:46 cgray: really?

17:46 too bad

17:47 ,(apply ~'/ '(1 3))

17:47 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote>

17:47 Turtl3boi: all just lists?

17:47 what's a list

17:47 gtrak```: ,(class '(1 2 3 4))

17:47 clojurebot: clojure.lang.PersistentList

17:47 gtrak```: ,'(1 2 3 4)

17:47 clojurebot: (1 2 3 4)

17:47 gtrak```: Turtl3boi, like a linked-list

17:48 TimMc: Turtl3boi: Any (...) form is a list. (+ 2 3) is a list of three elements to the compiler.

17:48 Turtl3boi: oh right basically some array-like datastructure

17:48 thanks Tim

17:48 gtrak```: but you have to quote if you want it to not eval the list

17:48 (+ 2 3)

17:48 clojurebot: *suffusion of yellow*

17:48 gtrak```: ,(+ 2 3)

17:48 clojurebot: 5

17:48 gtrak```: ,'(+ 2 3)

17:48 clojurebot: (+ 2 3)

17:48 TimMc: Turtl3boi: The [x] in (fn [x] x) is a vector (to the compiler).

17:49 Turtl3boi: thanks for the deconstruction TimMc, very helpful

17:49 gtrak```: ,(first '(+ 1 2))

17:49 clojurebot: +

17:49 gtrak```: get it?

17:50 Turtl3boi: &(second '(+ 1 2))

17:50 lazybot: ⇒ 1

17:50 Turtl3boi: &(fourth '(+ 1 2))

17:50 lazybot: java.lang.RuntimeException: Unable to resolve symbol: fourth in this context

17:50 Turtl3boi: aiya!

17:50 TimMc: Turtl3boi: The thing is that vector literals [+ 2 3] get reconstructed as vectors, whereas list literals (+ 2 3) are reconstructed as function calls.

17:50 &[+ 2 3]

17:50 lazybot: ⇒ [#<core$_PLUS_ clojure.core$_PLUS_@14f6e3f> 2 3]

17:50 daniel___: if should treat false and nil the same right? cant work out why this function isn't working,

17:50 TimMc: &(+ 2 3)

17:51 lazybot: ⇒ 5

17:51 qbg: daniel__: As long as the false is the real false value

17:51 daniel___: clojure.core=> (has-access? "daniel" "daniel")

17:51 {:_id #<ObjectId 4ee526709a1785d4dbe3f148>, :name "daniel", :password "daniel"}

17:51 clojure.core=> (has-access? "daniel" "da")

17:51 nil

17:51 Turtl3boi: makes sense since [ ] means an argument list so you wouldn't want it to be a function call

17:51 daniel___: should (if has-access?... work?

17:51 cgray: does unquote only work inside a backtick?

17:52 qbg: cgray: yes

17:52 devn: technomancy: you gotta tell #heroku that they need some sort of representation in #heroku besides a bot that posts the same message over and over.

17:52 TimMc: Turtl3boi: That's not why [ ] is used, though.

17:52 gtrak```: Turtl3boi, that's just sugar, in lisp and scheme they use ( ) for arglists

17:52 qbg: daniel__: You mean (if (has-access? ...) ...)

17:52 cgray: qbg: how can you unquote something outside a backtick then?

17:52 daniel___: yeah cgray

17:52 qbg: even

17:52 qbg: cgray: Just don't quote it?

17:52 cgray: you have an example?

17:52 cgray: qbg: I don't have that option :)

17:53 daniel___: isnt ~ reverse of a '

17:53 cgray: qbg: http://www.4clojure.com/problem/121

17:53 Turtl3boi: Why is [ ] used TimMc

17:53 cgray: qbg: I can't figure out how to apply '/

17:53 gtrak```: it improves readability

17:54 TimMc: Turtl3boi: [ ] as a syntax form is used to represent bindings of some sort -- such as in let or fn. It's visually distinct from ( ) and has the additional (sort of) connotation of a fixed-length collection.

17:54 That last bit is debatable.

17:54 Basically, it's just convention to do it that way.

17:55 qbg: cgray: Take a look at resolve

17:55 cgray: Or ns-resolve

17:56 TimMc: cgray: clojure.lang.LispReader defines unquote, I think...

17:56 cgray: #isUnquote ... return form instanceof ISeq && Util.equals(RT.first(form),UNQUOTE);

17:56 All hardcoded.

17:57 cgray: qbg: thanks, ns-resolve worked

17:57 daniel___: hmm seems i needed to restart the noir server

17:58 cgray: qbg: but ns-resolve trips the 4clojure alarm :(

17:58 qbg: cgray: The problem says you only need to support the 4 basic math operations

17:58 Turtl3boi: it's a binding? eh?

17:59 qbg: cgray: You could just use case to dispatch on the symbol

17:59 Turtl3boi: so "let [a 2]" means a = 2

17:59 cgray: qbg: true, but I wanted to do it the "right" way :)

17:59 gtrak```: Turtl3boi, ya

17:59 qbg: cgray: I think the point of the problem is to implement a simple eval

17:59 cgray: qbg: that's what I'm doing

17:59 qbg: cgray: So that would be the right way :p

17:59 Turtl3boi: what if i said "let [a 2 2]" does that means " a = 2 = 2"

18:00 gtrak```: it means you break clojure :-)

18:00 weavejester: Turtl3boi: Nope

18:00 TimMc: Turtl3boi: Try it, you'll get a complaint about a wrong number of elements.

18:00 qbg: Turtl3boi: That is invalid

18:00 Turtl3boi: then how do i bind 3 items

18:00 gtrak```: ,(let [a 1 b 2 c 3] [a b c])

18:00 clojurebot: [1 2 3]

18:00 qbg: Turtl3boi: You need an even number of elements

18:00 TimMc: Turtl3boi: and add commas to taste.

18:00 weavejester: It's a [key1 value1 key2 value2 ... keyN valueN] deal

18:00 gtrak```: normally, i'd line them up vertically, since i'd have more than one line

18:01 Turtl3boi: &(let '[a 1, b 2])

18:01 lazybot: java.lang.IllegalArgumentException: let requires a vector for its binding

18:01 Turtl3boi: &(let [a 1, b 2])

18:01 lazybot: ⇒ nil

18:01 gtrak```: ,(class '[1 2])

18:01 clojurebot: clojure.lang.PersistentVector

18:01 TimMc: Now put something in the body of the let for it to evaluate.

18:01 gtrak```: huh?

18:01 Scriptor: Turtl3boi: you can use commas in there to make it more readable, (let [a 1, b 2, c 3]), commas don't have any syntactic significance otherwise

18:01 alexbaranosky: ~turtleboy

18:01 Turtl3boi: &(let [a 1, b 2] [a b ])

18:01 clojurebot: Excuse me?

18:01 lazybot: ⇒ [1 2]

18:01 qbg: cgray: For this language, those ops are the special forms, so dispatching on them is the way to go

18:02 Turtl3boi: yes alex?

18:02 alexbaranosky: just playing with clojurebot :)

18:02 sorry to interrupt

18:02 Turtl3boi: lol you guys make programmign so fun

18:02 TimMc: yay!

18:02 gtrak```: ,(let '[a 1])

18:02 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: let requires a vector for its binding>

18:02 gfredericks: $inc us

18:02 lazybot: ⇒ 2

18:03 gtrak```: why does that break? ^^

18:03 TimMc: gtrak```: (quote [a 1])

18:03 qbg: let is a macro

18:03 TimMc: let's see...

18:03 gtrak```: TimMc, well yea :-)

18:03 why does that break it?

18:03 TimMc: &`(let '[broken stuff])

18:03 qbg: (let (quote [a 1])) is invalid for it

18:03 Turtl3boi: still hazy on the "closure" concept

18:03 lazybot: ⇒ (clojure.core/let (quote [clojure.core/broken clojure.core/stuff]))

18:03 TimMc: gtrak```: let looks at the first arg, finds a list instead of vector, SHIT GOES DOWN

18:04 gtrak```: ahhh

18:04 too much magic

18:04 qbg: Turtl3boi: A closure is a function that isn't at the top level in terms of lexical scope

18:04 alexbaranosky: TimMc, finds a symbol no?

18:04 weavejester: Turtl3boi: Do you know Python?

18:05 qbg: (fn [x] (fn [y] (+ x y)))

18:05 alexbaranosky: &(list? '[a 1])

18:05 lazybot: ⇒ false

18:05 qbg: The inner function is a closure

18:05 alexbaranosky: &(symbol? '[a 1])

18:05 lazybot: ⇒ false

18:05 qbg: and has access to x

18:05 brehaut: qbg: thats not really true

18:05 gtrak```: ,`'(+ 1)

18:05 Turtl3boi: so it's a function within a function

18:05 clojurebot: (quote (clojure.core/+ 1))

18:05 Scriptor: Turtl3boi: before you take on closures, understand lexical score first

18:05 Turtl3boi: k

18:05 Scriptor: *scope

18:05 TimMc: (╯°□°)╯︵ lɐʌǝ)

18:05 weavejester: Turtl3boi: It's basically a function that can access variables from outside.

18:06 gtrak```: ,`(list '(+ 1))

18:06 clojurebot: (clojure.core/list (quote (clojure.core/+ 1)))

18:06 gtrak```: ,(list '(+ 1))

18:06 clojurebot: ((+ 1))

18:06 alexbaranosky: &(vector? '[a 1])

18:06 lazybot: ⇒ true

18:06 TimMc: alexbaranosky: It's a cons, really

18:06 weavejester: So... (let [x 1] (fn [y] (+ x y)))

18:06 alexbaranosky: vector!

18:06 gtrak```: ,(apply list '(+ 1))

18:06 clojurebot: (+ 1)

18:06 weavejester: Is the same as: (fn [y] (+ 1 y))

18:06 alexbaranosky: ok enough lazybot for one day

18:06 TimMc: alexbaranosky: That's not what the compiler sees!

18:06 alexbaranosky: You have to check (first `'[a 1]), with the syntax quote.

18:07 weavejester: The anonymous function can access "x" defined outside.

18:07 TimMc: &(seq? `'[a 1])

18:07 lazybot: ⇒ true

18:07 qbg: &(vector? ''[a 1])

18:07 lazybot: ⇒ false

18:07 gtrak```: Turtl3boi, it's like running an anonymous inner class that uses a value in local scope after the function has terminated

18:08 Turtl3boi: i know a tiny bit of python weavejester kun

18:08 weavejester: Turtl3boi: Okay, so in Python it would be like...

18:08 TimMc: In Python this would require newlines, I think.

18:08 weavejester: Yeah, I was going to copy-paste :)

18:09 gtrak```: "A closure retains a reference to the environment at the time it was created (for example, to the current value of a local variable in the enclosing scope)"

18:09 Scriptor: ...it's pretty intuitive once you understand how lexical scope works

18:09 weavejester: def add(x):

18:09 def add_x(y):

18:09 return x + y

18:09 return add_x

18:10 TimMc: (Note: Multi-line copy-paste was performed by a professional. Do not attempt this at home.)

18:10 weavejester: So if I wrote add(1), this would return a function that added 1 to things

18:10 TimMc: Haha :)

18:10 The key point is that the inner "add_x" function remembers the value of x

18:10 That might seem obvious

18:11 gfredericks: but you can't do it in java

18:11 weavejester: yeah

18:11 gtrak```: sure you can, why not?

18:11 TimMc: It's just ugly as hell.

18:11 weavejester: Well, not 100% anyway

18:11 alexbaranosky: can't is not the same as is ugly

18:11 TimMc: Add a Box<T> class and you're good.

18:11 weavejester: I think Java has some restrictions. Like in Java, "x" would have to be final.

18:11 qbg: Or use a one element array

18:11 alexbaranosky: just create an anonymous class factory :)

18:12 qbg: weavejester: Same as clojure

18:12 TimMc: alexbaranosky: Like... an AbstractSingletonProxyFactoryBean?

18:12 qbg: The variables become a hidden field

18:12 weavejester: qbg: True :) - but Clojure is kinda built around immutability.

18:12 qbg: So that is why they need to be final

18:12 TimMc: A great example of closures is a let that binds an atom or ref and then returns some functions that have that ref in scope. The let is gone, but the closures retain a shared reference to that "box".

18:12 gtrak```: TimMc, is the joke that those modifiers have no associativity?

18:13 TimMc: gtrak```: The joke is that there is no joke. http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html

18:13 alexbaranosky: nice

18:13 gtrak```: Abstract(SingletonProxy)(FactoryBean)? or (AbstractSingleton)(ProxyFactory)Bean?

18:14 qbg: I think the first

18:14 TimMc: gtrak```: Like all dadaist art, it is up for the viewer to decide.

18:14 lucian: gtrak```: i've actually seen those

18:14 TimMc: gtrak```: The real gold is the description: "Convenient proxy factory bean superclass for proxy factory beans that create only singletons."

18:15 *convenient*

18:15 gtrak```: lol

18:15 qbg: Well, it does define some stuff for you

18:15 gtrak```: i think spring is way more complex than clojure

18:15 qbg: It makes Java better though

18:16 TimMc: qbg: As far as I can tell, Spring just makes it harder to follow the code path.

18:16 gtrak```: qbg, the line blurs once they start adding spel to the xml :-) at some point it just becomes a language

18:16 Turtl3boi: gtrak do you still do java or not?

18:16 gtrak```: yea

18:16 qbg: That is why you go for the anotations

18:17 Avoid most of the xml

18:17 gtrak```: qbg, right, that's when they realize what they've done :-)

18:17 TimMc: gtrak```: "spel"... please don't tell me that's "Spring Expression Language"...

18:17 gtrak```: TimMc, yup

18:18 * TimMc kills self

18:18 TimMc: That's terrible.

18:18 and I hope to never see it.

18:18 qbg: Avoid AOP I guess

18:18 gtrak```: it's just funny

18:19 Turtl3boi: so gtrak do you do heavily multi threaded programming now with clojure

18:19 gtrak```: <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>

18:19 alexbaranosky: TimMc, what languages do you use predominantly at work?

18:19 qbg: <property name="randomNumber" value="4"/>

18:19 gtrak```: Turtl3boi, not so much, I'm mostly stuck on java right now

18:20 TimMc: alexbaranosky: Java. Trying to wedge in some Clojure.

18:20 qbg: Spring MVC isn't so bad though

18:20 Except for the V and the C :)

18:21 gtrak```: Turtl3boi, if you recall, last time we talked I told you how scared i was of multi-threading :-), I still haven't started studying that stuff

18:21 TimMc: BeanFactoryTransactionAttributeSourceAdvisor -- this library is so far up its own ass...

18:21 Turtl3boi: rofl.....

18:21 alexbaranosky: TimMc, we do mostly Java then Scala then ruby for scripting

18:21 qbg: Check out Spring 3

18:22 gtrak```: but I'm working on backend rdf graph management code right now

18:22 lucian: alexbaranosky: that seems to me at least one language too many :)

18:23 alexbaranosky: lucian, don't forget the javascript then

18:23 gtrak```: TimMc, that's what you get when you try to mix code and data badly, though I kinda like the approach for ui's like with mxml

18:23 TimMc: and HTML and CSS -- not to be trifled with

18:23 Scriptor: alexbaranosky: how do you split what's done in java and what's in scala?

18:23 Turtl3boi: im supposed to know what rdf graphs are lol

18:23 TimMc: Turtl3boi: Haha, I'm trying to learn that stuff at work right now!

18:23 lucian: Turtl3boi: is that a reference to you rnick?

18:23 TimMc: SPARQL and all that.

18:23 alexbaranosky: lucian, to be fair the Ruby stuff isn't production code, just scripts, perhaps for performance testing etc

18:23 gtrak```: I don't really know what they are yet and I've been writing the code for a few months :-)

18:24 TimMc, what are you doing with that stuff?

18:24 TimMc: alexbaranosky: Yeah, Python occupies that niche where I work.

18:24 Turtl3boi: reference to my nick? nani?

18:24 lucian: alexbaranosky: i guess i just dislike scala a lot. i would use java + jruby or something

18:24 alexbaranosky: Scriptor, we do new modules in Scala, and write additions to old modules in Java ...... mainly that is the method we use to choose

18:24 TimMc: Turtl3boi: "TURTLE" is an RDF format.

18:25 "terse triple"

18:25 * lucian writes python and coffeescript at work

18:25 Turtl3boi: hahaha computer sci is so hard

18:25 alexbaranosky: lucian, what do you dislike about Scala, specifically?

18:26 lucian: alexbaranosky: syntax and type system

18:26 * qbg thinks Spring is what you get when you try to write Clojure in Java

18:26 alexbaranosky: I'm a clojure guy, but given the option between Java and Scala I can't think of any time I'd choose Java

18:26 lucian: alexbaranosky: but if jruby were added to that list, i'd choose that

18:26 even though i don't really know ruby that well

18:26 alexbaranosky: Scala's type system is much better than JAva's

18:26 TimMc: Hey, wow! I actually need to optimize something! :-D

18:26 lucian: sure, but it's worse than almost everything else

18:26 gtrak```: alexbaranosky, I guess i could probably figure out scala in a few weeks, but I don't see the point

18:27 alexbaranosky: but that makes it more complex of course

18:27 lucian: it's not as clean as haskells and it's not as simple as clojure/python's

18:27 and the syntax just makes my eyes bleed

18:27 gtrak```: qbg, yea

18:27 alexbaranosky: yeah to each his own, but if you like Java over Scala, I'm sorry but we can't be friends :D

18:28 lucian: heh

18:28 no, i don't

18:28 gtrak```: i'd say i like java over scala for familiarity reasons

18:28 alexbaranosky: to me it's a practical thing... I'm taking what options I have

18:28 lucian: but if i were in your position, i'd keep java for old code and use clojure/jruby/jython for new code

18:29 alexbaranosky: sure, i know it's not always an option

18:29 i'm not criticising you for writing it. i'm just saying if i had the choice, i'd do differently

18:29 and i was thinking if ruby is already in the door, jruby might be an easy sell

18:29 gtrak```: qbg, dependency injection is the new spaghetti code

18:29 alexbaranosky: Mayyyyybe, except I'd rather be selling Clojure

18:30 and also Ruby is really only used by a small number of us for scripting stuff

18:30 lucian: i see

18:30 TimMc: I think we tried using Python embedded inside a Java project and it failed miserably.

18:31 qbg: gtrak```: Yeah, don't try to test the result

18:31 gtrak```: jython's dead

18:31 lucian: a little, yes

18:31 TimMc: Not jython -- embedding a Python VM.

18:31 something like that

18:31 alexbaranosky: are ny of you looking for Clojure positions? (sorry can't help, just curious)

18:32 lucian: TimMc: oh. that does sound failure-y

18:32 Turtl3boi: is it possible to get a programming job without being super pro

18:32 alexbaranosky: yes

18:32 Turtl3boi: like, being a EE major instead of CS

18:32 TimMc: Turtl3boi: Absolutely.

18:32 lucian: alexbaranosky: i'm looking for a new job and i like clojure

18:33 alexbaranosky: Turtl3boi, most important thing about being a programmer is knowing the ins and outs of programming

18:33 Turtl3boi: i only took the data structures class in C/C++, but i didn't take compilers and all those other hard ass CS courses

18:33 TimMc: Turtl3boi: All those CS courses may or may not help you, depending on the profs.

18:33 lucian: Turtl3boi: don't worry much. the vast majority of graduates can't write fizzbuzz

18:33 alexbaranosky: Turtl3boi, learn that ish on your own

18:33 TimMc: but the stuff they *should* be teaching you is *really* important.

18:34 Scriptor: there's also computer engineering, get a mix of both cs and ee

18:34 alexbaranosky: Turtl3boi, I can give you a thirty book reading list - it'll make you better read than 99% of candidates

18:35 Turtl3boi, by that mean you would know important stuff

18:35 Scriptor: alexbaranosky: make that list ofr all of us!

18:35 qbg: Turtl3boi: It isn't hard to get to thedailywtf level, and somehow those people have jobs...

18:35 Turtl3boi: the only thing i've done is embedded programming on a 8051

18:35 * qbg provides the depressing view :)

18:36 Turtl3boi: and i wasn't the lead programmer. i was the bench testing guy who would test out how well the code works in the chip, and give feedback

18:36 so in other words i didn't have a programming job

18:36 alexbaranosky: qbg, thing is if you want to get into the business, but don't have credentials (like the wtf programmers do have) then it's best to know what you are doing really well

18:37 Turtl3boi: i really want to apply to google

18:37 i'm scared i will get smoked in the interview though

18:38 alexbaranosky: Turtl3boi, my approach is to come well prepared - if you do that, then you have nothing to be scared of ---- if you aren't well-prepared, you're just relying on luck to sneak into a job

18:39 gtrak```: Turtl3boi, Google, MS, those guys are willing to waste a lot of money on interviewing too many people, and aren't afraid of turning away good guys

18:39 alexbaranosky: Scriptor, seriously? If you want just contact me on github or something and I'll send a list

18:40 Scriptor: alexbaranosky: same username on github?

18:40 Turtl3boi: yeah, right, i need to become a solid programmer and now's my chance

18:40 i think i get OOP now

18:40 but that's not going to be enough

18:40 i need more experience in new ideas

18:41 gtrak```: these things take time

18:41 TimMc: Turtl3boi: What you need is exposure to idioms and thought patterns. Knowing syntax isn't enough.

18:42 Speaking of which, has anyone here read this? http://www.aosabook.org/en/index.html

18:42 "The Architecture of Open Source Applications"

18:43 alexbaranosky: getting a job takes multiple factors: programming skill, good community presence, good resume, good interview skills, networking

18:44 Turtl3boi, concepts trump syntax

18:46 Turtl3boi: i have zero community presence lol

18:46 jesus

18:46 that's probably what i need to work on

18:47 gtrak```: fundamentals

18:47 technomancy: devn: I know; it's so embarrassing =\

18:49 TimMc: (for anyone else who was confused, that was re: #heroku)

18:49 alexbaranosky: figured

18:49 Turtl3boi: it's funny how google has jobs right up my alley (hardware design), didn't expect that (not that i want those jobs)

18:50 alexbaranosky: TimMc, that open source book looks interesting

18:53 TimMc: I've been poking through it, it's kinda interesting.

18:53 All high-level stuff.

18:54 Turtl3boi: do you think i could have a "community presence" simply by making some stupid image processing java or clojure app and putting in a website to sell it

18:55 gtrak```: only if people give a shit :-)

18:55 alexbaranosky: I meant more like activity in the open source community or whatever

18:55 the jobs I've worked at would consider that a good thing for a potential junior develoepr hire

18:56 of course it also depends on what kinds of jobs you are targeting

18:56 I'd hone my resume and persona towards the specific place of business I most want to work at

18:56 darnit: see now I'm giving out my secrets ;)

18:56 Turtl3boi: hahaha

18:57 alexbaranosky: it is good to know what kind of work people need done, and make sure you're good at that.

18:57 Turtl3boi: lol google is such a pain because they have so many different personas working there

18:57 alexbaranosky: know what kind of person they look for too, and then do your best to achieve that

18:57 Turtl3boi: i just want to work for a company that is not gonna go belly up in 6 years from now

18:58 alexbaranosky: six years? That's like an eternity

18:58 Turtl3boi: yeah well i figure google is one of the few companies

18:58 gtrak```: if you can get a job at google, you can get a job at lots of places

18:59 alexbaranosky: what is your thought-process that led you to wanting to work somewhere that won't be belly up in 6 years? Curious to hear

18:59 gtrak```, definately

19:00 qbg: Turtl3boi: You could get a job a place that doesn't produce software for external use

19:01 TimMc: qbg: What's your thought process on that?

19:02 Turtl3boi: well alex, my first company i had a bad experience. i worked really hard for 5 years and at the end of 5 years i had seen 9 layoffs and 2 years straight of no raises. i barely made more than i had started off at

19:02 qbg: Software business can be volatile. Other industries need software and can be less volatile

19:03 Turtl3boi: this was a hardware company

19:03 qbg: Downsides to that though

19:03 alexbaranosky: Turtl3boi, it might depend on what region of the US you're in too... I'm in Boston, where there are lots of options for SW

19:04 Turtl3boi: i don't mind living in boston but i would prefer california only because my family is there

19:04 i have family both in so and norcal

19:04 alexbaranosky: San Francisco has lots of SW jobs too right?

19:04 Turtl3boi: yes but then it also is very competitive

19:05 alexbaranosky: Turtl3boi, there's really no way to escape the need to be awesome

19:05 at least a *little* awesome

19:05 life is competitive, you know?

19:06 Turtl3boi: the only thing i'm awesome in is probably like writing documentation

19:06 lol

19:07 gtrak```: if your documentation is coherent, then your code might be too

19:07 Turtl3boi: i did analog and RF test, i was pretty slick at that

19:07 but then, i'm trying to convert to more programming-ish....yeah good point gtrak

19:07 i can write great code gtrak, but then again i also take forever to do it

19:08 gtrak```: Turtl3boi, well, if you're writing the same code over and over you're doing something wrong

19:09 writing it the second time takes me about 1/10th the time as the first

19:09 Turtl3boi: alright gtrak, how do i make an app in clojure

19:09 gtrak```: start with leiningen

19:09 Turtl3boi: like an app with a frontend GUI

19:10 you know how java uses Swing right? does CLojure use that too

19:10 gtrak```: ah, there's a couple projects out there, you can write straight-up swing if you like or use another layer

19:10 Turtl3boi: k

19:10 alexbaranosky: leiningen with seesaw for gui programming or maybe noir for a webapp

19:10 gtrak```: clojure has java interop

19:10 Scriptor: Turtl3boi: clojure *can* make use of swing, but otherwise it has its own web frameworks

19:10 gtrak```: i've been meaning to take a look at seesaw myself

19:10 alexbaranosky: I personally wouldn't do swing straight

19:13 Turtl3boi: so clojure is more for web apps

19:13 gtrak```: i wouldn't say that..

19:14 but java on the desktop is classically not so good

19:14 Turtl3boi: it is for making a stupid little image processing demo GUI

19:15 ssideris: hello

19:15 gtrak```: well that will be fine

19:15 Turtl3boi: i just want to try out some of the multi threaded feature of clojure

19:15 and image processing is perfect for that

19:15 ssideris: what's the best way to check the clojure version at runtime?

19:15 Turtl3boi: well a lot of image processing algorithms do better when you multi thread them i would say

19:15 gtrak```: ,*clojure-version*

19:15 clojurebot: {:major 1, :minor 3, :incremental 0, :qualifier nil}

19:16 ssideris: gtrak```: thanks

19:17 gtrak```: Turtl3boi, so, what clojure's really good at is dealing with lazy-sequences

19:18 i don't think it's the best for implementing a low-level image-proc algorithm, but it'd be great for gluing together filters, for instance

19:18 Turtl3boi: you mean they consume and return sequences incrementally

19:19 gtrak```: yea

19:19 delayed computation

19:19 for example:

19:19 ,(map (fn [x] (+ 1 x)) [ 1 2 3 4 5])

19:19 clojurebot: (2 3 4 5 6)

19:19 gtrak```: ,(class (map (fn [x] (+ 1 x)) [ 1 2 3 4 5]))

19:19 clojurebot: clojure.lang.LazySeq

19:20 gtrak```: give me a sec

19:21 lol, how do I turn it into a vec :-)

19:21 alexbaranosky: (doc vector)

19:21 clojurebot: "([] [a] [a b] [a b c] [a b c d] ...); Creates a new vector containing the args."

19:22 gtrak```: ,(doall (map (fn [x] (+ 1 x)) [ 1 2 3 4 5]))

19:22 clojurebot: (2 3 4 5 6)

19:22 gtrak```: ,(class (doall (map (fn [x] (+ 1 x)) [ 1 2 3 4 5])))

19:22 clojurebot: clojure.lang.LazySeq

19:22 gtrak```: Turtl3boi, well, the point is, map doesn't actually compute the value until you ask for the first element of the lazy seq :-)

19:22 i'm just not demonstrating it :-)

19:23 alexbaranosky: ,(class (vec (doall (map inc [ 1 2 3 4 5])))

19:23 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

19:23 alexbaranosky: ,(class (vec (doall (map inc [1 2 3 4 5]) )))

19:23 clojurebot: clojure.lang.PersistentVector

19:24 gtrak```: ,(vec (map (fn [x] (+ 1 x)) [ 1 2 3 4 5])))

19:24 clojurebot: [2 3 4 5 6]

19:24 Turtl3boi: well never hurts to try

19:24 maybe i should just do a web app in clojure

19:24 gtrak```: point is, you can keep gluing stuff on for free

19:25 gfredericks: (second (concat (range) (range) (range) (range)))

19:25 ,(second (concat (range) (range) (range) (range)))

19:26 clojurebot: 1

19:26 gfredericks: ^ concatenating four infinite sequences

19:26 gtrak```: haha

19:26 ,(range)

19:26 clojurebot: (0 1 2 3 4 ...)

19:26 gtrak```: &(range)

19:26 lazybot: java.lang.OutOfMemoryError: Java heap space

19:26 gtrak```: hehe :-)

19:26 Turtl3boi: this actually seems great for image processing

19:27 but it's not going to be as fast as C or Java

19:27 qbg: You can use clojure as the glue between java components

19:27 gtrak```: Turtl3boi, well, depends on the algorithm, right? if you're doing a lot of mutable state, clojure's not right for that

19:28 Turtl3boi: mutable state.....image processing probably does better in a purely functional world

19:28 nix that last sentence

19:28 uhh what am i trying to say

19:29 oh actually i can see what you're saying

19:29 what's mutable state lol

19:30 gtrak```: haha

19:30 mbac: i made this with clojure https://www.youtube.com/watch?v=nZGCnDSC4Rc

19:30 source available if anyone's interested

19:30 ;)

19:30 gtrak```: overtone?

19:30 mbac: no just scraping memegenerator really

19:31 people here helped with it today so i thought i'd offer it up if anyone cared

19:31 blakesmith: Speaking of lazy sequences... Will this actually walk the sequence once or twice?

19:31 &(map inc (filter #(= 0 (mod % 2)) (range 10)))

19:31 lazybot: ⇒ (1 3 5 7 9)

19:31 gtrak```: once

19:31 weavejester: Once

19:31 blakesmith: Awesome.

19:31 I dig it.

19:32 I got worried doing too much chaining. ;-)

19:32 gtrak```: it can take it

19:32 if you can dish it out

19:32 Turtl3boi: what is mbac talking about

19:32 weavejester: filter and map are both lazy, so they don't do anything until you start iterating

19:32 qbg: And the results are cached

19:33 * blakesmith swoons

19:33 ben_m: Wow, that's pretty cool.

19:34 blakesmith: Are lazy sequences a common feature of most Lisps?

19:34 qbg: No

19:34 blakesmith: Seems like you'd pay some big performance penalties otherwise...

19:34 ben_m: Most lisps are more multi paradigm

19:34 qbg: How so?

19:35 Memory consumption would be the most obvious one

19:35 gtrak```: blakesmith, think of lazy seqs as just a way to describe and compose computations

19:35 stream processing

19:36 blakesmith: Ah, I see.

19:36 Turtl3boi: is leiningen for linux only?

19:36 gtrak```: nope

19:36 ben_m: No :)

19:37 blakesmith: qbg: I was thinking higher level functions like map and filter that would walk a sequence multiple times when chained together.

19:37 gtrak```: they won't

19:37 qbg: Nope

19:37 In CL you get a new list

19:38 So that doesn't happen even there

20:01 Turtl3boi: gtrak if you take me under your wing you won't be disappointed

20:02 i promise it will be the best investment you ever made

20:09 gtrak```: Turtl3boi, ha, can I buy stake in your future earnings?

20:09 Turtl3boi: if you help me land a job of course i'll kick you back some

20:09 we can set it up as one time payment or % of paycheck

20:11 gtrak```: nah, that seems too weird :-)

20:11 alexbaranosky: Turtl3boi, not too weird for me though :)

20:12 gtrak```: alexbaranosky can barely handle his emacs though

20:12 Turtl3boi: lol

20:12 alexbaranosky: emacs does not a programmer make

20:12 still not sold on it

20:12 :P

20:12 gtrak```: indeed :-)

20:12 alex, remember me from conj? i think we hung out a couple of times

20:13 alexbaranosky: yes! definitely

20:13 gtrak```: Turtl3boi, there aren't any shortcuts really, but i'm always willing to learn new stuff to help people out

20:14 Turtl3boi: you guys hung out?

20:14 alexbaranosky: Turtl3boi, I'm a big believer in reading great books and lots of practice

20:14 Turtl3boi: i read a lot actually

20:14 but i don't have any study partners

20:14 gtrak```: Turtl3boi, yea, at the last clojure conference

20:14 Turtl3boi: i wish i could do a project with someone decent

20:15 gtrak```: (un)fortunately, my job takes a lot out of me :-)

20:15 but the next thing I really want to look at is logic programming

20:16 alexbaranosky: Turtl3boi, you could work on some open source project

20:16 another great way to learn is to work with really smart people... best if in real life, but open source could be good too

20:18 Turtl3boi: can i work w/ you alex

20:18 gtrak what logical programming? like hardware description languages

20:19 alexbaranosky: Turtl3boi, I'd be inclined to say sure

20:19 Turtl3boi: however......

20:19 but......

20:19 unfortunately.....

20:19 gtrak```: Turtl3boi, no, like prolog

20:19 Turtl3boi: this is what i hear from women when i ask them out

20:19 ahh ok

20:19 ben_m: Where do you meet women that know Prolog?

20:19 :P

20:20 alexbaranosky: ha

20:20 gtrak```: where do you meet women that can tolerate a conversation about prolog? :-)

20:20 alexbaranosky: MIT!!!

20:20 ben_m: ?- like(prolog, women)

20:20 no.

20:20 gtrak```: damn, that was fast

20:20 alexbaranosky: Turtl3boi, in all seriousness, I love helping people, but one thing I hate is people who don't try

20:21 brehaut: ben_m: to start with you ask it like knows_prolog(X), sex(X, female), current_location(X, Y).

20:21 alexbaranosky: so ben_m are you saying something about women and logic???

20:21 lazybot: alexbaranosky: How could that be wrong?

20:21 ben_m: alexbaranosky, I would never!

20:22 Turtl3boi: alexbaranosky i try super hard at everything i do

20:22 ben_m: brehaut: awesome(X) :- likes_prolog(X), sex(X, female). ? :)

20:23 actually

20:23 Everyone who likes Prolog is pretty awesome.

20:23 and/or crazy

20:24 brehaut: its been a while since i wrote prolog, but i didnt think you had to created a predicate for a query?

20:24 Turtl3boi: does prolog help for control systems

20:24 ie, programming feedback for a microcontroller system

20:24 ben_m: You don't have to and that's not necessarily a query

20:30 alexbaranosky: Turtl3boi, you should probably send me an email telling me more about yourself, what you know, and what you want to know/achieve andw e could go from there alexander dot baranosky at gmail dot com

20:30 Turtl3boi: wow thanks now i have you and gtrak both

20:30 on my mailing list

20:30 gtrak```: Turtl3boi, always open to questions or talks, I'm just overcommitted

20:31 Turtl3boi: i understand

20:31 you probably also have a gf ,etc

20:31 haha

20:31 gtrak```: nobody's perfect :-)

20:33 Turtl3boi, but the clojure community's full of smart guys, i recommend getting involved, even if you don't end up writing clojure, you'll learn a lot

20:34 Turtl3boi: do you guys belong to a forum of clojure?

20:34 if so let me sign up

20:34 gtrak```: there's a mailing list, yea

20:35 http://groups.google.com/group/clojure

20:36 and the dev list is fun to watch but it's not for regular clojure users

20:39 Turtl3boi: damnit i might have to put my real identity out in cyberspace to grow my programming presence

20:39 gtrak```: just get over it

20:39 especially if you're a programmer

20:40 alexbaranosky: employers will google you

20:40 gtrak```: you can use it to your advantage

20:41 duck1123: if you're gonna show up in a google search, make sure it's for good things

20:41 Turtl3boi: k

20:41 alexbaranosky: gtrak```, exactly

20:41 Turtl3boi: maybe i should start a google+ and facebook too

20:41 duck1123: and drive that guy in california with the same name as you that was in a golf tournament and a high school play

20:42 off the net

20:44 alexbaranosky: yeah, it depends how unique your name is I guess

20:44 there's only one other version of *me* I've ever run into

20:50 Turtl3boi: nice

20:50 you must be russian

20:50 err polish

20:55 i wonder if it's too late for me to convert to programming

20:55 i just turned 30 :/

20:55 gtrak```: nah

20:56 it just might take longer than you think

20:57 Turtl3boi: yea worth a try tho

20:57 i still feel like i'm 22 even tho i'm 30


21:00 Turtl3boi: hahaha

21:00 gtrak```: clojure separates time and values

21:00 pdk: really if you can get used to putting yourself in the mindset appropriate for whatever programming paradigm you pick you'll be able to do stuff

21:00 gtrak```: if you have a good grasp of fundamentals, you will see everything is all the same under the covers

21:01 Turtl3boi: i have a weak understanding of low level stuff though

21:01 like computer architecture

21:01 x86 assembly

21:01 crap like that

21:01 gtrak```: I had a good comp arch class

21:02 well, my point is, programming really hasn't changed that much, what's changed are the relative tradeoffs

21:02 Turtl3boi: k

21:02 i'll trust you on that one

21:02 i am gonna go buy that clojure book at Fry's electronics now

21:02 before they close

21:03 later

21:03 gtrak```: cya

21:12 pdk: yo which book did your arch class use

21:36 alexbaranosky: whoa, is github down?

21:37 nickmbai`: hmm down for me

21:42 erewhon: scheduled maintenance

22:00 technomancy: oooh, ring 1.0.0. very nice.

22:00 brehaut: oh, its out?

22:01 fantastic

22:03 pdk: look at that version number

22:03 two perfect circles

22:03 so fitting for ring

22:10 devn: parsing stuff is fun

22:11 anyone here use parsatron? I'm surprised there's no sep-by or next-not or something, but maybe I'm missing something obvious

22:16 mbac: how do i do the equivalent of popen("zcat foo.gz") ?

22:20 bobhope: Is there a recommended way to do dataflow programming with clojure?

22:26 technomancy: bobhope: no, the dataflow contrib library is unmaintained

22:40 gtrak```: Turtl3boi, did you get it?

22:45 * devn parses everything

22:46 devn: technomancy: that project was looking for a maintainer though right?

22:47 d'oh he left

22:47 technomancy: devn: welllllll... maybe. when I talked to the author he basically implied that it should be rewritten with protocols

22:47 devn: i was going to encourage bobhope to look into it and consider taking it up as his own project

22:47 also, even if it's in old contrib that doesn't mean it's gone forever

22:48 he could still use old contrib.

22:52 alexbaranosky: anyone planning to go to Clojure/West? I want to submit some kind of TDD-ish presentation; mostly I'm scared out of my mind to do a talk though :)

22:54 Scriptor: alexbaranosky: I'm not, but presenting is fun anyways, go for it!

22:54 alexbaranosky: Scriptor, I am going to go for it!

22:57 Scriptor: I'd like to see something about combining TDD with bottom-up programming

22:58 I guess you write the tests for the "bottom" parts first

22:59 ooh, free hotel and airfare

23:04 Raynes: Anybody here have an Ubuntu 11.10 machine with leiningen handy that can run some tests for me?

23:04 gtrak```: i've got a vm

23:04 with kubuntu

23:04 Raynes: That should be fine. git clone git://github.com/Raynes/fs.git

23:06 alexbaranosky: Is reporting a couple of tests failing on his 11.10 machine, but I can't reproduce on OS X Lion or Ubuntu 10.04.

23:06 gtrak```: gimme a sec

23:07 someone else is welcome to beat me to it

23:07 Raynes: I'm in no hurry. Don't worry about it if it's a hassle.

23:08 technomancy: Raynes: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:1)

23:08 is what I get

23:09 Raynes: technomancy: I don't even use clojure.set anywhere in the library.

23:09 And that is certainly not what he was getting. :|

23:10 I'm thinking that Ubuntu 11.10 is just broken in general. Like IE 6, only newer.

23:10 ;)

23:11 alexbaranosky: Raynes, need me for anything?

23:11 Raynes: alexbaranosky: Yeah. I need you to fix your computer.

23:11 In all seriousness, no. Just trying to find someone else with the problem right now.

23:11 alexbaranosky: bah dump dump

23:11 Raynes: I'll email you if I need anything else.

23:12 alexbaranosky: cool

23:15 gtrak```: Raynes, works for me

23:15 Raynes: gtrak```: And that's 11.04?

23:15 gtrak```: wait, actually it says 0 tests

23:15 Raynes: Its supposed to.

23:15 It's*

23:15 gtrak```: that's on 11.10

23:16 Raynes: 'lein test' doesn't summarize midje tests, but it does run them, so if there were no failure messages, it worked.

23:16 gtrak```: Thanks alot.

23:16 gtrak```: Raynes, I also use sun jdk

23:16 Raynes: So do I. That could very well be a thing.

23:16 amalloy: that's what cake test ouutputs for me, on 10.04, fwiw

23:16 Raynes: amalloy: It's probably running the tests.

23:17 amalloy: openjdk

23:17 Raynes: Anybody else on OpenJDK that can test it?

23:17 Wait, we use OpenJDK on our VPS, don't we amalloy?

23:17 amalloy: yes

23:17 Raynes: So surely that isn't an issue.

23:18 mbac: what's the best way to collect the contents of a file into a buffer if you can only load it into 1k byte buffer at a time?

23:18 that is, my .read function returns 1k but the file is 50-100MB

23:20 alexbaranosky: Raynes, I use sun jdk

23:20 Raynes: I think your computer is broken, bro.

23:20 I'll get some more people to test it later. I know a guy who can run it past the last 5-6 Ubuntu versions.

23:21 gtrak```: Thanks a lot for the help.

23:21 gtrak```: yea, np

23:21 devn: is github back up?

23:21 alexbaranosky: devn yeah

23:21 * devn takes this opportunity to back up all of his repos to his own git server

23:22 devn: alexbaranosky: btw, what ever came of the heredoc macro discussion?

23:23 alexbaranosky: I found myself in a situation tonight where we wanted to play around with a parser and we just wanted a quick and dirty way to write some short example haml blocks to test out our parser.

23:23 alexbaranosky: devn, it's on the back burner - when I get the time and inclination I may do a little statistical analysis of percentage of escape characters used like we talked about

23:24 devn: I remember being sort of iffy about the whole idea, but I found it a bit annoying to have to (apply str (rest "

23:25 %here.is my-heredoc

23:25 %which is indent-sensitive

23:25 in order to have a clear view of the number of spaces, structure of the text, etc.

23:26 alexbaranosky: devn exactly: when you want it, you REALLY wish you had it

23:26 heredocs alla carte ;)

23:28 devn I don't consider the topic dead, I just have been waiting for either more peoplew ho care, or more data

23:39 duck1123: The thing that turns me off of heredocs in clojure is all the times I've viewed a sql file that was all messed up because emacs couldn't highlight it correctly. I like that that vary rarely happens in clojure

23:39 alexbaranosky: why should Clojure be held back by the tools?

23:40 duck1123: simple to parse is different than held back by tools

23:40 alexbaranosky: I mean... if there's a use case for them, then the tools should have to catch up with the language -- it should be driven by need for the feature, is all I'm saying

23:41 duck1123, so would you be against triple-quotes? Or some kind of quote that was a bit easier to parse than heredocs?

23:41 duck1123: alhough, I've yet to find the need for them. If it's complex enough, I'll just store it somewhere else

23:42 triple quotes seem preferable to heredocs, but still feel icky

23:45 amalloy: "my language hates it when i use strings, so here come six tick-marks to say i really mean it..."

23:45 alexbaranosky: amalloy, where do you stand on the super-string issue?

23:46 amalloy: eh

23:46 alexbaranosky: I mostly hate escaping, so anything that keeps me from needing to escape I prefer... and to me putting test data in files isn't a solution I would use ever

23:47 because I feel tests are more readable with the data in front of me

23:47 (there are times I'd put it in files, I just wouldn't want to be forced to )

23:55 technomancy: Raynes: oh, "lein test" completed just fine for me

23:55 it was lein midje that failed

23:55 fhd: Is there an article somewhere about the performance tweaks of Clojure? (I mean stuff like that conj doesn't copy the complete memory of a vector but only the added parts)

23:55 I once saw a talk about some of these things but I'd like to know some more

23:57 amalloy: $google higher order persistent hash tree

23:57 lazybot: [Understanding Clojure's PersistentHashMap ... - Higher-Order] http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/

23:58 fhd: amalloy: Brilliant, thanks :)

23:58 amalloy: fhd: fwiw, if you ever try implementing a persistent data structure in a functional language, a lot of the structural-sharing will just fall into place accidentally

Logging service provided by n01se.net