#clojure log - Jun 28 2012

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

0:24 gert: hi! Is there a way to get the values of a transient map? (vals (transient {})) doesn't work (because the transient map doesn't implement ISeq)

0:55 denysonique: hey

0:55 java.io.FileNotFoundException: Could not locate clojure/string__i

0:55 I installed Clojure by apt-get install clojure on Ubuntu

0:56 (use 'clojure.string) throws the above error

0:56 mybuddymichael: denysonique: Use leiningen instead.

0:56 TheBusby: denysonique: you probably want to use leiningen instead

0:56 denysonique: thanks

1:06 technomancy: Raynes: most conference recording is very short-staffed, but I think in the case of InfoQ they spread them out to guarantee a continual stream of traffic

1:16 lynaghk`: New C2 release, including some new data-binding and computed-observable stuff that may be of interest to anyone developing cljs apps: https://groups.google.com/forum/?fromgroups#!topic/clojure/KCe96DbMD6k

2:24 ktsuji: technomancy: I've started using leiningen2 and found that when I use lein run, "All namespaces already :aot compiled." is outputted to stdout even after it has been compiled once.

2:24 this didn't happen in leiningen1 but is there a way to turn off that output? I did some searching but could not find out the solution so far.

2:27 this goes the same with lein trampoline run as well.

2:28 I'm using Leiningen 2.0.0-preview7.

2:34 antares_: ktsuji: can you post your project.clj?

2:34 SrPx: When I define a function with (defn [a b] etc...) can I get the form I used after?

2:35 I read clojure programs can modify clojure programs easily. What that is supposed to mean.

2:36 antares_: SrPx: defn just defines a var but you can print it back to string that Clojure reader can read

2:37 SrPx: what?

2:37 antares_: I think "loading code and transforming it" case is pretty rare. It is more common to use a concise DSL that generates forms once.

2:37 SrPx: lets start with what Clojure reader is

2:37 SrPx: do you know what parser is?

2:38 parsers take strings and produce abstract syntax trees, a tree of code elements

2:38 in Clojure, they just produce Clojure forms

2:38 ,(read-string "1")

2:38 clojurebot: hello?

2:38 SrPx: but for example, I want to code a function search functionality that will search for some patterns on my source code's functions... I wonder if that is possible (I mean besides the ugly way)

2:38 antares_: hm

2:39 amalloy: antares_: clojurebot is dead, long live lazybot

2:39 SrPx: antares_: sure

2:39 amalloy: (he's actually just disabled for a while)

2:39 antares_: amalloy: ok

2:39 SrPx: try (read-string "1") or (read-string "[1 2 3 4]") in the REPL

2:39 SrPx: okay

2:39 amalloy: &(read-string "1")

2:39 lazybot: ⇒ 1

2:40 antares_: SrPx: of course, all programming languages have parsers, the difference is, at best you typically can only get an AST for some code in e.g. Ruby or Python

2:40 muhoo: stuff added with pomegranate doesn't show up in (System/getProperty "java.class.path")

2:40 is ther eany way to get a complete classpath that includes stuff added with pomegranate?

2:40 amalloy: muhoo: no such classpath exists

2:40 antares_: SrPx: in Lisps and Clojure in particular, you can get, transform (if needed) in Clojure itself and it will be compiled

2:41 amalloy: pomegranate uses a separate classloader, not the classpath-based classloader

2:42 muhoo: ah, but is there any way to get a list of what its classloader thinks is loaded? kind of alike a "lein2 deps :tree" output, but from within the repl?

2:42 antares_: SrPx: but there may be many ways in which you use it in practice. For example, defn is a macro and it does code transformation and it is written in Clojure itself, it is not something special Clojure compiler has support for

2:42 SrPx: AST?

2:42 antares_: SrPx: defn basically expands to (def fn-name (fn [a] …)), more or less, and it will attach docstring to the var it defines if you provide it, its. So it has some logic inside that generates code.

2:42 SrPx: AST is that tree structure that parsers produce

2:43 SrPx: antares_: and after that?

2:44 antares_: SrPx: after defn has done its work and defined a var, it is compiled to JVM bytecode (for JVM Clojure) and your program uses that var by calling the function in it or passing it around

2:44 SrPx: hmm

2:45 but wait

2:45 (fn [a b c] (+ a b c))

2:45 antares_: SrPx: the point is that all code in almost any reasonably popular language can be represented by a tree and that's what compilers, IDEs, code tools and so on actually use. They do not use strings per se, strings are parsed to trees and then trees as used.

2:45 SrPx: this is all compiled into bytecode?

2:45 antares_: SrPx: (def myfn (fn [a] a)) is compiled to bytecode, yes

2:45 SrPx: I mean, clojure doesn't keep track of the fact it is a function with 3 arguments that uses the other function "+"...

2:46 antares_: what do you mean does not keep track?

2:46 there are things the compiler does check, like references to vars that do not exist

2:47 other than that, it just takes those forms and turns them into JVM bytecode for JVM to execute

2:47 SrPx: a more advanced example, have you seen http://sqlkorma.com ?

2:48 it basically lets you write Clojure forms that are "compiled" to SQL, with some nice features about it

2:48 Korma manipulates Clojure data structures quite a bit to make that happen

2:48 SrPx: antares_: no, I mean I thought it keept it stored as ([a b c] (+ a b c)) (not in text, but with the reference to "+" and info regarding the position of the arguments).

2:49 and then called the machine code when you tried to access its value

2:49 antares_: SrPx: it is "stored" but in the bytecode form. When you load a namespace or file in Clojure, it is compiled. Including at runtime.

2:49 there is no interpreter or interpreted mode

2:49 SrPx: I'll see it hold on

2:50 antares_: so yes, you have information about + and your own functions at runtime, they are stored in namespaces (which are basically map/dictionary-like things)

2:50 SrPx: antares_: this is pretty (=

2:52 amalloy: SrPx: clojure doesn't keep track of + in some way; once it sees (fn [x y] (+ x y)) it emits bytecode that says, basically, "look up the symbol + in the namespace clojure.core, resolve it to a var, and then call theVar.invoke(x, y)"

2:52 SrPx: antares_: but back to the problem, how can I write a program that will allow me to search for a function by name, arity, etc., in some clojure files?

2:52 amalloy: after that, it throws away all the information it used to construct the bytecode

2:52 SrPx: antares_: actually wait, I can just read all the code can't I

2:52 ktsuji: antares_: just the template project.clj reproduces this issue.

2:52 (defproject test-lein2 "0.1.0-SNAPSHOT"

2:52 :description "FIXME: write description"

2:52 :url "http://example.com/FIXME"

2:52 :license {:name "Eclipse Public License"

2:52 :url "http://www.eclipse.org/legal/epl-v10.html"}

2:53 :dependencies [[org.clojure/cloju

2:53 antares_: SrPx: your program would load said files and then use runtime information about functions to perform searches. But as amalloy points out, not everything is preserved for runtime. But you also treat code files like data structures and implement searches over arity, etc. This is how clojuredocs.org analyzer works, more or less.

2:53 ktsuji: sorry the last line is :dependencies [[org.clojure/clojure "1.4.0"]])

2:53 SrPx: amalloy: theVar.invoke(x,y) wouldn't that cause it to run imediatedly

2:54 antares_: sure, thanks (=

2:54 amalloy: the bytecode emitted is not immediately executed; it's loaded into the .invoke method of a new class that represents your function

2:55 SrPx: hmmm

2:56 oh and, does clojure has any kind of support for events?

2:57 antares_: what events?

2:57 events are produced by libraries and parts of a program, any language can support them

2:58 I/O, network, fs events and so on are available through JDK libraries, 3rd party libraries that build on top of that and so on

3:02 SrPx: I just mean a way to define this behavior: an object that can fire an event and other objects can sign in to listen it and get a callback called when it does happen

3:03 eh also some lib for keyboard/mouse events but I can just google that

3:05 for example...

3:06 on Python you can say value = input("What is your decision?")

3:06 and then do something with that input

3:06 you could (defn get-input [prompt] (println prompt) (read-line)) and then just do the same on clojure

3:06 but I feel like it is the wrong way?

3:07 Raynes: Nothing wrong with that.

3:07 SrPx: I guess the 'right' way to do it would be to have a kind of object representing the prompt... have it fire an event when the user writes something... and let whoever signs to it deal with the event

3:08 something like (watch input-machine enter-text (fn [text] (println text)))

3:08 "on" in the place of watch would make it more readable

3:09 Raynes: what do you think

3:09 michaelr`: depends if you want to block on input or not

3:09 SrPx: I don't mean it's wrong just not the way Clojure was supposed to work, I guess

3:09 Raynes: *shrug*. Seems like two different problems.

3:10 SrPx: michaelr`: not!

3:10 michaelr`: events are good sometimes but they can also turn into a mess in a medium to big application

3:10 SrPx: really? why?

3:10 michaelr`: events sphagethi

3:10 Raynes: lazybot is entirely event-based.

3:10 SrPx: how?

3:10 Raynes: <3 events

3:10 SrPx: Raynes: <3

3:10 so can I do it? create a class that can fire events and can be signed for those events?

3:11 Raynes: Well, Clojure isn't object oriented, so it's best to stop thinking in terms of objects and classes and the like.

3:11 denysonique: Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/contrib/server_socket__init.class or clojure/contrib/server_socket.clj on classpath: (server.clj:0)

3:12 when I try to run $ clojure myscript.clj

3:12 michaelr`: well, let's say that when the application grows it is harder to keep track of all the evented connections in the application, thus methods such as mvc developed to make it a bit more manageable (backbone.js as an in example from the js world)

3:12 denysonique: in the lein repl I can import it fie

3:12 fine*

3:13 michaelr`: SrPx: think an event which triggers a function which modifies a model which in turn triggers multiple events subscribed to the changed property on that model and so on

3:13 denysonique: michaelr`: re backbone, what is a good Clojure library for exposing a RESTful API for Backbone.js?

3:14 michaelr`: denysonique: sorry, my experience with backbone was on .net :)

3:15 denysonique: echo "(use 'clojure.contrib.server-socket)" | clojure

3:15 muhoo: trying to use korma to get access to an sqlite3 db, and getting this: https://www.refheap.com/paste/3349 when doing (select foo (:limit 1)) or (select foo (:order :ASC)). but just (select foo) seems to work

3:15 michaelr`: denysonique: but i guess the default would be compojure or noir

3:15 denysonique: results in Clojure 1.2.1

3:15 user=> java.io.FileNotFoundException: Could not locate clojure/contrib/server_socket__init.class or clojure/contrib/server_socket.clj on classpath: (NO_SOURCE_FILE:0)

3:16 works fine when I pipe that into lein repl

3:16 SrPx: michaelr`: hm

3:16 denysonique: How do I use clojure.contrib with /usr/bin/clojure?

3:17 'clojure.contrib*

3:18 amalloy: denysonique: i think the answer is: never use /usr/bin/clojure, it's not designed to do anything actually-good

3:18 Raynes: You don't 'install' Clojure, so your 'clojure' thing isn't going to work the way you want. Use Leiningen. If you want to run a script, make a project with leiningen.

3:18 And regardless, clojure-contrib was split into several independent libraries ages ago, so you probably don't want that either.

3:19 adu: omg

3:19 I just tried clojurescript

3:19 :D

3:19 denysonique: and what is it like?

3:19 amalloy: speaking of which, let me tell you how good it feels to just be like "i'ma start a new project, put 1.4.0 in project.clj, and require some libraries" and have it just work. the pain of 1.3.0 is finally over

3:20 adu: denysonique: return [cljs.core.str("Hello "),cljs.core.str(n)].join(''); … beautiful!

3:20 Raynes: amalloy: Feels even better to only have :requires in my ns in non-library projects. :>

3:20 denysonique: adu: what is the output of this?

3:20 * denysonique is new to clojure

3:20 denysonique: or lisps

3:21 adu: denysonique: it's what (defn greet [n] (str "Hello " n)) compiles to

3:21 denysonique: might be called "Hello " + x in other languages

3:21 denysonique: right

3:21 that looks nice

3:21 nice js output

3:22 adu: denysonique: yes, yes it is

3:22 denysonique: how long have you been into clojure?

3:23 denysonique: just installed it about an hour ago

3:23 muhoo: amalloy: what was painful about 1.3 that is fixed in 1.4?

3:23 adu: denysonique: I have a great command-line app I wrote a couple days ago

3:23 Raynes: Dynamic vars.

3:23 For one.

3:23 amalloy: muhoo: well, a few things. but mostly the pain was in going from 1.2 to 1.3+

3:24 muhoo: oh gawd, i missed that transition, and i'm damn glad i did. :-)

3:24 amalloy: and now that everyone's basically done that, 1.4 is just as easy as 1.3

3:25 muhoo: cool. maybe i should just try 1.4 and enjoy the uneventful non-breakage then

3:26 denysonique: adu: I would like to see it

3:27 adu: What do you think about ClojureScript on the serverside on node.js?

3:29 adu: https://gist.github.com/3009680

3:29 denysonique: I don't

3:29 I'm a big fan of compilers to JavaScript, but I'm not a big fan of node.js

3:30 denysonique: why?

3:30 adu: the idea of node.js is great, but the way it's implemented doesn't respond well to scrutiny

3:33 besides, if you're doing stuff on the server-side, then I would think clojure->jvm would be the way to go

3:33 unless you have an existing node.js code base you need to integrate with

3:41 denysonique: anyways

3:41 the commandline app is similar to the 'mustache' command-line tool

3:59 xumingmingv: any usecase for clojurescript?

4:00 adu: a webgl app?

4:04 xumingmingv: dont know whether front-end developer would like to change from javascript to clojurescript?

4:04 or clojurescript is for backend-developer to write front-end code?

4:04 or it is for writing code to run on v8 engine on backend?

4:05 adu: if you have a code base for your server logic, then it's nice to use that in client logic too

4:13 ro_st: xumingmingv: writing clojure client and server side makes things like github.com/shoreleave possible

4:39 muhoo: what would be the current state-of-the-art if i wanted to just get a hello world going in cljs, possibly with some stuff like crate and fetch up in the mix too?

4:42 ro_st: isn't there a lein project template for cljs?

4:42 and the lein-cljsbuild plugin

4:44 muhoo: you could probably grab this and remove noir (or not, as you prefer): https://github.com/ibdknox/cljs-template

4:45 it includes fetch, crate, jayq, noir, and noir-cljs: https://github.com/ibdknox/cljs-template/blob/master/src/leiningen/new/cljs_template/project.clj

4:55 muhoo: fantastic, thanks

4:59 ro_st: i can't wait to start playing with cljs myself

5:00 muhoo: i have a few weeks off, and my two goals are 1) cljs, and 2) datomic

5:00 ro_st: isn't datomic like really expensive?

5:00 you can't just grab it and use it like you would mongo?

5:00 muhoo: that's what they want you to think :-)

5:01 it's free for the first 2 peers, IIRC

5:01 plus you can run it using postgres instead of the amazon thing.

5:01 ro_st: peers meaning one app instance and one database server

5:02 muhoo: i'll find out over the next 2 weeks :-) but they spell it out here: http://datomic.com/product/pricing

5:03 ro_st: nice

5:03 enjoy. fun learning new things

5:04 muhoo: i'm old, so learning new things really isn't fun. but learning BETTER things, that i enjoy. and datomic has got to be better than what i've had to deal with so far in db-land.

5:08 ro_st: old? what, like, 30? -grin-

5:09 _nmmn: im old too then :\

5:09 ro_st: (i'm 33)

5:09 _nmmn: and you are old also ;]

5:09 * _nmmn gets depressed of old age and switches to work mode

5:36 * lucian plans to keep hacking until death

5:40 ro_st: seconded

5:40 * vijaykiran plans to keep hacking eternally with the help of continued-reincarnation

5:46 * ro_st thinks of Pratchett's Thief of Time

5:46 ro_st: BIKKIT

5:54 muhoo: hm... ok.... https://www.refheap.com/paste/3350

5:54 looks like the only thing uglier than java stacktraces is cljs stacktraces

5:55 also looks like there's no "use" or "require" in cljs?!

6:02 ro_st: muhoo: this livecode might be instructive

6:02 https://vimeo.com/43808810

6:02 code from the talk https://github.com/bodil/mylittlecthulhu

6:08 muhoo: thx

8:25 maaruks: where is source code of clojure 1.4 ?

8:27 omg github :-)

8:56 antares_: maaruks: Clojure is at github.com/clojure/clojure

9:03 progo: uuuglyyy. I have to update more than one value in a map. Nested update-ins aren't elegant.

9:12 llasram: &(-> (update-in {} [:first] (fnil inc 0)) (update-in ,, [:second] (fnil conj []) :value))

9:12 lazybot: ⇒ {:second [:value], :first 1}

9:12 llasram: progo: What abotu that?

9:12 well, looks nicer when you align the `update-in` forms, but you get the gist

9:13 progo: llasram, I guess that has to do :)

9:27 chico_chicote: hi all. i'm trying to launch a standalone swank-clojure server, but i can't find the executable (downloaded it with leiningen2)

9:27 any tips?

9:28 ro_st: you need lein-swank installed

9:28 then you can simply lein swank

9:41 antares_: ro_st: heya

9:41 chico_chicote: ro_st: if i lein swank, i get a 'Couldn't find project.clj, which is needed for swank'

9:42 from what i understand, this means i must be in a leiningen project, right?

9:42 isn't there a way to just launch a standalone server?

9:42 duck1123: lein swank should work standalone

9:42 but it's just as easy to create a dummy project

9:42 lein new foo; cd foo; lein swank

9:43 that way you have a project file for your next question "how do I add a library"

9:43 S11001001: or "how do I change clojure versions to something recent"

9:48 ro_st: antares_: :-) howdy

9:49 antares_: ro_st: you are a monger user if I remember correctly, is this right?

9:50 ro_st: yes, daily at the moment

9:50 antares_: ro_st: ok. Is there anything you want to see improved in the docs?

9:52 ro_st: aside from the one or two things i mentioned before ( :nested.field.access and the simplest way to get the :_id for a newly inserted document ), not really

9:52 also, i was thinking it might be handy for monger.core to have a convenience fn for ObjectId

9:52 so that we don't have to import it all the time - makes repling that bit easier too

9:52 antares_: ro_st: there are a few in monger.util

9:53 ah, I see

9:53 well, you still have to refer to monger.core functions

9:53 ro_st: ie, {:_id (new-object-id) :myField 1 :myOtherField 2} etc

9:55 wingy: when i learned node.js the main concept was: one thread -> do async style! in clj, immutability, everything is an expression

9:56 duck1123: I'd like one like this https://github.com/duck1123/jiksnu/blob/master/src/jiksnu/model.clj#L219 so I can pass an id or just get a new one

9:57 ro_st: yeah that looks great

9:57 antares_: duck1123: the real problem is monger.collection/insert which returns write concern

9:57 that was a mistake but it is too late to change what is returned

9:57 what we can do I guess is use a subclass that effectively works like a Clojure map

9:58 duck1123: Yeah, that was the biggest issue for me when I switched

9:58 I've had to resort to always generating my own id

9:58 antares_: ok, I will think about

9:58 ro_st: i think pre-setting the id is better

9:58 antares_: duck1123: that's what I do, too

9:58 ro_st: for testing

9:58 by making that the 'way', it makes testing automatically easier

9:58 antares_: ro_st: MongoDB Java driver tries to mutate the object you insert

9:58 but we don't return it

9:59 we can add a new function but all the options I have suck

10:00 insert-map, insert-doc, insert! are all not very good names

10:01 duck1123: perhaps a monger.sweet with a higher-level api ?

10:02 antares_: duck1123: hm, no, I don't like "sweet API" namespaces

10:02 the entire API should be sweet, why have sweet and bitter parts :)

10:02 I think returning a subclass of WriteResult that acts like a Clojure map + has the actual document may work

10:04 we can also call the next release Monger 2.0 and break this thing

10:04 I am open to that

10:04 anyway, my question was mostly what is missing in the docs :)

10:05 duck1123: more information about different ways to dynamically create queries

10:05 antares_: with monger.query?

10:05 foxdonut: antares_: do you know of anyplace one could host a webapp with clojure and mongo?

10:05 antares_: foxdonut: heroku

10:06 with the mongolab addon. Or is it monghq. Or both.

10:06 Monger supports connections via URI, specifically for those platforms

10:06 ro_st: yup. you can have it running in 10 minutes

10:06 super easy

10:11 foxdonut: antares_, ro_st: great, thanks

10:12 duck1123: antares_: yes. I don't even know if this is possible, or how you'll go about it, but I know I'll need it soon. Looking for ways to compose the query options. (in response to external parameters)

10:12 antares_: duck1123: it is possible

10:12 duck1123: I figured it was. I'm sure I can figure it out, but it's not in the docs

10:13 antares_: duck1123: https://github.com/michaelklishin/monger/blob/master/test/monger/test/querying_test.clj#L253-287

10:13 yeah, ok

10:13 I am finishing the indexing guide tonight

10:13 then I can work more on querying and maybe How-Tos

10:13 ro_st: indexing, awesome. i still need to do that

10:14 it's pretty straightforward i believe

10:14 wingy: is there a favorite CSS preprocessor in Clojure world?

10:15 ro_st: wingy, don't think a clojure one exists

10:15 i use sass, works for me

10:15 wingy: aight

10:15 antares_: wingy: LESS has a Lein plugin

10:16 duck1123: are you looking to generate css from clojure, I think there is one, it's in my following list, have to find it

10:16 antares_: which uses the official Java compiler

10:16 works great for me

10:16 wingy: antares_: i find SASS better alternative .. LESS seems less maintained

10:16 antares_: I don't do much frontend development so I can't speak about sass but i had huge issues with haml before

10:17 haml is the single library I absolutely hate

10:17 ro_st: haml isn't great. sass is fantastic

10:17 wingy: duck1123: not necessarily from clojure .. from a higher level CSS like SASS/Stylus etc .. but I am opened to any suggestion

10:17 antares_: it is developed by people who don't give a damn about any sort of compatibility

10:17 wingy: seems that with clojure you can have a DSL for everything

10:17 antares_: and sass is developed by the same dude

10:17 wingy: perhaps in the future it would be simpler to just generate CSS from clj?

10:17 antares_: https://github.com/paraseba/cssgen

10:17 wingy: like you do with HTML

10:17 antares_: wingy: you can with https://github.com/paraseba/cssgen :)

10:18 wingy: hmm seems unmaintaned

10:18 is it abandoned?

10:18 ro_st: 2 months ago

10:18 wingy: oh 2 months ago

10:18 ro_st: that's pretty recent

10:19 maybe it does everything it should, already :-)

10:19 wingy: yeah .. im used to node.js maintainance .. they are having far more watchers and maintainence

10:19 like 8 hours ago .. 2 days ago...

10:19 :)

10:19 2000+ watchers

10:20 is it bad thing to couple styling with clojure code

10:20 since now you cannot outsource styling to designers

10:20 and developers might do a terrible job in styling

10:29 scriptor: don't a lot of projects use enlive or something like it for layout?

10:29 TimMc: wingy: Eh, they can learn it.

10:29 scriptor: if designers have to touch the html…I wonder how easy that is for them

10:30 TimMc: It's a restricted subset of Clojure.

10:33 paraseba doesn't look like it can handle some important things like embedding values in selectors, e.g. a[href="$FOO"]

10:33 If you don't give a convenient way to escape data values for embedding in syntax, you're gonna break something.

10:34 Or rather, the people using your lib will.

10:37 foxdonut: wingy: there is also https://github.com/briancarper/gaka

10:39 I used this fork for more recent clojure version: https://github.com/crimeminister/gaka

10:39 pretty simple (and effective) stuff.

10:40 antares_: wingy: commits does not necessary mean maintenance and node.js break things every release (as told me by a person working at a Node.js cloud platform provider)

10:41 0.8 has so many serious changes that we have a blog post going out mentioning them for travis-ci.org users

10:42 what sucks about some Clojure libraries is that their developers never have any docs or state what Clojure versions are supported

10:47 wingy: gaka seems really unmaintained

10:47 one of my rules is to never use unmaintained repos

10:48 the library ecosystem seems so small compared to ruby/node

10:48 antares_: that's a good rule to live by

10:48 wingy: thats the only disadvantage of clojure in my opinion

10:50 but on the other hand i can ditch libs like: LiveScript, prelude-ls (which is LiveScript's std lib), async (for node.js async style), sugar (utility methods since JS lacks a lot)

10:50 what is the best way to make HTTP requests?

10:50 duck1123: clj-http or aleph.http if you want async

10:51 wingy: duck1123: is there really synced http requests?

10:51 antares_: wingy: yes, there are sync HTTP clients, what's the problem?

10:51 wingy: antares_: not used to it haha

10:52 antares_: async is not silver bullet. clj-http uses a thread pool under the hood, people build Web crawlers with it just fine

10:52 wingy: as long as it works with high concurrency i have no problems

10:52 have to investigate on thread pool and how clojure does things

10:52 antares_: wingy: if you take Java libraries into account, Clojure has access to more libraries that most languages. And some of those libraries are very mature and pretty good.

10:53 wingy: antares_: oh yeah forgot that

10:53 that should make npm and gem seem like baby poops

10:53 and then i can use JS libs/frameworks on frontend with cljs

10:54 so more power than JS only!

10:54 duck1123: In many cases, it's easier to make a sync request in a different thread than an async one with a callback. (depends on the situation)

10:54 wingy: duck1123: how much does the thread take in memory?

10:55 will server manage 100 000 http requests at once?

10:55 duck1123: did you mean this one: https://github.com/dakrone/clj-http/

10:56 duck1123: depends, how awesome is your server? yes

10:56 wingy: but node.js can make 100 000 without needing a very great server .. seems it so cheap with async operations

10:56 since it ..

10:57 duck1123: there's also an clj-http-async (or something) but I just use aleph since I'm already using it

10:57 wingy: ok i have to yet decide what to use

10:57 duck1123: If you think async is going to be important for you, check out lamina/aleph

10:59 uvtc: antares_, Do you mean Java standard libraries, or 3rd-party Java libs? Or both?

10:59 wingy: duck1123: so it boils down to async with one thread: aleph/netty and sync with many threads: noir/jetty .. is this correct?

11:01 antares_: uvtc: 3rd party but JDK itself has plenty of good parts and if you have to do any kind of work that involves a lot of PKI, TLS and related stuff, JDK is a life saver compared to Ruby, Python and (I am sure) node.js

11:02 uvtc: My guess is that new Clojurians who have no experience with Java have very little idea what 3rd-party libs are available, or where to find them. Is there a "clojure-toolbox" for Java?

11:02 wingy: heh .. error in the book

11:02 (reduce max [0 -3 10 48])

11:02 ;= 10

11:03 cemerick: wingy: yeah, we'll be haunted by that :-|

11:03 Of all the things…

11:03 wingy: cemerick: but why did he do like that?

11:03 duck1123: not quite. Noir sits atop it all and can be used with either jetty or netty/aleph. Both of them don't care what you're doing with threads, but with aleph, you get a channel that you can asyncronously emit your response to

11:03 wingy: why use reduce

11:03 ah

11:03 the collection is a []

11:04 metellus: you could also use apply in that case

11:05 wingy: yeah

11:05 antares_: uvtc: in practice if you want a library for a data store or something NLP or IR related, there is always a Java library, often an official Java client for your store and so on. There are "clojure toolboxes" with 100+ projects each in the Java world: Apache, Eclipse, even Codehaus

11:06 uvtc: search.maven.org may be useful. But typically finding a library is not a problem. A bigger problem is finding an easy to use or wrap, well documented library and knowing which alternative to pick. But it's a good problem to have in my opinion.

11:07 wingy: i wonder if i would enjoy working in FP style if I haven't done OOP

11:07 foxdonut: wingy: most of the time I agree but for something as simple as taking a clojure data structure and generating css, there isn't a whole lot to maintain

11:07 uvtc: clojurebot: IR

11:08 antares_, NLP == "natural language processing"? "IR"?

11:08 TimMc: Information Retrieval

11:08 wingy: perhaps the reaction would be .. "OOP looks so natural, not like math, i want a book for my app so i create a book"

11:09 uvtc: TimMc, sounds like something out of the ministry of information. :)

11:09 TimMc: wingy: You still "create a book", it just doesn't have methods attached.

11:10 The difference is in how code is applied to data.

11:10 wingy: yeah

11:10 antares_: uvtc: information retrieval, search and indexing. Lucene and related projects.

11:10 wingy: there is a good slide that explains what i have realized very well *looking*

11:11 uvtc: antares_, thanks for the info. Yes, pretty good problem to have (need to choose among alternatives). Perl's CPAN seems to have some of that issue.

11:11 wingy: http://www.slideshare.net/smartrevolution/how-a-clojure-pet-project-turned-into-a-fullblown-cloudcomputing-webapp

11:11 page 92

11:11 antares_: uvtc: I think all mature communities do, to some extend Python has it, too

11:12 wingy: to page 100

11:12 antares_: uvtc: Clojure's sweet spot is data processing, things like Web crawling, large scale stream processing, indexing and so on. those things in the Java ecosystem really shine. clojurewerkz.org is so focused on DB clients for the same reason.

11:12 cmajor7: is there a way to include dependency (e.g. [clj-time "0.4.3"]) just for a single repl session, e.g. without creating a project?

11:13 antares_: uvtc: also, statistics, math, linear algebra, machine learning in Java are well covered. One of the best in its kind. Of course, some things (like LESS and SASS implementations) are in significantly worse shape and it does affect Clojure

11:13 duck1123: There are some libraries and functions that allow you do manipulate the classpath, but you get into some dark magic there

11:14 cmajor7: duck1123: you mean https://github.com/cemerick/pomegranate ?

11:15 uvtc: cmajor7, I think there's a lein plug-in for that ...

11:15 wingy: perhaps thats one of the main benefit of using clojure .. there isn't a huge pool of libs compared to OOP langs since you don't need any

11:15 or not that much

11:16 you dont need ActiveModels like in Rails. or Doctrine like in Symfony

11:16 uvtc: cmajor7, https://github.com/mtyaka/lein-oneoff

11:17 adu: duck1123: "dark magic"?

11:17 duck1123: cmajor7: That should do the trick. I haven't used that one, I just know that add-classpath used to be a pain

11:17 TimMc: Doesn't oneoff require a file?

11:17 uvtc: cmajor7, is that what you mean?

11:18 cmajor7: uvtc: almost :) it does require you to code "in a file", I was looking for a pure repl based dep

11:18 uvtc: Oh, I mis-read. Right. :)

11:19 cmajor7: e.g. I'd like to play with [clj-time "0.4.3"] without having to create a file/project

11:19 it is not all that hard, I can create a single "playground" project for things like that, and just keep adding deps into the "project.clj", and run "lein repl"

11:19 just thought there is a easy way :)

11:20 uvtc: That's what I do (create playground projects).

11:20 cmajor7: or should I say "simple" :)

11:22 duck1123: you could try listing it as a plugin in your profile. that might work

11:23 cmajor7: duck1123: you mean just drop the jar into "~/.lein/plugins/" ?

11:23 duck1123: worth a shot. I haven't tried it as I don't have my clojure setup here

11:23 wingy: anyone here using cljs and have opinions about google closure?

11:23 atm im using ExtJS but they are so OOPish and wont fit with cljs

11:25 cmajor7: duck1123: thx, I'll try that

11:25 kmicu: wingy: G Closure LIbrary?

11:25 wingy: kmicu: yeah for UI http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/index.html

11:25 seems pretty sweet

11:26 cgag: i feel like no one uses it, or at least I don't think I've ever heard it mentioned outside the context of cljs

11:26 wingy: cgag: what are people using then?

11:26 they create html/css from scratch?

11:26 duck1123: They're using one of the hiccup clones

11:26 cgag: no idea, i haven't done much with javascript

11:27 wingy: duck1123: but those dont provide UI elements

11:29 uvtc: antares_, I added Apache and Eclipse the list at http://www.unexpected-vortices.com/clojure/brief-beginners-guide/libs-available.html#other-java-libraries ,

11:29 but I didn't see any libraries listed at http://www.codehaus.org/ .

11:29 antares_: uvtc: feel free to link to clojurewerkz.org, too :) we focus on things for day-to-day development, like data stores

11:29 uvtc: Oh, right, almost forgot. Thanks!

11:30 If you know of any other places for users to find Java libs, please let me know.

11:31 antares_: uvtc: codehaus site is a bit silly and not friendly. Groovy is hosted there, JRuby started there, but it does a terrible job of actually letting you browse and track project development. I'd just link to search.maven.org instead.

11:31 uvtc: antares_, Yep, got that one, thanks.

11:32 antares_: uvtc: also, you may want to add a note that eclipse.org is just a huge umbrella foundation. there are both tools (eclipse/jdt, for example) and libraries (like jgit)

11:32 and many tools have components that can be used as libraries

11:32 cmajor7: wingy: "what are people using then?": I just use hiccup.. quite simple really, enlive is also praised, but I have not used it

11:32 antares_: Jetty is now also an Eclipse project

11:33 duck1123: I tried using Closure templates, but reverted to using hiccup

11:35 cmajor7: it feels that some folks prefer enlive to hiccup, do you know why?

11:35 antares_: uvtc: also, I'd suggest you to rename "Java standard libraries" to "Java standard library: JDK" and link it to http://docs.oracle.com/javase/7/docs/

11:35 kmicu: wingy: I do not recall a project that uses gclosure ui libs, some poor examples @ https://github.com/search?q=goog.ui&repo=&langOverride=&start_value=1&type=Everything&language=Clojure

11:36 duck1123: some people like enlive because it forces that separation of concerns. Some people don't like it for that same reason

11:36 cmajor7: duck1123: separation from what and what? :)

11:37 kmicu: cmajor7: in enlive you can jack-in to existing html created by gfx artist, hiccup is good when developer want to create some html in clojure :]

11:39 duck1123: envlive take html and plugs in the values using matching. With hiccup, you produce all your html as a sequence of vectors, keywords, and maps

11:39 cmajor7: kmicu: huh.. that's neat. yea I create it myself, but that'd be a cool ability. especially for "inspired" existing html/css

11:39 wingy: i wonder why noone is using closure

11:40 duck1123: wingy: I think beccause the people really into cljs built cljs libraries that accomplish many of the same things but feel nicer.

11:41 cmajor7: duck1123: I see, jquerymobile follows the same "separation".. you give it HTML, it hooks to it

11:41 wingy: hope someone is going to release something soon so we can all benefit from it

11:41 a UI framework working on tablets and phones as well

11:41 cmajor7: wingy: is twitter bootstrap not cutting it for you?

11:44 wingy: cmajor7: *checking it out*

11:46 cmajor7: cool concept

11:46 pbostrom: I like the enlive/bootstrap combo personally, since there is a lot of existing bootstrap html/css out there, it's a lot of work to translate it all to hiccup

11:48 duck1123: actually, with hiccup, you can write functions thaat abstract a lot of that away

11:49 for example: https://github.com/duck1123/jiksnu/blob/master/src/jiksnu/sections.clj#L7

11:50 cmajor7: duck1123: yep, that is what I have.. several hiccup builders that I reuse all over

11:50 pbostrom: thx, I'll check out enlive, feels like I have to, to be in the loop

11:51 cgag: i've only really used enlive for scraping so far, haven't done any generating

11:51 pbostrom: duck1123: I'm pretty lazy, so that constitutes "a lot of work" :)

11:51 cgag: it's selectors are nice for that

11:51 wingy: enlive is generating HTML using CSS selectors while Hiccup is using clojure right?

11:52 32 000 watchers of bootstrap lol

11:52 raek: you only use css selectors to specify where to apply the rules

11:52 the transformations are written in clojure

11:53 the selectors can be too

11:53 wingy: raek: ah .. so you have a regular HTML file with skeleton, then you apply html elements dynamically

11:53 raek: yup

11:53 cgag: this tutorial is pretty solid for enlive: https://github.com/cgrand/enlive/wiki/Table-and-Layout-Tutorial,-Part-1:-The-Goal

11:53 wingy: cool

11:54 well .. seems to ExtJS is history for me

11:54 pbostrom: I also like dnolen's tutorial: https://github.com/swannodette/enlive-tutorial/

11:54 wingy: do most of the people here suggest enlive or hiccup?

11:54 and aleph or noir

11:55 raek: wingy: you wonder if those two together are the most common, or which one of them is the most common?

11:56 duck1123: wingy: the choices are aleph / jetty and noir / not-noir

11:57 cgag: i'm curious to hear people's opinions on the aleph / jetty choice

11:57 wingy: duck1123: is not-noir its own stack?

11:58 m0smith: hello, is anyone home?

11:58 duck1123: A lot of people do just fine not using noir. and there are other options slighty in that space

11:58 wingy: raek: i wonder what stack is the "best" to use for serving HTTP

11:59 duck1123: My choices have been: Hiccup, Aleph, Ciste

11:59 m0smith: I use hiccup with stencil to keep the html separate

12:00 raek: well, before noir came "the stack" was just your own combo of your favorite libs

12:00 gtrak: duck1123: Ciste, attempting to provide a structure to clojure applications, ha

12:00 m0smith: swing: there are lots of choices, do any stand out?

12:00 raek: wingy: take a look at the diagram under the Common Stack section here: http://brehaut.net/blog/2011/ring_introduction

12:01 gtrak: What's a documentation-generation stack I can use with lein that will handle tables and things?

12:01 raek: I think noir initially some of those libs bundled together with added syntactic sugar

12:02 also, most web-related libs (including ring-jetty-adapter, aleph, and noir) are based on the Ring spec

12:10 m0smith: Is anyone using Swing?

12:10 qbert_: noone uses compojure ?

12:11 * gfredericks uses compojure

12:13 technomancy: compojure is the best

12:15 gfredericks: that statement is true even when totally unqualified

12:16 uvtc: gtrak, you mean for just generic documentation, or for api docs in the source code?

12:19 qbert_: out of curiosity, what are you guys building currently with clojure ?

12:20 gfredericks: an SVG-based demo of quantum computation

12:20 technomancy: leiningen

12:20 gfredericks: technomancy: that's quite a pun

12:21 acheng: observation re: clojure.test + lein + test selectors ... my fixture marked for :each test apparently runs for both unit tests in my namespace even though only one test is selected to run

12:23 technomancy: yeah, test selectors run inside fixtures

12:24 mmarczyk: gfredericks: ping

12:24 gfredericks: mmarczyk: pong

12:24 mmarczyk: gfredericks: hi

12:24 gfredericks: greetings

12:24 mmarczyk: gfredericks: just a quick question

12:24 acheng: technomancy: ok. it's still a great improvement over actually running those extra tests.

12:25 mmarczyk: have you been working on cljs-324? (format)

12:25 acheng: but if i have 30 tests and only wish to run 1, i'll get 29 instances of firefox opening and closing :-P

12:25 gfredericks: mmarczyk: nope. I took a quick look at the java docs and panicked :)

12:25 mmarczyk: gfredericks: oh, ok

12:26 acheng: maybe i'll run the one by hand as a regular fn then

12:26 mmarczyk: gfredericks: :-)

12:26 gfredericks: GClosure does actually provide a formatter

12:26 gfredericks: mmarczyk: phew

12:26 is it similar?

12:26 mmarczyk: gfredericks: I can attach a patch and you can try it out :-)

12:26 gfredericks: I assume it doesn't should be identical

12:26 mmarczyk: gfredericks: honestly, I've no idea

12:26 gfredericks: the sprintf-like basics should be pretty close

12:27 gfredericks: right

12:27 mmarczyk: gfredericks: I mean, they should be the same :-P

12:27 gfredericks: I don't know about the acceptance criteria for the issue; I assume dnolen's opinion is more relevant than mine

12:27 mmarczyk: gfredericks: just wanted to know if you were in the middle of writing our own sprintf-like formatter :-)

12:28 gfredericks: I did fantasize about that for several seconds

12:28 mmarczyk: :-D

12:30 ok, attached a patch to cljs-324 with GClosure-based format and printf... if they won't cut it, at least it's an 11-liner :-P

12:31 so no great loss of effort

12:31 gfredericks: mmarczyk: sweet

12:31 dnolen: mmarczyk: gfredericks: cool

12:32 mmarczyk: :-)

12:32 gfredericks: does lein-cljsbuild let you specify or provide a particular version of cljs?

12:32 mmarczyk: dnolen: hi! cljs-324 applies on top of cljs-328

12:32 dnolen: the latter being a bugfix for a bug in :require handling... missed the (:require [lib.ns]) case

12:33 dnolen: gfredericks: not really, I'm increasingly convinced it should do anything at all. You need to specify CLJS yourself.

12:33 shoudln't

12:33 brainproxy: wingy: I'm using hiccup to generate "templates", i.e. my term for logic-less skeletons of html documents

12:33 dnolen: erg

12:34 brainproxy: wingy: then I use enlive to realize views of data in terms of one or more templates

12:34 gfredericks: dnolen: so a lein-cljsbuild patch along those lines would be welcome?

12:35 mmarczyk: I thought lein-cljsbuild already uses the version of cljs specified among the project's :dependencies (if any)? or at least that it used to...? otherwise I've no idea how some of the things I've been doing with locally built CLJS versions could have possibly worked

12:36 gfredericks: I've never specified cljs in my deps

12:36 I'm not even familiar with the maven releases of cljs, if there are any

12:36 so apparently I don't know how things work

12:37 mmarczyk: there are

12:37 for tags in the main repo

12:37 hm, not sure if the last tag actually got a release

12:37 brainproxy: wingy: doing that way helps me (I think) to build up the semantic profiles for my hypermedia base type w/o getting bogged down in fine details of uri schemes and the particulars of parsing data into a representation, i.e. with respect to templates

12:37 mmarczyk: anyway, gotta dash now, bbl

13:01 gtrak: uvtc: generic documentation

13:01 I guess I'd probably have to use latex or something

13:02 uvtc: Nah. I suggest you write them in markdown, but use the extras that Pandoc provides http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown . Then just process the docs yourself with the `pandoc` command.

13:03 It supports tables, definition lists, LaTeX math, and some other goodies.

13:03 gtrak: oh neat

13:06 uvtc: gtrak, here's a brief example: http://www.unexpected-vortices.com/sw/gouda/quick-markdown-example.html .

13:36 wingy: do you prefer to use anonymous functions or function literals in HOFs?

13:37 antares_: wingy: for anything non-trivial, I personally try to use named functions (because they can be tested easily)

13:38 scriptor: they could also be re-used elsewhere

13:38 wingy: okay

13:50 TimMc: If you do (map (fn munger [x] ...) ...) then "munger" appears in stack traces.

13:52 wingy: TimMc: it seems that named functions is always the best then

13:52 if it was me and fn literals have very little gain..i would have ditched it from the lang

13:53 antares_: duck11231: do you think this section on object ids is good enough? http://clojuremongodb.info/articles/inserting.html#document_ids_objectid

13:53 wingy: they are useful in those rare cases when you need to use loop/recur with otherwise trivial functions

13:56 ffwacom: sexp motherfuckers

13:56 duck11231: antares_: the link didn't go to the section, but the text looks good

13:56 antares_: duck11231: ok, thank you

13:58 duck11231: "Unfortunately, it does so" reads oddly, and I would drop "So" from the next paragraph

13:58 dnolen: wingy: fn literals, anon fns, letfn all have their use cases. takes some time to figure it out.

13:59 wingy: since FP is separating data and code, perhaps the presentation should be separated as well

13:59 antares_: duck11231: refresh

13:59 wingy: it is easy to take analogies too far

13:59 wingy: which means twitter bootstrap (CSS/HTML) is more suitable than ExtJS

14:00 they separate everything in object level .. MVC

14:00 FP + Html/Css is it's equivalent without all the objects/classes

14:01 antares_: but it seems right to have it like that .. the data {:name "foo"} has nothing to do with the logic map/reduce which has nothing to do with how you present the data to users

14:01 antares_: duck11231: Monger docs are OSS and I am not a native English speaker so feel free to edit them and submit pull requests ;) https://github.com/clojurewerkz/monger.docs

14:02 wingy: where you are using <div>/.div and html templating where you pass in a collection and it will render a table

14:02 antares_: wingy: I agree but sometimes more separation does not yield anything in practice

14:02 wingy: antares_: where is the _more_ in this kind of separation?

14:02 antares_: just like sometimes the best solution is to not remove duplication if it makes code harder to understand

14:02 wingy: how can i possibly have presentation in the collections

14:03 antares_: wingy: I am not talking specifically about one case or idea

14:03 wingy: i am :)

14:03 antares_: just suggesting not refer to Clojure and FP's ideas of separation as the universal law applicable to everything:)

14:03 wingy: it could?

14:04 simplicity is what i want to achieve .. seems nothing can be more simple than data in data out

14:04 then the presentation stuff is just for people right

14:04 TimMc: wingy: Non-named and literal fns improve readability in many, many cases. Less to read!

14:04 wingy: how to present a collection for users .. which has nothing to do with data -> fn -> data

14:05 feels that im getting much smarter reading about FP than OOP where they abstract everything away .. heading towards complexity

14:06 TimMc: yeah

14:13 antares_: uvtc: by the way, another huge umbrella project for a lot of Java tools and libraries is JBoss: http://www.jboss.org/projects, Clojure on JBoss App Server: http://immutant.org

14:25 uvtc: The docs (manual) for immutant are easy to navigate. Easy to see right where you are at any given point. Very nice.

14:25 jcrossley3: uvtc: thanks! :)

14:25 uvtc: What are you using to generate them?

14:26 jcrossley3: uvtc: tcrawley is so happy you asked that!

14:26 tcrawley: heh

14:26 uvtc: tcrawley, did you whip something up to generate them?

14:26 tcrawley: jcrossley3: does that mean you are delegating to me to answer it?

14:26 jcrossley3: tcrawley: yes, i'll just bask here in your glow. :)

14:27 uvtc: (Oh, I almost thought I'd made a mistake; it says "jboss.org" at the top of http://immutant.org/documentation/current/ )

14:27 tcrawley: uvtc: the docs themselves are written in emacs org-mode format. We then run them through emacs in batch mode to export html

14:28 technomancy: what's the motivation behind having immutant be installed in ~/.lein/immutant?

14:28 tcrawley: uvtc: that html is then munged by a ruby script to match the jboss.org doc format, which allows us to use the jboss.org doc css

14:29 uvtc: which assumes you are generating the docs from docbook

14:29 technomancy: good question!

14:29 austinh: Is there a way to make paredit-reindent-defun (M-q) keep a function definition's parameters on the line after the doc-string?

14:29 tcrawley: technomancy: I wish I could remember the answer :)

14:30 uvtc: tcrawley: Neat! I'd written a doc generator myself, which produces something sorta similar in structure, but not nearly as polished: http://www.unexpected-vortices.com/sw/gouda/ . Instead of org files (?) it uses a flat dir of .md (er, .txt) files.

14:30 jcrossley3: tcrawley: technomancy: i think it was a pretty arbitrary decision at the time. it was a directory we knew would exist. :)

14:30 technomancy: tcrawley: it's just that lein is generally pretty project-centric; the only outside-project stuff it's done has been shell wrappers, which were mostly unused.

14:30 uvtc: tcrawley, Oh, you have better navigation. I should fix the gouda header to have the arrows on each side like yours.

14:31 technomancy: tcrawley: two thumbs up for supporting meta rel=next/prev

14:31 tcrawley: technomancy: seriously though, I put it there since it was installed by and managed by a lein plugin. it may be better to use ~/.immutant

14:31 technomancy: tcrawley: so you're using leiningen as a general clojure CLI interface rather than specifically a tool to operate on projects?

14:32 tcrawley: technomancy: correct - most of the plugin's commands work inside or outside of a project

14:32 technomancy: interesting

14:33 tcrawley: for example: 'lein immutant deploy' will deploy the current project if you are in one, otherwise you can give it a path to one from anywhere: 'lein immutant deploy foo/bar'

14:33 and can be used to deploy apps that aren't even lein projects (but why anyone would do that I don't know)

14:33 technomancy: is the stuff installed by `lein immutant install` used at dev time or for deployments?

14:33 or both?

14:34 tcrawley: well, the question becomes 'what is dev time?' - if you are developing an immutant app, you're probably deploying it quite a bit

14:35 or deploying a basic version of the app w/swank enabled, and doing repl based development

14:35 inside the immutant container

14:35 but what's installed is a full blown installation of immutant

14:36 uvtc: Thanks for that heads-up, antares_ . Added.

14:36 tcrawley: uvtc: I'll take a look at gouda, thanks for the tip

14:38 technomancy: tcrawley: have you considered a higher-order task?

14:38 tcrawley: technomancy: what do you mean?

14:38 jcrossley3: uvtc: thx for the link on your page

14:38 technomancy: `lein immutant swank` could run the swank task inside immutant

14:38 tcrawley: eval-in-project is a multimethod, so you could add support for :eval-in :immutant

14:39 and have all eval-in-project code sent to the app server

14:39 then all existing lein tasks could port over, provided you can handle classpath stuff

14:39 just a thought

14:39 tcrawley: technomancy: ah, right. that would require some clojure app deployed to the app server to receive it, but that wouldn't be difficult. it would need the deps of the current project, yeah

14:40 but it's doable

14:40 technomancy: ideally you could make it work without the need for an explicit `lein immutant install` step

14:40 jcrossley3: that'd actually be pretty cool if jack-in could run the swank task inside immutant, too.

14:40 technomancy: anyway, that's what I would do

14:40 but I'm obsessed over higher-order tasks

14:40 so take it with a grain of salt

14:41 tcrawley: 'install' installs immutant itself, so there would have to be an install happening at some point.

14:41 so 'lein immutant swank' would d/l and install immutant on the first call

14:41 technomancy: right; ideally you could have it happen on-demand

14:41 and the project could declare the version it needs (separately from :dependencies probably)

14:42 tcrawley: I like that idea a lot

14:42 I'll put that on the list

14:42 technomancy: thanks for the suggestion!

14:42 technomancy: no problem; lemme know how it works out for you

14:42 tcrawley: will do

14:58 wingy: what does "concrete types of data" mean?

15:02 amalloy: not much without context, i suspect

15:08 uvtc: wingy, the concrete data types are hash-map, vector, list, and set. There's syntax for them, and you create them in your code. They implement various abstractions that Clojure has notions of.

15:09 * nDuff notes that "data types" is a term of the art, where as "types of data" is... confusing.

15:11 uvtc: I was just looking at amalloy's solution at http://stackoverflow.com/questions/11225562/idiomatically-merge-maps-into-a-map-of-value-sets-with-clojure ,

15:11 and thought it seemed like I could do the same like so:

15:11 https://gist.github.com/3013269

15:11 But I'm getting "UnsupportedOperationException nth not supported on this type: PersistentHashMap".

15:12 Am I going about that the wrong way?

15:12 wingy: uvtc: why are they called _concrete_? strings, booleans and numbers are data types but not concrete?

15:13 gfredericks: uvtc: I think your my-merge-maps is set to use varargs but you call it with a single arg

15:13 uvtc: gfredericks, Doh! Thanks!

15:15 wingy, my understanding is that those are all concrete data types. You can make them in your code ... hold them in your hand, so to speak. :) As opposed to abstract data types which are descriptions of how a data type would act if it were to implement said abstraction.

15:23 Cheiron: Hi, I'm trying to mimic "Composite columns" section of https://github.com/Netflix/astyanax/wiki/Getting-Started

15:23 (defrecord Session [^{Component {:ordinal 0}} gid ^{Component {:ordinal 1}} tid])

15:37 wingy: anyone know how i get a error message: https://gist.github.com/3013395

15:38 cgag: you're calling columns

15:38 xeqi: wingy: you're calling columns as a function on line 7

15:38 amalloy: how to get an error message? easy, just keep doing what you're doing

15:39 Raynes: Hahahaha

15:41 wingy: cgag xeqi oh thx

15:56 uvtc: `merge-with` figures out what the new val should be by calling `(f curr-val this-new-val)`, correct? That is, the job of `f` is to come up with a completly new replacement for the val ... is that correct?

15:57 nDuff: uvtc, yes.

15:58 uvtc: Nice. Thanks, nDuff.

16:02 gfredericks: ,(merge-with + {:a 2 :b 4} {:c 100 :d 200})

16:02 clojurebot: {:d 200, :c 100, :a 2, :b 4}

16:02 gfredericks: that was a terrible example

16:03 progo: :)

16:03 uvtc: And for that, you must pay. 5 laps around the hash-map while the rest of the team waits.

16:03 gfredericks: ,(apply merge-with + (repeat 100000 {}))

16:03 clojurebot: {}

16:03 gfredericks: ,(apply merge-with + (repeat 100000 {:a 1}))

16:03 clojurebot: {:a 100000}

16:04 gfredericks: ,(apply merge-with + (repeat 100000 {(rand-int 4) (rand-int 4)}))

16:04 clojurebot: {1 100000}

16:04 gfredericks: whoops

16:04 ,(apply merge-with + (repeatedly 100000 #(hash-map (rand-int 4) (rand-int 4))))

16:04 clojurebot: {0 37323, 1 37768, 2 37303, 3 37310}

16:05 uvtc: gfredericks, I was trying to get this to work https://gist.github.com/3013575 but it's returning

16:05 [{:a 1, :b 2} {:a 11, :c 5, :b 22} {:a 7, :c 6}]

16:07 If the key is already in the result, but `curr-val` is not a set, then `curr-val` must just be the first number that made it in...

16:09 llasram: uvtc: missing an `apply` -- `merge-with` is getting passed a vector of maps, rather than maps as a sequence of arguments

16:10 uvtc: llasram, Ah!

16:10 scriptor: hmm, probably can't use cljs, but that's not gonna keep me from trying to code like I was

16:19 uvtc: llasram, it works (updated the gist). At first I didn't see why, but then remembered that you can pass in optional args to `apply` after the func but before the sequence you wish the func applied to.

16:19 solussd: how do you change chunk size?

16:19 llasram: Awesome!

16:20 uvtc: llasram, yes. Thanks. :)

16:21 llasram: Argh. I seem to do no better than chance at choosing the correct one of #{< >} in Clojure. A problem I don't seem to have with any other operators, or in languages where those operators are infix. Anyone else experience this?

16:22 aperiodic: it took me a few months to get the hang of that, but i must confess that i've just gotten good at mentally rearranging it to infix notation in my head

16:22 uvtc: llasram, if it's ">", then everything after it gets smaller.

16:22 If it's "<", then everything after gets bigger.

16:23 (I mean, for the expression to be true.)

16:23 aperiodic: ooh, that's a good mnemonic

16:23 gfredericks: increasing vs decreasing

16:23 uvtc: Don't want to take credit for that one. Read it somewhere... (maybe in Joy of Clojure?)

16:24 llasram: That's pretty similar to how I'd started thinking of it, but I just found a place where I messed it up again. Guess the solution is just to be more careful...

16:24 hiredman: ,(doc >)

16:24 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically decreasing order, otherwise false."

16:24 hiredman: it is how the doc string describes what it does

16:25 uvtc: Ha. Thanks. Guess that's where I saw it. :)

16:25 amalloy: you can also write (-> x (> 10)), which reads kinda well as "x greater than ten"

16:25 Bronsa: nice trick

16:25 * technomancy realizes he doesn't know the meaning of monotonically

16:26 uvtc: I'll have a monotonic, on the rocks.

16:26 technomancy: I thought monotonically increasing meant increasing by one but apparently that's not it. sneaky prefixes!

16:26 uvtc: Wait. Make that diatomic.

16:27 amalloy: technomancy: i think it's just a fancier word for "strictly" in that context

16:28 raek: I think of monotonic as "derivative does not change sign"

16:28 aperiodic: a monotonic function only goes in one direction; strictly monotonic ones *always* go in that direction

16:29 constant functions are monotonic, but not strictly monotonic

16:29 amalloy: aperiodic: that's what i thought too, but if so the doc for > is wrong, right?

16:29 $dict monotonic

16:29 lazybot: amalloy: adjective: of or using the Greek system of diacritics which discards the breathings and employs a single accent to indicate stress.

16:29 amalloy: $google monotonic increasing

16:29 llasram: Oh, that makes sense

16:29 lazybot: [Monotonic function - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Monotonic_function

16:30 amalloy: &(doc >=)

16:30 lazybot: ⇒ ------------------------- clojure.core/>= ([x] [x y] [x y & more]) Returns non-nil if nums are in monotonically non-increasing order, otherwise false. nil

16:30 aperiodic: amalloy: yes, a mathematician would say that the doc for > should say "strictly monotonically"

16:31 amalloy: aperiodic: or you could just discard "monotonically" from the docs for all the comparison functions, at once making them more accurate and easier to understand

16:31 > decreasing, >= non-increasing: done

16:32 aperiodic: yeah, that's much more accessible

16:34 amalloy: perhaps someone more strong-willed than i am could make a jira ticket suggesting that

16:36 uvtc: amalloy, tehehe :)

16:36 llasram: github pull requests are not a valid way of submitting patches?

16:36 technomancy: =(

16:37 llasram: Oh

16:37 Oh well. I probably should have guessed

16:39 juhu_chapa: Hi All! How can a method from a proxied class use a binded var?

16:39 hiredman: bound

16:40 llasram: juhu_chapa: Do you have a particular example in mind?

16:42 nDuff: juhu_chapa: it should just work, unless the method is only called somewhere else (outside of the binding's scope, ie. a different thread or a different time)

16:42 wingy: are you guys using java std lib a lot when using clojure?

16:43 are there any libs in java you prefer when doing web apps

16:44 technomancy: why doesn't c.j.jdbc convert numbers into j.sql.Timestamps upon insertion?

16:44 nDuff: wingy: ...I really tend to prefer compojure for building webapps, or do you mean libraries for a specific purpose beyond what Clojure-native bits provide?

16:44 juhu_chapa: nDuff: the method is called from another thread.

16:44 nDuff: juhu_chapa: non-root bindings are thread-local by nature, so it sounds like they may not be the right tool for what you're trying to accomplish.

16:45 hiredman: technomancy: I don't think c.j.jdbc does any conversion, any conversion that happens is from the jdbc driver

16:45 technomancy: oh, gotcha

16:46 juhu_chapa: nDuff: How can I declare a root binding?

16:46 ppppaul: anyone know of an HTML to JSON converter?

16:46 hiredman: which makes things really painful, because different jdbc drivers map standard sql types to different jvm types

16:46 nDuff: juhu_chapa: ...well, (def var value) is setting the root binding of var to value...

16:47 technomancy: hiredman: yeah, well database portability isn't

16:47 juhu_chapa: nDuff: thank you.

16:47 nDuff: juhu_chapa: ...there's also alter-var-root, but if you want to use that from a proxy method, it means that a var is probably the wrong tool and maybe you should be using a different abstraction (an atom, perhaps?)

16:47 timvisher|work: technomancy: thoughts on why swank.cdt would fail when I try to require it with the latest version of jack-in?

16:48 i'm getting CNFE

16:48 technomancy: timvisher|work: probably because tools.jar is specifically designed to make good tooling impossible =\

16:48 timvisher|work: figures

16:48 nDuff: juhu_chapa: (that said, using def from inside a proxy would be even more wrong than alter-var-root, so... yar, a continuum, but probably an atom is more the right tool)

16:48 technomancy: the cdt bits of lein-swank haven't been updated for 2.x

16:48 timvisher|work: what's even weirder is that i swear i had this working some time last week

16:48 and i don't think i've changed anything

16:49 i shouldn't need to specifically specify it as a plugin or anything, yes?

16:49 nDuff: my impression is that it _is_ a separate plugin

16:50 timvisher|work: the cdt jar shows up in .m2

16:50 technomancy: the problem is tools.jar

16:50 it hasn't been updated to work with 2.x yet

16:50 timvisher|work: nDuff: agreed, of course, but my impression was that jack-in does all sorts of fun stuff to get it on your classpath for easy access

16:50 wingy: nDuff: yeah any Java lib you usually need in addition to clojure ones

16:50 * timvisher|work has the light dawn on him

16:50 timvisher|work: so what you're saying is that it won't work under 2.x?

16:50 nDuff: wingy: ...nope, I don't have any of those.

16:50 technomancy: that's basically what I'm saying

16:51 in a nutshell, yes =)

16:51 juhu_chapa: nDuff: is it ok to do root binding at -main method?

16:51 timvisher|work: gotcha gotcha

16:51 lol

16:51 ok, thanks!

16:51 technomancy: should be an open issue for it in swank-clojure if you want to give it a crack

16:52 timvisher|work: lol, i'm getting a backlog of things i should give a crack at :)

16:52 sigh…

16:52 if only i had more time or different priorities

16:52 :)

16:52 nDuff: juhu_chapa: ...problematic. During ahead-of-time compilation, anything that expects to reference the var will want it to be defined earlier, ie. at top level.

16:53 juhu_chapa: you might consider a promise, and then deliver to it from your -main

16:53 (that, or an atom)

16:55 mattmoss: I'm working on some java interop, and I wonder if you might have opinions on this: https://gist.github.com/3013845

16:56 Trying to handle calls into clojure code from java code on a separate java thread.

16:56 juhu_chapa: nDuff: ok, let me check that.

16:56 mattmoss: Just wondering if I'm thinking too hard about the problem and making things more complicated than they need to be.

16:57 The code works, but... seems maybe I'm doing overkill?

16:58 hiredman: why not just have a single queue?

16:58 mattmoss: hiredman: All events into one agent?

16:59 hiredman: no

16:59 why are you using agents at all?

16:59 do you really want a reference type? or a queue of events?

17:00 mattmoss: hmm... I think initially I put in an agent because I thought "coming in from non-main thread", but that's probably wrong thinking.

17:00 hiredman: you may want to look at something like lamina

17:00 mattmoss: Also, I wanted "the clojure way" which this probably isn't.

17:01 I also wanted someone able to watch just event-3... but reify needs all three functions defined, even if they do nothing.

17:02 I suppose, overall, I thought letting clients add watches was better than adding multiple listeners, but I can't say why I thought that was better.

17:03 llasram: I think it depends on what "watch" means for your application, but ref-watching is probably not the right fit

17:04 mattmoss: Apologies, also, that I can't be more specific about what event-1 et. al. actually are.

17:04 llasram: Secrets!!!

17:04 mattmoss: lolz

17:05 llasram: From what you've presented so far, you could just allow each watcher to register a different listener, making it pretty by keeping internal the reify'd Listener closing over the functions to invoke. Maybe?

17:05 mattmoss: I should probably just drop the agents, and write functions more like the swing utils add-action-listener

17:06 acheng: i have (defmulti name "doc string" :key) ... but (doc name) doesn't show "doc string"... what did i do wrong?

17:07 mattmoss: llasram: Yeah, something like that.

17:12 jweiss: i'm using clojure to write tests, and as i posted on the mailing list, i'm having trouble writing out my tests (which can be considered both clojure code and data) in a way that I can read it back in. i keep coming back to eval, but everyone says eval is bad. i know no other way to conserve the original code as data, other than very fancy stuff like serializing all the functions and java objects and everything else.

17:12 gfredericks: jweiss: read-string doesn't help?

17:13 jweiss: gfredericks: that would turn a string into clojure data, but it would barf on #< ...>

17:13 which it always does, for me, since my data is full of that

17:13 gfredericks: why is your data full of that?

17:14 jweiss: gfredericks: well, let's say i have a data driven test. and one of the pieces of data is the function it needs to call to produce some value. the function gets printed out as #< ...>

17:14 so now my results are unreadable

17:14 if i used eval i could have saved the unevaluated form first.

17:15 TimMc: jweiss: Does serializable-fn help? It's half-joke, half-awesome.

17:15 jweiss: TimMc: actually i do use serializable-fn. it helps for functions. but there are plenty of other non-serializable types.

17:16 Raynes: TimMc: It's hardly half-joke. I'm using it for pretty important stuff in clojail as of today.

17:16 TimMc: ok

17:16 Raynes: It works really well for a lot of things.

17:16 TimMc: I didn't say it wasn't useful. :-)

17:16 technomancy: yeah, those don't have to be mutually exclusive =)

17:16 look at elnode

17:16 well actually don't

17:17 aperiodic: ...i don't even

17:17 technomancy: I warned you

17:17 TimMc: I thought it had its genesis as a reaction to the repeated attempts at serializable functions.

17:17 jweiss: TimMc: i also have a lot of timestamped values. so i don't want my results to say "I tested abc-123454654564" i want it to say 'I tested (timestamp "abc")'

17:17 TimMc: technomancy: Is that what I think it is?

17:17 technomancy: TimMc: run away!

17:17 Raynes: TimMc: An evented IO server in Emacs.

17:18 jweiss: serializable-fn would just show me the implementation of the timestamp function, which i don't want.

17:18 TimMc: ahhh WTF

17:18 technomancy: jweiss: a var might help

17:19 jweiss: yeah i realized i could refer to the function by var instead of symbol. that would make the output nicer but my code uglier.

17:19 technomancy: life is full of compromises =\

17:19 TimMc: jweiss: I have used eval for printable inputs: https://github.com/timmc/seqs-and-colls/blob/master/src/seqs/core.clj#L175

17:21 jweiss: technomancy: that is true, but i don't want to assume i have to compromise until i'm sure i have to :)

17:23 TimMc: ok if you did it, it is not such a crazy idea. My intent was to just quote the code and eval it when the test is executed. i figured the main issue might be namespaces, but i think syntax quote should take care of it.

17:24 TimMc: jweiss: In my case I used strings, but that's because of the function literals. If not for that, I would have 'quoted them.

17:24 jweiss: all right then i guess i will branch and try out eval and see how it goes :)

17:25 TimMc: godspeed

17:26 wingy: is it possible for a pure function to use a library when you do not know if the functions you are using are pure or not

17:26 if they are introducing side effects then your fn is not pure either

17:26 TimMc: Clojure doesn't have reified "pure functions".

17:35 timvisher: technomancy: so with lein2-preview6 on my mac, swank.cdt works, but on windows at the same version it doesn't

17:35 thoughts?

17:35 mhanson: All the things, they are broken.

17:35 Whoops, wrong channel.

17:36 acheng: phew!

17:36 wingy: mhanson: that's why they are broken!

17:36 you are not using clojure

17:36 mhanson: wingy: Hah.

17:36 wingy: HAH!

17:36 mhanson: But it's true, I'm using Groovy.

17:36 Yuck!

17:37 technomancy: timvisher: I don't understand how it could work on lein2 anywhere

17:37 xeqi: timvisher: do you have CLASSPATH set?

17:38 timvisher: xeqi: nope

17:38 xeqi: or whatever the mac equivalent

17:38 timvisher: lein version: Leiningen 2.0.0-preview6 on Java 1.6.0_33 Java HotSpot(TM) 64-Bit Server VM

17:38

17:39 https://gist.github.com/3014101

17:39 wingy: ok noob question

17:39 https://gist.github.com/3014094

17:39 why isnt the first line in the body executed

17:40 llasram: wingy: Your code is just referencing the function, not calling it

17:40 Use/mention distinction!

17:40 wingy: yeah haha

17:40 haha im such a noob

17:40 timvisher: wingy: Also if you're in a full featured environment like slime you won't see that output unless you pop open the repl

17:41 wingy: timvisher: hm havent used slime im on light table

17:41 slime is something for emacs?

17:41 xeqi: timvisher: how bout something like (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))) ?

17:41 timvisher: wingy: nice!

17:41 like it?

17:41 wingy: yeah a lot

17:41 best repl ever

17:42 timvisher: xeqi: https://gist.github.com/3014112

17:42 wingy: could someone explain what slime is

17:43 timvisher: wingy: i wonder how long the best features will take to port to emacs

17:43 :)

17:43 still, light table's one of the more impressive demos i've seen for an ide

17:43 xeqi: hmm, I don't see it there either.. wonder if the mac jdk is built differently :/

17:43 wingy: timvisher: how does it compare to emacs

17:43 so lispers are usually using emacs and not vim?

17:44 tbaldridge: wingy: the thing with emacs is, it's written in lisp (more or less)

17:44 wingy: tbaldridge: yeah .. why people is using it more in lisp world i guess

17:44 tbaldridge: so for me it came down to 1) use vim that's just a real barebones ide, or 2) use a editor that has been editing lisp for years

17:45 wingy: yeah pretty natural thinking

17:45 tbaldridge: So for instance, in emacs you can type (+ (1 2) 3)

17:45 Now place your cursor over the 1 and hit ALT+s and it turns the code into this (+ 1 2 3)

17:45 wingy: or 3) use light table which is built on Clojure

17:46 tbaldridge: once you understand paredit it's insane how easy it is to throw things into lists

17:46 aperiodic: tbaldridge: you can do that with paredit.vim, though it's not as full-featured as emacs's paredit

17:46 Raynes: It's pretty good.

17:46 m0smith: wingy: where would one get Light Table?

17:46 TimMc: m0smith: It's more "when" than "where".

17:47 Raynes: And combined with Vim's built in text objects, I found myself never wanting anything from it that I couldn't get.

17:47 wingy: m0smith: its not fully featured yet .. just a demo

17:47 or the REPL version of it

17:47 m0smith: :(

17:47 wingy: m0smith: http://www.chris-granger.com/2012/06/24/its-playtime/

17:48 timvisher: xeqi: it is a special port of the jdk

17:48 as far as i understand it

17:48 oh well

17:48 m0smith: thanks

17:49 wingy: np

17:49 could be used as a good repl atm

17:49 its using clj 1.5

17:49 m0smith: on another subject is there a defacto way of interacting with Swing or another such?

17:59 technomancy: people say seesaw is nice for swing

18:00 m0smith: ok thanks

18:06 wingy: memoize is cool

18:07 doesn't FP mean that all our functions should be wrapped in memoize since what is the point in recalculating if the return value always is the same?

18:07 given the same args

18:07 technomancy: depends how you feel about memory leaks, I guess

18:08 amalloy: and about doing lookups in a large map to find the result of (inc 1)

18:09 gtrak: wingy: we shouldn't write code, only lookup tables, clearly

18:09 technomancy: amalloy: what do you think about implementing a clojurebot backend for clojure.core.cache?

18:09 amalloy: heh. this just made me think: "classes are cool. maybe we should wrap all our functions in classes"

18:09 "oh nooooo what have we done"

18:10 rlb: was reading something recently talking about some of the tradeoffs being different than you might expect with the jvm, i.e. (re)computation cheaper than storage, etc.

18:10 amalloy: technomancy: what do i think? knock yourself out, dude

18:10 technomancy: amalloy: I guess you've been around too long to fall for my tricks.

18:11 Raynes: technomancy, amalloy: If we all delegate work to each other, I'm pretty sure none of it can ever get done.

18:11 * amalloy doesn't understand anything anymore

18:12 wingy: so use memoize only in big calculations?

18:12 gtrak: hmm... how do I make my lookup table more dynamic...

18:13 wingy: use it in good taste?

18:13 wingy: gtrak: taste is best practice for me

18:13 trying to figure out what that one is for memoize

18:13 dont forget im a beginner in all this

18:13 gtrak: performance opts best practice is to do it after profiling

18:14 wingy: what is a good way to profile your code?

18:14 gtrak: write for clarity and see how far that gets you first?

18:15 wingy: jvisualvm has some profiling built-in, you can mess with that, you have to simulate some kind of load, you can send a ton of web requests with apachebench (ab)

18:15 then look for hotspots and things

18:16 clojure itself has a 'time' function

18:18 I'd say though you should *never* use memoize if you inputs/outputs are out of your control? prefer something like core.cache

18:18 technomancy: I wish core's memoize just got slightly more clever and c.c.cache built on that

18:18 because there are lots of cases where pulling it in is huge overkill

18:19 wingy: this one ? https://github.com/clojure/core.cache

18:19 gtrak: or just make static things static, ie do the work at compile-time

18:22 technomancy: shouldn't be too hard to write a simple cache?

18:23 technomancy: yeah, but it would take 3 lines to make the built-in memoize significantly smarter

18:24 gtrak: you could also use google's thing

18:24 technomancy: just place the cache atom on the metadata of the function returned and accept an argument for an alternate swap! function

18:24 now you can easily switch to LRU or some other strategy

18:24 Cheiron: Hi, I'm wrapping Hector library in Clojure to be used in realtime system. should I use type hints?

18:25 brehaut: Cheiron: only if a) *warn-on-reflection* warns you or b) you need it for interop call site resolution

18:26 Cheiron: i'm thinking to use types hints since the software is realtime

18:26 gtrak: Cheiron: realtime is not java

18:26 hiredman: is realtime the same thing as webscale?

18:26 brehaut: Cheiron: type hints are magic pixie dust, and they are not static types.

18:27 Cheiron: well, I'm using Storm (realtime processing) , you are right.

18:27 TimMc: I thought they *weren't* magic pixie dust.

18:27 brehaut: sorry

18:27 wingy: have you guys encountered many aspies in programming world?

18:27 brehaut: TimMc is write and i typoed

18:27 hiredman: type hints let you avoid the overhead of reflection, so unless you know you are using relfection, don't use them

18:27 technomancy: if you have to ask, don't type hint

18:28 gtrak: maybe storm is 'real-time' in comparison to batch, the way that hadoop is normally used

18:28 Cheiron: ok. crystal clear

18:28 one more thing would you please check section :composite columns: of https://github.com/Netflix/astyanax/wiki/Getting-Started ? I tried to mimic it

18:28 (defrecord Hit [^{Component {:ordinal 0}} gid ^{Component {:ordinal 1}} tid])

18:28 technomancy: type hints are for after you've determined 0) it's slow and 1) it's slow because of reflection

18:29 hiredman: Cheiron: that isn't even correctly type hinting

18:29 Cheiron: I'm not type hinting here

18:29 I'm using annotations

18:29 earlier I typed: one more thing, so this is another topic :)

18:30 so, this is a valid use of annotations in Clojure?

18:31 hiredman: Cheiron: there is little to no use of the annotations stuff (as far I as can tell) so generally you best bet is to read the code

18:32 of course I've read the code, and don't recall, I think when I messed with it I didn't need an annotation with a value

18:32 (and of course I wanted an annotation on a constructor, which wasn't (isn't?) support)

18:32 supported

18:32 Cheiron: in case of Astyanax (the link I posted) , annotations are necessary

18:33 hiredman: http://dev.clojure.org/jira/browse/CLJ-948

18:34 most likely you'll need something more like what a java consumer would expect, strings for keys (maybe the annotation stuff calls name?)

18:35 Cheiron: I don't know really, I'm experimenting :)

18:44 wingy: so in clojure besides executing a function, what are the differences between lists and vectors?

18:44 which one should i use as an array in other langs to store multiple items

18:45 nDuff: wingy: Depends. Do you need efficient indexed access? Do you need to add things to the beginning or the end?

18:45 wingy: if i do that would be vector?

18:45 nDuff: wingy: the beginning, or the end?

18:45 wingy: which one?

18:46 wingy: end!

18:47 nDuff: wingy: for efficiently adding to the end, or efficient indexed access, you want a vector.

18:47 (likewise for efficient removal from the end)

18:48 ...which is why neither lists _or_ vectors make good queues

18:49 aperiodic: well, lists make great FIFO queues

18:49 er, LIFO queues

18:49 :P

18:50 nDuff: great stacks, indeed

18:50 brehaut: wingy: a simple rule if you havent internalised the details: you want vectors unless you are writing a macro ;)

18:50 nDuff: ...but the point I was trying to make to wingy was the need for PersistantQueue

18:50 wingy: ...also, if you don't care about where you add something (beginning or end), use conj, and it'll do whichever is efficient.

18:51 wingy: ok

18:52 TimMc: brehaut: For macros I use seqs, not lists.

18:54 brehaut: TimMc: i take any excuse to use list*

19:02 TimMc: &(type (list* 1 2 [3]))

19:02 lazybot: ⇒ clojure.lang.Cons

19:02 TimMc: brehaut: FYI ^

19:02 brehaut: a mere technicality :P

19:03 TimMc: hah!

19:05 wingy: btw what is the real point in having vectors and lists and not one data type for them?

19:05 with indexed access in it

19:05 brehaut: well to start, lists arent an indexed

19:06 nDuff: wingy: ...so, vectors are fast, but adding and removing things from the head of a linked list is _incredibly_ fast.

19:06 wingy: does that mean they have no order?

19:07 ok

19:07 they are fast!

19:08 list is an unindexed fast vector

19:08 nDuff: They're fast for different things.

19:08 Because vectors are indexed, they're fast for random access

19:09 whereas lists are only fast when working with the head.

19:09 wingy: nDuff: so there is no way to pick a specific item in the middle of a list?

19:09 nDuff: ...not "no way"

19:09 no _fast_ way.

19:09 it's an O(n) operation depending on how far into the list it is.

19:09 brehaut: wingy: only by walking (potentially) the entire list

19:09 wingy: ok

19:10 nDuff: whereas vectors are O(log32 n)

19:10 wingy: i get it more now

19:10 nDuff: which is practically O(1)

19:10 ("amortized constant time")

19:10 wingy: yeah if things arent indexed you have to traverse

19:16 Cheiron: clojurebot: Tesla or Edison?

19:16 clojurebot: Excuse me?

19:17 amalloy: brehaut: i disagree with "if you don't know the difference, use vectors". it leads to people being like "halp i have this function that produces a list but i need a vector because brehaut said so"

19:17 duck1123: Has anyone experienced an issue with the new lein and cljsbuild? I'm not seeing it as a task

19:18 brehaut: amalloy: geez, that would be the single worth appeal to authority in the world :( i agree with your refutation

19:19 Cheiron: I need to use a fixed list of values, so I create a mao of keywords. any better ideas?

19:20 duck1123: ok, I had it specified in my project.clj, but not in my .lein. I see it now. Should it show up if it's in profile.clj?

19:21 ok, ignore my question altogether

19:21 aperiodic: Cheiron: why not a set?

19:25 Cheiron: Hmm. also possible

19:26 but I don't feel using a map or set is neat

19:26 clojurebot: In Ordnung

19:26 Cheiron: (:A set) (:B set)

19:30 aperiodic: you can get all the members of a set in a seq by just calling seq on it, if that's more convenient

19:31 kovasb: ohpauleez: hey, are there any sample apps in the shoreleave repo set? most interested in the pubsub and services stuff

19:32 ohpauleez: kovasb: I haven't had time to finish up the app I showed at the meetup (which uses the google maps service and the pubsub stuff)

19:32 (traveling a little this week and next)

19:32 kovasb: ohpauleez: understood. are there any examples of usage somewhere?

19:34 i think i saw some on your slides.. will try to look them up

19:38 ohpauleez: There are some on the slides, and I just put this together: https://gist.github.com/3014746

19:38 should give you a very rough idea

19:40 kovasb: ^

19:40 kovasb: ohpauleez: thanks! will bug u if i have any issues :0

19:40 ohpauleez: Cool, thanks for trying it out

19:44 kovasb: And services (google maps geocode) : https://gist.github.com/3014768

19:44 kovasb: tight.

19:53 gfredericks: is it really CinC before jvm-clj is finished?

20:01 ohpauleez: gfredericks: what do you mean?

20:01 gfredericks: ohpauleez: just trolling

20:29 frozenlock: Is there a function to recursively replace a matching key in a map with a new value?

20:29 Kinda like `update-in', but for any depth.

20:31 technomancy: frozenlock: clojure.walk might have something

20:32 frozenlock: I must be using it wrong :(

20:32 $(clojure.walk/prewalk #(if (:b %) {:b 10} %) {:a {:b 2 :c {:e 4}}})

20:33 ,(clojure.walk/prewalk #(if (:b %) {:b 10} %) {:a {:b 2 :c {:e 4}}})

20:33 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.walk>

20:33 frozenlock: Wut.. it works on my machine.

20:33 Well no it doesn't work, but it gives something -_-

20:34 aperiodic: frozenlock: you probably want (assoc % :b 10) instead of just replacing the map in your then clause

20:34 frozenlock: Of course!

20:34 * frozenlock bangs his head on the wall

20:35 frozenlock: Works like a charm, thanks to both of you :)

20:36 aperiodic: you're welcome

21:06 devn: how do I update the clojure.org documentation?

21:06 wingy: is there a reference for all functions for a collection, sequence, string etc

21:06 aperiodic: wingy: http://clojure.org/cheatsheet

21:07 devn: http://clojure.org/cheatsheet

21:07 wingy: cool

21:07 aperiodic: i win this round of "cheatsheet URL quickdraw" ;)

21:07 devn: wingy: you might also be interested in clojureatlas.com

21:07 (ooohhh I just 1up'd you aperiodic)

21:07 wingy: this project seems dead http://clojuredocs.org/

21:08 aperiodic: aw, nuts

21:08 devn: wingy: it's not. I submitted examples recently.

21:09 wingy: havent been updated for a while

21:09 devn: aperiodic: you ever print clojure code with the pretty printer?

21:09 wingy: and its showing 1.3

21:09 devn: wingy: the changes from 1.3 to 1.4 are still pretty small. is there something you're looking for in particular?

21:09 wingy: i couldnt find seq

21:10 aperiodic: devn: i don't recall having done so off the top of my head, why?

21:10 devn: wingy: http://clojuredocs.org/clojure_core/1.3.0/clojure.core/seq

21:10 wingy: because i was blind

21:10 devn: lol, no worries

21:10 wingy: a lot of references!

21:10 devn: aperiodic: hm, it's just not working like it used to

21:11 wingy: are you referring to the very limited "see also" section?

21:11 wingy: in which reference? im having at least 4 up :)

21:12 http://clojure.org/Reference http://clojure.github.com/clojure/ http://clojure.org/cheatsheet http://clojuredocs.org/quickref/Clojure%20Core

21:13 devn: heh, i was referring to the seq examples on clojuredocs

21:13 seq should probably have quite a bit of "see also" in it

21:14 wingy: atlas looks cool

21:14 and productive

21:17 a good feature for the REPL could be that when you hit ENTER or enter it for the first time it will place you in (_)

21:17 no need to type () all the time

21:18 amalloy: wingy: i kinda have to point out that (a) you type parens all the time anyway, and (b) that makes lots of things impossible, such as printing [(foo) (bar)] or *clojure-version*

21:19 wingy: one backspace for deleting them

21:19 since they are paired .. but probably unnecessary since its just a simple repl

21:20 devn: wingy: yeah, that's up to other tools IMO

21:20 wingy: actually better without since now you can copy paste :)

21:20 i thought i was smart

21:22 he has a great product but the demo is killing it .. cut it down to 1-2 min .. im falling asleep

21:26 anyone here using Atlas? do you recommend it?

21:28 brehaut: wingy, im pretty sure cemerick would recommend it ;)

21:29 wingy: he's the author?

21:29 brehaut: yes

21:30 * cemerick denies all culpability

21:46 alfred1: is there a clojure wrapper for neo4j, the graph database?

21:51 wingy: alfred1: https://github.com/mattrepl/clojure-neo4j

21:51 this is a better one i think: https://github.com/michaelklishin/neocons

21:51 clojurebot: Ok.

21:51 wingy: clojurebot: ?

21:51 clojurebot: It's greek to me.

21:51 wingy: clojurebot: i bet

21:51 clojurebot: sharing code between client and server is not as simple or great as it sounds: http://blog.ianbicking.org/2011/03/30/js-on-server-and-client-is-not-a-big-deal/

21:55 alfred1: second one, neocons, looks cooler, thank you wingy

21:55 wingy: np

21:55 alfred1: cypher is pretty cool as well .. you can do a lot with it nowadays

21:56 just a post request to HTTP cypher endpoint

21:57 CREATE (person {name: {name}, age: {age}})

21:57 so the need for a lib is smaller with the latest version

21:58 one of the few things it doesn't do is indexing when you are creating an entity .. that's what i think neocons would help you with

21:59 alfred1: i'v just started tasting neo4j, haven't got clue of what cypher really is, is it the query language used in neo4j?

21:59 wingy: yeah for CRUD

21:59 and traversal

22:00 (wingy)-[:LIKES {since: "yesterday"}]->({name: "Clojure"})

22:01 alfred1: cool.

22:15 eck: what is generally used for parsing command line flags/options

22:16 aperiodic: eck: I usually use https://github.com/clojure/tools.cli

22:16 eck: cool, thanks

22:17 gtuckerkellogg: aperiodic, how to you find that compares to clojopts?

22:23 aperiodic: gtuckerkellogg: i haven't used clojopts before (or heard of it, even). it looks pretty similar, but a bit nicer, with the only thing missing being a handy way to create flags.

22:25 frozenlock: If I want to change a static variable in a jar, could I just open the .clj inside the jar, change the value, save and close? This way I could make "personalized" jar without doing lein uberjar each time.

22:35 wingy: i cant distinguish lists and seqs

22:36 they look the same

22:36 amalloy: good. don't distinguish them. just treat them as seqs

22:37 wingy: amalloy: thats the way?

22:37 Scriptor: wingy: they're supposed to have the same interface, what do you need to differentiate them for, might be able to solve the source of the problem

22:37 wingy: reading Clojure Programming

22:37 "Sequences are not lists"

22:38 Scriptor: not all sequences are lists, yes

22:38 wingy: donno .. i guess i just want to know the details when someone say list or seq

22:38 '(1 2 3)

22:38 is that a list or seq

22:38 Scriptor: that's specifically a list

22:39 but lists implement the interface for seqs

22:39 first, rest, next

22:39 TimMc: lists *happen to be* seqs.

22:39 Scriptor: yep

22:39 wingy: ok seq is an interface

22:39 Scriptor: all squares are rectangles, but not all rectangles are squares

22:39 same things

22:39 TimMc: wingy: No, seq is an abstraction.

22:39 wingy: ok

22:39 Scriptor: wingy: yes, ISeq is the name of the actual interface

22:39 wingy: TimMc: Hah!

22:39 Scriptor: well, TimMc is also right

22:40 when we talk about seqs, we talk about the general idea

22:40 and ISeq is just the code that implements that idea

22:40 TimMc: e.g., nil can be used in the seq abstraction, but does not implement ISeq

22:40 wingy: so now this is a seq: (seq '(1 2 3))

22:40 Scriptor: '(1 2 3) is also a seq

22:40 wingy: oh yeah .. that implements seq as abstraction/interface

22:41 TimMc: '(1 2 3) is reflectively a seq; (seq '(1 2 3)) is... semantically? a seq.

22:41 wingy: so there is no need for doing: (seq '(1 2 3))

22:41 Scriptor: here's ISeq.java https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java

22:41 wingy: since '(1 2 3) is already a seq?

22:41 Scriptor: it's astoundingly simple

22:41 right

22:41 ideally_world: has anyone here been able to get Slime to work with ClojureScriptOne?

22:42 TimMc: wingy: If this seems confusing, you're right -- this is a grungy part of Clojure that incurs a bit of cognitive load.

22:42 wingy: so "string" is also a seq?

22:42 TimMc: Nope!

22:42 wingy: since we can do first on it

22:42 Scriptor: nah, that just "happens" to be able to support first

22:42 TimMc: wingy: 'first calls 'seq on its arg.

22:43 This is true of a lot of seq-consuming fns.

22:43 wingy: ah

22:43 amalloy: wingy: strings and vectors are seqable, but not seqs

22:43 TimMc: And the fn 'seqable? is a lie.

22:43 wingy: is a list seqable or a seq?

22:43 TimMc: Yes.

22:43 (Both.)

22:43 Scriptor: list is a seq

22:43 wingy: is list the only seq?

22:43 amalloy: it is a seq, and implements seqable by returning itself

22:44 TimMc: wingy: (range), (seq [1 2 3]), and (cons 5 []) are all different kinds of seqs.

22:44 Scriptor: wingy: no, there's also lazy lists

22:44 ideally_world: seq is seqable, but seqalbe isn't necessarily a seq?

22:44 wingy: ideally_world: thats sounds right

22:44 Scriptor: ideally_world: seqable just means you can call (seq ...) on it and it will reqturn a valid seq

22:44 TimMc: or nil

22:45 &(seq [])

22:45 lazybot: ⇒ nil

22:45 TimMc: Nil-punning is a hell of a drug.

22:45 Scriptor: check out the java source for first() https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L564

22:45 wingy: ok there are different kinds of lists .. they are all seqs and seqable

22:45 so only lists are seqs?

22:45 Scriptor: not quite

22:46 (cons x ...) returns, internally, a cons object

22:46 joshua__: &(source seq)

22:46 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

22:46 wingy: this is bad design shouldnt be this hard to get haha

22:46 TimMc: wingy: (range), (seq [1 2 3]), and (cons 5 []) are not lists!

22:46 Scriptor: again something you can see by looking at the source! https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L554

22:46 TimMc: wingy: Half bad idea, half good idea.

22:47 Scriptor: yea, once you internalize it it makes a lot of sense

22:47 wingy: Scriptor: im not a source code guy :/

22:47 yet

22:47 Scriptor: ah, still, try to check them out

22:47 TimMc: wingy: http://www.brainonfire.net/files/seqs-and-colls/main.html

22:47 Scriptor: the functions are pretty small

22:48 for example, in cons, you can see that (unless you're consing onto null, ignore that for now) you get: return new Cons(...)

22:48 so an object of the class Cons, which is a different class than what lists use

22:48 however, both Cons and PersistentList (the class for lists) are seqs

22:49 brehaut: where does the .lein directory (and thus the lein2 profile.clj) live on windows?

22:51 wingy: cool to look at the source

22:51 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IPersistentCollection.java

22:51 Scriptor: right? :)

22:51 wingy: all collections are seqable

22:51 but the doc should make that clear

22:52 is there a way to know that all collections are seqable besides looking from the source?

22:52 xeqi: brehaut: reading the shell script mentions %USERPROFILE%\.lein

22:52 brehaut: xeqi: thanks

22:53 wingy: i hope light table fixes this in the future .. no more jumping around

22:53 that's their goal i guess

22:53 technomancy: wingy: there's no way to tell

22:54 wingy: i have like 4-5 references up

22:54 technomancy: just try it

22:54 wingy: actually there is

22:54 if the java doc was generated

22:54 and we get something like this: http://docs.oracle.com/javase/7/docs/api/index.html?java/lang/String.html

22:55 metellus: i don't really see why you would need to know about seqable at all, unless you were digging into clojure's internals

22:55 aperiodic: wingy: http://clojure.org/data_structures notes that all collections support sequencing

22:55 wingy: its confusing to not knowing the differences when you are trying to learn a programming language .. you dont know how its all related and dont know how to look it up

22:56 technomancy: don't look it up

22:56 try it in the repl

23:00 PeregrinePDX: Indeed I think I've learned more from just trying in a repl

23:00 with the occasional (doc ) in the repl as well

23:06 TimMc: "Empirical programming", a coworker called it.

23:06 aniero: hey, i'm trying to figure out the best concurrency mechanism in clojure to use for wrapping a Process

23:07 i've got multiple incoming threads that need to access it, but it may or may not be running yet, or may have failed, or whatever the case may be, and i need to have all but the first thread waiting for the process to start correctly before proceeding, while the first thread in sets it all up

23:08 the best i can think of is to use an agent for the Process, and use (await (send-off (find or create ...))), but joy of clojure implies this is an antipattern

23:09 brehaut: ,(let [p (promise)] (dotimes [n 5] (future (do @p (prn "done")))) (Thread/sleep 3000) (deliver p true)) ;; no idea if this is a good idea

23:09 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

23:10 brehaut: &(let [p (promise)] (dotimes [n 5] (future (do @p (prn "done")))) (Thread/sleep 3000) (deliver p true)) ;; is lazybot my friend?

23:10 lazybot: java.lang.SecurityException: You tripped the alarm! future-call is bad!

23:10 brehaut: nope

23:10 TimMc: Hey, clourebot used to allow threads, yeah?

23:10 brehaut: i thought so

23:11 but hiredman has been tweaking his eval recently

23:11 xeqi: hiredman did some security updates recently.. threads might have been a casuality

23:11 wingy: the book says (range 1 5) is returning a collection

23:11 but the repl and doc says seq

23:11 TimMc: wingy: http://www.brainonfire.net/files/seqs-and-colls/main.html

23:12 aniero: brehaut: hm, use a promise to say "hey, this thing is all good"?

23:12 brehaut: aniero: maybe? misuse of promises is a great way to deadlock though

23:13 aniero: hmmm, if i create the promise at init time before letting any of the threads through, there won't be a race condition for initializing it either... hm.

23:13 technomancy: aniero: does it have to be synchronous? you could use in-process queues

23:13 xeqi: Raynes: I saw the clojail update, is lazybot updated too?

23:14 aniero: technomancy: first thread in needs to initialize some stuff, anything coming in during that needs to wait, after that everything's fine

23:14 this is on-demand or i'd do the initialization first :)

23:14 brehaut: (let [p1 (promise) p2 (promise)] (future (do @p1 (deliver p2 :done))) @p2 (deliver p1 :done)) ;; aniero

23:14 cemerick: wingy: all seqs are collections, too

23:15 ,(coll? (range 1 5))

23:15 clojurebot: true

23:15 wingy: yeah

23:16 so we have two seqs

23:16 (range) and '()

23:16 amalloy: brehaut: that...never terminates, right?

23:16 brehaut: amalloy: correct

23:17 amalloy: just showing that its easy to deadlock with promises, even if they are created before they are used

23:17 wingy: what would i do without that reference

23:17 technomancy: wingy: it occurs to me that you're heading towards burning out on splitting hairs and would have a lot more fun if you just got to coding; most of this stuff makes sense once you've been using it for a while

23:18 wingy: technomancy: no going forward without knowing!

23:18 brehaut: wingy: not knowing never stopped a PHP programmer ;)

23:18 wingy: i feel happier to read on when i dont ignore things

23:18 aperiodic: aniero: in this sort of situation i use an atom that initially holds nil, and to decide which thread does the init, they (swap! atom (fn [id] (or id (.getId (Thread/currentThread)))) and see if the swapped value was their id

23:18 wingy: thats why they are using PHP

23:18 if they only knew

23:18 cemerick: wingy: non satis non scire

23:19 wingy: php was my first lang

23:19 no it was bash

23:19 aperiodic: heh, my first lang was ActionScript2

23:19 wingy: no . dos!

23:20 TimMc: You freaks. Mine was English.

23:20 I still don't know how it works.

23:20 aperiodic: nobody does, that's why it's so much fun

23:20 aniero: aperiodic: ah, so when a thread sees that it didn't set its own id, it waits somehow for the winner to do its job?

23:21 aperiodic: aniero: yeah, and you can use a promise for that w/out deadlock; winner delivers, everyone else derefs

23:22 technomancy: huh; did github switch back to showing SSH clone URLs by default? thank goodness

23:23 wingy: why did they show HTTPS

23:23 technomancy: ugh

23:23 wingy: wanted to add security?

23:23 aniero: aperiodic: (let [id (.getId (Thread/currentThread)] (if (= (swap! a (fn [i] (or i id)))) (do (initialize) (deliver p)) (deref p)

23:23 technomancy: because some pitiable souls have horrible firewalls, I think

23:24 maybe also so you could use the same URL for public clones and pushes

23:24 aperiodic: aniero: looks good, except you're missing the comparison to id (that is, = only has one arg)

23:24 aniero: er, right. but cool, ok!

23:25 hircus: LauJensen: ping

23:25 aniero: and then i get to figure out how to handle timeouts / restarts of that shared resource...

23:25 technomancy: hircus: hey, how goes the packaging?

23:27 aniero: aperiodic: thanks!

23:28 aperiodic: aniero: you're welcome!

23:29 TimMc: technomancy: When I wrote to them to tell them they were showing HTTPS by default, they said "That's a known bug, we have a ticket open to get it fixed."

23:29 That was June 4.

23:29 technomancy: oh, cool

23:29 TimMc: Or... hmm. That was re: showing HTTPS in the new-repo instructions, which is a bit different.

23:31 wingy: (cons [1 2] [4 5 6])

23:31 Returns a new seq where x is the first element and seq is

23:31 the rest.

23:31 the last one is not a seq!

23:31 TimMc: It gets seq'd.

23:32 wingy: lol

23:32 TimMc: &(type (rest (cons 1 [2 3])))

23:32 lazybot: ⇒ clojure.lang.PersistentVector$ChunkedSeq

23:37 wingy: i guess i dont want to know the details after all

23:38 as long as it just works

23:38 brehaut: TimMc: surely you mean 'class not 'type

23:38 TimMc: brehaut: Surely I do!

23:38 Bad PHP and Python habits.

23:38 * brehaut steps of his tiny hobby horse

23:38 brehaut: off

23:44 cemerick: What's wrong with type? A bit of a child of its times, but…

23:49 TimMc: One rarely wants the ad-hoc hierarchy info.

23:49 amalloy: TimMc: if a multimethod dispatches on type, as print-method does, you can customize how a particular instance of a single class behaves by giving it metadata

23:49 hircus: technomancy: hullo! going well, but Leiningen itself is stalled on some Maven2 packaging bugs

23:50 amalloy: eg, serializable-fn uses this to make closures serialize

23:51 hircus: (the Maven2 maintainer wanted to wait for some packaging guideline clarification before creating more Maven2 compatibility modules, and right now the shipped modules are... er, missing dependencies). can Leiningen 1.x work with Maven 3?

23:57 JulioBarros: Anyone know of an easy way to generate the SHA1 hash of a file?

23:57 Or of a project I could borrow some code from?

23:58 wingy: are you guys unit testing your functions?

Logging service provided by n01se.net