#clojure log - Jun 18 2012

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

1:16 michaelr525: good morning

1:16 !

1:28 tomoj: is there a good way to write new macros with recur semantics?

1:28 e.g. imagine loop didn't exist, could you cleanly write it as a macro the way it works with recur?

1:30 I suppose if you could, loop* wouldn't exist..

1:39 amalloy: tomoj: sure. you can macroexpand to ((fn [] ... (recur)))

1:40 but you're stuck with recur

1:42 you might find https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L108 relevant

1:42 it's a loop-like construct that lets you use either a regular recur, or a lazy-recur, which goes through lazy-seq

1:43 tomoj: hmm

1:44 I was thinking it would be harder to use an alternate name

1:44 amalloy: (sample usage at https://gist.github.com/776f35f77c198cf98bff)

1:44 tomoj: the lack of hygiene seems weird

1:45 but that's better than whatever I was imagining with "recur", and no less hygienic..

1:46 amalloy: well, loop/recur aren't hygenic either, really. recur is a symbol implicitly captured by loop

1:46 tomoj: yeah

2:07 it seems like in clojurescript if you (println 1 1), it prints "11\n", but (println 1 2) prints "1 2\n" O_o

2:12 bbloom: tomoj: ?

2:12 tomoj: whoa. lol

2:12 wtf?

2:13 tomoj: https://gist.github.com/2225f2e6152d9a052cb1

2:14 ahh

2:14 bbloom: tomoj: yeah, i was just looking at that… i'm not sure what it's trying to do

2:14 tomoj: at first I was like, why the heck did they write lines 7-8, now I get it

2:15 it's just a buggy version of interpose

2:15 bbloom: tomoj: yeah. do you want to make a patch?

2:15 tomoj: I will, but is there a CA I have to mail off :/

2:15 bbloom: can you open a ticket & i'll make a patch? :-)

2:16 tomoj: great

2:17 amalloy: wow, that's a pretty remarkable implementation of println

2:17 bbloom: amalloy: what's the "remark" you'd make about it? :-)

2:19 amalloy: i abstain

2:19 bbloom: amalloy: heh, i'm actual curious. what do you think is wrong with it?

2:21 tomoj: bbloom: http://dev.clojure.org/jira/browse/CLJS-319

2:21 amalloy: well, the obvious error, right? i think it's probably there's some more-general bug this is a special case of, something like "don't look at the values of your sequence if you're not supposed to care what they are"

2:22 bbloom: amalloy: oh. i thought you were referring to the more general pr-seq approach

2:22 tomoj: thanks, testing a patch now

2:22 amalloy: i don't know enough about cljs's internals to comment on that

2:23 i can't really tell what pr-seq does, even

2:24 bbloom: amalloy: in short, it's an optimization for building big strings out of many small parts. instead of stitching strings and re-stitching strings, you just always stitch them into a single buffer by walking over a sequence

2:25 tomoj: there is also the same bug in pr-with-opts

2:26 tomoj: that's where I saw the bug, is it copied somewhere else?

2:26 bbloom: tomoj: oh, sorry, yeah, the other one is pr-sb

2:26 tomoj: ah

2:26 bbloom: tomoj: two versions of the same thing. one writes to "*out*" so to speak, and the other to a string buffer

2:27 try println-str

2:27 probably could be made higher order :-P

2:28 actually, probably not w/ the string buffer and all… *shrug* i'll just make the fix twice :-)

2:29 tomoj: https://gist.github.com/e3c23b2ba35439c604c0

2:29 not sure how I feel about this

2:29 bbloom: I'm fixing it :-)

2:30 what's that after-loop stuff?

2:30 async?

2:30 tomoj: (I mean about my macro, not the print bug)

2:30 it's pretty much a port of rx's recursive relative-time scheduling

2:30 bbloom: ah neat

5:51 Kototama: what's the problem with maven today? first I got a problem downloading data.json and now that: http://paste2.org/p/2055280

5:55 oh yeah 503 error http://repo1.maven.org/maven2/org/clojure/java.jdbc/0.1.2/java.jdbc-0.1.2.jar

7:18 cshell: cemerick: Why does the friend authenticate method need to be called for each URI? Couldn't we tie it specifically to the login url? It seems like the authenticate method could execute for a particular URI, update the session, and then not need to be called again - am i missing something?

7:23 cemerick: cshell: the authenticate middleware is what turns unauthorized accesses into redirects to your login uri. If you don't need that, then you could probably get by with applying it only to your login route.

7:24 That might be a hint that authenticate should be split up into two separate bits of middleware. Something to think about, anyway.

7:25 cshell: cemerick: Okay, cool - I was looking at the OpenId workflow and it checks specifically that the uri is the login uri else it returns null

7:25 sorry, nil :)

7:26 I modeled my gitkit workflow off of that and only execute if we're on the callback uri - the one that comes back to us from the OpenId provider (so halfway through the existing openid workflow)

7:30 Chiron_: Hi, any performance penalties associated with multimethods?

7:31 ro_st: slower'n protocols :-)

7:32 Chiron_: in my case, check for a parameter and save to a different column family in cassandra depending on event type. I only have 6 cases

7:32 could be done with cond but multimethod provides a higher view (and some sexiness)

7:33 ro_st: coding for performance usually moves one away from coding for .. sexiness

7:34 ohpauleez: Chiron_: If you know you'll only have those six, and there's no possibility the domain will ever grow, you should use cond

7:34 Optionally, use core.match, which will get compiled as cond

7:35 Chiron_: multimethods shouldn't be touched for a small number of cases?

7:35 ohpauleez: If the domain will grow, of the function used to classify them could change with business logic, use multimethods

7:36 Chiron_: Multimethods are useful when you need open-ended dispatch on a variable number of things, and you know those things will change in the future (or you want to open the system to new things further down the road)

7:37 * dispatch on more than just type

7:37 If you're dispatching on type, just use a protocol

7:38 Chiron_: how much it is hard to learn and use core.match?

7:39 i know nothing about it

7:39 si14: ohpauleez: why did you split your framework to separate packets?

7:39 btw, looks awesome

7:39 *repos

7:39 ohpauleez: si14: There will be a "master" package/repo/clojars release

7:40 the split is to allow people to use it ala carte if they're building up their own stuff

7:40 For example, someone could build something and want to stand on top of just my pub sub stuff

7:40 thanks! that's good to hear!

7:41 si14: ohpauleez: Google Closure will eliminate all dead code, doesn't it?

7:41 Chiron_: ohpauleez: what is your framework? :)

7:41 ohpauleez: si14: Yes, it totally will. But, I've had enough requests to split it up, so I did.

7:42 ro_st: which framework is this?

7:42 ohpauleez: Not ready for the public yet, but Shoreleave: https://github.com/shoreleave

7:42 I'll be debuting it on Wednesday at the NYC Clojure meetup

7:43 ro_st: wicked!

7:43 Chiron_: a new web framework?

7:43 ohpauleez: It's a group of CLJS utilities

7:43 Chiron_: clojure on the server and the client?

7:43 ro_st: ohpauleez: i have a 'traditional' gclosure app which i'm aching to cljs-ify.

7:44 ohpauleez: not so much a framework, but what I had to build to start building serious CLJS apps

7:44 ro_st: Shoreleave should help. It extends a lot of protocols to gClosure stuff

7:44 Chiron_: yep!

7:45 It allows you to expose server-side namespaces as namespaced client-side calls

7:45 (and has security, like CSRF protection) built in

7:45 and a bunch of other stuff haha

7:45 Chiron_: cool! how it differes from ClojureScript One ?

7:46 ohpauleez: CS:One is similar, but is more a collection of functions grouped into a base application that you can use as a starting block

7:46 Shoreleave is a set of functions and services you use to build whatever you want

7:47 si14: I'm wondering if anyone actually made CS:One into useful app

7:47 Chiron_: "It allows you to expose server-side namespaces as namespaced client-side calls" something like DWR strategy?

7:48 ohpauleez: There's no starting block. You can use Shoreleave's pub sub system to declaratively bind your app together, the remotes package to call your server and third-party servers (like a SOLR server somewhere), there are embedded web workers, and a lot of browser functionality extended to CLJS facilities/protocols

7:48 ro_st: ohpauleez: a word of advice / a huge request: working sample code that exercises the stuff in the libraries, please!

7:48 ohpauleez: ro_st: On it's way, I have two apps: One that uses SOLR and JSONP. And the TODO app

7:49 ro_st: as a clojure newb, i have difficulty grokking clj libraries unless they map to stuff i'm used to

7:49 ohpauleez: again, this stuff isn't ready, I've been hesitant to talk about it (which is why it's not in Clojars yet)

7:49 but it should all be there by Wednesday

7:49 ro_st: i would love it if someone (cough @ cshell) could share their friend implementations, for example

7:50 ohpauleez: ro_st: Also have a look at the Marginalia docs for each module. They're just in first drafts, but hopefully that'll help too

7:50 ro_st: it'd be awesome if friend had some samples

7:50 ohpauleez: ro_st: I toyed with the idea of a Shoreleave/Friend demo

7:50 so maybe I'll see if I can make that happen

7:50 ro_st: cool, i will do ohpauleez. i'm still thoroughly in backend-land for a while, so i'll probably only get to shoreleave in a couple weeks

7:51 ohpauleez: (Client-side auth comes up often enough)

7:51 cool

7:51 ro_st: very grateful that you're sharing with us, though. i love the idea of using clojure end to end

7:51 i just found out travis-ci supports selenium testing!

7:52 cemerick: ohpauleez: What is Shoreleave?

7:52 ro_st: cemerick: https://github.com/shoreleave/shoreleave-core

7:52 ohpauleez: cemerick: CLJS bliss haha

7:52 A collection of utilities for CLJS apps: to build end-to-end CLJS apps

7:53 ro_st: just reading the marg docs. looks great

7:54 ohpauleez: cemerick: a pub sub system that supports functions, atoms, local storage, and embedded web workers as topics. Embedded web workers. Exposing server-side namespaces as client-side namespace'd calls, wrapped browser functionality

7:54 ro_st: Awesome!

7:55 cemerick: CSRF-protection, and XSS escaping where needed

7:57 cemerick: hah, didn't realize that there's a cljs enlive impl

7:57 ohpauleez: It's pretty solid. It has DOM listeners, and DOM "Actions"

7:57 so coupled with my pubsub, I can declaratively bind my entire application

7:58 ro_st: that is hot

7:58 can't wait to see that in action

7:58 so -ing tired of writing gclosure events

7:58 feel like i have to sing 99 bottles of beer on the wall every time i want something to happen!

7:59 ohpauleez: Agreed!

8:02 ro_st: what is your approach to state in cljs, ohpauleez?

8:02 as a newb, i'm not sure if stuff like MVC still applies in client side clojurescript

8:03 i guess your todo example app will answer that :)

8:03 piranha: ro_st: heh, I have same problem (coming to mvc, wondering what to do with state)

8:03 started with reading https://github.com/lynaghk/c2-demos/blob/master/todoMVC/src/cljs/imtodo/core.cljs

8:03 *coming from mvc

8:04 backbone.js, etc

8:05 ro_st: right now i have a context obj which gets passed injection style to all the key manager classes, and each manager has its own internal state. managers all listen to each other and event out when they need to share state changes or when views need to update

8:06 easily 50% of my code is all the hopscotchery of state declaration and setting state (and testing same)

8:06 * cemerick notes down "hopscotchery" for later use :-)

8:07 ro_st: the state machine stuff in cljs one looked a bit alien to me, to begin with. seemed like a helluva lot to go through to move back and forth between the two simple views that its sample has

8:07 piranha: yeah... I'm jumping between different approaches, still can't decide how should it be done :(

8:08 ro_st: cemerick: -grin-

8:08 piranha: tried to get simple event system + state, which fires those events

8:08 but it was a bit creepy to me, so I scraped it...

8:09 ro_st: this is why ohpauleez's declarative bindings sounds great. in adobe flex, we had the same thing. views were templates + bindings, and simple event handlers to deal with user interactions -> model changes

8:09 piranha: it would be interesting to see some at least moderately sized application

8:09 ro_st: yes. agreed

8:09 piranha: hm, declarative bindings?

8:09 yes, in backbone we have the same: models, and views, which render templates and handle user input and model changes

8:10 ro_st: yes. <Label text="{ thing.name }" />. change thing or thing's name, and Label's text is replaced

8:10 piranha: yep

8:11 ro_st: they did decl bindings with a compilation step. that'd be compiled down to as3 with enough event boilerplate for a small country

8:12 was nice to use, but performance is horrible.

8:12 piranha: :-)

8:12 so, are his declarative bindings available somewhere? :-))

8:13 ro_st: as he said: cljs-enlive and shoreleave-pubsub

8:13 he's doing a release of shoreleave on wednesday. i'd hold out until then :-)

8:13 piranha: :-)

8:14 hey, here is quite a bit of good stuff on shoreleave github org

8:14 I guess I can stop using most of google closure

8:14 sounds great ;D

8:17 ah, it still uses goog.* behind the scenes

8:17 ro_st: it will do. cljs uses goog

8:17 you want to use goog. you just don't want to have to write that code yourself, like i am currently :-(

8:17 ohpauleez: piranha: Yeah, it just wraps most of the nonsense up

8:18 ro_st: thousands of dev hours in that library, lots of battle testing across more browsers than we could ever hope to virtualise ourselves

8:18 ohpauleez: ro_st: I manage state in the DOM and local storage. Only one of my apps uses an atom to hold "join-data" for state

8:18 piranha: ohpauleez: yeah, the thing is that I've used Jsonp from goog yesterday and resulting (compiled with :advanced) file became 10k bigger...

8:18 ro_st: so anything that isn't present in the view (ie, on display) is in local storage?

8:19 ohpauleez: ro_st: More often than not

8:19 My layout looks like this:

8:19 piranha: ohpauleez: hm, what's wrong with atoms?

8:20 ohpauleez: main.cljs -> hook up history, wire up the bindings, set up brepl, attach listeners. listeners.cljs -> all the listeners I need. render.cljs -> All the DOM actions I need and the template functions

8:21 then a file per major action of service

8:21 ro_st: that sounds awesome. can't wait to see a working project.

8:21 ohpauleez: like search.cljs if I'm working with SOLR. mail.cljs for all my remote calls for emailing

8:21 piranha: Nothing, I just don't have a use for them

8:21 piranha: ok :)

8:23 ohpauleez: piranha: I still use atoms, but more often than not. The data tucked in the DOM and pushed into localStorage is enough

8:23 but more often than not, **

8:24 piranha: yeah, I see, it's just that I'm used to backbone's approach of storing everything in your objects and syncing to DOM/localStorage/server when I need/want this

8:24 and atoms sound like a perfect replacement for this :)

8:24 ro_st: i've been doing the MVC thing: user action event triggers a command class (so i can track usage and do undo/redo). command affects model. model changes event out, causing listening views to re-render their DOMs

8:25 piranha: yep, and atoms with add-watch sound like good plan there to me...

8:25 ohpauleez: ro_st: I think there is a different paradigm that CLJS opens up in the client. I'm not sure MVC is the best approach. Most of my apps operate on streams of data/actions. They're shaped a lot like how I write backend systems for Clojure. Declarative/reactive bindings seem the best fit here.

8:25 piranha: hm

8:26 I'd like to see working code if that would be possible, honestly, I really need shift in my head it seems :)

8:26 ohpauleez: When I need to store data across multiple interactions, I use an atom. When I want to save off parts of results or large data sets, I use localStorage. I save small nuggets of view-specific data with the history via HTML5 history API

8:27 ro_st: interesting

8:27 ohpauleez: There is still very much a separation between data, view, control/binding - but it doesn't force you to solve all problems with the same devices (something I think Backbone suffers from)

8:28 ro_st: my app is document based. start it up, choose a library of content to work from, create your own document, save/export. so i definitely need the M in MVC here

8:28 ohpauleez: regardless of the best approach, using CLJS has been a blast and extremely productive

8:29 ro_st: the library of content can be an atom (because you can switch libraries) and any amount of fns to retrieve data (it's quite structured). the user's doc can also be an atom, and internally it'll have all the required state… undo/redo, user-added data, etc

8:29 ohpauleez: ro_st: Yeah, you need to manage incremental changes. This is the type of app most people are coming up against

8:29 ro_st: yes

8:29 piranha: argh, I have to run. ohpauleez: if you'll do some write up or open source release, it would be awesome to see them :)

8:30 ro_st: two atoms, because i want to be able to easily serialise and deserialise the workspace atom from localstorage or the server

8:31 another big use of state in client-side js is for performance: reducing repeated lookups by caching local references

8:32 i wonder how well the gclosure compiler is able to optimise for this from cljs's generated js

8:32 (if at all)

8:33 ohpauleez: ro_st: So one thing I'm not sure about is the need to go atom->ls or ls->atom

8:33 I extended protocols to ls, so you can use it in sane way. Which is why I haven't made use of atoms (I just bang on localstorage)

8:34 I'm not sure this is a good practice, but it saves me one layer of control logic

8:34 ro_st: for example, i want users to be able to resume (on mobile). so save-button serialises the workspace into LS. reloading the browser page fetches your latest save and re-hydrates the view

8:36 ohpauleez: Right. But I'm just not sure the advantage of using an atom to store off partial data (say, all the things related to user) over having a :user entry in ls

8:37 ro_st: again, performance. localstorage stores strings

8:37 not objects

8:37 ohpauleez: and using (assoc! ls :user {}) => (reset! user-atom {})

8:37 but we have the reader

8:37 so now it stores everything

8:37 ro_st: i thought you can't eval clj browser-side?

8:37 ohpauleez: you can read it, you can't veal it

8:37 eval*

8:38 ro_st: so you can get back maps, vecs, sets and lists of primitives, but not of fns that you can then execute?

8:38 interesting

8:38 ohpauleez: exactly

8:39 and I wrapped all that up

8:39 works in cookies too

8:39 and in history states

8:39 ro_st: very compelling

8:39 definitely going to have to play with it

8:39 just need to figure out a way to not have to sleep anymore

8:39 ohpauleez: haha

8:40 ro_st: what's the cljs testing story like?

8:40 midje et al?

8:41 ohpauleez: ro_st: That story is largely absent, but there people are working on it

8:42 At tutorspree, we have cucumber+selenium anyway, and that continues to work for us

8:42 ro_st: ok cool. right now i use jasmine bdd specs (written in coffeescript)

8:42 ohpauleez: jasmine is awesome too

8:42 ro_st: and i run them on my CI via a 3-liner cuke

8:43 excellent. exciting

8:46 trying to use a non-Emacs editor after using Emacs for a couple weeks is infuriating

8:52 TimMc: C-s C-s C-s dammit why can't I search?

8:53 ro_st: C-M-space to select a form. C-a and C-e for start/end line (amazing how quickly those stick!) C-c C-c C-d for docs

8:54 i can already see a javascript-mode emacs setup on the horizon

9:01 vijaykiran: ro_st: I think you mean js2-mode :)

9:01 ro_st: yes, thank you!

9:02 i can use paredit with that, right?

9:02 foxdonut: ro_st: I feel the same way about vim

9:02 emacs has too many keystrokes to get things done

9:03 vijaykiran: ro_st: didn't try it but yes, you can

9:03 ro_st: i can do silly stuff like store some clojure source in a database, and pull it out and eval it and execute it, assuming a standard interface for calling into the code, right?

9:04 vijaykiran: ro_st: yes, check eval

9:04 ,(doc eval)

9:05 you probable need to load the text first, since eval operates on datastrcture

9:05 ro_st: ok so to use eval i'd first have to (read ) it first

9:05 -first

9:05 oh i see (load)

9:05 perfect

9:07 is there a variant that'll load, run some code in a closure, and then unload it all again once the closure completes? kinda like with file io

9:07 like with-open

9:07 vijaykiran: http://clojuredocs.org/clojure_core/clojure.core/read

9:08 example looks like what you want

9:09 ro_st: that looks great. so in my case, i'd (read r) and then add (func-from-that-file args-it-expects) and it'd return its results all the way up and toss all the transitory stuff

9:10 TimMc: I hope you have a good reason for using eval...

9:10 or are you just playing around?

9:11 ro_st: use case is that items in our library have quiz elements and each quiz is different. i'd like to put a small clojure fn in each library item that calcs the associated quiz's results, so that when that quiz is submitted, server reaches in, finds the result-calc, calcs it, and stores the result

9:11 without having to hard-code each quiz into the main server codebase

9:12 vijaykiran: ro_st: probably a dumb question - but is there a way you can just save the "rules" of calculating the quiz results instead of storing implementation ?

9:13 may be you can avoid read/eval

9:14 ro_st: i should probably look into doing that

9:14 foxdonut: Storing code in the database is a Bad Idea.

9:14 ro_st: as I crawl on the ground, bloody and half-dead, I whisper, "don't do it!"

9:14 ro_st: in this case, it's more storing a formula that is expressed as evaluatable code

9:15 vijaykiran: well, this can be a valid usecase for that - considering it as "rule" for the rule engine

9:15 ro_st: otherwise i have to concoct a rules language and a parser

9:15 vijaykiran: :)

9:15 TimMc: ro_st: How complex a formula might you have?

9:16 ro_st: it's really ridiculously simple. ensure i have 40 answers. check each one against the quiz for = or not=. sum up the hits. return a percentage

9:16 some quizes need two distinct percentages, each using some subset of the answers. some quizes allow multiple correct answers. some require all the correct answers to be present

9:17 foxdonut: ro_st: you could perhaps store the name of the function and just have a name->fn map in code?

9:17 then, no eval

9:17 ro_st: ie, super easy to express in JS (current impl) or clojure. but a P.I.T.A to create a language and parser for

9:17 i could do that, but that puts concrete impls back into my main codebase, which is precisely what i'm trying to avoid

9:18 down the road i want to use this same clojure code (as cljs) to present results clientside, and then have the server re-run the server-side copy to validate

9:18 i could clojail it? wouldn't that prevent the disadvantages somewhat?

9:19 TimMc: ro_st: No, it's your own data, so clojail isn't indicated.

9:20 ro_st: No parser is needed, just read in some data structures and process them.

9:22 You can read in something like {:main {:qCount 40, :answers {0 1, 1 1, 2 3, 3 0...}}, :alt {...}} where :main is the main score, :alt is some other one...

9:22 qCount isn't needed either, for that matter, just count the answers map.

9:22 ro_st: Scoring code isn't programmatically modifiable in the general case, but data structures are.

9:22 ro_st: qcount is to validate that the client sent enough answers. otherwise i could answer one correctly and send it and get 100%

9:23 ok. i'll have a go at this approach

9:23 TimMc: "just count the answers map" <-- as in, the expected answers

9:23 ro_st: oh, right :) duh

9:23 TimMc: :-)

9:23 ro_st: thanks guys. eval avoided.

9:24 TimMc: \o/

9:24 ro_st: i promise not to store code in the database, foxdonut, even at Web Scale

9:24 TimMc: haha

9:25 ro_st: oh, he left

9:26 ohpauleez: dustingetz: it's nice to see you in here as a regular

10:05 alexyakushev: Hello, could anyone please tell how can I provide some arguments to AOT-compilation process so the code being compiled would be aware of them?

10:06 In other words, I have two types of AOT-compilation: "debug" and "release", and I want the macroexpansion to depend on whether is used

10:07 ifesdjeen: alexyakushev: can't you use leningen2 profiles for that?

10:07 like --with-profile debug etc

10:07 TimMc: alexyakushev: Perhaps some environment variables?

10:08 alexyakushev: TimMc: I thought about it, but where can I set them? Before calling to clojure.core/compile?

10:09 TimMc: I mean, via System.setProperty() ?

10:09 ro_st: alexyakushev: you can prepend calls to lein wth env vars

10:09 DEBUG=true lein2 compile

10:09 TimMc: FOO_MODE=release lein uberjar

10:10 and then use System/getenv

10:11 alexyakushev: ro_st, TimMc: Thanks, that's an option, but I already use "DEBUG=true" calls to act like I'm running the Leiningen itself in the debug mode, not the application I'm compiling

10:11 TimMc: Do the env vars get through to your macro code?

10:14 alexyakushev: TimMc: I've just tried to do "FOO=true lein compile" and it didn't end up in (System/getProperties)

10:15 Or it should be inside the System/getenv ?

10:16 TimMc: getenv

10:16 alexyakushev: Yes, it works with System/getenv, but I'm still rather control it from inside

10:17 Perhaps, System/setProperty will be OK if I pickup a property that does not mingle with anything else

10:18 ro_st: just use a unique name

10:18 alexyakushev: OK, thanks for your help!

10:18 ro_st: thanks for teaching me how to do this in future :-)

10:19 gfredericks: am I crazy, or is there no simple way in minikanren to reverse a list faster than O(n^2)?

10:26 ro_st: looks like you're crazy :-)

10:49 wjlroe: Is there any ring middleware (or something like that) for recompiling my clojure code for every request (in development, while running with slime/swank) ? I tried writing my own but it didn't work

10:50 The reason being, if I change a template file, enlive doesn't serve up the new one until the deftemplate is recompiled

10:50 vijaykiran: I think ring has wrap-reload

10:51 but it doesn't monitor html files - enlive has few forks that do it for you

10:51 wjlroe: oh ok, interesting

10:53 dnolen: gfredericks: you should look at Prolog solutions to this, nrev

10:54 gfredericks: I believe most Prolog implementations may cheat with nrev - it is handled specially.

10:55 gfredericks: similarly, I see no problems with just calling Clojure reverse from within your core.logic program.

11:03 gfredericks: dnolen: surely reverse wouldn't handle a logic variable

11:14 lypanov: is this a new thing?

11:14 maven failing on release day?

11:17 anyone know what i can replace repo1.maven.org with?

11:21 :(

11:21 first two releases on clojure and both failing. this is really not looking good to the rest of the team.

11:21 vijaykiran: http://uk.maven.org/maven2

11:22 lypanov: ^

11:22 lypanov: vijaykiran: ah so repo1 is the central but is mirrored everywhere else.

11:22 where can i place that in order to have lein ignore central?

11:22 currently central is 503ing on everything after multiple minutes.

11:22 has been doing since this morning.

11:23 do i just add an extra repo line to project.clj?

11:23 or should i edit my maven config itself somehow?

11:24 vijaykiran: try - http://maven.apache.org/guides/mini/guide-mirror-settings.html

11:25 lypanov: "For example, the ID of the main Maven Central US repository included by default is central"

11:25 missed it first time i read that page. thx for linking again!

11:25 so i'm guessing the repo line in lein can also just take that

11:25 and it'll override… trying.

11:27 Exception in thread "main" java.lang.IllegalArgumentException: Duplicate key: central (NO_SOURCE_FILE:0)

11:27 meh

11:28 the exact block of code from the page in a new settings.xml (didn't have one) is doing the same.

11:29 does anyone know how to make leiningen not check maven but instead just use my lib/ dir?

11:29 as if release wasn't stressful enough.

11:29 will be ripping out maven asap. just as bad as its always been.

11:30 vijaykiran: lypanov: set :offline? to true

11:30 lypanov: to make leiningen not check maven

11:31 lypanov: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L164

11:32 lypanov: thank you.

11:32 owe you a few pints if we ever meet.

11:35 Wild_Cat: hrmm. Clojure uses not= instead of !=. Surprising.

11:35 uvtc: I'd wondered about that myself.

11:38 Wild_Cat: it's weird how functional languages all use a weird operator construct for that.

11:38 uvtc: Oh well though, 6 of one, half-dozen of the other.

11:39 Wild_Cat: yeah, its not that much of a problem. Plus, at least, not= looks more explicit and obvious than /= or <>

11:39 mhanson: help

11:39 Hm.

11:40 lucian: haskell is pretty insane about its function names

11:40 <*, *>, <*>, ==<, ...

11:40 and don't forget $

11:41 RickInGA: >>=

11:41 lypanov: vijaykiran: lein run just ignores it.

11:41 what is the way that most people are doing this?

11:41 as in, what am i doing wrong?

11:41 pepijndevos: How does detect-silence work in Overtone?

11:42 I want to detect-noise and then run a synth

11:42 lypanov: or is it really just me for which two production runs in a row have involved maven failures?

11:42 Wild_Cat: lucian: yeah, Haskell is crazy about 4-non-alphanumeric-character operators :p

11:42 lypanov: does http://repo1.maven.org/maven2/noir-cljs-lypanov/noir-cljs-lypanov/0.3.5/noir-cljs-lypanov-0.3.5.pom fail to respond for anyone else?

11:43 zacht: lypanov 404

11:43 vijaykiran: lypanov: try adding offline in settings.xml

11:43 lucian: Wild_Cat: yeah, you'd think naming things hadn't occured to them

11:43 lypanov: zacht: wtf?

11:43 axle_512: emacs/clojure question: Any reason why I would get tab completion in the slime repl, but not while editing my .clj file?

11:43 vijaykiran: axle_512: check if clojure_mode is on?

11:43 semperos: axle_512: you have to do C-c TAB

11:44 Wild_Cat: lucian: well, when they *do* name things they use the opposite meaning of what's associated with the name (hello, return :p )

11:44 semperos: in a file, whereas at the REPL simply TAB does completion

11:44 lucian: Wild_Cat: that too

11:44 axle_512: semperos: that was it!

11:44 lypanov: zacht: 503 after 2-3 minutes here.

11:44 axle_512: semperos: thanks!

11:44 semperos: axle_512: np

11:44 Wild_Cat: I keep wanting to love Haskell for its elegance, but it keeps finding reasons for me not to.

11:45 Chiron_: Hi, for a structure like this: {:timestamp-1 {:links { .. } , :buttons {.. }}, :timestamp-2 {:links { .. } , :buttons {.. }} , this structure should be stored to a DB . what would be an idiomatic way to iterate over it?

11:45 as you figured it out, it is a data for analytics :)

11:46 semperos: Chiron_: what are you trying to do by "iterating over it"? what output do you need?

11:46 zacht: lypanov http://search.maven.org suggests that the repository has nothing with noir, cljs, or lypanov in its name.

11:47 lypanov In which case a 404 is exactly right. :-)

11:48 Chiron_: I need values to be saved to a database . for something like this :timestamp-1 {:links {blog-1 4} , :buttons {blog-11 100} blog-11 should be saved to table buttons and blog-1 should be saved to table links

11:49 lypanov: zacht: problem is, its not doing that.

11:49 here its giving 503s.

11:49 anyway, i'm done with this.

11:49 time to replace this half assed toolchain.

11:51 its fixed.

11:52 nope. just a fluke. !@#$.

11:54 lynaghk`: dnolen: I didn't even know there was a *clojurescript* var; if that's the case, are there plans to remove the core.match.js custom namespace?

11:55 dnolen: lynaghk`: not really, that var is bound in macro in the core.match.js ns.

11:57 lynaghk`: dnolen: okay. I'll just change the keyset issue then. Do you want the patch against master or alpha9?

11:57 dnolen: lynaghk`: master please.

11:58 lynaghk`: dnolen: sure thing.

12:00 pepijndevos: how can I make overtone block until a sound has finished playing?

12:03 semperos: Chiron_: here's some example code: https://gist.github.com/2949115

12:03 with println's where you could write your DB-handling code

12:04 main tactic there is using destructuring to deal with your map structures

12:04 lypanov: how do most people deal with mavens complete lack of ability to keep a stable infrastructure?

12:04 should i run my own local mvn server?

12:05 Chiron_: semperos: Thanks! that is really cool. I really appreciate your time :beerchug:

12:05 semperos: Chiron_: no problem

12:05 lypanov: that's what my company does

12:06 solussd: does anyone know if enlive supports sibling selectors?

12:07 pipeline: lypanov: yes you absolutely should

12:07 lypanov: btw this sucker makes maven way easier to live with http://www.sonatype.org/nexus/

12:09 lypanov: are there any sanely priced cloud solutions?

12:09 or is this secure / easy enough to setup that i can just shove it on a rackspace instance and be done?

12:12 found the book. downloading.

12:20 ibiblio works.

12:20 uk doesn't work because it is the same damn thing as repo1

12:21 (lots of fun that the freaking mirror example uses it therefore)

12:22 also mirrorOf doesn't work.

12:22 *sigh*

12:22 Downloading: org/clojure/clojurescript/0.0-1069/clojurescript-0.0-1069.pom from repository central at http://repo1.maven.org/maven2

12:23 still looking at the wrong thing.

12:24 and <mirrorOf>*</mirrorOf> doesn't appear to be listened to by leiningen for some reason.

12:24 (it still uses the fallbacks)

12:25 okay fix for that last one is to not have something that doesn't actually exist.

12:26 ( ;) )

12:28 the-kenny: Is Central broken? We're having massive problems here.

12:29 lypanov: its down yes.

12:29 use ibiblio.

12:29 http://mirrors.ibiblio.org/pub/mirrors/maven2

12:29 http://maven.apache.org/guides/mini/guide-mirror-settings.html

12:30 first code block, replace uk mirror with http://mirrors.ibiblio.org/pub/mirrors/maven2

12:31 (reason for that is that uk mirror is also down)

12:32 its not really that its down. its just that they are all so incompetent that 404s are timing out instead of returning 404s.

12:36 technomancy: so this outage is about more than just the org.clojure group?

12:37 lypanov: yeah.

12:38 basically unless you have a repo mirror with all content you're gonna see massive delays during deploy.

12:38 so i'm gonna take pipeline and semperos 's suggestion and just set up nexus or something locally.

12:38 twice now we've had release day critical failures.

12:38 (and no, uberjar is not a solution i want to use)

12:39 technomancy: yeah, nexus would definitely insulate you from outages

12:39 lypanov: technomancy: i can't be angry at anyone other than myself that way :P

12:43 technomancy: related: http://whoownsyouruptime.com

12:43 pepijndevos: how do you install supercollider plugins into overtone?

12:46 technomancy: lypanov: what's your geographic region?

12:46 lypanov: europe. .nl.

12:48 technomancy: lypanov: it's taking 8 seconds here to return a 404 on central; is that close to what you're seeing?

12:48 lypanov: 1 minute and upwards sometimes. let me check.

12:48 Bronsa: yeah, here too

12:48 [italy]

12:50 technomancy: ok, now I'm getting huge delays

12:52 189.492 secs

13:03 lypanov: technomancy: trying in browser sometimes gives it back fast. more reliably broken without proxy as in curl.

13:50 S11001001: TimMc: what is this code-and-cocktails thing?

14:03 Chiron_: Hi, can we use a generic type in Clojure? in my case, I'm going to use Hector API http://hector-client.github.com/hector/build/html/content/getting_started.html

14:03 ColumnFamilyTemplate<String, String> template = .....

14:03 S11001001: Chiron_: yes, clojure is post-erasure, just pretend the typevars aren't there

14:03 Chiron_: S11001001: I'm totally in love with update-in and fnil xD blowed my mind

14:05 uvtc: "post-erasure"? What does Clojure have to do with 80's pop music?

14:06 Chiron_, also get-in. So nice.

14:06 nDuff: uvtc: Java's generics are a language feature that isn't actually represented in the bytecode

14:07 ...so, the extra type information is discarded after being used for checking during compilation.

14:08 uvtc: nDuff, Oh, I see. Tried to make a joke, then learned something. :) Thanks.

14:17 TimMc: S11001001: Beats me.

14:17 Chiron_: clojurebot: do you like Frank Sinatra?

14:17 TimMc: lazybot: Do you like 70's music???

14:17 lazybot: TimMc: How could that be wrong?

14:18 Chiron_: huh! where is our lovely clojurebot ?

14:18 hiredman: oom killed, what I get for using a t1.micro

14:36 * nDuff ponders tracking maintaining plugin->namespace associations for a shared clojure runtime; it's not that hard _until_ multiple plugins start using the same libraries, at which point... hmm.

14:51 rdsr: On startup my clojure repl switches to a namespace I've decided.

14:51 This namespace just "uses" other namespaces and doesn't define

14:51 any of its own vars, but when my repl starts up I'm unable to

14:51 access any of the public vars defined in other namespaces. Is

14:51 there a way I can accomplish this?

14:51 Here's my startup command

14:51 java -cp $classpath clojure.main -e "(ns A) (clojure.main/repl) (in-ns 'A) (clojure.core/use 'clojure.core)"

14:51 s/decided/defined

14:52 what' im doing in namespce A

14:52 (ns A

14:52 (:use [B]

14:52 [C]))

14:53 gfredericks: rdsr: you have a file with that code in it? is that file getting loaded?

14:54 rdsr: @gfredericks. Yes that file is A.clj

14:54 gfredericks: rdsr: how does it get loaded?

14:55 solussd_: can I "extend" a namespace without having to add (load …) forms to the original namespace file. E.g. if I wanted to add to the some.lib.thing namespace with a new file

14:55 rdsr: hmm. It mostly not getting loaded.

14:56 nDuff: rdsr: Consider require'ing A before switching to it.

14:56 rdsr: thanks @nDuff and gfredericks I'll try that out

14:58 SrPx: is clojure a lisp fam language? how is it different from cl and scheme?

14:59 rdsr: So something like "java -cp $classpath clojure.main -e "(ns A) (clojure.main/repl) (require 'A) (in-ns 'A) (clojure.core/use 'clojure.core)"" should work right?

14:59 nDuff: SrPx: (1) Yes (2) Lots of ways; it'd be easiest to start with a book.

14:59 AimHere: Yes; and the major difference is that it's not Lisp all the way up. Clojure is actually written in Java

14:59 Also what nDuff said

14:59 Also more parentheses

15:00 You get to play with [] and {} as well as ()

15:00 nDuff: AimHere: ...not to be forgetting ClojureCLR...

15:00 AimHere: Or clojurescript

15:01 nDuff: (well, clojurescript still has Java involved, albeit not at runtime)

15:01 SrPx: is it more or less productive? (know it is subjective but any words on that?)

15:01 I just have to chose which dialect to learn but it is hard because I well, dont know

15:01 nDuff: SrPx: Clojure is written with a very major focus on being useful for real-world work.

15:02 SrPx: more than java you'd say?

15:02 nDuff: SrPx: from that perspective, I'd take it over Scheme any day, and CL is just plain something of a mess (for historical reasons, but nonetheless)

15:02 sritchie: SrPx: clojure dev is much faster than java development

15:02 nDuff: SrPx: There's a major learning curve if you can't think in FP or LISPy terms yet, but once you've got that handled? Yes, very much so.

15:02 AimHere: Well CL is probably better if you want to write native applications; Scheme is better if you need an academic toy language. Clojure is for real work

15:03 SrPx: nDuff: learning clojure is enough to have an idea of what is lisp , what it has to offer, etc? without missing anything?

15:03 rdsr: thanks @nDuff and @gfedericks. Got it working now :)

15:03 SrPx: sritchie: kind of answer I'm expecting. what is faster than clojure, then? in your opinion

15:03 AimHere: SrPx, Pretty much, except that some of the implementation details aren't written in Clojure

15:03 SrPx: AimHere: sorry, what do you mean

15:04 AimHere: So if you're doing that SICP thing of writing your lisp in your lisp for learning or experimentation purposes, maybe scheme or CL might be more useful

15:04 mthvedt: are there any good guides or docs for implementing pprint for some data structure?

15:05 AimHere: SrPx, if you want to know how to implement Clojure, you have to learn some Java; that might be irrelevant to you, but it might not. Depends what you want

15:06 mattmoss: mthvedt: I *just* this moment did that, for a simple java object that pprint was stumbling over.

15:07 nDuff: SrPx: *nod* -- if having an idea of what a LISP means implementing one yourself, you might start with a simpler one. If you mean grokking enough of the concepts to be able to pick up another LISP quickly, Clojure should be fine.

15:07 mattmoss: (with-ns 'clojure.pprint (use-method simple-dispatch org.xyz.abc.LocalizedText #(pr (.toString %))))

15:07 with-ns coming from clojure.contrib.with-ns

15:08 mthvedt: mattmoss: thanks!

15:08 mattmoss: And this article, which is sadly incomplete. http://richhickey.github.com/clojure/doc/clojure/pprint/PrettyPrinting.html

15:08 lazybot: Nooooo, that's so out of date! Please see instead http://clojure.github.com/clojure/doc/clojure/pprint/PrettyPrinting.html and try to stop linking to rich's repo.

15:09 mattmoss: o_O

15:09 uvtc: SrPx: one thing Scheme does differently is that with Scheme you use cons/cdr for lists. Clojure just uses regular lists, and has extra built-in syntax for vectors, hash-maps, and sets. Clojure's quite likeable.

15:11 mattmoss: Lol... for a moment, I thought I was being scolded. Then I see it's just lazybot.

15:12 Wild_Cat: uvtc: aren't Clojure's lists implemented with cons cells?

15:12 uvtc: SrPx, so, if you go with Clojure, you sidestep the whole cons/car/cdr thing. Also, you asked about productivity: from Clojure you can directly access all Java libs (no wrapping libs or anything like that required). So, there's that.

15:12 cemerick: mattmoss: you were being scolded; richhickey.github.com is *old* :-)

15:12 Wild_Cat: (I do enjoy that they got rid of car and cdr, though)

15:12 uvtc: Wild_Cat, as far as I know, no.

15:12 ieure: Wild_Cat, They're actually arrays of java.lang.Object instances.

15:12 Wild_Cat: ieure: arrays? Now that's surprising.

15:12 ieure: Wild_Cat, Go read the source. It's enlightening.

15:12 Wild_Cat: I'd have expected vectors to be arrays, but surely not lists.

15:13 mattmoss: cemerick: Yeah, true that... But I thought a bot was scolding me for my answer to the pprint question, not the link.

15:13 I'm better now.

15:13 uvtc: cemerick, where should I send feedback on the Clojure Programming book?

15:14 cemerick: uvtc: as in, errata? help@clojurebook.com will do. I think O'Reilly has some form for submitting errata as well, but I don't have a link handy.

15:14 Wild_Cat: btw, are there any Clojure books (published or close to being so) that were written with 1.4 in mind?

15:14 uvtc: cemerick, Not errata. A section that seemed out of the blue to me.

15:15 nDuff: Wild_Cat: really, a book that covers 1.3 is close enough; 1.4 is not very different at all.

15:15 amalloy: Wild_Cat: lists are conses, but seqs are more general and might or might not be conses

15:16 Wild_Cat: nDuff: fair enough -- what about books written for 1.3? :p

15:16 nDuff: Wild_Cat: ...in terms of something recently published and quite up-to-date, I'd suggest the O'Reilly one (Clojure Programming)

15:16 Wild_Cat: OK, thanks

15:16 cemerick: Wild_Cat: The only significant additions in 1.4 are custom reader literals and mapv/filterv, and a variety of minor tweaks.

15:17 uvtc: sure, help@clojurebook.com is a sane place for anything :-)

15:17 uvtc: cemerick, thanks. Will do.

15:17 Wild_Cat: cemerick: wasn't a bunch of stuff from contrib folded into the stdlib too? (note: Clojure noob, completely unsure of what I'm saying :p )

15:18 nDuff: Wild_Cat: The contrib reorg was a 1.3 thing.

15:18 cemerick: Wild_Cat: That happened in 1.2 and 1.3.

15:18 Wild_Cat: right. Thanks guys.

15:18 solussd_: new question, if I have two namespaces that I want to alias using (require <namespace> :as <alias>), can I have them, somehow, share an alias? i.e. all symbols from both namespaces can be accessed under the same alias?

15:23 cemerick: solussd_: There's always a way, but such a thing would be a horrible thing to do to anyone that looks at the code later. :-)

15:28 solussd_: cemerick: ;) fine… what I really want to be able to do is extend an existing namespace

15:28 cemerick: solussd_: that's much easier to do; but just don't do it from library code

15:29 solussd_: cemerick: yeah, just for me. e.g. I want to add validator functions to noir.validation, for example

15:30 cemerick: solussd_: mindful use of in-ns, then

15:33 jedmtnman1: why does this work

15:33 ,(((comp symbol name) "foo")

15:34 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

15:34 jedmtnman1: or not

15:34 ,((comp symbol name) "foo")

15:34 clojurebot: foo

15:34 jedmtnman1: but this does not

15:34 mhanson: ,(not= true false)

15:34 clojurebot: true

15:35 mhanson: Is that the idiomatic way to do not-equal in Clojure?

15:35 jedmtnman1: (-> {:name "foo"} :name (comp symbol name))

15:35 mhanson: Or is (not (= true false) the more common way?

15:35 Bronsa: jedmtnman1: ##(-> {:name "foo"} :name ((comp symbol name)))

15:35 lazybot: ⇒ foo

15:35 jedmtnman1: Bronsa: ah, hmm. is there a better way to write that

15:36 Bronsa: makes sense now that i see it, but still a little odd, no?

15:37 Bronsa: seems right to me

15:38 TimMc: jedmtnman1: ##(-> {:name "foo"} :name name symbol)

15:38 lazybot: ⇒ foo

15:38 Bronsa: you can do ##(let [f (comp symbol name)] (-> {:name "foo"} :name f))

15:38 lazybot: ⇒ foo

15:38 Bronsa: or that too.

15:38 jedmtnman1: TimMc, Bronsa, thanks!

15:38 TimMc: jedmtnman1: ##((comp symbol name :name) {:name "foo"})

15:38 lazybot: ⇒ foo

15:39 Bronsa: ,'foo ;even better!

15:39 clojurebot: foo

15:39 TimMc: genius!

15:39 Bronsa: :D

15:47 Chiron_: How core.match works? https://github.com/clojure/core.match#about unable even to understand the first example :"\

15:49 amalloy: about 500 instances of jedmtnman1's question could have been averted if -> and ->> didn't implicitly convert symbols to lists :P

15:51 Chiron_: I don't mean under the hood.

15:52 Oh, it matches match [x y z] for possibilities [t f f] [f f t] [t t t]

15:52 right?

15:52 clojurebot: flatten |is| rarely the right answer. What if your "base type" is a list

16:05 TimMc: clojurebot: You're terrible.

16:05 clojurebot: No entiendo

16:06 mhanson: clojurebot: help

16:06 ohpauleez: clojurebot: What he's saying is that you're bad at your job

16:06 clojurebot: http://www.khanacademy.org/

16:06 c'est bon!

16:09 llasram: Is June 18th International Bot Non Sequitur Day or something?

16:10 S11001001: (inc clojurebot)

16:10 lazybot: ⇒ 10

16:10 arrdem: wat

16:10 (type clojurebot)

16:11 amalloy: (+ 3 3)

16:11 clojurebot: *suffusion of yellow*

16:11 mattmoss: (println clojurebot)

16:11 arrdem: ooh this'll be good

16:14 mhanson: Why are there two bots?

16:14 arrdem: on topic: any ideas how map can pass two arguments to an fn? I'm (map)ing over a list of strings and I'm getting an arity exception of two args to an fn which takes one.

16:14 S11001001: arrdem: give map another arg

16:14 and it'll give the fn another arg

16:15 _ulises: arrdem: care to paste the offending code?

16:15 llasram: ,(map #(vector %1 %2) (range 5) (range 5 10))

16:15 clojurebot: ([0 5] [1 6] [2 7] [3 8] [4 9])

16:15 arrdem: github.com/rdmckenzie/Doubletake/blob/master/src/doubletake/java/spec/core.clj

16:15 raek: ,(map vector (range 5) (range 5 10))

16:15 clojurebot: ([0 5] [1 6] [2 7] [3 8] [4 9])

16:16 arrdem: the offending defn is on line 136

16:16 llasram: raek: Yeah, I was just explicitly calling out the arguments for pedagogical effect

16:24 S11001001: woe is this for, arrdem: apply (fn [x] ["alt" x])

16:26 arrdem: S11001001: it's as close to code generation for the fnparse library as I've been able to come

16:26 S11001001: what this entire file does is do dependency resolution (where possible) and then generate what is almost valid clojure that I can complete by hand

16:27 S11001001: no, I'm saying that doesn't make sense

16:27 ,(doc apply)

16:28 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

16:28 arrdem: derp. so I could just be concat-ing

16:30 S11001001: also

16:30 ,(doc concat)

16:30 clojurebot: "([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."

16:31 S11001001: more like mappend interjection than mconcat

16:31 arrdem: correction: (concat ["alt"] (map....))

16:31 ,(doc mappend)

16:31 clojurebot: Huh?

16:31 S11001001: if you want a lazy seq instead of a vector

16:32 oh, I was speaking haskell

16:32 arrdem: ok.

16:32 S11001001: probably what you really want is ["alt" (map ...)]

16:32 aaelony: What's the best way to debug Enlive. For example, what (h/html-content "blah") becomes?

16:32 arrdem: S11001001: also thanks, that was in fact the bug somehow. (e) was lying to me.

16:34 muhoo: i find it harder and harder to keep different languages straight in my head. i was fixing something yesterday that wasn't clojure, and put the ( before the function name.

16:34 S11001001: type errors in lazy seqs get delayed until they're needed, so the backtrace has to be treated as a potential candidate list, rather than listing the actual location as the innermost or outermost frame you own

16:34 it is probably allowed :)

16:35 arrdem: muhoo: lol. I swear my next project is going to be a REPL which figures out what language I'm typing before trying to eval..

16:35 S11001001: that makes sense. thanks again.

16:36 technoma`: the commas get me every time

16:38 aaelony: aha, render is what i needed!!

16:38 jtoy: clojure doesn't have the means to parse this? "Mon Jan 31 09:23:21 +0000 2011" clj-time doesn't seem to work

16:39 hiredman: ~google java date parsing

16:39 clojurebot: First, out of 486000 results is:

16:39 SimpleDateFormat (Java 2 Platform SE v1.4.2)

16:39 http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html

16:39 jtoy: hiredman: the problem is that I can't get Jan to be parsed

16:40 hiredman: jtoy: I believe in you, read the docs

16:40 jtoy: haha

16:40 thx

16:43 hiredman: the doc is wrong, it says M Month in year Month ;July; Jul; 07 but it doesn't actually work

16:45 amalloy: the doc is not wrong

16:45 http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html#month

16:54 jtoy: (import '(java.text SimpleDateFormat)) ; (SimpleDateFormat. "E M d H:m:s Z y");(def parser (SimpleDateFormat. "E M d H:m:s Z y") ); (. parser parse "Mon Jan 31 09:23:21 +0000 2011") => java.text.ParseException: Unparseable date: "Mon Jan 31 09:23:21 +0000 2011" (NO_SOURCE_FILE:0)

16:54 what am I doing wrong here?

16:54 hiredman: not reading the docs

16:56 jtoy: hiredman: which part?

16:56 lypanov: Z

16:56 oops no.

16:56 * lypanov also can't find it

16:57 lypanov: jtoy: the examples section is really weird.

16:57 maybe you're meant to follow that.

16:58 i don't see how if thats the format you're meant to use this lib can possibly work though.

16:59 jtoy: hmmmmm...

17:00 lypanov: like seriously, how f'n arbitrary is "MMMMM"?

17:00 Wild_Cat: jtoy: (def parser (SimpleDateFormat. "EEE MMM dd HH:mm:ss Z yyyy"))

17:01 lypanov: i don't see the diff Wild_Cat.

17:01 the docs say "For parsing, both forms are accepted, independent of the number of pattern letters. "

17:01 Wild_Cat: lypanov: yeah. Looks like the docs are wrong.

17:02 lypanov: so "not reading the docs" was really "not reading the docs badly"?

17:03 Wild_Cat: why is it that no programming language has a sane, working, well-documented date/time parsing lib?

17:03 technoma`: Wild_Cat: because it's inhumanly difficult

17:03 jtoy: ruby's is pretty sane

17:03 lypanov: aye.

17:03 rubys rock.

17:03 jtoy: Time.parse("and it f*cking works")

17:04 technoma`: last I checked ruby Time objects had to either be in UTC or in local time

17:04 Wild_Cat: technoma`: well, at the very least I'd like it to parse the ISO format...

17:04 lypanov: technoma`: not when you use rails.

17:04 * Wild_Cat rages at Python's strptime on a regular basis

17:06 jtoy: so is the answer that java/clojure doesn't have a library to parse that date?

17:06 S11001001: joda-time

17:06 love it

17:06 add it to all your projects

17:06 brehaut: clj-time

17:07 (which is a thin wrapper around joda)

17:07 Wild_Cat: jtoy: it does. Look at the line I posted.

17:07 jtoy: the documentation sucks, but it can be parsed.

17:07 jtoy: Wild_Cat: I tested your line, i couldn't get it to parse

17:08 (def parser (SimpleDateFormat. "EEE MMM dd HH:mm:ss Z yyyy")) ; (. parser parse "Mon Jan 31 09:23:21 +0000 2011")

17:08 Wild_Cat: ,(.parse (java.text.SimpleDateFormat. "EEE MMM dd HH:mm:ss Z yyyy") "Mon Jan 31 09:23:21 +0000 2011")

17:08 clojurebot: #inst "2011-01-31T09:23:21.000-00:00"

17:08 Wild_Cat: see? it works!

17:08 jtoy: hmm, is it because I'm on the mac jam?

17:08 jvm

17:08 Wild_Cat: jtoy: I am on a Mac JVM too.

17:09 (1.6.0_33)

17:09 jtoy: Java(TM) SE Runtime Environment (build 1.6.0_31-b04-415-11M3635)

17:10 Raynes: Works for me on a mac jvm too.

17:10 In fact, same jvm as you, jtoy

17:10 S11001001: what is "I couldn't get it to", jtoy?

17:10 jtoy: (.parse (java.text.SimpleDateFormat. "EEE MMM dd HH:mm:ss Z yyyy") "Mon Jan 31 09:23:21 +0000 2011")

17:10 java.text.ParseException: Unparseable date: "Mon Jan 31 09:23:21 +0000 2011" (NO_SOURCE_FILE:0)

17:11 Raynes: Perhaps if you live in a black hole just outside of the milky way...

17:11 Wild_Cat: weird

17:12 S11001001: locale

17:12 Wild_Cat: ah, good point. jtoy: try removing the "Mon"?

17:13 * technoma` can tell you some horror stories about pathological date parsing cases

17:13 jtoy: removing Mon didnt work

17:13 lypanov: start minimal and build it up then.

17:13 * arrdem shudders in fear and returns to writing his Java parser praying it won't be as bad

17:13 jtoy: ok, it should work though, ill test on my server instead

17:13 i really hate programming

17:14 lypanov: whats your locale look like?

17:14 technoma`: you can't blame time formats on computers; those are humans' fault 100%

17:14 lypanov: technoma`++

17:14 Wild_Cat: jtoy: if you can though, try supplying dates in YYYY-MM-DDTHH:mm:ssZZZZ format, with nothing language-specific

17:14 (in particular, avoid all non-numeric chars)

17:15 lypanov: "default locale" whatever the hell that means.

17:15 arrdem: lypanov: your c_locale?

17:15 Wild_Cat: lypanov: nobody knows what it means >.<

17:16 lypanov: arrdem: i'd like to hope so but honestly i don't trust java to do the right thing.

17:16 arrdem: *actually. Java source is UTF8 through and through so... maybe not?

17:16 lypanov: encoding != locale.

17:17 technoma`: it's UTF-16

17:17 and even that's just internal

17:17 most macs default to an archaic MacRoman encoding

17:17 Wild_Cat: technoma`: no, source file encoding is UTF-8. Internal string encoding is butchered up UTF-16.

17:18 lypanov: aye. bugs the crap out of me.

17:18 Wild_Cat: (although I don't remember how butchered up it is exactly0

17:18 lypanov: i'm sure they have 8bit strings in the jit.

17:18 even js engines use 8bit strings now.

17:19 technoma`: JS engines don't have nearly the legacy baggage of the JVM

17:19 jtoy: it works fine on my server, not sure why not on my mac

17:19 so ill just leave it at that, i still hate programming though

17:19 lypanov: i love it.

17:19 i just hate people. all of them.

17:19 jtoy: haha

17:19 technoma`: especially people who observe daylight savings

17:19 those are the worst kind of people

17:19 mattmoss: grrrr

17:20 lypanov: that they observe it i don't mind.

17:20 jcromartie: technoma`: hey that was my government's decision

17:20 lypanov: that they change their f'n mindns… that i do.

17:20 technoma`: jcromartie: government's authority stems from the consent of the governed.

17:20 borkdude: this is a nice website though: http://everytimezone.com/

17:20 technoma`: rise up!

17:20 lypanov: RISE UP!

17:20 technoma`: throw off your shackles

17:20 arrdem: .... #clojure is inciting revolution now?

17:20 lypanov: on that topic (completely off topic) anyone watching continuum?

17:21 jcromartie: ooh that is nice

17:21 Wild_Cat: jtoy: my guess is that your Mac isn't using English as its primary UI language.

17:21 lypanov: ditto.

17:21 jtoy: Wild_Cat: yes, its in chinese

17:21 technoma`: borkdude: .nl is #3 in terms of visitors to http://leiningen.org; you must be doing a great job spreading the word. =)

17:22 lypanov: jtoy: type Mon right then! :)

17:22 Raynes: lypanov: Goodness no. I've had enough with timp jumping and stuff with Fringe and Quantum Leap.

17:22 borkdude: technoma` I press f5 all day

17:22 Wild_Cat: jtoy: well, there you have it. SimpleDateFormat will attempt to parse dates using your system's language, and neither "Monday" nor "January" is valid Chinese.

17:22 lypanov: Raynes: other than the flashbacks there is not much time jumping.

17:22 Wild_Cat: (which is why I recommended you stick to purely numeric dates)

17:22 lypanov: Raynes: and fringe is on a whoooole different level. as in, not just 4th dim.

17:23 S11001001: or always specify which locale you mean

17:23 lypanov: Raynes: its actually fun.

17:23 Wild_Cat: lypanov: what is Continuum?

17:23 technoma`: jtoy: also consider developing on a virtual machine that matches your production setup

17:23 borkdude: technoma` kidding, well 27 students used it, but I don't know if that would explain it all ;)

17:23 * Wild_Cat watched Primer again last weekend. Still pretty good.

17:23 technoma`: jtoy: developing on OS X opens you up to all kinds of subtle incompatibilities

17:23 lypanov: us tv series. i'm enjoying it but i'd like someone to explain wtf is going on with the whole backstory.

17:23 jtoy: Wild_Cat: yeah, those dates come from a 3rd party, but i use numbers internally

17:23 aperiodic: ++ to using a dev VM

17:23 lypanov: as in, i am supporting the bad guys…

17:23 aperiodic: saves so many headaches

17:23 lypanov: death to mac.

17:24 jtoy: i am going to program with a vm

17:24 * lypanov uses a virtual box fedora on top of his iMac so he doesn't have to deal with this crap

17:24 mattmoss: death to mac (sent from my iMacBookPro)

17:24 technoma`: been meaning to try out vmfest as a vagrant alternative; anyone know how it stacks up?

17:24 lypanov: technoma`: it rules.

17:25 Wild_Cat: VMs suck up memory. Tons of it.

17:25 lypanov: chef blows massive sweaty donkey balls.

17:25 buy more.

17:25 jtoy: i am planning to use a vm, how do you guys share the folders between OSes though

17:25 technoma`: oh gosh don't I know it

17:25 * lypanov has 12 gb

17:25 jtoy: virtualbox

17:25 technoma`: re chef

17:25 Raynes: I tried using a VM. If I had a mac that was powerful enough to run OS X, I might consider it again.

17:25 borkdude: jtoy what machine do you have now?

17:25 jtoy: macbookair with 4 gb of ram

17:26 tbatchelli: jtoy: with vmfest you can share local folders amongst VMs

17:26 borkdude: jtoy I used VirtualBox but I switched to Parallels, I'm really happy with it

17:26 technoma`: vbox isn't the zippiest on I/O, but it has a killer API for automation

17:26 borkdude: jtoy it's really easy to share folders with it

17:26 lypanov: i don't share files.

17:26 why would you need that?

17:27 Raynes: i'm 99% sure that i'm gonna ditch osx on my iMac anyway. tired of it.

17:27 Lion is freaking awful.

17:27 jtoy: lypanov: so i can use a mac editor and test in the vm

17:27 lypanov: jtoy: ah, i use vim.

17:27 anything less than vim is the suck.

17:27 jtoy: lypanov: me too, macvim

17:27 technoma`: yeah, shared dirs between the VM and the host feels a bit like an antipattern

17:28 lypanov: jtoy: from my experience doing it in term is better overall.

17:28 macvim blows anyway.

17:28 borkdude: jtoy http://www.mupromo.com/ <- Parallels for real cheap

17:28 lypanov: virtualbox.org. vbox for real cheap.

17:28 :P

17:28 * lypanov doesn't really get why macvim is so popular when vim cocoa was so much better

17:29 lypanov: jtoy: are you on lion?

17:29 jtoy: yes

17:29 borkdude: lypanov I used virtualbox, but being able to keep pressing Cmd-c instead of ctrl-c without configuring anything is really worth the money to me :P

17:29 lypanov: jtoy: if not then yeah, term.app blows so then iterm2.

17:29 borkdude: 4 win?

17:30 jtoy: In short, MacVim is a more feature-rich, more Mac-integrated version, while vim-cocoa follows a simpler, more lightweight and faster approach.

17:30 lypanov: parallels/vmware are far better for win.

17:30 jtoy: never heard of it anyway

17:30 borkdude: lypanov windows vm in osx yes

17:30 lypanov: but vbox is fine for linux vm.

17:30 jtoy: yes. you're right.

17:30 screw more mac integrated though. :P

17:30 * lypanov wants fast

17:30 * brehaut doesnt get why vim is so popular when evil-mode is so much better ;)

17:31 lypanov: brehaut: unless you actually know vim.

17:31 nDuff: lypanov++

17:31 borkdude: also virtualbox only recently made it possible to expand existing virtual disk images, that was really crazy

17:32 technoma`: huh; I've been doing that for ages

17:32 borkdude: technoma` really? how

17:32 technoma`: it just expands on-demand

17:32 nDuff: convert to raw, dd onto the end, convert back

17:32 technoma`: only if you made the base size large enough; I presume borkdude is referring to the case where one didn't.

17:33 borkdude: nDuff right

17:33 SrPx: Anyone here who logs the chan, could you send me today's log please?

17:33 lypanov: i use pallet.

17:33 nDuff: SrPx: it's googlable.

17:33 lypanov: so when i want it bigger i change the config and rebuild.

17:33 technoma`: nDuff: sure, but since it expands on demand why would you ever make the base size something other than absurdly huge?

17:33 lypanov: i can't imagine having to manually maintain a vm image.

17:33 it'd be just as bad as having my mac be my dev env again.

17:34 nDuff: technoma`: Not wasting space (and fsck time) on extra inodes and other metadata?

17:34 lypanov: whole point is reproducibility and transparency.

17:34 borkdude: http://www.webupd8.org/2011/02/how-to-easily-resize-virtualbox-40-hard.html

17:34 technoma` I just wanted to be sure that my VMs don't took up more than X space

17:35 did not take

17:35 nDuff: *nod* -- the error conditions when they need to expand but don't have the physical space available are more corruption-inducing than merely being out-of-space

17:35 so that's a valid concern too.

17:35 technoma`: hm; I guess I've just been lucky

17:36 cshell_w: does anyone know where clojure conj 2012 is going to be held?

17:36 SrPx: hmm

17:36 nDuff: thanks

17:37 borkdude: I also like the fact that Parallels just stuffs the virtual machine definition and disk into one "thing"

17:37 I can just copy the thing if I want another virtual machine, or make a template out of it, etc

17:37 clojurebot: my lisp machine is the jvm

17:37 lypanov: for win using vbox is silly.

17:37 but while i'm on mac and vmware / parallels have no support for e.g. vmfest.

17:37 i don't care for them.

17:38 technoma`: yeah, automation wins every time

17:38 nDuff: There's automation available for VMware

17:38 lypanov: not for mac.

17:38 nDuff: Ahh.

17:38 borkdude: lypanov I don't have that many VMs, so not an issue for me I guess

17:38 lypanov: technoma`: lets put pallet this way, i replaced my entire vagrant/chef infrastructure within days. to upgrade to chef 10.0 would have taken longer.

17:38 technoma`: hah; nice

17:38 lypanov: borkdude: somedays i run 8+.

17:39 technoma`: I have a sneaking suspicion chef's client-server architecture is designed specifically in order to make it so they can sell subscriptions

17:39 lypanov: its just crap.

17:39 complicated crap.

17:39 * nDuff isn't sure he buys that.

17:39 lypanov: my pallet code is completely readable and tiny in comparison.

17:40 cp -ax'ing recipes is not my idea of reusability for the year 2012.

17:40 nDuff: There _are_ aspects to Chef that are more complex than some other systems, but those complexities are there to add features that aren't necessarily available elsewhere.

17:40 SrPx: hmm thanks you guys for the answers you gave some hours ago ( :

17:40 lypanov: nDuff: pallet can do everything and more.

17:40 chef is lacking huge amounts of things i can do with pallet due to its embeddable nature.

17:40 SrPx: nDuff: are there languages more productive than clojure ?

17:40 nDuff: lypanov: when I last looked at it, admittedly a bit over a year ago, pallet was not even _remotely_ close to feature-competitive.

17:40 lypanov: out of the box no.

17:41 but if you can actually code, chef is a joke.

17:41 and feature checks lists always put the worst at the top.

17:42 nDuff: lypanov: I'd have to actually see a large-scale, complicated environment being maintained with pallet in practice before I could be sold.

17:42 technoma`: chef is a great example of making things that should be orthogonal tightly coupled

17:42 lypanov: depends on what you mean by "see" nDuff

17:42 nDuff: lypanov: ...and to be clear, when I say "in practice", I mean real-world, ie. deploying proprietary "solutions" that don't allow systems to be nuked-and-paved but force incremental maintenance.

17:43 lypanov: no clue. never worked on a system that was so badly designed that i couldn't ditch half of it at a days notice.

17:43 (i.e., never worked in a large company built on legacy, would never wish to)

17:44 technoma`++

17:44 nDuff: lypanov: I very, very much appreciate wanting to stay in a greenfield environment, but _someone_ has to have a toolchain that's up to managing the legacy applications.

17:45 lypanov: i have to be honest i don't think chef is.

17:45 nDuff: technoma`: I'm not sure it's as much so as you may think. The services offered by the Chef server are actually well-defined and limited; it's the client side that's... err... more of a mess.

17:45 lypanov: puppet maybe sure.

17:45 but chef is insanely limited.

17:45 nDuff: *snerk*.

17:45 lypanov: anyway i do agree that i don't think its malicious on ill intended on the chef guys part.

17:45 nDuff: lypanov: I was half of the two-man team managing MessageOne's operations -- multiple multi-thousand-machine DCs worldwide -- on Puppet.

17:45 lypanov: they are nice guys that want to do a good job.

17:45 nDuff: lypanov: Puppet is utter, utter, UTTER crap.-

17:45 lypanov: nDuff: i know. but it works.

17:45 nDuff: ...now, mind you, the other half of that team is now at Puppet Labs

17:45 lypanov: haha.

17:46 nDuff: ...so maybe we came away with somewhat different impressions...

17:46 ...but I moved to Chef for my next gig, and came away far happier.

17:46 lypanov: yeah chef is far better.

17:46 but its not the best imo.

17:46 seen the company list for pallet?

17:46 they have some impressive clients.

17:46 * nDuff missed the Pallet talk at last year's conj, and somewhat regrets it

17:46 technoma`: inventing your own language and dependency mechanisms inside an existing language limits the damage you can do vs designing a language from scratch =)

17:47 lypanov: technoma`: yes.

17:47 nDuff: ...but I spent enough time investigating Pallet to at least get a few patches in, and my impression at the time was that it simply didn't have the facilities I needed.

17:47 lypanov: nDuff: no the base system is small and limited.

17:47 but i find that my dev speed with it is far better than chef.

17:48 aperiodic: cshell_w: i seem to recall hearing New York, which is consistent with the image on clojure-conj.org, but don't quote me

17:48 lypanov: maybe its just because i actually got into clojure via pallet.

17:49 seancorfield: aperiodic: the NYC October 1st thing is SkillsMatter; the conj is in November (and will be in Raleigh/Durham as far as I know?)

17:50 aperiodic: seancorfield: I assumed so as well, but I seem to recall lynaghk telling me it was in NYC.

17:50 cshell_w: the real answer is "wait until they announce it"

17:51 seancorfield: that would be more consistent with the image on the web site, true... so i might finally get to go to NYC :)

17:51 aperiodic: I don't know where lynaghk was getting his info, though. it's probably all hearsay at this point.

17:52 lynaghk`: aperiodic: dude, I know you live in portland but...look at that cityscape: http://clojure-conj.org/

17:52 hugod: nDuff: I would be interested in hearing what you were missing from pallet, if you have some time to pass by #pallet

17:52 lynaghk`: aperiodic: that look like raleigh to you? =P

17:54 aperiodic: lynaghk`: i can, in fact, recognize NYC, i was just pointing out that nothing's official at this point.

17:55 Raynes: I didn't see any dead hookers, so I'm unconvinced.

17:55 lynaghk`: aperiodic: there's also a nyc grid coordinate reader literal in JIRA

17:55 cshell_w: aperiodic: thanks, it did look like NYC but I wasn't sure

17:56 any idea on dates? I have to be in nyc for thanksgiving

17:56 aperiodic: lynaghk`: grid coordinate reader literal?

17:56 technoma`: lynaghk`: sign me up

17:57 wait aren't NYC blocks already labeled by UUID? so you should get that for free.

17:59 lynaghk`: technoma`: the literal is useful when you want to query .asOf("New Amsterdam")

18:00 dmiles_afk: http://pastebin.com/ysN0PAz3 - here is teh C# syntax and the prolog Syntx.. what "should" the Clojure syntax be?

18:00 i suppose this is a Clojure-CLR question

18:45 emezeske: l

18:46 * emezeske sees now that this is not a terminal.

18:46 mwillhite: anyone run into this before? Exception in thread "main" java.lang.IllegalArgumentException: No matching method found: setRequestHeaderSize for class org.mortbay.jetty.bio.SocketConnector

18:48 bbloom: mwillhite: much more information needed

18:48 mwillhite: ha

18:48 np

18:50 bbloom: mwillhite: what libraries are you using? what are you trying to do? do you have a stack trace? do you have a reliable repro case? a minimal one?

19:03 mwillhite: no worries, I was just tossing it out there, its a complicated app but we got it figured out…it was a ring dependency conflict

19:03 thanks thos

19:03 *though

19:05 dmiles_afk: any anwers to my question?

19:06 http://pastebin.com/ysN0PAz3 - here is teh C# syntax and the prolog Syntx.. what "should" the Clojure syntax be? (i suppose this is a Clojure-CLR question)

19:07 hiredman: dmiles_afk: I guess I don't understand the context

19:09 dmiles_afk: this code idiom needs to be used several 100 times.. a codebock that looks like that C#... new ResetEvent+make a lambda + register it + call something + wait fo the evetn to finish + unregister the event + return some value

19:09 hiredman: I would be more inclined towards the prolog style if I was writing a generate search/query interface, something more method/fn call like if it wasn't a search, but just a quick lookup

19:10 if you are only ever expect one answer, and a just getting via the "primary key" then method/fn like, if it is a search with possible multiple results, prolog

19:11 dmiles_afk: in this cases of these functions yes only one answer is ever needed

19:12 for the prolog version i hade to create helper functions like cli_new_event_waiter/cli)block_unbtil_event

19:12 * nDuff grouses at the use of the (annoyingly ad-ridden) pastebin.com

19:13 dmiles_afk: ok so the clojure-clr version probly will want the same two functions

19:14 oh so that anonomous function .. (cli-block-until-event WaitOn 10000 #'(lambda (Evt) (equals (jcall "QueryID" Evt) QID)))

19:15 would be like that that?

19:15 minus the CL jcall of course :)

19:16 hiredman: annd clojure doesn't have a special form "lambda"

19:16 dmiles_afk: i am very clojure newbie.. but it does have this sort of lambda?

19:16 hiredman: it is fn

19:16 or #()

19:16 #' means something entirely different in clojure

19:16 nDuff: dmiles_afk: ...though what you look for smells a lot like reify

19:17 dmiles_afk: so be like? (cli-block-until-event WaitOn 10000 #(fn (Evt) (= (QueryID Evt) QID)))

19:17 hiredman: no

19:18 #() is a synonym for (fn [] ())

19:18 so #(fn ...) is almost never what you want

19:18 well

19:18 #(...) is a synonym for (fn [] (...))

19:19 dmiles_afk: (cli-block-until-event WaitOn 10000 #([Evt] (= (.QueryID Evt) QID)))

19:19 hiredman: arglists in clojure are specified using vectors

19:19 nah

19:20 at this point I will refer you to the number of fine clojure books available on amazon, and the detailed docs on clojure.org

19:20 dmiles_afk: i see though.. you answered my main question

19:21 is that such a code idiom might be fin the prolog way rather than constructing a macro to relfect the C3 structure

19:22 is that such a code idiom might be fine the prolog way rather than constructing a macro to relfect the C# structure

19:23 i had worjdered if that code was so comman .. creating a ResetEVent that clojure didnt have already someting in the library for this

19:25 sort of the way C# uses "using"

19:27 nDuff: dmiles_afk: Asking questions in such a way that folks need to know C# to answer them is going to substantially reduce the number of answers you get here; most of us are JVM-based.

19:30 devn: (or not JVM-based)

19:31 what i mean is: Java is not a pre-requisite per se, nor is any other language. It's best to describe what you're interested in doing.

19:31 (without resorting to "How do I write this C code in Clojure?")

19:32 nDuff: devn: ...well, the questions coming from dmiles seem fairly specific to CLR interop

19:32 dmiles_afk: java doesnt have the registration of event handlers.. so a bit awkward portign it to java.. but can be done i think

19:34 nDuff: dmiles_afk: Are you asking how similar code would be implemented using Clojure idioms on both sides, ie. where the API you're interacting with is natively Clojuresque?

19:34 dmiles_afk: yes nDuff, good paraphrase

19:35 clojure would end up creating (proxy [s Evt] ...) that would hold some fn

19:35 i guess really wonderign if a macro is what a user would want to type to do that code

19:36 nderign if a macro is what a user might feel most comforttable when they want to call that code

19:36 sorry.. "when they want to impelment that"

19:37 then when i expand their macro.. what closureqeness should i be doing

19:37 frozenlock: I'm doing a function of the form (with-something &body). I would like to provide some keywords argument, such as with {:keys [arg1 arg2]}. Is their a way to combine the two? &body and &{:keys}

19:38 dmiles_afk: when a personon interates a list.. they ussualyl get a free hidden iterator out of clojure.. i was hoping i could get a free hidden resetEvent object

19:39 oh in JVM terms a hidding object.wait() object.notify()

19:39 hiddem object.wait() object.notify()

19:42 * dmiles_afk finding https://groups.google.com/forum/?fromgroups#!topic/clojure/foqaJ4DQoWM helpfull

19:50 dmiles_afk: ok.. my question has been answered :) the answer i's i do a wait/notify inside a macro that inserts 4 functions, Setup,testEvent,sendRequest,AfterQuest is recived

21:55 brehaut: is it possible to get lein to only AOT compile when building a jar/uberjar rather than for the repl?

22:02 antares_: brehaut: rather than the repl?

22:03 brehaut: antares_: i have a project that i uberjar for deployment, the only AOT stuff is to get a main entrypoint. it doesnt need to be AOT'd when teh repl is launched

22:04 antares_: brehaut: I am afraid main ns will always be AOT compiled, even with a separate profile (lein2)

22:04 brehaut: thats what i thought :(

22:04 oh well

22:04 antares_: brehaut: you can keep the repl open, why restart it all the time?

22:05 SrPx: is clojure better than cl in general? ;s

22:05 oh what a bad question

22:05 I mean,

22:05 brehaut: antares_: its not a problem for me, its a project with non-clojure people getting started, and explaining the timeout with nrepl as it compiles the entry point is proving to be a real headache

22:05 SrPx: is clojure kind of updated taking in account cl and schemes mistakes, or something?

22:06 antares_: brehaut: ah

22:06 brehaut: antares_: my current solution is to get them to run a lein compile first

22:06 antares_: SrPx: Clojure was designed with some problems in CL in mind, yes

22:06 brehaut: yes, that's probably the best solution right now

22:07 dnolen: SrPx: it's a Lisp with modern affordances yes. CL is not evolving as a language, and there's lots of pressure to keep Scheme very miminal.

22:07 SrPx: antares_: can ou name some?

22:08 dnolen: are there even newer lisps?

22:08 dnolen: SrPx: people are creating new lisps all the time - the beauty of Lisp is that's not a herculaen task.

22:08 antares_: SrPx: I'd name immutable data structures, solid concurrency/time model, syntax that does not use lists for everything (see let forms or defn, for example)

22:09 SrPx: Clojure influenced at least 1 Lisp I know of, Joxa

22:09 and some non-Lisps, too (like Elixir)

22:09 SrPx: I want to get into it but I'm not sure how... many implementations, not sure if I even get the need for macros

22:09 antares_: hmm

22:11 dnolen: SrPx: Lisps generally implements themselves in terms of macros over primitive forms

22:11 antares_: and there are multimethod implementations in JavaScript and so on, inspired by Clojure (or even directly ported)

22:13 SrPx: antares_: sorry what?

22:13 (googling that)

22:13 antares_: SrPx: if you want to get into a new language, just start building something in it. In a few months you will have some initial feeling that is beyond "I like/dislike the syntax". Clojure Programming from O'Reilly is the book I recommend for beginners.

22:13 dnolen: SrPx: what languages are you familiar with?

22:13 antares_: SrPx: people port good features from clojure to JS, that's the point

22:13 some can be ported

22:13 some are relatively unique to lisps

22:14 adu: antares_: my favorites are (1) rot13 (2) json (3) xml (4) scheme, usually in that order

22:14 also, webapps in languages prone to that sort of thing

22:15 antares_: adu: sorry?

22:15 adu: "things to build in a new language"

22:15 antares_: ahhh

22:15 SrPx: dnolen: python c++ lua and javascript , all very similar

22:15 antares_: yes, json parser and generator is a good start

22:15 SrPx: (except c++)

22:15 antares_: but I think to get the real feel you need to build a little service or a Web app

22:16 SrPx: antares_: i see

22:16 adu: it's easier to build a webapp if you already have an xml serialization :)

22:17 dnolen: SrPx: Clojure is pretty different from all of those.

22:17 SrPx: I know

22:17 lisps are pretty different from anything non - lisp, I guess

22:17 dnolen: SrPx: so you'll have some fun ahead of you if you stick with it.

22:17 antares_: I'd say there are similarities between python/Clojure and JS/Clojure, although immutable data structures will be novel

22:18 adu: how similar is clojure and racket?

22:19 antares_: adu: I am barely familiar with racket but it 1) Has mutable data structures, 2) Has no interop with another language, 3) Does not have the same concurrency model. Otherwise lisps are largely similar.

22:19 adu: racket has immutable pairs...

22:19 (which is novel for a scheme)

22:19 antares_: that's my opinion, I am only really familiar with Emacs Lisp and Clojure

22:20 SrPx: immutable data structures?

22:20 antares_: adu: yes but by default lists and maps (dictionaries) are mutable, right?

22:20 SrPx: antares_: I thought you said they removed those

22:20 what they are

22:20 antares_: SrPx: who removed what?

22:20 adu: antares_: lists are immutable by default in racket (hence novel)

22:21 antares_: SrPx: if you have a vector of [1 2] and want to ad something, you do not modify the same data structure. Instead, you get back a new vector (but the implementation is not naive copying, so it is pretty time and space efficient)

22:21 adu: hashmaps (iirc) are mutable

22:21 SrPx: someone said an improvement from cl to clojure was not having those?

22:21 antares_: adu: aha. Good to know.

22:21 SrPx: antares_: like haskell?

22:21 antares_: SrPx: the opposite

22:22 yes

22:22 adu: antares_: racket vectors are mutable tho

22:22 SrPx: antares_: why is this useful

22:22 antares_: SrPx: it makes many classes of problems with concurrency completely go away

22:22 adu: antares_: I've noticed that with Haskell

22:22 antares_: you never have to worry "does this function modify what I pass to it", like you have in C++ all the time

22:23 SrPx: antares_: but if this is a default behavior will not it be very hard to implement things that require mutability, like, for example, a game character with position, hp, exp and so on?

22:23 antares_: which makes for easier testability and maintainability

22:23 adu: I probably have more experience with Haskell than Scheme

22:24 antares_: SrPx: it's a typical FP misconception that things "cannot be mutated"

22:24 SrPx: they can, but in a different way

22:24 SrPx: antares_: which way?

22:24 antares_: SrPx: you can add things to lists, the thing is, you do not modify the original data structure

22:25 SrPx: antares_: the character hp case?

22:25 antares_: SrPx: read a Clojure book, it explains things much better than I can on IRC :)

22:25 SrPx: hp case?

22:25 SrPx: antares_: sure, thanks !

22:25 eh..

22:26 like a character with a HP that can go up or down. normally it would be a hashtable with a hp key

22:26 antares_: SrPx: there is also a talk by Clojure creator about Clojure's approach to state/mutation/identity, it is not easy to understand the first time but it usually seriously changes perspective for developers, especially those who have worked with concurrency a lot

22:26 if you want I can find a link

22:27 SrPx: not yet, thank you!

22:27 still trying to get the basics

22:27 dnolen: ,(update-in {:hp 100} [:hp] #(- % 10))

22:27 clojurebot: {:hp 90}

22:27 antares_: SrPx: basically, you can have atomic references in Clojure (one approach) so if you want to mutate something that is a hash map, you do it in a way that looks like you are mutating an existing thing but in reality a new data structure is created and then atomic reference is switched

22:27 dnolen: SrPx: no mutation occurred ^

22:28 antares_: SrPx: the key to understanding is that identity ("a list of todos") and state ("current items on the list") are separate in Clojure

22:28 in most languages, they are one thing and it means you have a whole group of issues and features to solve them

22:29 SrPx: ,(update-in {:hp 100 :mana 50} [:hp] #(+ % 10))

22:29 clojurebot: {:mana 50, :hp 110}

22:29 SrPx: ,(update-in {:hp 100 :mana 50} [:hp] #(+ % :mana))

22:29 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number>

22:29 SrPx: heh

22:29 antares_: ah, I am getting the :hp thing

22:29 SrPx: basically, in clojure you'd have an identity (character) and a number of states it goes through

22:29 SrPx: antares_: hmm

22:29 antares_: which is how it is in the real/virtual world, right

22:30 not the same thing that changes "in place"

22:30 in moment A this identity will point to {:hp 100}

22:30 after a hit, it wil point to a different state, {:hp 80}

22:30 but the original state is not modified.

22:30 SrPx: antares_: just wondering, wont this be a big punch on performance?

22:31 antares_: I imagine if you have to copy an entire 20-keys hash for each position update which happens serveral times a second for thousand of diferent objects

22:31 antares_: SrPx: a naive "copy everything" approach would but guess what, Google' Guava works that way and Google seems to find it OK to have in their "standard library"

22:31 SrPx: clojure's approach is not naive

22:31 data structures are implemented as trees

22:31 so there is structural sharing going on

22:31 internally

22:32 SrPx: hmm

22:32 antares_: so a list A = (1 2 3)

22:32 when added a 0 at the head

22:32 becomes (0) => (1 2 3) kind of structure

22:32 where the "tail" is list A

22:32 and the entire thing is list B

22:33 there are nice colorful pictures that explain this in various books and blog posts

22:33 SrPx: are familiar with git?

22:33 *are you

22:33 or mercurial

22:33 actually, no, mercurial is somewhat different

22:34 SrPx: I think you need to watch http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey, it is a bit heavy on philosophy in the beginning but there are pictures and examples in the 2nd part

22:37 xeqi: brehaut: you can add :prep-tasks [] to not do javac and compile

22:37 brehaut: xeqi: thanks

22:37 xeqi: but then you'd have to either `lein compile, jar` or use a profile with them back on

22:37 SrPx: calm down o.o

22:38 antares_: SrPx: ehm?

22:38 SrPx: wrong window

22:38 antares_: not sure if I'm confortable with this behavior?

22:38 have to put a little more thuoght on it

22:38 let me check it

22:41 gfredericks: SrPx: mutable data structures are the new GOTO

22:41 antares_: SrPx: Clojure was designed this way by a person with like ~ 20 years of development of complex systems in C++, Java and C#. It is not a nice theory somebody came up at a uni somewhere :) so don't worry, it certainly will take some time to get this but it has plenty of benefits (mostly around concurrency, but not just)

22:42 SrPx: I'd say, play with basic data structures in the REPL and then try atoms

22:42 atoms are easy to understand and demonstrate identity/state separation

22:42 SrPx: gfredericks: wow, this is a strong statement

22:42 antares_: the rest will sink in after that

22:43 gfredericks: SrPx: the more I use immutables the more I feel that way

22:43 SrPx: antares_: so on that topic, clojure, when well done, will automatically scale up to additional processor cores?

22:43 antares_: SrPx: in the world wtih 16 cores being the norm (we are not there yet but it no longer feels surreal), I'd say gfredericks is close to being correct

22:43 SrPx: antares_: so one can say clojure, haskell and others are soon to outperform C++ and such?

22:44 dnolen: SrPx: outperform at what? developer happiness?

22:44 gfredericks: GOTOs are quite performant

22:44 SrPx: dnolen: too?

22:44 dnolen: but I meant performance

22:44 antares_: SrPx: Clojure, haskell and several other languages will make it much easier to write radically more peformant systems for multicore machines

22:44 SrPx: dnolen: just for curiosity actually, because I am searching developer happiness indeed (:

22:44 gfredericks: but you could still write 1.5x more performant code with 20x more effort

22:45 antares_: SrPx: C++ cpmpilers will probably produce faster for a long time but single threaded performance won't matter as much

22:45 SrPx: I see gfredericks

22:45 antares_: and it is not really about just crazy performance

22:45 it is about maintainable software, too

22:45 dnolen: SrPx: C++ is very close to the metal, I imagine you can always write faster code in it than Haskell or Clojure or any other FP lang. Just depends on what you'd rather spend your time on.

22:45 SrPx: that said, Haskell & Clojure both take performance very seriously.

22:46 lynaghk`: gfredericks: I'd never thought about it that way re: goto. The issue with goto is "how the hell did I get here?" and with mutable state, "how the hell did this get this way?"

22:46 gfredericks: lynaghk`: :D I think it's mostly the chaos of unnecessary powers

22:47 antares_: SrPx: so, Clojure tries to be "fast enough for the 80% cases, constantly looking for ways to improve on multicore", when it comes to performance. But performance is only part of the story, like I said.

22:47 SrPx: Hmm, okay.

22:47 gfredericks: lynaghk`: the public-attributes issue from OOP is similar

22:47 antares_: as for haskell, I am not familiar with it enough to judge but I've heard from people who use haskell for very performance sensitive things and it is surprisingly close to C

22:47 lynaghk`: gfredericks: unnecessary is a hard thing to pin down. I just spent the last hour putting together slides about why something like Hiccup is nicer than Handlebars because the former uses the same abstractions (i.e., on standard data types) and lets you do whatever you want.

22:48 antares_: but it takes 1/10 of time to develop the same thing in haskell compared to C (again, just anecdotal evidence of some people I know)

22:48 gfredericks: lynaghk`: yeah; I suppose it's the sort of thing that takes decades to notice

22:50 SrPx: antares_: which is probably true

22:51 devn: if you can get designers to use hiccup, I applaud

22:51 lynaghk`: gfredericks: heh. I can understand where the no-logic-in-templates folks are coming from, but in practice I've always found it to be more annoying than helpful. Then again, maybe I'm just not working on big enough apps/teams for it to get useful.

22:51 In the same way that Ruby folks complain about Java's insane config and factory factories---until they try to build a sufficiently complex app.

22:52 devn: most of the time I sit down over beers with designers to work out general markup and structure, then they handle 95% CSS

22:53 devn: I'm not sure if that's something super-specific to the kind of work that we do, though (data visualization)

22:53 brehaut: lynaghk`: i think that with referential transparency, all the so called advantages of logicless templates evaporate unless you really want non-technical people to be doing technical work

22:55 lynaghk`: brehaut: yeah, I think something along the same lines. Referential transparency and immutablity takes away most of the pain of logic-ful templates. My guess is that most of that pain comes from folks who don't have a the distinction in their mind anyway, and start to do crazy stuff in templates just for convenience.

22:56 brehaut: lynaghk`: yup agreed. its hard to put the mutable cat back in the bag

22:56 gfredericks: I like that (transients aside) all of the intentionally mutable stuff in clojure is a reference to a single value

22:57 rather than a composite structure of some kind

22:57 * gfredericks neglects to mention the glaring exception

22:58 antares_: SrPx: if you have any questions, please ask here, many folks in here would be happy to help

22:58 SrPx: andrewclegg: indeed you are being very helpful, thank you very much!

22:58 andrewclegg: meant for antares_ sorry

22:58 gfredericks: (inc andrewclegg) ;; for being helpful

22:58 lazybot: ⇒ 1

22:59 lynaghk`: gfredericks: what do you mean? Do you think (swap! ref #(update-in ...)) is an anti-pattern?

22:59 gfredericks: lynaghk`: no; an atom pointing to a map is still a single pointer to an immutable object

23:00 which is much simpler than e.g. an array

23:00 I think mutable data structures are essentially equivalent to something like (atom {:foo (atom 1) :bar (atom 2)})

23:00 which is of course terrible horrible no good very bad

23:01 lynaghk`: gfredericks: The only appeal to me about something like that would be more efficent view updates

23:01 gfredericks: oh that sounds like a fun problem

23:01 devn: lynaghk`: more ownership over the layout makes for a faster design loop IMO

23:01 gfredericks: I've been mulling over how to replace backbone with cljs for a while

23:01 devn: a layout does not live forever

23:02 lynaghk`: Haven't run into a situation where that is absolutely crucial, though. Most apps lately have been using the idea of binding a collection to view items according to a key-fn.

23:02 uvtc: Just learned about `mapcat` and added an example to http://clojuredocs.org/clojure_core/clojure.core/mapcat that I thought was needed (I don't yet get what the 2nd example there is doing). Please LMK if it's not good.

23:02 lynaghk`: devn: yep, for sure.

23:09 antares_: uvtc: the 2nd is where they split strings?

23:09 xeqi: brehaut: :profiles {:dev {:prep-tasks ~(with-meta [] {:replace true})} will stop javac,compile for most tasks, but allow it for jar/uberjar

23:10 brehaut: xeqi thats great, thanks!

23:10 xeqi: I forgot you could replace earlier

23:10 uvtc: There are 3 examples for mapcat. Mine is the 3rd. Mine consists of three pieces: the part where you see what the `map` is doing, the part where you see a way to get what you want, and the part where you see that mapcat can get you there in style. :)

23:10 antares_, ^^

23:10 xeqi: supposedly :prep-tasks ^:replace [] should work, but I couldn't get the metadata to stick

23:11 antares_: uvtc: ah. Then you example is a lot better than the 2nd one.

23:11 uvtc: Great. Thanks, antares_.

23:14 gfredericks: ,`C#

23:14 clojurebot: C__27__auto__

23:15 amalloy: lynaghk`: well, (swap! x #(update-in % ...)) is usually a mistake, but only because it should have been written just as (swap! x update-in ...)

23:17 lynaghk`: amalloy: noted, thanks!

23:17 SrPx: wait I still don't get it well, why are macros necessary? functions seems to be everything we need

23:17 dnolen: it always fun to change an atom from a inside a filter operation *evil laugh*

23:18 SrPx: a lot Clojure the language is defined in terms of macros.

23:18 SrPx: but it could be def in term of funcs

23:18 amalloy: SrPx: functions are all you need from a fundamental point of view. macros remove redundant code, and make some things that could technically be done with functions much prettier

23:18 SrPx: amalloy: an example?

23:18 gfredericks: pattern matching

23:18 logic programming

23:19 SrPx: code example, I mean

23:19 amalloy: (let [x 1] x) could be written as ((fn [x] x) 1)

23:19 dnolen: SrPx: show me the functions that can provide destructuring *syntax*

23:19 kovasb: i don't think the likes of deftype/defrecord could be done with functions

23:19 amalloy: let is (or could be) a macro that lets you write the nicer version on the left instead of the ugly stuff on the right

23:20 uvtc: SrPx: macros let you create new operators/syntax in the language. For example, you can make your own specialized type of `for` loop using macros. You can see which parts of Clojure are macros by using `doc` --- a line in there should tell you if the thing you're asking about is a macro. For example:

23:20 ,(doc for)

23:20 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], ...

23:20 uvtc: &(doc for)

23:20 lazybot: ⇒ "Macro ([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightm... https://www.refheap.com/paste/3223

23:20 SrPx: amalloy: wow I actually found the right one surprisingly englightening for other reason

23:20 gfredericks: SrPx: enlightening != fun to read

23:20 uvtc: There --- lazybot says it's indeed a macro, right at the beginning.

23:21 dnolen: ,(let [{hit-points :hp} {:hp 100 :mana 10}] hit-points)

23:21 clojurebot: 100

23:21 dnolen: ,(let [{[f & r] :items} {:hp 100 :mana 10 :items '[sword bread]}] [f r])

23:21 clojurebot: [sword (bread)]

23:21 SrPx: gfredericks: didnt say that

23:22 gfredericks: SrPx: yeah I shouldn't have said it

23:22 SrPx: macros also give you compile-time optimizations

23:22 e.g., assert

23:22 er

23:22 antares_: SrPx: a good example of a simple but useful macro is if-let

23:22 gfredericks: that's more an example of something slightly different I guess

23:23 antares_: SrPx: books often use "unless" (the opposite of if) but I find it much less useful (never had the need to write unless, but use if-let all the time)

23:23 gfredericks: antares_: because if-not is shorter :P

23:23 no it isn't

23:23 but it probably uses fewer pixels

23:24 antares_: gfredericks: no, because if-let captures a common "structural" pattern and unless is a matter of taste

23:24 SrPx: dnolen: what did you do there with the [f & r] thing

23:24 gfredericks: antares_: my comment was less stupid back when if-not was shorter

23:24 dnolen: SrPx: destructured the head and the tail of a sequential data structure '[sword bread]

23:24 uvtc: gfredericks: hehehe ("Your language is ok, but too fast and loose with it's pixel usage...")

23:25 dnolen: ,(first '[sword bread])

23:25 clojurebot: sword

23:25 dnolen: ,(rest '[sword bread])

23:25 clojurebot: (bread)

23:25 antares_: SrPx: [f & r] destructures a value that is a collection. f gets the first element value, r becomes the "rest".

23:25 gfredericks: uvtc: dashes are cheaper than underscores

23:25 dnolen: ,(let [[first-thing & rest-of-it] '[sword bread]] [first-thing rest-of-it])

23:25 clojurebot: [sword (bread)]

23:26 SrPx: ,(let [{[f & r] :items} {:hp 100 :mana 10 :items '[sword bread apple hammer]}] [f r])

23:26 clojurebot: [sword (bread apple hammer)]

23:26 SrPx: okay

23:27 gfredericks: "why does clojure need macros?" kind of turns into "why do languages need features?"

23:27 SrPx: ,(let [{[x & y] :items} {:hp 100 :mana 10 :items '[sword bread apple hammer]}] [x y y])

23:27 clojurebot: [sword (bread apple hammer) (bread apple hammer)]

23:27 dnolen: SrPx: that actually expands out into function calls of course - but the sugar avoids the tedium. major selling of point of macros.

23:28 SrPx: most languages you would need to extend the compiler ... ugh.

23:28 SrPx: I don't get that syntax, how do that stuff end up on x / y

23:28 dnolen: Hmmm...

23:28 metellus: {[x & y] :items} means you only want :items from the map

23:28 SrPx: I got that, but how? would that happen without the let?

23:29 antares_: SrPx: consider a, b = (1, 2) in Python

23:29 SrPx: ({[x] :items} {:items '[a b c]})

23:29 ,({[x] :items} {:items '[a b c]})

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

23:29 SrPx: antares_: continue

23:29 antares_: SrPx: let is how you assign locals (local vars)

23:29 SrPx: hmm

23:29 antares_: SrPx: so, a and b gets their values from positions

23:29 dnolen: SrPx: anyplace where you can bind names, destructuring works. let, binding, function arguments, loop/recur, etc.

23:30 antares_: now imagine that everything after (1, 2) would also be tacked on to b

23:30 this is how it works in the case of (let [[a b] [1 2 3 4 5]] b)

23:31 SrPx: oh I see

23:31 antares_: and this "pattern matching" can be nested

23:31 gfredericks: ,(macroexpand-1 '(let [{[x & y] :items} {:hp 100 :mana 10 :items '[sword bread apple

23:31 hammer]}] [x y y]))

23:31 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

23:31 gfredericks: ,(macroexpand-1 '(let [{[x & y] :items} {:hp 100 :mana 10 :items '[sword bread apple hammer]}] [x y y]))

23:31 clojurebot: (let* [map__220 {:hp 100, :mana 10, :items (quote [sword bread apple hammer])} map__220 (if (clojure.core/seq? map__220) (clojure.core/apply clojure.core/hash-map map__220) map__220) vec__221 ...] [x y y])

23:31 SrPx: so let's first argument is a array with 2 values, the first one would be the thing to the left, the second one would be the thing to the right, in relation to pythons a,b = 1,2 ?

23:31 with that tail stuff added

23:31 an array*

23:31 metellus: it can take any even number of values

23:32 ,(let [a 1 b 2])

23:32 clojurebot: nil

23:32 metellus: ,(let [a 1 b 2] (+ a b))

23:32 clojurebot: 3

23:32 SrPx: ,(let [a b] [1 2] a b)

23:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: b in this context, compiling:(NO_SOURCE_PATH:0)>

23:32 gfredericks: ,(let [x [1 2], a (first x), b (rest x)] [a b])

23:32 clojurebot: [1 (2)]

23:32 SrPx: ,(let [[a b] [1 2]] a b)

23:32 clojurebot: 2

23:32 antares_: SrPx: in Python it would look like a, b = [1, 2, 3, 4] and a would be 1, b would be [2, 3, 4] (just as example, I know this is not valid Python)

23:32 SrPx: ,(let [[a b] [1 2]] [a b])

23:32 clojurebot: [1 2]

23:32 SrPx: ,(let [[a b] [1 2 3 4]] [a b])

23:32 clojurebot: [1 2]

23:32 SrPx: what!?

23:33 metellus: ,(let [[a & b] [1 2 3 4]] [a b])

23:33 clojurebot: [1 (2 3 4)]

23:33 SrPx: oh ok

23:33 antares_: SrPx: you need & if you want the entire tail

23:33 SrPx: but you used a different syntax

23:33 [a 1 b 1] vs [[a b] [1 1]]

23:33 metellus: they're different things

23:33 antares_: SrPx: I was trying too hard to stay close to the Python example :)

23:34 SrPx: I see

23:34 antares_: ah, wait

23:34 SrPx: so either way works

23:34 what is the prefered?

23:34 antares_: SrPx: this example is for collections like vectors or lists

23:34 SrPx: you can also destructure maps, this is slightly different

23:34 SrPx: [var val var val var val...] or [[var var var] [val val val]], is that it?

23:34 antares_: and then you can combine the two

23:34 SrPx: õo

23:34 antares_: no, that's nesting (if I understand you correctly)

23:34 gfredericks: SrPx: the one you want is preferred

23:35 antares_: SrPx: imagine that you have a Web form that sends :name and :age

23:35 SrPx: and your Web library passes them to you as a map, {:name "joe", :age 30}

23:35 but you wnat to pick them into locals and use them separately

23:36 like log "saw Joe, 30 years old"

23:36 you need separate vars for that, right?

23:36 this is what map destructuring does, takes values from a map

23:37 ,(let [{:keys [name age]} {:name "Joe", :age 30}] name)

23:37 clojurebot: "Joe"

23:37 antares_: ,(let [{:keys [name age]} {:name "Joe", :age 30}] age)

23:37 clojurebot: 30

23:37 antares_: ,(let [{:keys [name age]} {:name "Joe", :age 30}] (format "Saw %s, %d years old" name age))

23:37 clojurebot: "Saw Joe, 30 years old"

23:38 SrPx: õo

23:38 antares_: SrPx: I wish I could do a multiline example but clojurebot is not advanced enough. It would make more sense

23:38 let me gist it

23:38 clojurebot: when will you grow up?

23:38 clojurebot: Excuse me?

23:38 SrPx: ,(let [{:keys [a b]} {:name "Joe", :age 30}] a)

23:38 clojurebot: nil

23:39 SrPx: ,(let [{:keys [name]} {:name "Joe", :age 30}] name)

23:39 clojurebot: "Joe"

23:39 SrPx: ,(let [{:fff [name]} {:name "Joe", :age 30}] name)

23:39 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.Exception: Unsupported binding form: :fff>

23:39 SrPx: binding form, interesting

23:39 is not there a less redundant way to write that single example?

23:40 antares_: SrPx: https://gist.github.com/82d0c67a18fd624207f1

23:40 SrPx: (let-keys {:name "Joe", :age 30} name)

23:40 or something

23:40 antares_: SrPx: you can write a macro that would do that, in Clojure itself :)

23:40 metellus: SrPx: two different things are happening here

23:41 antares_: but I think most of the time going that far is not worth it

23:41 SrPx: in my gist above I destructure right what is passed in the function

23:41 metellus: or really, the reason that looks awkward is because this is a contrived single line example

23:41 antares_: without using let

23:41 SrPx: wait

23:41 antares_: what metellus said

23:42 SrPx: you are using that in the place of function(what_would_be_here) { }

23:42 antares_: we have to use let and fit everything into one line

23:42 SrPx: I think I get it now

23:42 antares_: SrPx: yes, I destructure right on the parameters

23:42 SrPx: in, say, Python, I would do "give me name from kwargs, then give me age"

23:43 here you have them in the params definition, sort of

23:43 SrPx: hold on, { } is a dict and [ ] is an array right

23:43 antares_: yes

23:43 SrPx: this is not usual for lisps is it

23:43 antares_: SrPx: correct, CL and Scheme use lists for everything

23:43 but that's why let in emacs lisp is pretty noisy

23:43 Clojure by design uses vectors for let, defn and in some other places

23:44 [ and ] stand out visually

23:44 so this is intentional

23:45 uvtc: SrPx: in Clojure, `[]` produces a vector. The term "array" is generally used for referring to Java arrays (which you shouldn't encounter while learning Clojure).

23:45 antares_: SrPx: for comparison: https://gist.github.com/4af7b60fcc19aefc2493

23:46 SrPx: antares_: this is good... any other syntax sugars?

23:47 uvtc: SrPx: there's a handful of them. #{:a :b :c} is for creating a set. #"foo" is for creating a regex.

23:47 antares_: SrPx: in more sophisticated forms like cond, condp you will find similar simplifications

23:48 yes, sets and regular expressions in the syntax is a good example of what many lisps do not have

23:48 SrPx: can I somehow use macros to turn it into an array language?

23:49 antares_: SrPx: what is an array language?

23:49 brehaut: something like APL or J i think

23:49 SrPx: it is a language where arrays can be treated like instances

23:49 michaelr`: good morning

23:49 tvladeck: hi, does anyone here use vimclojure?

23:49 antares_: SrPx: there are macros in math/stats packages like Incanter that make it possible to write things similar to (1 + 2 + 3) instead of (+ 1 2 3)

23:50 brehaut: ~anyone

23:50 SrPx: ((+ 1) [1 2 3 4]) would translate into [2 3 4 5] or something like that

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

23:50 tvladeck: sure

23:50 SrPx: (+ 1) being partial application

23:50 clojurebot: 1

23:50 tvladeck: i can't get vim to connect to a running nailgun server

23:50 antares_: SrPx: partial application is done a bit differently but yes, you can even do things like that

23:50 dnolen: SrPx: people were asking that question in 1979 http://dl.acm.org/citation.cfm?id=804474

23:50 SrPx: brehaut: how would he ask ? o.o

23:50 tvladeck: i keep getting the error: 10 Reason:

23:50 11 Vim(let):E484: Can't open file /var/folders/4r/6ndrr64x24n9kfxh7xcfmt_r0000gn/T/vPI9Uyw/1

23:51 antares_: SrPx: I would not say it is always a good idea, but Clojure will give you that much freedom in case you need it

23:51 brehaut: SrPx: he would ask his question directly, eg 'I'm using vimclojure and i [want to do X|cant get Y to work]'

23:51 SrPx: I need to see this article

23:51 arubin: Is there any particular reason why maps are functions but records are not?

23:51 SrPx: damn

23:52 brehaut: ok

23:52 tvladeck: apologies; new to clojure and programming in particular. i am trying to use vimclojure and cannot for the life of me get a repl started in vim

23:53 brehaut: tvladeck: no offense. its just a channel etiqutte thing

23:53 tvladeck: brehaut: for sure. no worries

23:54 antares_: arubin: there is but I cannot find the link and recall it myself

23:54 arubin: basically, this is by design

23:55 brehaut: tvladeck: now hopefully someone who uses vimclojure will be around and can help you. there are people who use it who frequent the channel

23:55 tvladeck: brehaut: awesome. going to spend that time doing the emacs tutorial :)

23:55 brehaut: good plan :)

23:55 emezeske: tvladeck: are you using lein-tarsier?

23:55 tvladeck: i am

23:56 SrPx: dnolen: how did you find that paper so fast and how can I read it

23:56 emezeske: tvladeck: how did you go about installing the vimclojure plugin?

23:57 tvladeck: pathogen

23:57 brehaut: SrPx: dnolan is actually citeseer; the number of scheme and haskell papers cited gained critical mass, and the result was an intelegent entity that inhabits the channel and produces clojure libraries

23:58 emezeske: tvladeck: I don't know what all this /var/folders/4r/... business is

23:58 tvladeck: emezeske: me neither!

23:58 xeqi: and builds clojurescript

23:58 uvtc: tvladeck, if you're new, you might just consider having vim open in one window, and the `lein repl` running in another. You can make changes to your src/core.clj file, then in the repl reload those changes by doing `(require 'foo.core :reload)`.

23:59 brehaut: xeqi: its the only scenario that makes any sense

23:59 dnolen: brehaut: haha

23:59 tvladeck: uvtc: that's how i have been doing things, and it's actually quite productive

23:59 uvtc: tvladeck, (that is, assuming for that example that your project is named "foo")

23:59 tvladeck: lein repl (namespace) is pretty good

23:59 uvtc: tvladeck, me too (though I'm using Emacs)

23:59 dnolen: SrPx: Lisp is 50 years old. Nearly any CS idea anyone has ever had has probably appeared in a Lisp paper in some form or another.

Logging service provided by n01se.net