#clojure log - Jul 16 2012

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

0:07 Raynes: sproc: I call it annoying.

0:07 ;)

0:12 michaelr`: good morning everybody!!!

0:21 pppppaul: who here is on a mac?

0:31 akhudek: I am, can I help?

0:44 duck1123: "In a recent poll in #clojure, 100% of respondants reported using a Mac"

0:48 musicalchair: is there something I have to do to get local vars to show up in a slime stacktrace (using swank)?

0:48 All I ever see is

0:48 kreig1: crime in the city

0:48 scottj: musicalchair: clojure?

0:48 musicalchair: "[No locals]" (whoops, accidentally hit return)

0:49 yeah

0:49 scottj: musicalchair: oh, thought I was in #emacs :)

0:49 musicalchair: scottj: heh

0:50 scottj: musicalchair: I think you only see them if you call (swank.core/break) and then some are cleared. clojure 1.4 has an option to turn locals clearing off. I haven't done any of this in months though so my memory could be wrong.

0:54 musicalchair: scottj: hmm ok - that works. I'll dig around for the locals clearing toggle

0:55 scottj: musicalchair: also ritz might support showing locals in more cases than clojure-swank.

0:57 arrdem: is there a better parser library for Clojure than fnparse?

1:01 musicalchair: scottj: cool, I'll look into that. Thanks

1:01 arrdem: and by better I simply mean more up to date... I see some updates on clojars but none which is a clear successor too joshua-choi's

1:01 akhudek: arrdem: not that I know of. You could always try using ANTLR (java lib) if fnparse doesn't work for you.

1:02 also, no updates is not necessarily a bad thing

1:03 although I guess a proper clojure 1.3 update would be good

1:03 arrdem: akhudek: I've used fnparse before and I love it... but post-1.3 and not requiring clojure-contrib (which lein2 no longer supports) would be nice

1:03 and is why I ask

1:04 dakrone: arrdem: https://github.com/protoflex/parse-ez maybe?

1:05 arrdem: dakrone: that's cool...

1:05 technomancy: parsatron looks nice, but I haven't used it

1:05 akhudek: this is always good to check too: http://clojure-libraries.appspot.com/

1:07 * arrdem head explodes from options

1:09 technomancy: clojurebot: ok, go get a mop

1:09 clojurebot: https://github.com/technomancy/robert-hooke

1:10 technomancy: that'll do

1:10 arrdem: I..... what is this witchcraft

1:11 besides awesome that is

1:38 dsrguru: is there a way to have lein download functions to use or require in the repl?

1:38 *download code containing functions I want to use ...

1:48 ro_st: download from where?

1:48 dsrguru: from their repositories

1:49 ro_st: from git?

1:49 technomancy: dsrguru: pomegranate does that

1:49 dsrguru: as in, have lein do its magic from the repl

1:50 technomancy: I just did a brief google, but pomegranate's main functionality seems to be add-classpath, which I don't think is what I'm looking for

1:51 technomancy: I'm trying to find a way to have lein pull .clj files from wherever lein normally does, but from within the repl

1:51 technomancy: sure; that's exactly what pomegranate's add-classpath does

1:51 dsrguru: oh really?

1:51 oh I see

1:51 technomancy: thanks so much

1:53 technomancy: but I have a bit of a chicken/egg problem--how do I load pomegranate from the repl to begin with? XD I'm not running this from within a project where I could add pomegranate to the project.clj

1:55 technomancy: you could add pomegranate in your user profile

1:55 ro_st: or just paste the source of pomegranate into the repl

1:55 dsrguru: ro_st: ^_^

1:55 ro_st: (hopefully it ain't too much)

1:55 dsrguru: technomancy: is a user.clj the same structure as a project.clj?

1:56 ro_st: what if it depends on other libraries? =O

1:56 ro_st: https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md

1:56 technomancy: yeah, or `lein help profiles`

1:56 dsrguru: neither actually contains the text "user.clj" or anything.clj besides profiles.clj for that matter

1:56 ro_st: technomancy: curious about using MD for the help text. is there some way to get plain-plain text, or is it just because you re-used the github content?

1:57 dsrguru: oh it's just ~/.lein/profiles.clj

1:57 got it

1:57 technomancy: ro_st: no way to get plain text, no

1:57 it'd be lossy; I think even if it's a bit ugly in places having the URLs is an overall win

1:58 ro_st: true

1:58 i've been piping it to Mou anyways

1:58 http://mouapp.com/

2:02 xumingmingv: ,(meta pos?)

2:02 clojurebot: nil

2:02 xumingmingv: why (meta pos?) is nil? shouldn't it has some metadata such as :added and :inline?

2:02 ,(source pos?)

2:02 clojurebot: Source not found

2:02 ro_st: &(source pos?)

2:02 lazybot: java.lang.RuntimeException: Unable to resolve symbol: source in this context

2:03 dakrone: ,(meta #'pos?)

2:03 clojurebot: {:ns #<Namespace clojure.core>, :name pos?, :file "clojure/core.clj", :line 1183, :arglists ([x]), ...}

2:05 dakrone: xumingmingv: you want metadata on the var itself, not the value

2:05 xumingmingv: thanks dakrone

2:06 dsrguru: technomancy: thank you so much, pomegranate is exactly what I needed

2:14 ro_st: does sorted-set return a set that automatically sorts itself when ever more stuff is added?

2:14 or does it just do a one time sort

2:15 i guess that's a misnomer, because you can't add stuff to a set, it's immutable :)

2:16 so i'd have to use sorted-set whenever i want a fresh one with something added

2:17 huh. looks like the sorting is kept even when i conj

4:44 stefi: ciao

4:44 !list

5:42 augustl: why does .clj files have to use underscores in order to be found? Artifacts of the jvm classloader stuff?

5:56 raek: augustl: I think it has to do with the names of the classes that clojure emmits

5:57 class names can not have hyphens in them

5:57 augustl: raek: ah I see

6:07 hcumberdale: Hi ;)

6:07 How to provide webservices from clojure?

6:13 augustl: will keywords always stay in memory once they're used, similar to Ruby symbols?

6:14 in Ruby, it's unsafe to use keywords for user input (like query strings), for example, as that gives users the ability to make the ruby process go out of memory

6:14 s/keywords/symbols/

6:15 Guest60085: augustl: afair symbols are interned like strings

6:18 hcumberdale: can't find a solution

6:18 http://blog.japila.pl/2011/02/learning-clojure-and-jax-ws-at-once-clojure-supports-annotations-but-jax-ws-doesnt-like-it/

6:18 only people trying it without success

6:23 Guest60085: hcumberdale: if you find no clojure lib, search a java lib for webservices that does not need annotations to work

6:25 hcumberdale: Guest60085 there is clj-soap

6:26 It uses Axis2 and the implementation is from 2011

6:26 Guest60085: Guest60085?

6:26 hcumberdale: Once you tried axis2, you'll likely never touch it again

6:27 Guest60085: because of configuration stuff? or runtime performance/quality?

6:28 hcumberdale: Guest60085 yes

6:28 Everything!

6:28 Guest60085: humm, am I displayed as guest?

6:28 hcumberdale: Starting with how webservices can be developed. There is no clear way

6:28 Guest60085 << yes?!

6:29 ~clgv@saturn.informatik.uni-ulm.de

6:29 clojurebot: Huh?

6:29 Guest60085: strange my client tells me different and had no auth problems

6:29 hcumberdale: I'm using MIRC,... strange

6:29 AXIS is jut not simple

6:30 Guest60085: but if clj-soap does a good wrapper job, it could be simple with this lib. did you try it?

6:30 hcumberdale: But their homepage is crazy fast

6:30 No, not yet. Sure I will

6:31 It is crazy that this is the only one lib

6:31 And it is not 100% clojure ;(

6:31 Wrap axis2 sounds not nice, cause there are so many ways how to deal with axis2

6:31 Guest60085: well, maybe the soap hype is over ;)

6:32 hcumberdale: I think soap is a good thing

6:32 Guest60085: honestly, it has only one small source file, so I doubt there is much comfort built-in

6:32 hcumberdale: but it is a bit complex. All the specifications (Assured delivery, security,...)

6:33 It seems it is way too abstract.

6:34 Hardcoded casting of objects,... no byte[] handling

6:34 And damn no MTOM support

6:34 Guest60085: do you need soap specifically?

6:34 hcumberdale: yes!

6:34 Cause part of my job is standard software integration

6:34 they rely on soap

6:35 Guest60085: you could use your favorite java lib

6:35 and maybe build a clojure wrapper-layer if it is worth it

6:36 hcumberdale: Yeah, but I have no favourite java lib

6:36 Guest60085: then one that gets the job done ;)

6:36 hcumberdale: It is like selecting bad or worse :)

6:37 Services and POX seem to work pretty well with clojure

6:37 Guest60085: well, then you can only start with the specification and build a 100% clojure solution ;)

6:37 hcumberdale: but POX is missing binary attachments and so on

6:37 Guest60085, that will be the best possible

6:37 Guest60085: but a lot of work, I assume

6:38 hcumberdale: yes that is what i'm affraid of

6:38 Guest60085: probably the spec has 300+ pages? ;)

6:38 hcumberdale: It is possible to run axis2 standalone, in a server as a servlet, as a embedded service (war),...

6:38 Guest60085 I think more

6:38 the most implementations are not 100% compatible

6:39 that's the pain of the companies using all the webservice stuff

6:40 Guest60085, ever worked with generated objects from a design model in java?

6:41 Guest60085: nope. tried that in a different environment, though

6:42 hcumberdale: Webservices in java work in common with a contract (WSD)

6:42 and the frameworks are generating java pojos from that contract or a contract from java pojos

6:42 wsdl2java.exe java2wsdl.exe

6:43 It is insane what kind of bullshit is coming out of the code generators

6:43 but it works

6:43 And it's part of your code (you have to maintain)

7:11 augustl: I have an app that depends on a mongodb helper library. Is there a way to make hy app use my local file system version of the library, so I can integration test without deploying a new version of the mongodb helper?

7:11 this is a leiningen question I guess

7:11 not going to check this local file system dependency into git, it's just temporarily before I push

7:13 Bronsa: ls

7:13 ops.

7:25 tomoj: augustl: you know about "checkouts"?

7:26 I think you can just `mkdir -p checkouts && ln -s /path/to/your/local/project checkouts/project`

7:27 leave the dependency in project.clj

8:51 augustl: tomoj: ah, I'll try that, thanks

9:20 gtrak: duck1123: I managed to get the swank in java-app working pretty trivially, now I'm trying to see what it would take to proxy every spring bean in the app

9:20 duck1123: cool

9:20 I didn't even bother to try that over the weekend

9:21 gtrak: https://gist.github.com/3122677

9:21 I think it'd be fun to wrap every bean in clojure somehow

9:21 though probably totally useless

9:21 spring has methods to generate a union interface of a list of interfaces from a class

9:22 and a AOP post-processor

9:23 I could totally abuse AOP

9:25 not terribly useful since IDE's have hot code-reloading, but could be fun

9:54 augustl: after http://pastie.org/4266135 I still get "com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class org.bson.types.ObjectId" - any ideas why?

9:56 I do a println the line before I add it and I see it print when running my tests so I'm pretty sure it's hooked up correctly ;)

9:57 duck1123: It doesn't know how to turn a object id into json

9:57 nvm

9:59 augustl: oh you seem to need to use the "encode" from the "custom" namespace

10:00 wingy: in a file i am using "ns" and i required a namespace :as another alias .. i run that file from the repl..switching to that namespace but i cant access the namespace via the :as alias

10:00 is there a way to do that? so i can interact with that namespace from the repl instead of from the file

10:00 Guest60085: wingy: in "lein repl" ?

10:00 wingy: Guest60085: yeah

10:01 Guest60085: wingy: how did you switch?

10:01 wingy: in-ns

10:01 the def vars i defined in that file worked

10:01 but the ns :require lib :as lib-alias didn't work

10:01 i mean i cant access it from the repl

10:01 only from the file

10:02 Guest60085: try (require 'that.ns.you.were.talking.about) and then (in-ns 'that.ns.you.were.talking.about)

10:05 wingy: here is an example about what im talking about: https://gist.github.com/3122894

10:05 ro_st: wingy, what Guest said

10:06 (in-ns doesn't trigger the target ns's require/use statements

10:06 augustl: are there any generic ways of deep-mapping any sort of collection so that all keys or values matching a predicate gets filtered through a function?

10:06 ro_st: augustl: clojure.walk

10:06 augustl: want to .toString all ObjectId instances in maps

10:06 ro_st: looking it up, thanks

10:06 Guest60085: augustl: tree-seq might be an option as well

10:06 ro_st: look at keywordize-keys for nice reference code

10:07 wingy: ro_st: yeah but now i used "ns" from the repl but it still doesn't work

10:07 ro_st: do a require of the aliased namespace, then a require of the target namespace, then in-ns the target namespace

10:07 wingy: the test file i ran with this could access the symbols without problems .. i wonder why i cant access them from the repl

10:07 Guest60085: wingy: "yi" cannot be resolved since it is only an alias. try to call a function with yi

10:07 ro_st: you could try inspecting the value of your alias in the repl as well

10:09 duck1123: does in-ns-ing into a non-existant ns still mess everything up?

10:09 wingy: Guest60085: oh right .. yi is a namespace :P

10:09 Guest60085: wingy: that worked (ns blubb (:require [clojure.string :as s])) s/replace

10:09 wingy: no! yi is an alias to a namespace

10:09 duck1123: I remember at one time, if you did this than you dodn't even have clojure.core

10:09 Guest60085: duck1123: exactly

10:10 ro_st: duck, afaik the ns form does in-ns internally?

10:10 yup

10:10 wingy: Guest60085: yeah to yobistore.core .. and typing yobistore.core yields the same problem since it's not a symbol .. anyway .. i get it now .. i accessed the vars in it and it works now

10:10 timmc: &(macroexpand-1 '(ns foo))

10:10 lazybot: ⇒ (do (clojure.core/in-ns (quote foo)) (clojure.core/with-loading-context (clojure.core/refer (quote clojure.core))))

10:10 wingy: thx for the help

10:11 duck1123: I was asking because he was in the ns before hand. (because of previous testing, no doubt)

10:11 ro_st: in-ns should be idempotent? make it if it aint there, otherwise just switch?

10:12 duck1123: well, looking at that expand, there really isn't much "making" the ns, just making sure that clojure is also referred

10:14 ro_st: ,(doc 'in-ns)

10:14 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol>

10:14 ro_st: ,(doc in-ns)

10:14 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

10:14 Guest60085: duck1123: especially not loading an ns with the same name from classpath ;)

10:16 duck1123: (doto 'the.ns.inquestion require in-ns) is always handy

10:16 augustl: oh my, postwalk is brilliant :O

10:17 ro_st: duck1123: clever!

10:21 wingy: i know a great feature for lein repl

10:21 () matching

10:21 gtrak`: augustl: tree-seq?

10:22 wingy: so when i type ( it will give me () with the cursor in between

10:22 ro_st: wingy: emacs slime repl with paredit :)

10:22 wingy: that would save us a lot of times

10:22 ro_st: but does that work in repl mode?

10:22 ro_st: i have full code completion and paredit and rainbow parens in my repl

10:22 source and doc lookup too

10:22 wingy: oh

10:22 are you new to emacs?

10:23 duck1123: wingy: it does, but IMHO it's more pain than it's worth

10:23 wingy: i guess i should give emacs a try

10:23 ro_st: quite new, yes

10:23 wingy: duck1123: why?

10:23 ro_st: swore like a trooper for the first week. all good, now

10:23 wingy: :)

10:23 duck1123: since enter in slime submits when you have matching parens, you can't enter a newline without accidentally submitting

10:23 wingy: ro_st: you got good tutorials?

10:24 i guess that emacs is a better fit then vim for clojure?

10:24 duck1123: I love paredit, but everytime I turn it on in the repl, I get annoyed and turn it back off

10:24 ro_st: wingy, the emacs peepcode is good

10:24 scriptor: wingy: emacs has way better tool support for clojure, yes

10:24 ro_st: as for clojure in emacs, https://github.com/technomancy/swank-clojure

10:25 scriptor: also much more clojure+emacs documentation around

10:25 ro_st: the cheatsheet halfway down the page

10:25 write it out and make the effort to use them

10:25 also http://emacswiki.org/emacs/PareditCheatsheet

10:26 some utterly indispensible ones that aren't on there: C-M-space to select entire form, and C-M-k to select-and-cut entire form

10:26 good luck, and apologies in advance -grin-

10:26 my uptodate emacs config https://github.com/robert-stuttaford/.emacs.d

10:27 includes symbol highlighting, where if you rest on a symbol it'll highlight all the occurences in the buffer. super useful when refactoring

10:28 in my config, f11 opens the custom keybindings config file and f12 opens the main custom config file, where i set colour and fonts etc

10:28 so you can see what i've added

10:28 wingy: oh emacs was already installed

10:29 emacs is written in common lisp?

10:29 ro_st: in emacs lisp

10:29 timmc: and C, probably

10:29 duck1123: F12 is hardwired into my brain for drop-down terminal now.

10:29 ro_st: i have iterm fullscreen on monitor 2

10:29 bound to cmd-shift-` at the OS level

10:32 wingy: but when light table is coming out will you switch to it or still use emacs?

10:33 ro_st: emacs for sure

10:33 with the paredit editing shortcuts, all the bracket hopscotchery just melts away

10:34 also, midje-mode

10:36 https://www.shortcutfoo.com/app/tutorial/emacs

10:37 wingy: great link

10:37 also there is a internal tutorial in emacs

10:37 i love such tutorials

10:37 ro_st: yeah

10:37 you can also C-h f clojure-mode

10:37 timmc: wingy: http://www.brainonfire.net/blog/emacs-n00b-start/

10:37 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

10:38 TimMc: clojurebot: Hush.

10:38 clojurebot: Cool story bro.

10:38 vijaykiran: wingy: The first thing to try will be C-h t in emacs - in built tutorial

10:44 wingy: a little bit uncomfortable fingerposition to hit the CTRL all the time

10:45 which finger do you use to press CTRL and ALT?

10:45 vijaykiran: I swap Ctrl - Capslock

10:45 wingy: how?

10:45 clojurebot: with style and grace

10:45 wingy: what?

10:45 clojurebot: what is short for ,(doc ...)

10:45 vijaykiran: and for Alt - (C-x m) is mapped to Alt-x for looking up other commands

10:46 wingy: on Mac, you can just change the keys in system settings

10:46 gtrak`: isn't the fastest math stuff in fortran anyway?

10:47 wingy: vijaykiran: yeah it worked

10:47 and you others .. which finger do you use for CTRL and ALT

10:52 hmm my ALT+v gives me a character

10:54 ok now it works .. i changed what it meant in iTerm

10:54 you have to have it meaning ESC

10:54 for soem reason

10:55 Guest60085: clojurebot: botsnack

10:55 clojurebot: thanks; that was delicious. (nom nom nom)

10:55 llasram: I use a Kinesis keyboard and have the big left thumb keys which are typically Backspace and Delete mapped to Control and Meta

10:56 It's a little sub-optimal using the same hand for pressing the modifiers every time, but since it's the thumb and doesn't need to move very far, it isn't too bad

10:57 TimMc: obligatory foot-pedal remark

10:57 llasram: Yeah -- still need to give that a try :-)

10:58 wingy: seriously

10:58 ro_st: i'm on a mac, but i use an MS ergo 4000. i made the alt key trigger Cmd, and the win key trigger Alt (or meta). so i can cmd with my left thumb. then i made caps lock trigger Alt

10:58 wingy: that would be way better than having to press CTRL and ALT

10:59 ro_st: pinky on ctrl, ring-finger on caps, thumb on cmd. feels natural

10:59 wingy: ro_st: is there a win key on mac

10:59 ro_st: ya, the Command key

10:59 uvtc: Using Emacs on a Mac was a pain for me due to that Cmd/clover key. Seems much easier on GNU/Linux where, for the most part, there's just ctrl and alt.

11:00 gtrak: i like my little leopold KB: http://elitekeyboards.com/products.php?sub=leopold,tenkeyless&pid=fc200rtab

11:00 ro_st: i'm using mac emacs, which supports cmd c/v/x for copy paste cut

11:00 i also have find-file-in-project mapped to cmd-t, like textmate

11:00 wingy: ro_st: isnt CMD reserved for other things

11:00 in iTerm

11:01 ro_st: it's not quite the same as textmate's fuzzy, but it's close enough

11:01 i dont emacs inside a terminal

11:01 i use this http://emacsformacosx.com/

11:01 wingy: wow looks cool

11:01 ro_st: with this, i can have emacs put windows on multiple monitors

11:01 sh10151: is there an idiomatic way to guard against closing *out* when using with-open and writer from clojure.java.io ?

11:01 uvtc: I meant that, in Emacs, you're using ctrl and alt all the time, but in mac-land you're using Cmd, and I didn't have any spare room on my keyboard to map Cmd to.

11:01 sh10151: or really, any already open stream

11:01 ro_st: so i've got 4 buffers open and visible at 120 characters wide

11:02 sh10151: i'd like to use with-open liberally but i don't want to close streams that are already opened by calling code, like *out*

11:03 kreig1: sh10151: hmm, why would with-open end up closing *out*?

11:03 sh10151: i think it closes anything?

11:03 kreig1: sh10151: no, it closes what you give it

11:03 ro_st: which is great for having a code file, a midje file, a repl, and stuff like compilation output and whatnot visible all at once

11:03 sh10151: right, so I want to use with-open and reader

11:03 so if someone wants to they can pass a filename

11:04 or an open stream

11:04 or a URL

11:04 the trouble is guarding against the open stream case

11:04 kreig1: sh10151: if they pass you an open stream, assume they are gonna take care of closing it

11:04 sh10151: don't be closing my stream that I pass in, wether it's *out* or not

11:04 sh10151: right, so I have to special case and only use with-open if they don't pass a stream

11:04 i was wondering if there is an idiomatic way to do that

11:05 also it seems like something that might be nice to take care of in the macro

11:05 confusing that with-open takes stream arguments and yet misuses them

11:05 wingy: ro_st: i wonder if using that one is better than the terminal one

11:06 kreig1: sh10151: well, proly cause some streams are a little mroe involved to create

11:07 so I want the operation to work on a stream too, even if I have to write some kind of complicated constructor, like for a video transcoding stream or whatever

11:07 TimMc: sh10151: Don

11:08 ro_st: wingy: for me, it certainly is

11:08 TimMc: sh10151: Don't use with-open, then. Get a stream for whatever it is, write to it, and done.

11:08 wingy: ro_st but i lose the ability to run emacs in ssh session

11:09 ro_st: only if you ssh into that mac from elsewhere

11:09 sh10151: TimMc: that's what reader is doing in all cases but when an already-open stream is passed in

11:09 ro_st: is that what you're doing?

11:09 wingy: yepp

11:10 no but i could use emacs instead of vim to edit remote files

11:10 ro_st: wingy: i'm not sure which parts of my config require the full ui. haven't bothered to check. pretty sure you get most of it though

11:10 llasram: wingy: Actually, you don't, or at least shouldn't if the backing Emacs version is up-to-date. If there's a running Emacs version, you can do `emacsclient -t` to create a new Emacs terminal frame backed by the existing Emacs process

11:10 ro_st: ah, but that's emacs on a remote host, not the local emacs

11:10 (inc llasram)

11:10 lazybot: ⇒ 1

11:10 TimMc: sh10151: with-open doesn't know anything about streams.

11:10 ro_st: that's very cool!

11:10 wingy: llasram: i see

11:10 duck1123: I find this alias helpful. alias ed='emacsclient -c -n -a ""'

11:11 starts a server if emacs isn't running, connects otherwise

11:11 wingy: i heard that emacs is not an editor. it's an operating system

11:11 sh10151: TimMc: fair enough, my criticism is more directed toward clojure.java.io/writer I suppose

11:11 TimMc: duck1123: I couldn't have that alias without thinking ED IS THE STANDARD TEXT EDITOR every time.

11:12 sh10151: TimMc: it allows OutputStream/Writer parameters and the docs say "should be used inside with-open," but it doesn't guard against closing that stream

11:12 duck1123: I have run into that, but that was what the guy I copied it from had.

11:13 TimMc: sh10151: Ah, you want a close-shield.

11:13 kreig1: sh10151: yah, because sometimes if it didn't how would it work with compound streams and shit, like say, zip compression streams 8)

11:13 sh10151: aka, things that are not magically construted by the cojure.java.io funcs

11:13 sh10151: I'd think that writer would not close things that it didn't open

11:14 kreig1: with-open is not opening anything

11:14 it's always being given a reader

11:14 sh10151: I understand that now

11:14 llasram: I have wondered why it isn't called with-close instead...

11:14 TimMc: heh

11:14 kreig1: sh10151: indeed

11:14 sh10151: Or rather, I understand that it's reader/writer that I am concerned about

11:14 llasram: `with-closing` maybe?

11:14 kreig1: cause that's all it does 8)

11:14 sh10151: because it wraps the streams and writers without guarding against closes on the wrapper

11:14 nDuff: Has anyone poked at using one.test outside a ClojureScript One environment?

11:15 kreig1: yah, it's named as a throwback to a lisp func, but then got lobotomized in the proper clojure style and never had the name fixed

11:15 that's my guess 8)

11:16 sh10151: so given that clojure.java.io/writer won't change

11:16 ro_st: wingy: and lisp isn't a programming language, it's a building material :-)

11:16 sh10151: what's an idiomatic way to guard these streams in my code, given that right now I am just delegating all of the logic of parameter parsing to reader/writer

11:17 kreig1: you need to see if you are being given a stream

11:17 if so, set a bool

11:17 sh10151: um no

11:18 how about an if either returning the writer in with-open or the original stream

11:18 but at this point I'm just doing some kind of with-open-writer

11:18 ro_st: sh10151: wrap in a (cond stream? (do (work) (close thing)) :else (work)

11:18 kreig1: (let [close-sheild (class Reader arg) input (clojure.java.io.reader arg) ] (do (try (my shit) (finally (when close-sheild (.close input))

11:18 llasram: sh10151: You could have a function which accepts a writer/stream, generates a writer as necessary, then wraps that writer in a `proxy` which implements Writer and forwards everything but `.close` ?

11:19 sh10151: OK so the sense I'm getting is that there isn't an idiomatic way

11:19 kreig1: llasram: really?

11:19 sh10151: :-D

11:19 kreig1: llsaram just so it works with a macro?

11:19 idiomatic?

11:19 llasram: kreig1: So it solves the general problem of wanting to pass off a writer to be something and be certain that recipient won't close it

11:20 TimMc: That's called a close-shield.

11:20 sh10151: well, the general problem I am trying to solve is that clojure.java.io/writer does almost everything I need except in the case of being passed an OutputStream or Writer

11:20 llasram: TimMc: Cool! Does it exist already somewhere?

11:21 sh10151: or rather, the combination of with-open and writer

11:21 kreig1: sh10151: have you read the with-open macro?

11:21 sh10151: yes

11:21 TimMc: llasram: org.apache.commons.io.output.CloseShieldOutputStream :-/

11:21 kreig1: sh10151: so why not just have your own try finally clause that knows if the input arg was supposed to be closed by you or not

11:22 TimMc: Can't be hard to implement.

11:22 Sounds like sh10151 never wants to close streams.

11:22 sh10151: because that is just going to be a specialization of the writer/with-open combination that doesn't use with-open in the case of a stream

11:22 TimMc: and wants to prevent callees from doing so as well.

11:23 kreig1: TimMc: not impression I got

11:23 sh10151: and what is wrong with that when it caries out the rather specific contract you want to present to the user?

11:23 llasram: TimMc: Awesome! V useful to know

11:23 kreig1: if you give me a filename, or a URL, I will read from it and close it, if you give me a stream, I'll read, but not close it

11:23 sh10151: in the context where I am using writer, I don't want anyone to close streams that were passed to writer

11:23 so TimMc is right

11:24 kreig1: ah, ok, so you don't want them closing it outside of your func either?

11:24 sh10151: kreig1: but clojure.java.io/writer doesn't follow that rule

11:24 kreig1: which is my whole point :)

11:24 kreig1: what rule?

11:24 clojure.java.io does shit about closing

11:24 sh10151: "if you give me a filename, or a URL, I will read from it and close

11:24 it, if you give me a stream, I'll read, but not close it"

11:24 kreig1: I don't understand how it cannot follow a rule about closing 8)

11:24 sh10151: yes it does

11:24 it allows you to close the streams it creates from streams

11:25 and close on those streams closes the underlying streams

11:25 so it does do shit about closing

11:25 kreig1: sure it ALLOWS you to close it

11:25 sh10151: not only does it allow you to close the streams it returns

11:25 but that closes whatever stream it was passed

11:25 which is counter to the advice "use with-open" in its docstring

11:25 kreig1: tht's a function of java streams if I recall

11:26 aka, that's how streams work in java

11:26 I could be wrong on that tho, been two years since I did raw java

11:26 llasram: sh10151: To be fair, in the Java I/O library/ies, I think that's usually what you want. You'll create a stack of writers on top of a stack of streams and then want to forget it's anything but a singular entity

11:28 kreig1: if you don't want your func to close the stream, don't call .close on it

11:28 sh10151: All right. So really what we have here is a documentation bug?

11:28 kreig1: there is no bug

11:28 sh10151: the docs for writer/reader shouldn't even mention with-open

11:29 kreig1: you want with-open to work in some context where you are trying to provide a specific contract to those who pass in some generating output argument

11:29 go polish a turd somewhere else 8)

11:29 there are many in clojure 8)

11:29 duck1123: in most (all?) of the cases where they show with-open, they create the reader right there

11:29 kreig1: sorry, that's how I refer to my own fixations on things like that, no personal jie meant 8)

11:29 sproc: Are there any built-in functions for converting a Java array into a vector or list?

11:30 sh10151: duck1123: yes, and that doesn't work if you say, pass *out* as the argument to reader

11:30 er writer

11:30 :-P

11:30 or rather, calling code passes you *out*

11:30 kreig1: sure it does

11:30 it just doesn't do what you want it to 8)

11:30 cmiles74: sproc: You can pass a Java array to vec.

11:31 kreig1: if I'm writing a script and want to make sure things get flushed out, it would be doing the write thing 8)

11:31 cmiles74: & (vec (into-array ["hi" "bye"]))

11:31 lazybot: ⇒ ["hi" "bye"]

11:31 * nDuff ponders whether he has time to try to help out in getting the cljs branch to Midje merged

11:31 TimMc: cmiles74, sproc: Note that the resulting vec is mutable if someone has access to that array.

11:32 cmiles74: TimMc: That I did not knwo.

11:32 duck1123: nDuff: Midje in cljs? You can find the time. :)

11:32 TimMc: &(let [a (into-array (range 5)) v (vec a)] (aset a 0 17) (get v 0))

11:32 lazybot: ⇒ 17

11:33 TimMc: If you're given an array to turn into a vec, best to pour it into a new one.

11:33 &(let [a (into-array (range 5)) v (into [] a)] (aset a 0 17) (get v 0))

11:33 lazybot: ⇒ 0

11:33 kreig1: &(true)

11:33 lazybot: java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn

11:34 sproc: Thanks cmiles74 and TimMc, that was exactly what I needed.

11:34 kreig1: well, neither could let!

11:34 TimMc: ...but if you created that array yourself and do not allow anyone else access to it, vec is fine.

11:35 kreig1: IFn was the compiler's last attempt at making sense of the head position there.

11:35 kreig1: TimMc: I know 8)

11:36 pandeiro: can anyone tell me what i need to do to get clojure-jack-in to work again after upgrading to lein2?

11:36 kreig1: pandeiro: add this to your ~/.lein/profiles.clj

11:37 {:user {:plugins [[lein-swank "1.4.4"]

11:37 [lein-cljsbuild "0.2.4"]

11:37 ]}}

11:37 err, you can drop the lein-cljsbuild bit, sorry

11:37 in lein2 such plugins are installed at the "user" level

11:37 pandeiro: kreig1: no that's great i use it, too - but can i just put it there and avoid having to list it in projects?

11:37 kreig1: yup

11:37 pandeiro: (ie, will lein only grab it if there's a cljsbuild key in the project?)

11:38 kreig1: no clue

11:38 you still have to define hooks and stuff I assume

11:38 it might show up in the help listing etc...

11:38 pandeiro: yeah but i guess the costs are minimal once it's already in my local .m2

11:38 kreig1: yah, only about 500g of disk space, three JVMs, and a Net4.0 runtime

11:39 pandeiro: for cljsbuild? that's reasonable

11:42 nestastubbs: hardest part of clojure so far is unlearning all my Common Lispism

11:42 I went and wrote a CLIM-like presentation-type system

11:43 and then realized it was so delicate and enterprisey it was not worth the trouble over a couple of multi methods

11:43 Hodapp: gaaah enterprise

11:44 pandeiro: nestastubbs: my repl's back; thanks

11:44 Hodapp: enterprise has too much become synonymous in my head with "when this shit fails, you have NO chance of comprehending why"

11:44 * Hodapp looks in the direction of IBM WebSphere

11:44 TimMc: $inc Hodapp

11:44 lazybot: ⇒ 1

11:44 Hodapp: bah?

11:45 TimMc: Karma points. :-)

11:49 uvtc: When using Compojure, how can I try out (in the repl) the routes individually?

11:49 Is there any easy way to do that?

11:50 nestastubbs: uvtc: to invoke a page programmatically?

11:50 or to give it a url and have ittell you which route would be fired?

11:51 uvtc: I've got `(cc/defroutes app* (cc/GET "..." ...) (cc/GET ...) etc.`. I want to programmatically --- and from the repl --- try those "handlers" out...

11:51 ro_st: i made this fn uvtc:

11:51 uvtc: Not the "top-level" handler ("app*"), but the individual ones within it.

11:51 pandeiro: what's the best way to do str manip on keywords? just do (name ...) and manip then go back to (keyword ...)?

11:52 nestastubbs: pandeiro: that's how I do it

11:52 curious as to what your output is tho

11:52 aka, what kind of munging you are doing

11:52 at most I am upcasing, or adding a prefix/suffix (rarely)

11:52 pandeiro: nestastubbs: trying to modify hiccup vectors on the fly

11:52 add classes etc

11:53 ro_st: uvtc: https://www.refheap.com/paste/3629

11:53 TimMc: Yeah, usually string manipulation on keywords means you shouldn't be using keywords. :-)

11:53 nestastubbs: pandeiro: ah, how about just adding/modding the attrbute map?

11:53 ro_st: used from the repl, within the ns that defines it. usually the one that defines app*

11:53 nestastubbs: pandeiro: this is something I am interested in a general solution for 8)

11:54 pandeiro: but I can't recall if the class attribute in the map overrides all classes in the keyword form

11:54 pandeiro: TimMc: nestastubbs: hmm, hadn't thought about just trying to add a {:class "foo"} to the vector... (won't that override any existing classes?)

11:54 yah

11:54 ro_st: is there another way other than (name) … (keyword)?

11:54 nestastubbs: pandeiro: it might append

11:54 I don't have a repl handy to test that

11:54 pandeiro: overrides

11:55 nestastubbs: damn

11:55 pandeiro: I actually thinkg that id and class attributes should merge there

11:55 I beelive that's how such things work in say, HAML

11:55 pandeiro: yeah would be nice

11:55 nestastubbs: well, fork hiccup 8)

11:55 pandeiro: so i just need to destructure from the keyword

11:55 that should be an easy fn

11:55 i can probably steal some of hiccup's own internals

11:55 uvtc: ro_st: Thanks. Looking at your example...

11:56 nestastubbs: let's cahnge hiccup to do that

11:56 cause that's what I want it to do too 8)

11:56 pandeiro: nestastubbs: yeah seems like a more common use case to me

11:56 but i'm sure some people are relying on the current behavior

11:56 nestastubbs: any other hiccup users have a opinion on this?

11:56 ro_st: uvtc: ymmv. written by a newbie. works for me, though. and yes, it does trigger the top level app fn.

11:57 uvtc: Ok. Each of those lines in my defroutes evaluates to a function ... `(cc/GET "/" request "Welcome!")` gives me a function. I suppose Compojure calls that function with the request map.

11:57 pandeiro: would it be idiomatic for hiccup to maybe have a *merge-attrs* that could be set?

11:58 ro_st: yeah

11:58 nestastubbs: pandeiro: hmm

11:58 ro_st: in my case, my api methods are returning a hash with :body set

11:58 so that my json-response middleware can generate json appropriately

11:59 pandeiro: nestastubbs: i dunno if libs do that the same way clojure.core does? is that common?

11:59 wingy: i dont think im the emacs guy

11:59 the arrow keys is like WTF

11:59 ro_st: what's the prob, wingy? you can do it

11:59 uvtc: ro_st: I don't know what you mean by "api methods" in the context of a compojure webapp.

11:59 ro_st: uvtc: i'm using compojure to write a json rest api

11:59 so, in my case, all my routes are api methods

11:59 wingy: i just dont get why that is helpful to navigate with weird arrow keys

11:59 ro_st: sorry for the confuzz

12:00 uvtc: ro_st: Oh, I see. Thanks.

12:00 ro_st: The api of your web service. :)

12:00 wingy: why p b f n

12:01 ro_st: oui

12:01 uvtc: wingy: next/previous, forward/back.

12:01 n/p, f/b

12:01 nestastubbs: pandeiro: hiccup/core.clj:76

12:01 ro_st: wingy, remember, emacs is *old*

12:01 nestastubbs: that is the line that would need ot change

12:01 wingy: uvtc: ok that makes more sense now

12:01 nestastubbs: it's just merging the parse of the keyword with the attr map

12:02 pandeiro: and since the attrs come last, they override

12:03 pandeiro: nestastubbs: what hiccup u lookin at?

12:03 old school?

12:03 nestastubbs: ouch, 0.3.7

12:03 sheeeit

12:03 I suppose I should update, what is latest?

12:03 pandeiro: get off my lawn style

12:03 1.0.0-beta1?

12:03 nestastubbs: oh, any big changes?

12:03 will it fuck me if I upgrade a week before deploying a 20k line app 8^)

12:04 pandeiro: nestastubbs: huge re-arrangement of ns

12:04 hiccup.core is 17 lines long now

12:05 jsabeaudry: Firebug is angry when I check if myvar is defined using (when js/myvar ...), what other method can I use?

12:06 nestastubbs: you types tht into firebug?

12:06 firebug cannot compile clojurescript

12:06 you want to start a clojurescript repl

12:07 and then tell your browser to connect to i

12:07 pandeiro: going thru commit logs now

12:07 jsabeaudry: nestastubbs, nah it gets translated to cljs.core.truth_(myvar), which firebug complains about because myvar is undefined

12:08 perhaps a more appropriated question is how to check for undefined vars in cljs

12:08 nestastubbs: jsabeaudry: ok, sorry, didn't mean to be pedantic about that, it's just cljs can be confuzzing

12:09 jsabeaudry: how about (.typeof js/myvar)

12:10 wingy: ro_st: ok . still in emacs .. phew .. the movements kinda makese sense after all :)

12:10 uvtc: cemerick: In the CP-or book, url-shortener example (p.537), a Ref was used for `mappings`. My understanding was that you use refs for times when there's more than one of them, and changes need to be coordinated. Why use a Ref there instead of an atom? Was it because you check it for the given key before altering it?

12:10 nestastubbs: see fi that gives you "undefined"

12:10 ro_st: wingy: C-a and C-e was my bugbear. so used to home/end keys to move to begin/end of line

12:11 wingy: try C-M-space somewhere. keep pressing it. you'll see it selects forms, always keeping the selection balanced on brackets

12:13 nestastubbs: jsabeaudry: luck?

12:13 jsabeaudry: nestastubbs, not on himera, will try directly in code

12:13 ro_st: gclosure has goog.isDefAndNotNull(); as the catch-all way to ensure a variable is good or not. not sure if cljs wraps it internally

12:32 technomancy: http://axisofeval.blogspot.com.es/2012/07/when-i-see-that-new-language-makes.html

12:33 wink: awesome gifs :)

12:36 doesn't beat http://runningastartup.tumblr.com/ though

12:37 technomancy: there's more though: http://axisofeval.blogspot.com.es/search/label/thispltlife

12:42 dnolen: technomancy: it's pretty hilarious

12:43 technomancy: dnolen: he's definitely a troll, but there's something to be said for appreciating a skilled troll =)

12:44 dnolen: technomancy: agreed. I certainly prefer his style over the LoperOS drivel.

12:44 nDuff: Hrm.

12:44 cmiles74`: Ugh, LoperOS.

12:45 * nDuff finds the cljs midje branch relying on cljs.compiler/namespaces, which doesn't exist any more.

12:46 nDuff: ...ahh, moved to the analyzer.

12:57 SegFaultAX|work2: What's the purpose of the grave mark in: (list* `defn (with-meta name (assoc (meta name) :private true)) decls)

12:58 How is it modifying defn? Or is it an entirely different function?

13:02 TimMc: SegFaultAX|work2: It's the reader shorthand for syntax-quote.

13:02 &(+ 1 2)

13:02 lazybot: ⇒ 3

13:02 TimMc: &`(+ 1 2)

13:02 lazybot: ⇒ (clojure.core/+ 1 2)

13:03 SegFaultAX|work2: TimMc: Is there a good place to read about all the reader shorthands?

13:03 TimMc: In this case, you are presumably looking at the internals of the defn- macro?

13:03 http://clojure.org/reader

13:03 SegFaultAX|work2: TimMc: Yes I am.

13:04 TimMc: Actually maybe I should defer this conversation; I haven't yet got to the macro chapter in Clojure Programming.

13:05 augustl: are there any utils to list all namespaces in a directory?

13:05 SegFaultAX|work2: One of my biggest issues with this book is that the authors tend to introduce dozens of functions without ever saying what they do.

13:06 So I constantly have to be going back and forth between the (sub-par) documentation and the text.

13:06 TimMc: SegFaultAX|work2: You can use ` outside of macros, too -- it's just not very common.

13:06 technomancy: augustl: bultitude does that

13:07 TimMc: Yes, clojure.core's docs are not the best. :-/

13:07 augustl: technomancy: looking it up, thanks

13:07 TimMc: ClojureDocs is pretty good.

13:07 hxiao: I use the cheat sheet all the time

13:07 augustl: the actual use case is for loading all my "model" namespaces so I can ensure mongodb indexes

13:07 SegFaultAX|work2: TimMc: I'll still read this page on Reader syntax. Just meant (future macro-discussion)

13:07 hxiao: http://clojure.org/cheatsheet

13:08 TimMc: &(let [middle [4 5 6]] `[10 11 ~@middle 12 13])

13:08 lazybot: ⇒ [10 11 4 5 6 12 13]

13:08 SegFaultAX|work2: hxiao: Wow, that's super handy. Thank you!

13:08 wingy: should we manually have to worry about when to use java.math.BigDecimal instead of java.lang.Double?

13:09 ,(= (java.math.BigDecimal. 10.67) 10.6699999999999999289457264239899814128875732421875M)

13:09 clojurebot: true

13:09 technomancy: augustl: if you're thinking of adding side-effects at the top-level you should reconsider

13:10 wingy: ,(= (-> 10.67 .toString (java.math.BigDecimal.)) 10.67M)

13:10 clojurebot: true

13:11 wingy: should i have to use java.math.BigDecimal manually like this when dealing with math precision or should i just use the numbers directly?

13:12 SegFaultAX|work2: wingy: That probably depends heavily on what you're doing.

13:12 wingy: SegFaultAX|work2: i will handle financial numbers

13:13 so it has to be specific results

13:13 in Java they tell you to use java.math.BigDecimal when dealing with accuracy

13:13 how is it in Clj>

13:13 is it taking care of that in the background for me using BigDecimal?

13:14 SegFaultAX|work2: wingy: I don't think being explicit in this case could hurt.

13:14 Eg using BigDecimal literals.

13:15 But I'm not a Clojure expert so my opinion is worth very little.

13:15 (If anything)

13:16 wingy: i forgot there is M

13:16 (not= 10.67M 10.6699999999999999289457264239899814128875732421875M)

13:16 ,(not= 10.67M 10.6699999999999999289457264239899814128875732421875M)

13:16 clojurebot: true

13:16 wingy: seems to work better

13:22 cheater: what does M do?

13:23 SegFaultAX|work2: cheater: It's BigDecimal literal syntax.

13:23 cheater: thx

13:26 augustl: technomancy: the models just define the data structures, then a separate task will read the data and create the indexes

13:27 technomancy: gotcha; carry on

13:27 augustl: :D

13:28 arrdem: is there a good way to do Clojure generation in Clojure? I'm trying to write a program which will generate the FNParse gramar for a BNF input, and I can't find a clear way to manipualte the expressions without evaling them to code

13:30 SegFaultAX|work2: arrdem: Macros are a form of code generation in Lisps, generally speaking.

13:32 arrdem: SegFaultAX|work2: thanks for the hint... all I needed was some backquotes and an unquote

13:35 SegFaultAX|work2: TimMc: So, what exactly is the purpose of the syntax-quote in the case of defn?

13:35 TimMc: Other than just qualifying all of the symbols.

13:37 ibdknox: SegFaultAX|work2: the ability to unquote things into the structure you're building

13:38 SegFaultAX|work2: ibdknox: Hmm, could you explain that a bit futher?

13:38 ibdknox: you can do it with standard quote, but it requires a lot more manual lifting - it's the difference between concating strings and using format

13:38 technomancy: SegFaultAX|work2: in the case of the example you gave, it's only for qualifying

13:38 SegFaultAX|work2: Are lists the only type that can be used in unquote-splicing?

13:41 ibdknox: SegFaultAX|work2: vectors should work too I believe

13:41 emezeske: ,`(1 2 ~@[3 4] 5)

13:41 clojurebot: (1 2 3 4 5)

13:41 emezeske: SegFaultAX|work2: ibdknox is right ^

13:41 SegFaultAX|work2: Neat!

13:41 emezeske: ,`(1 2 ~@#{3 4} 5)

13:41 clojurebot: (1 2 3 4 5)

13:41 emezeske: Apprently sets too

13:41 ibdknox: ,`(1 2 ~@{:a 3})

13:41 clojurebot: (1 2 [:a 3])

13:42 ibdknox: anything seqable

13:42 emezeske: Well I'll be

13:42 SegFaultAX|work2: That's useful.

13:48 TimMc: &['a `a]

13:48 lazybot: ⇒ [a clojure.core/a]

13:49 TimMc: &(apply str `[\a ~@"bcd" \e])

13:49 lazybot: ⇒ "abcde"

13:50 wingy: clj has made me hate syntax .. looking at java makes me think it's messy

13:52 amalloy: unquote-splicing just uses apply/concat

13:52 &'`(x ~@y)

13:52 lazybot: ⇒ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/x)) y))

13:53 TimMc: &'`[~@a]

13:53 lazybot: ⇒ (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat a)))

13:53 emezeske: amalloy: Interesting, thanks!

14:00 gtrak: there seems to be some difference in semantics with reduce in 1.4, anyone seen this before? java.lang.AbstractMethodError: null https://gist.github.com/3124046

14:03 jsabeaudry: Finally found a satisfying solution to my undefined problem for me and firebug, I use (not= js/undefined (.-myvar window)) (just for the channel records)

14:03 oops i meant js/window

14:04 amalloy: &(reduce + 0 nil)

14:04 lazybot: ⇒ 0

14:04 amalloy: gtrak: no, sounds like you have some mismatched AOT versions or something

14:04 gtrak: amalloy: ah I thought I was careful about that, I'll look into it some more

14:05 Zeldan_: Could anyone help me out with problem? Described it on SO: http://stackoverflow.com/questions/11508881/clojure-repl-unable-to-resolve-symbol-for-all-functions

14:06 d0c0nnor: Does anybody know the easiest way to transform just the values of a map ? Say, to make the city names uppercase here: {"Kansas" "Lawrence" "Oregon" "Salem" "Ohio" "Columbus"} Is there a function for that ?

14:08 When I say 'transform' I mean return a new map with the transform applied ..

14:08 llasram: d0c0nnor: `update-in` simulates "updating" the values

14:09 nDuff: d0c0nnor: I tend to use zip-map and just pass the keys through unmodified.

14:09 llasram: d0c0nnor: Well, individual values

14:09 nDuff's idea sounds better for hitting everything

14:09 d0c0nnor: llasram: I'm not sure that that will work because I don't know the keys

14:10 Will try the zip-map, cheers!

14:10 amalloy: &(into {} (for [[k v] {"Kansas" "Lawrence" "Oregon" "Salem" "Ohio" "Columbus"}] [k (.toUppercase v)]))

14:10 lazybot: java.lang.IllegalArgumentException: No matching field found: toUppercase for class java.lang.String

14:10 amalloy: &(into {} (for [[k v] {"Kansas" "Lawrence" "Oregon" "Salem" "Ohio" "Columbus"}] [k (.toUpperCase v)]))

14:10 lazybot: ⇒ {"Oregon" "SALEM", "Kansas" "LAWRENCE", "Ohio" "COLUMBUS"}

14:11 amalloy: although as always, let me recommend that if you're using a map for something *other* than fast lookup by key, you treat it as a seq of tuples until you finally do need fast lookup, and then make it back into a map

14:12 d0c0nnor: amalloy: Makes sense, thanks.

14:17 jsabeaudry: amalloy, if I understand correctly, the transformations on a tuple seq are fast so better do all the manipulation on that and use the map solely for lookups?

14:18 amalloy: well, more accurately, it's expensive to build a map, and if all you're going to do is tear it back down into tuples...

14:18 jsabeaudry: ok! thanks

14:34 mononofu: I'm currently looking for useful libraries, but everywhere I go I see "___ is not under active development"

14:35 kreig1: welcome to a new language

14:35 mononofu: eg penumbra as an OpenGL wrapper

14:35 yes, but I'd expect libraries which are updated a lot

14:35 not libraries which haven't been touched in over a year

14:36 gtrak: whine whine whine :-)

14:36 dnolen_: mononofu: ztellman has a paying gig at Runa, so I think most of his Clojure energies go into Aleph. Penumbra was something he did in his free time.

14:36 amalloy: mononofu: github.com/flatland/useful

14:36 technomancy: also sometimes projects are done

14:36 dnolen_: mononofu: I think he's mentioned several times that he'd be happy to pass the torch on Penumbra.

14:37 mononofu: but no takers yet.

14:37 kreig1: yah, but you also have lot sof experiements

14:37 see Clojure LWGL as well

14:38 hehe, useful 8)

14:39 dnolen_: my CA was mailed, if that patch for cljs use didn't already make it in...

14:39 cbrozefsky: there we go

14:40 dnolen_: cbrozefsky: oh, howdy :)

14:40 cbrozefsky: I think you'll be happy to hear that reflection is just around the corner for CLJS. Some HackerSchool folks are putting together a patch.

14:40 cbrozefsky: oh good

14:41 I do fine in messy opaque places, myself

14:41 which is why I prolly write messy opaque code, ha

14:42 madsy: dnolen_: Hooray

14:43 dnolen_: madsy: yes, finally docstring, macroexpand, etc should all be just around the corner.

14:43 cbrozefsky: how you getting macroexpand?

14:43 madsy: Hopefully someone will pick up the torch and make a better repl

14:43 dnolen_: cbrozefsky: there'll be a new ns cljs.reflect or some such, JS can query the REPL server

14:43 cbrozefsky: madsy: agreed, what do you think a better repl shoud look like?

14:43 ah

14:44 dnolen_: madsy: the improvements are REPL implementation agnostic.

14:44 cbrozefsky: most of my bitching about the repl is namespace related

14:44 (in-ns ..) doesn't pick up the ns-aliases

14:45 amalloy: dnolen_: what is reflection in javascript? just iterating over the object's properties?

14:45 cbrozefsky: or it doesn't in the revision I am using

14:45 hiredman: dnolen_: I assume cljs.reflect will be extensible? like could you replace repl querying with a static data set?

14:45 cbrozefsky: dnolen_: metadata too?

14:45 dnolen_: amalloy: no querying the compilation environment

14:45 cbrozefsky: anything the compiler has that the evaluation environment does not.

14:45 madsy: cbrozefsky: The usual stuff. Breakpoints, stackframes, autocompletion. But I have only limited experience with SLIME so..

14:46 cbrozefsky: hmm, so no squirting this stuff into the JS objects represeting the namespace then?

14:46 or maybe a canonical runtime dictionary of metadata?

14:46 madsy: I'm sure more knowledgable people than me have a better idea

14:46 dnolen_: madsy: breakpoints & stackframes etc are not really a part of this.

14:46 cbrozefsky: I was thinking more like reflection that works at runtime without the repl link (macroexpension would be out of course)

14:47 dnolen_: cbrozefsky: yes non-goal at this point.

14:47 madsy: dnolen_: I answered cbrozefsky on the side topic

14:47 But yes

14:47 cbrozefsky: madsys: ok, I see now

14:48 dnolen_: ok, so this is mostly about reflection into the compiler runtime while hooked up to the repl

14:48 dnolen_: cbrozefsky: yep.

14:49 cbrozefsky: dnolen_: that's welcome improvement. Was stuffing reflection data into the runtime world withdrawn from consideration for a reason other than resource/time/complexity?

14:49 madsy: dnolen_: I didn't mean to imply that reflection has anything to do with the current REPL lacking features. It's just the two biggest disadvantages with CLJS right now

14:49 cbrozefsky: dnolen_: pointing me at this converstaion iN JIRA or whatever is sufficient answer 8)

14:50 dnolen_: cbrozefsky: resource is a big one. non-reified namespaces & vars allows us to leverage aggressive GClosure compression.

14:51 cbrozefsky: ok, and non-reified namespace is why for instance when IN (in-ns someplace in the REPL, I don't have a way to identifying the aliases active when it was compiled

14:52 dnolen_: cbrozefsky: yes ... tho that seems like it wouldn't be hard to handle.

14:53 cbrozefsky: dnolen_: I don't know much about gclosure compression, so can't comment on that, but it seems that a significant part of reflection could be done by throwing the metadata into a array that is just not made if being aggresive in compilation

14:54 dnolen_: I thinka hybrid is gonna be the end result

14:54 dnolen_: cbrozefsky: dump cljs.analyzer/namespaces and let me know how big it is ;)

14:55 cbrozefsky: when running under the JVM this stuff doesn't matter, targeting JS becomes an issue.

14:55 cbrozefsky: dnolen_: checking...

14:57 dnolen_: I think I misunderstood you statementabout dumping cljs.analyzer/namespace

14:58 dnolen_: you mean froma running repl

14:58 dnolen_: cbrozefsky: cljs.analyzer/namespaces holds all the metadata plus information that's missing without reified ns'es & vars.

14:58 cbrozefsky: yah, got that part now

14:59 dnolen_: cbrozefsky: repl or no repl. cljs.analyzer/namespaces is not small. 6000 lines of cljs.core + whatever code you ship.

14:59 cbrozefsky: sorry, I was looking for namespaces function, as in, I thought you were trying to show how complicated namespace compilation was 8)

14:59 dnolen_: cbrozefsky: plus a lot of info won't matter since GClosure dead code eliminates.

14:59 cbrozefsky: yup

14:59 you enter into the world of PDB files basically

15:00 aka, your reflection/debugging data is seperate and loaded on demand

15:00 haha

15:00 dnolen_: cbrozefsky: even a namespaces outside of dev function makes no sense - all those names will be rewritten.

15:00 cbrozefsky: yup

15:00 I usually run with whitespace optimization only BTW

15:00 so I often debug by reading the JS

15:01 dnolen_: cbrozefsky: yes I think most folks do.

15:01 cbrozefsky: dnolen_: see the point now

15:02 dnolen_: in this deployment environment, performance is prolly a higher priority

15:02 dnolen_: cbrozefsky: yep. it's easy for the generated JS to be 600-700k.

15:02 space savings from GClosure can be 7X

15:03 cbrozefsky: wow

15:03 mine is 1.2m

15:03 for libre

15:03 with whitespace only

15:04 dnolen_: heh yep. if you want macros and compiled JS perf w/o producing a bloated monster - CLJS strategy is the best I've seen for Lisp->JS.

15:05 saua: there's one thing I'm not getting. When googling i see a lot of references to libraries located in clojure.contrib, but that's been discontinued right?

15:05 TimMc: saua: Correct, monolithic contrib is no more.

15:05 ~contrib

15:05 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

15:05 cbrozefsky: 1.2m with whistepsace optimization, 215k with :advanced

15:06 is there a performance win with those optimizations as well?

15:06 dnolen_: cbrozefsky: + gzip you're down to what 60k? 70k?

15:06 cbrozefsky: yes, we do whole program optimizations that don't kick in outside of :static-fns true or :optimizations :advanced.

15:07 cbrozefsky: mostly around fn invocations and protocol representation - many more improvements still to come.

15:07 cbrozefsky: 47k

15:07 dnolen_: cbrozefsky: :D

15:08 cbrozefsky: smaller than a gzipped processing.js 8)

15:08 dnolen_: cbrozefsky: tots

15:09 augustl: how do you get a "def" from a namespace that might or might not be present?

15:09 saua: ty TimMc

15:10 cbrozefsky: augustl: in cljs or clj?

15:10 augustl: cbrozefsky: clj

15:11 cbrozefsky: try and resolve th var

15:11 if cannot, then require the namespace?

15:12 weavejester: me and another hacker were talking about hiccup earlier today

15:12 augustl: trying `(get (ns-publics ns) 'my-thing)`, it yields `#'my-ns/my-thing`

15:12 not sure how to get the actual value from that :)

15:12 cbrozefsky: weavejester: we were thinking that the classes in the attr-map should append to the ones defined in the element keyword

15:13 weavejester: thoughts?

15:13 amalloy: ,@#'*clojure-version*

15:13 clojurebot: {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"}

15:13 weavejester: cbrozefsky: They should

15:13 cbrozefsky: Send me a patch, I'll add it in.

15:13 augustl: ns-resolve yields the same thing

15:13 cbrozefsky: sweet, I'll have to update to the latest revision first tho

15:14 weavejester: also, on that whole ring-csrf token thing, I discovered that I really needed it working at the noir level

15:14 augustl: it's `type` is "Var", odd

15:14 cbrozefsky: weavejester: so I ended up redoing it there, sorry to drop that without a note

15:14 augustl: or clojure.lang.Var to be specific

15:14 weavejester: cbrozefsky: Working at the Noir level? What do you mean?

15:15 cbrozefsky: I wanted it to use noir sessions

15:15 weavejester: cbrozefsky: I thought Noir sessions were built on top of Ring sessions.

15:16 cbrozefsky: yes, they are, but there was something else that came up, and I need a minute to recall

15:17 augustl: ah, I had to dereference it

15:19 cbrozefsky: weavejester: sorry, I can't recall now. I also added a bypass hook for my case, but that's not the "reason" I was thinking of. Just ignore I said anything 8)

15:19 amalloy: augustl: i did try to show you that. not explicit enough, i guess

15:20 augustl: amalloy: oh I didn't notice, sorry

15:20 and thanks :)

15:22 TimMc: &(let [r (atom nil)] (reset! r r))

15:22 lazybot: java.lang.StackOverflowError

15:22 TimMc: This is not what I expected.

15:24 ToxicFrog: TimMc: that's pretty cool

15:24 TimMc: &(let [a (atom 1) b (atom 2)] (reset! a b) @@a)

15:24 lazybot: ⇒ 2

15:24 TimMc: &(let [a (atom 1) b (atom 2)] (reset! a b) (reset! b a))

15:24 lazybot: java.lang.StackOverflowError

15:25 joly: &(let [a (atom 1) b (atom 2)] (reset! a b) (reset! b a) nil)

15:25 lazybot: ⇒ nil

15:26 faust45: hi guys

15:27 if i have type storing in var, how i can make instance ?

15:27 TimMc: joly: Arg, it's the printing! Got it.

15:27 faust45: any suggestins?

15:28 amalloy: short answer, faust45: you can't

15:28 faust45: (var-storing-type. "data")

15:28 amalloy: long answer: you can't in any way that is fast or reliable

15:28 faust45: like this

15:28 amalloy: so i need macros ?

15:30 TimMc: faust45: No one can tell you that without knowing more about your specific problem.

15:31 gtrak: amalloy: re 1.4 AOT, yep you were right

15:31 faust45: TimMc: i have https://friendpaste.com/53MKnWboUIKj7JwCqIQCCp

15:31 TimMc: need to build chess figures

15:31 in simple way

15:32 cmcbride: is there any core function for parsing boolean-like values?

15:32 I'm writing a noir app and I want to parse GET params

15:33 so I'd like "0" to return false

15:34 TimMc: faust45: And Queen is some class you don't control?

15:34 Anyway, what's wrong with (Queen. 'd1) ?

15:38 faust45: TimMc: Queen is my typedef, (Queen. 'd1) not working for me i want be able to build few same figures in diff positions

15:38 like [Elephant 'c1 'f1]

15:39 amalloy: faust45: i think everyone in this room would recommend against defining new classes for the different pieces

15:40 just use a keyword or symbol to represent the kind of piece (eg :queen), and define functions that contain the polymorphism you want (eg, a multimethod like (get-legal-moves piece-type current-location board))

15:49 faust45: thanks for suggestions guys

15:52 kovasb: dnolen_: what is the new cljs repl goodness?

15:54 augustl: are there any html form builder libraries out there? Something that takes a data representing the HTML, the values and validation errors, and spits out a string of HTML or hiccup data.

15:54 dnolen_: kovasb: having access to analyzer info / compiler at the repl.

15:54 augustl: "takes a data" :)

15:54 kovasb: nice. that would be useful

15:55 dnolen_: kovasb: docs strings, namespace introspection, var inspection, macroexpand etc.

15:56 kovasb: dnolen_: cool. would also be useful to have that info when the compiler complains

15:56 dnolen_: kovasb: have you checked out the CLJS reactive thread yet?

15:56 kovasb: can you be more specific?

15:56 kovasb: dnolen_: yes but i was not approved for dev mailing list memberhsip

15:56 dnolen_: is it for CA'ed people only?

15:56 dnolen_: yeah, like my mysterious "this is not a protocol" error

15:57 dnolen_: would be nice to know what exactly the analyzer was thinking

15:57 dnolen_: i don't have a printer so I haven't mailed the CA

15:57 dnolen_: kovasb: :P

15:59 kovasb: can you make a ticket + minimal repo case in JIRA - also you are using CLJS head right?

16:00 wingy: time for cljs!

16:01 kovasb: dnolen_: not using head, since I don't know how to do it in conjunction with cljsbuild

16:02 emezeske: kovasb: https://github.com/emezeske/lein-cljsbuild/wiki/Using-a-Git-Checkout-of-the-ClojureScript-Compiler

16:02 kovasb: dnolen_: i mean, i know i can built it manually but haven't had the time

16:02 nice

16:03 dnolen_: its pretty hard to use git bisect since the namespaces changed with the analyzer breakout

16:03 but ill try head and see if it works now

16:03 dnolen_: kovasb: yeah, can't help much unless you were against head.

16:03 s/were/work

16:04 kovasb: dnolen_: is there any chance my tagged literals thing will get worked on?

16:04 dnolen_: or should i just plan on doing it myself

16:04 wingy: can't the PDF be made online in http://himera.herokuapp.com/index.html

16:04 so you don't have to download it

16:04 dnolen_: kovasb: if you work on it :) or bug fogus, I haven't looked at the reader literal stuff closely.

16:05 kovasb: dnolen_: alright ill try bugging him on twitter :)

16:06 dnolen_: kovasb: or bring it up on regular ML and CC him.

16:06 kovasb: ok

16:07 i see stuart sierra is gonna come to the next meetup

16:07 he's also involved with this on this clj side

16:07 dnolen_: kovasb: right

16:08 kovasb: letting undefined tags pass through without meltdown is pretty important

16:09 dnolen_: kovasb: yes, you've brought it up before - always worth rebumping and mentioning Session - folks know about that.

16:10 kovasb: dnolen_: yeah. last week or two i've been more focused on drinking beer etc but time to ramp up again

16:10 dnolen_: kovasb: sounds like fun :)

16:10 kovasb: mid-air refueling :)

16:11 technomancy: kovasb: would it make sense to connect alternative clients to a session server? seems like the reified history would be useful in other contexts

16:11 kovasb: technomancy: by clients, you mean the evaluation services?

16:12 technomancy: more like what if you wanted to use something other than webkit to view a session session

16:12 err--something other than a browser

16:12 kovasb: technomancy: i see. Yes, absolutely

16:12 technomancy: the idea is, if its just this declarative data structure, you can build other tools on it as well

16:13 technomancy: like slide show view, or whatever

16:13 technomancy: is that stuff factored out from the browser-centric UI?

16:13 kovasb: technomancy: also the graphics stuff should be portable to swing and other hosts

16:13 technomancy: not yet, but that is the intention. the blocker is that the user-defined tagged literal support is not there yet

16:13 technomancy: cool

16:14 kovasb: technomancy: so its all hacked into one project at the moment

16:14 nDuff: Hrm.

16:14 technomancy: I wonder if it would make sense as an nrepl middleware

16:14 * nDuff is having trouble pulling some of zi's dependencies down from the sonatype Maven repo

16:14 kovasb: technomancy: that would be cool. hiredman tried to do that but hit some issue

16:15 "I think the issue is the nrepl requests are not stateless, and so the session/cookie info is being lost across requests. There doesn't seem to be a quick fix for that"

16:15 not sure what that means. but nrepl support would be great

16:15 technomancy: oh, as a middleware even

16:16 hiredman: kovasb: oh, it works now, except for the last bit in the cascalog example, which I haven't looked in to, but I think it comes down to how cascalog tries to map classes to vars

16:16 kovasb: technomancy: what would a middleware do?

16:17 hiredman: middleware is a different beast entirely from evaling via nrepl

16:17 technomancy: kovasb: just makes it easier to tie into an existing stack IIUC

16:17 kovasb: technomancy: like, send the output to get rendered in session or something?

16:18 SegFaultAX|work2: I don't suppose there is an automatic administration panel library like ActiveAdmin, RailsAdmin, or Django Admin, is there?

16:19 kovasb: hiredman: i definitely want cascalog to work, so will look into it

16:19 technomancy: I was thinking something like content-negotiation where if a client indicates he's compliant with session-style reified history then he gets it, otherwise it falls back to regular nrepl

16:19 hiredman: kovasb: it is a sweet demo

16:19 kovasb: hiredman: thanks :)

16:19 gtrak: SegFaultAX|work2: most of the web frameworks are tiny

16:19 kovasb: technomancy: i see. interesting

16:21 gtrak: SegFaultAX|work2: maybe try https://github.com/macourtney/Conjure/ ?

16:27 wingy: when do you think that cljs will be out of its alpha status and have most of the clj features in place?

16:27 kovasb: wingy: what features are you thinking of?

16:28 wingy: all that are still missing that could be implemented

16:28 https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure

16:30 kovasb: wingy: the vast majority of that stuff is "intentional differences" and thus unlikely to change anytime soon

16:30 dnolen_: wingy: the remaining ones will happen as people submit patches.

16:35 wingy: what does this mean: Macros are written in Clojure

16:35 i write them in Clojure and they are converted into cljs?

16:36 or js i mean

16:36 TimMc: wingy: They are written in cljs and convert cljs to other cljs.

16:36 arg

16:36 *written in clj

16:36 wingy: i write them in clj and its converted into cljs?

16:36 kovasb: wingy: macros execute in the JVM, but the code they transform is cljs

16:37 wingy: i c

16:37 Raynes: It's WEEEEEEEEEEIRD

16:37 kovasb: wingy: macros only need to execute once to achieve their code transformation purpose, so don't need to run in js (unless you have eval in cljs which we dont)

16:37 wingy: yeah i get it

16:38 i write in clj .. the macro should convert cljs to cljs

16:38 :)

16:38 kovasb: it is a little weird

16:38 right

16:38 wingy: cool . that means i can use original clj

16:38 dnolen_: wingy: pretty much.

16:38 kovasb: you just need to remember that the output needs to be valid cljs (with the correct namespaces, not references java classes etc)

16:38 SegFaultAX|work2: wingy: Presumably as long as the expanded code is valid cljs.

16:39 wingy: i actually like original clj better since its more powerful in server side .. are there strong reasons to use cljs on node.js on server side?

16:39 dnolen_: wingy: on trick I used in core.match is to simply call the macros with a dynamic var *clojurescript*

16:39 kovasb: wingy: not yet

16:39 SegFaultAX|work2: wingy: There is no reason to use node.js, no.

16:39 * SegFaultAX|work2 *ducks*

16:39 wingy: :)

16:39 since you lose concurrency and other good stuff

16:40 brehaut: but you lose startup latency right?

16:40 wingy: yeah

16:40 technomancy: brehaut: yeah, but CLI apps are just a different kind of client

16:40 wingy: but i have realized i dont wanna run a script each time from the cli

16:40 SegFaultAX|work2: wingy: Since you lose the ability to write your server code in a sane language.

16:40 * Hodapp looks at SegFaultAX|work2

16:40 wingy: i wanna run a repl and run everything inside it

16:41 * SegFaultAX|work2 looks back

16:41 brehaut: technomancy: perhaps its too early here, but i dont understand

16:41 kovasb: wingy: yes, you can still execute cljs code at the repl

16:41 wingy: eg. instead of "lein test" i wanna do "(run-tests 'myapp.core-test)" from the repl instead

16:41 Hodapp: SegFaultAX|work2: eh, I've never used JavaScript much.

16:41 wingy: brehaut: so the latency doesn't matter in clj land

16:41 Hodapp: SegFaultAX|work2: why do folks like writing server-side JS?

16:41 technomancy: brehaut: oh, I thought he was asking about client-side vs server-side

16:41 SegFaultAX|work2: Hodapp: Mental illness, probably.

16:41 kovasb: wingy: there is the browser-connected repl, and the rhino one

16:42 Hodapp: SegFaultAX|work2: this is true.

16:42 brehaut: technomancy: he may well be

16:43 kovasb: though i don't understand if its possible to define and use a macro at the cljs command line

16:48 wingy: i dont quite get bindings .. so i define a Var with "def" and then I can rebind it to another value that is thread-local .. why would i wanna do that and not just use another local?

16:48 gtrak: wingy: dynamic scoping

16:49 duck1123: As an example, bind a var at the start of a web request, it''ll be bound for only that request's thread

16:49 alandipert: wingy: you might also have code you didn't write inside your binding, and you want it to "see" your new value

16:50 duck1123: makes sense

16:50 wingy: alandipert: yeah that one i get

16:50 gtrak: consider as an example.. (maybe bad design but whatever), you need to alter the behavior of a function by a switch, but you don't want to change its signature, add a var with the default behavior, bind it to another value to change it.

16:50 duck1123: mt

16:50 gtrak: wingy: real world example ^

16:51 wingy: perhaps i dont understand how threads are working explicitly

16:52 kovasb: a pretty typical example is binding the database resource

16:52 wingy: if i have a source code and run it it will be run by a main thread

16:52 (def ^:dynamic a 1) (binding [a 2] a) vs (def a 1) (let [a 2] a)

16:52 gtrak: having them be thread-local is for safety in a multithreaded environment... you don't want to change behavior for other people's requests when you bind a var, do you?

16:53 kovasb: wingy: the binding only happens within the (binding ..) clause, and when the execution emerges, its back to its original value

16:53 wingy: gtrak: so in the second example if that happened in one thread all other threads will see the value of a as 2?

16:54 kovasb: in the let case, a is for all intents and purposes a unique name

16:54 rather than overriding an existing one

16:54 gtrak: wingy: no... other functions can't see what's in your let unless you pass the value along

16:54 dynamic vs lexical scoping

16:55 in your binding example, other threads will see whatever the value was before you bound to it

16:55 it's a stack

16:55 kovasb: its not just other threads

16:56 in this case

16:57 (def a 1) (def b a) (let [a 2] b) --> 1

16:57 gtrak: (def ^:dynamic *a*) (binding [a 1] (binding [a 2] (binding [a 3] (println a)) (println a)) (println a)) ; prints 3 2 1

16:57 amalloy: wingy: forget threads entirely; the thread-locality of vars is just a safety feature, not the important point

16:58 _zach: Does clojure support native string interpolation? I'm seeing a lot of "~{}"-like things in the clojurescript source, but there's likely some cleverness I'm missing

16:58 duck1123: didn't a library recently add that officially?

16:58 amalloy: (def a 1) (defn foo [] a) [(foo) (let [a 2] (foo)) (binding [a 2] (foo))] returns [1 1 2]

16:58 dnolen_: _zach: js* is an implementation hack which should not be relied on.

16:58 duck1123: incubator?

16:59 SegFaultAX|work2: wingy: This concept is called shadowing. The value in the local binding is shadowing the binding in the level above.

16:59 kovasb: Overriding means something slightly different.

16:59 alandipert: duck1123: : yes i think cemerick's string interp. stuff is in core.incubator

17:00 kovasb: duck1123: theres a variety of string templating projects on github

17:01 cemerick: duck1123: FWIW, https://github.com/clojure/core.incubator/

17:02 There's really no such thing as "native string interpolation", though. Just fast compile-time templating, or slow runtime templating. :-P

17:03 _zach: cemerick: I kinda just meant built-in when I said native :). I was just reading some cljs source incorrectly.

17:03 brehaut: cemerick: you missed out very slow runtime templating

17:03 wingy: http://emacswiki.org/emacs/DynamicBindingVsLexicalBinding lets see if i get any smarter

17:04 cemerick: _zach: yeah, no worries, I was just being snarkily pedantic. :-)

17:05 _zach: cemerick: that's the best kind of snarky, and the best kind of pedantic :)

17:05 kovasb: wingy: lexical just means the code that literally exists inside the let statement. if the symbol you are let'ing is not literally present in that block of code, it isn't effected

17:06 lexical, e.g. like find/replace in the text editor

17:07 gtrak: kovasb: huh?

17:07 gerunddev: Is there a form of map equality that ignores order?

17:07 gtrak: find/replace sounds like alter-var-root to me

17:07 gerunddev: Basically permo for maps.

17:08 amalloy: gerunddev: yes, every form of map equality

17:08 kovasb: http://en.wikipedia.org/wiki/Lexicon

17:08 gtrak: ,(= {:a 1 :b 2 :c 3} {:b 2 :a 1 :c 3})

17:08 clojurebot: true

17:08 kovasb: lexicon is the words and phrases

17:08 gtrak: ,(.equals {:a 1 :b 2 :c 3} {:b 2 :a 1 :c 3})

17:08 clojurebot: true

17:09 gtrak: ,(.identical {:a 1 :b 2 :c 3} {:b 2 :a 1 :c 3})

17:09 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: identical for class clojure.lang.PersistentArrayMap>

17:09 Raynes: &(identical? {:a 1 :b 2 :c 3} {:b 2 :a 1 :c 3})

17:09 lazybot: ⇒ false

17:09 gerunddev: Ok, that makes sense.

17:09 gtrak: quickdraw Raynes: :-)

17:09 kovasb: not having to do with meaning, e.g. value

17:09 gerunddev: So then I should blame this on clojure.test:

17:09 * Raynes tips his hat

17:09 gerunddev: actual: (not (= {:include_docs false, :limit :21} {:limit 21, :include_docs false}))

17:09 ?

17:09 Raynes: gerunddev: :21 != 21

17:10 Notice that one of those is a keyword.

17:10 wingy: damn my finger nails are too long .. it hurts when i type

17:10 technomancy: gerunddev: lein-difftest will help you spot those issues

17:10 Raynes: &:21

17:10 lazybot: ⇒ :21

17:11 * gerunddev face palm

17:11 gtrak: ,(= {:include_docs false, :limit (int (name :21))} {:limit 21, :include_docs false})

17:11 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Character>

17:11 kovasb: dynamic scoping is perhaps an unfortunate phrase, perhaps more accurately "runtime" scoping

17:11 technomancy: "deep" binding helped me understand it

17:11 Raynes: gerunddev: It's okay. I've done worse.

17:11 gtrak: ,(= {:include_docs false, :limit (Integer/valueOf (name :21))} {:limit 21, :include_docs false})

17:11 clojurebot: true

17:12 Raynes: gtrak: Think we get the point. ;P

17:12 * gtrak thinks that dead horse wants some more

17:13 wingy: i start to get the diff

17:13 logancampbell: say i am modeling a file system in datomic. i have folders and they may have many children. (:folder/child has a cardinality of many). how could i write a query that returns all folders with no children?

17:14 gtrak: wingy: I feel like vars are controlled global variables

17:14 wingy: lexical/static binding is resolved by looking _where_ the identifier is used .. while dynamic binding is resolved by looking at _when_ the identifier is used

17:15 the former is about place .. the latter is about time

17:15 kovasb: yes

17:15 TimMc: spacebinding and timebinding

17:15 wingy: yes!

17:15 technomancy: nice

17:15 TimMc: Winner of the prestigious 2012 Sounds Cooler Than It Is Award.

17:15 gtrak: can we really decouple time from lexical bindings?

17:16 that'd be a neat trick

17:16 kovasb: yes, it essentially happens at compile time

17:16 gtrak: errr... in some sense I guess

17:16 that seems strange to say to me, being a von-neumann guy first

17:18 maybe if everything was lazily evaluated I'd believe you

17:20 lookup parameterization vs actual values at runtime I guess is what we're arguing about

17:22 I suppose jvm overhead and GC is kinda like laziness

17:24 siscia: (Hi everybody, I have a little question about the design of a bayesian network, direct acyclic graph, anybody has a little of experience and can help me ?)

17:24 hiredman: kovasb: https://github.com/actsasgeek/nota-bene

17:25 :( noir

17:25 technomancy: hiredman: `lein deps` =(

17:25 kovasb: hiredman: whoa

17:27 wingy: wow .. read the first section of http://c2.com/cgi/wiki?DynamicScoping .. another perfect explanation

17:27 kovasb: who knows what lurks on github..

17:29 hiredman: interestingly doesn't store the result of a computation in the work book

17:29 wingy: but that is the same as the place and time explanation .. lexical: where is the identifier used? inside this scope, that is inside this scope, that is …. dynamic: when is the identifier used? when this fn is called, which is called by this fn, which is called by...

17:29 kovasb: well, thats a problem :)

17:29 penthief: How do I add tools.jar to the maven-clojure-plugin clojure classpath?

17:30 amalloy: oh, i like the time/place explanation. that's cute

17:31 wingy: for someone that is interested: http://info.rjmetrics.com/blog/bid/51652/Lexical-vs-Dynamic-Scope-in-Clojure

17:35 in a let binding the symbol is directly naming the value whereas in a def the symbol is naming the var that is pointing to a value?

17:40 gtrak: wingy: I was reading that one

17:40 yes, what you said is correct

17:40 wingy: great :)

17:40 gtrak: if you want to get at the var itself when you reference it, you can use (var ..) or #'

17:40 wingy: yepp

17:40 gtrak: ,(var +)

17:40 clojurebot: #'clojure.core/+

17:41 gtrak: ,(class (var +))

17:41 clojurebot: clojure.lang.Var

17:41 gtrak: ,(class +)

17:41 clojurebot: clojure.core$_PLUS_

17:41 wingy: dynamic binding is so powerful


17:42 gtrak: kinda like global variables

17:42 wingy: with great power comes great responsibility

17:42 Raynes: Yeah, except not at all. ;)

17:44 arrdem: Well I mean if you rebind + to - don't come crying here

17:44 siscia: (Hi everybody, I have a little question about the design of a bayesian network, direct acyclic graph, anybody has a little of experience and can help me ?)

17:45 brehaut: ~anyone

17:45 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 ..."

17:45 brehaut: ^ siscia

17:45 gtrak: arrdem: actually not sure if that will totally break

17:46 ,(letfn [(test [] (+ 1 2))] (with-redefs [+ -] (test)))

17:46 clojurebot: 3

17:46 gtrak: turns out + is inlined

17:48 ,(letfn [(test [] (println 1 2))] (with-redefs [println -] (test)))

17:48 clojurebot: -1

18:00 siscia: I was wonder if in the designed of a graph would be better have a very basic "node" (name, table, childs) and have more complex function in the graph. Or it would be better have more complex node (name table parents non-descendants child) and simpler function for the graph structure... It is making any sense ? It's not easy to explain...

18:02 kovasb: siscia: what is "table" referring to?

18:03 siscia: kovasb: i am trying to build a bayesian network, every node should have a probability table to work...

18:06 aaelony: siscia: have you looked at cemerick's talk? http://blip.tv/clojure/chas-emerick-modeling-the-world-probabilistically-using-bayesian-networks-in-clojure-5961126

18:08 siscia: aaelony, yes i did thanks... but it didn't really give me a lot of ideas for the designed...

18:08 I guess that the better way could be keep the node as "easy" as possible...

18:08 aaelony: siscia: after minute 23 he shows how he represents models

18:13 gtrak: oo, I found something fun

18:13 &(let [m (zipmap (range 10000) (range 10000))]

18:13 (time (dotimes [x 100] (into {} m))))

18:13 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

18:13 gtrak: (let [m (zipmap (range 10000) (range 10000))] (time (dotimes [x 1000] (into {} m))))

18:13 &(let [m (zipmap (range 10000) (range 10000))] (time (dotimes [x 1000] (into {} m)))) ; sorry

18:13 lazybot: ⇒ "Elapsed time: 5322.963618 msecs" nil

18:14 gtrak: &(let [m (zipmap (range 10000) (range 10000))] (time (dotimes [x 1000] (persistent! (reduce-kv (fn [acc k v] (assoc! acc k v)) (transient {}) m)))))

18:14 lazybot: ⇒ "Elapsed time: 2385.999993 msecs" nil

18:14 gtrak: reduce-kv is a faster into for maps

18:16 siscia: aaelony, yes i saw that, but... The better way to represent a node for a bayesian network should be (:name (parents) (non-descendants)) that is what you want if you need to find independence between node in order to get faster query. But in this way is gonna be very hard given a node find the child.

18:19 aaelony, its looks like that cemerick has just memorized the child and he will pass the model in a function to get the parents and non-descendants, but now i also need to make sure that is a DAG (direct acyclic graph) and not just a graph.

18:19 well I guess i am going for the cemerick way anyway, it's look smarter...

18:20 the talk is very interesting...

18:22 kovasb: what up talios

18:22 talios: hola - not much this morning yet is up.

18:23 * talios could do with a coffee

18:26 cemerick: siscia, aaelony: https://github.com/cemerick/raposo is indeed the right link, though I've not yet fixed the implementation enough to be comfortable putting it out there.

18:27 In hindsight, I shouldn't have promised it in the first place, since it wasn't tightened up yet by the time the conf rolled around, and it ended up needing more than I originally expected.

18:29 technomancy: cemerick: having a conference talk blocked on writing code that doesn't exist yet is the worst thing =\

18:29 siscia: cemerick, I completely understand it is harder that what it looks in the books... I am implementing the DAG like a set what you think is so stupid like idea ?

18:30 cemerick: technomancy: well, the shitter of it is that the code *does* exist. But, the week prior, I had a friend of mine look it over that had expertise in that area; he pointed out some serious flaws in the maths that, by happenstance, didn't manifest themselves with my dataset.

18:31 But, mea culpa in any case.

18:32 At this point, I feel better about leaving the repo empty than putting out stuff that probably will have undefined results with someone's protein analysis or something.

18:33 technomancy: ouch =(

18:35 siscia: cemerick, i would suggest to just push the infractuture and not the math part... it is still a lot of work...

18:35 cemerick: meh, the maths are the real meat of it

18:38 siscia: I know but maybe someone that has time to work on the math would find your repo...

18:42 aaelony: siscia: I would look to see how Weka and Mahout implement BNs and also perhaps other packages that (may not) scale but take other approaches

18:43 siscia: aaelony, thank for the hit

18:43 brehaut: ive never understood why they chose the name Weka for an AIish system

18:43 those are some pretty dumb birds

18:43 aaelony: hehe...

18:44 maybe see how matlab or octave implements as well

18:44 brehaut: oh. its an acronym

18:46 aaelony: siscia: maybe this is also helpful (??) https://code.google.com/p/bnt/

18:48 siscia: aaelony, yes it is definetily is, thanks

18:49 the real problem is that oo code helps (weka and mahout) but not so much...

18:50 aaelony: siscia: yeah, performance will be key

18:50 siscia: there is likely (somewhere) a github fork of Bradford Cross' old Infer library code that might have something as well, not sure

18:52 siscia: aaelony, https://github.com/aria42/infer this ?

18:53 aaelony: siscia: possibly, there exist some machine learning stuff in there, don't remember if there was any BNs

18:54 siscia: aaelony, i will give a look

18:54 thank you anyway, I appreciate

18:54 aaelony: siscia: sure. also take a look at incanter. http://incanter.org/docs/api/

18:56 siscia: aaelony, right, thanks again... Now it is about 1 AM in my country I should go to sleep... Thank again

18:57 aaelony: the sun never sets on Clojure IRC ... :)

18:58 siscia: LOL

19:01 gfredericks: I dunno. when it's 1-4am in the US it can be pretty quiet

19:01 maybe 3-6 more accurately

19:08 aaelony: siscia: for when you're up tomorrow, perhaps a graph db like jiraph will be worth looking into as well? https://github.com/flatland/jiraph

19:09 amalloy: $mail siscia forwarded message from aaelony: siscia: for when you're up tomorrow, perhaps a graph db like jiraph will be worth looking into as well? https://github.com/flatland/jiraph

19:09 lazybot: Message saved.

19:10 aaelony: amalloy: that is cool

19:10 amalloy: that's why Raynes wrote it!

19:10 aaelony: Raynes is cool

19:14 gerunddev: (defprotocol P (f1 [x] [x y] [x y z]))

19:59 mindbender: how do I make heroku use lein2? It's insisting on using a cached version of 1.7.

20:00 technomancy: mindbender: heroku config:add BUILDPACK_URL="http://github.com/heroku/heroku-buildpack-clojure.git#lein-2"

20:00 more details at https://github.com/heroku/heroku-buildpack-clojure/tree/lein-2

20:03 kovasb: dnolen: unleashed a rant on the ML. feel free to chime in with a +1 or something :)

20:10 dnolen: kovasb: cool, you really need to get your CA in :)

20:11 kovasb: yeah, too bad there is no e-signature option

20:11 "who uses dead trees anymore"

20:12 gfredericks: what on earth does an e-signature mean?

20:12 kovasb: signing pdfs

20:12 gfredericks: oh like a scanned hand-signature?

20:13 technomancy: gpg signature =)

20:13 gfredericks: technomancy: srsly

20:13 hiredman: I signed all the forms for work by using latex to place an eps of my signature on the pdf

20:13 dnolen: kovasb: I don't have much to add since I'm not actively working with literals. A Confluence page at this point would be better - I'm still not sure I understand the nuances.

20:13 hiredman: Super Secure(tm)

20:13 kovasb: dnolen: content less important than visibility in this case

20:14 gfredericks: my favorite is "click this button to e-sign."

20:14 kovasb: dnolen: i mean, if you totally flamed me, that would also work :)

20:14 technomancy: gfredericks: "click this button if you think there's any validity at all in this process"

20:14 gfredericks: :)

20:14 hiredman: being able to work with unknown instance literals would be useful

20:14 gfredericks: doesn't the IRS use something equivalent?

20:15 technomancy: gfredericks: "if you question the usefulness of a signature mechanism that can be trivially forged, turn to page 45."

20:15 gfredericks: lol

20:15 kovasb: hiredman: without that, its basically no better than arbitrary reader macros, where everyone needs the exact same setup

20:16 hiredman: kovasb: maybe a better approach is the ability to define a cache all reader

20:17 might be more flexible

20:17 catch all :)

20:17 (catch all? fall back? something like that)

20:17 kovasb: hiredman: that could work. though i figure you can extend-type on the UndefinedLiteral as well

20:18 dnolen: kovasb: I could chime in but I don't think it would help. A Confluence page w/ a design / solution could spark some focused discussion. Then a patch could fall out of that.

20:18 hiredman: with the fallback, you could just define it as identity, and get the unprocessed value

20:19 dnolen: kovasb: basically, people work on what they need. If you need it - then you probably need to work on it.

20:19 kovasb: hiredman: yeah but if you need to transmit the data to the next guy, you need to reconstruct the literal

20:19 hiredman: kovasb: *shrug* if you need to do that, then you set the fallback reader to something that lets you do that

20:19 kovasb: dnolen: alright looks like there is a kinkos within a couple of blocks from me. will put on my big boy pants

20:20 hiredman: i think that is the most common case, that should just happen automatically

20:20 penthief: Is there a maven-cljsbuild plugin yet?

20:21 kovasb: hiredman: though for my solution to work, you effectively need a catch-all anyway

20:21 hiredman: so one should be able to redefine it as well

20:27 emezeske: penthief: You don't like leiningen? :)

20:30 penthief: I don't think so, there are better tools for maven.

20:33 Are we trying to take over the entire stack?

20:35 emezeske: penthief: Well, Leiningen uses maven repositories, so I don't think it's replacing the entire stack, just the frontend.

20:35 amalloy: &((fn x [] (x))) ;; we did it, took over the whole stack!

20:35 lazybot: java.lang.StackOverflowError

20:35 kovasb: destroying the village in order to save it

20:46 wingy: Oracle is porting JavaScript to JVM .. does that mean ClojureScript will be using that one instead of Rhino?

20:56 emezeske: wingy: ClojureScript doesn't target any one virtual machine

20:56 wingy: So presumably Oracle's JS port to JVM will just add another platform for ClojureScript to run on

20:56 wingy: hm

20:56 yeah im reading https://github.com/clojure/clojurescript/wiki/The-REPL-and-Evaluation-Environments

20:57 so you start your JVM and then you start the JS repl inside of it it seems

20:57 emezeske: CLJS runs on rhino, node.js, v8, spidermonkey, etc

20:57 wingy: The backend for running REPL commands is configurable

20:59 wingy: emezeske: im trying to get how it all works

20:59 what is the best guide to use cljs in my browser app?

20:59 emezeske: wingy: If you're just getting started, I'd start with lein-cljsbuild (shameless plug)

21:01 dnolen: emezeske: that said if Nashorn is significantly faster than Rhino, which is cruelly slow, I'm all for it :)

21:02 emezeske: dnolen: Oh, hell yeah

21:05 kovasb: they are claiming its 3-5 times faster, but i fail to see the point

21:05 dnolen: kovasb: hmm 3-5 faster? That's it? Forget about it.

21:06 kovasb: according to some random info world article

21:06 dnolen: kovasb: I thought idea was to be competitve w/ things like V8, JSC, and SM

21:07 kovasb: dnolen: granted it is brand new

21:08 wingy: oracle want a piece of the pie

21:08 dnolen: kovasb: I suppose perf is tied to perf of invokeDynamic.

21:08 jhulten: wingy: Oracle wants to own the means of pie production...

21:09 wingy: :D

21:13 dnolen: kovasb: did you take a look at halgari's reactive lib?

21:14 kovasb: dnolen: yes i've looked at all that stuff to some degree

21:14 dnolen: kovasb: thoughts?

21:15 kovasb: i haven't had that magical "this is it" feeling yet

21:16 I'm not sure what to think, other than its good people are exploring the domain

21:19 dnolen: "Special macro code is needed for if, and let." not a good sign

21:25 dnolen: i do agree that its better to have a dsl than to manually connect the pieces together

21:25 wingy: is this a nice way to get how to use cljs with clj? https://github.com/brentonashworth/one

21:25 dnolen: kovasb: I think part of the problem is that people are thinking about DSL instead of thinking about what the machinery should look like first.

21:26 kovasb: dnolen: yes i agree

21:26 dnolen: one big thing that is getting complect here is, the sources and sinks of the events are mutable objects

21:27 dnolen: so we are have an impledence mismatch problem as well as a "reactive update" problem

21:28 dnolen: i basically got my DSL as far as i could go before realizing i couldn't really conceptualize what was actually happening

21:28 wingy: clojurescriptone seems outdated

21:28 dnolen: wingy: there's an up to date branch M003 or something.

21:30 wingy: dnolen: yeah

21:31 dnolen: im not very good at git . do you know how i fetch that branch?

21:31 gfredericks: git fetch; git branch -a; git co branch-name

21:32 by "co" I mean "checkout"

21:34 wingy: gfredericks: thanks

21:34 https://github.com/brentonashworth/one/tree/M003

21:34 it says that i should run lein bootstrap but there is not such task

21:35 kovasb: dnolen: the dsl is describing the relationships better, but overloading the existing the constructs of clojure to do it doesn't quite cut it

21:37 dnolen: reminded of how the reducers library deconstructs the concept of map. need something like that for programming constructs in this domain

21:37 dnolen: kovasb: hmm, RxJS really doesn't look that bad.

21:38 kovasb: I'm looking at drag & drop, http://theburningmonk.com/2011/03/drag-and-drop-using-reactive-extensions-for-javascript/

21:38 cbrozefsky: wingy: bootstrap is a addon for lein or part of lein2, I can't recall specifics

21:38 you'll also need git-deps

21:39 wingy: cbrozefsky: git-deps?

21:39 dnolen: kovasb: for starters I wonder if simply attaching observers could be made functional.

21:39 wingy: http://comments.gmane.org/gmane.comp.java.clojure.user/57636

21:40 cbrozefsky: you want lein2

21:40 wingy: "I suspect it's an incompatibility with lein2. Try leiningen 1.x."

21:40 :(

21:40 cbrozefsky: oh the other way? I don't think so

21:40 wingy: im on lein2

21:40 kovasb: dnolen: that part is a good idea

21:40 cbrozefsky: hehe

21:40 dnolen: kovasb: (subscribed (observable x)) returns a new observable, no mutation of the observe list.

21:40 er subscribe.

21:40 wingy: noway i got back to lein 1

21:41 cbrozefsky: http://clojurescriptone.com/documentation.html#leiningen.bootstrap

21:41 so if I am correct, those come in as files lein will load up

21:41 you know, you can download lein 1.X call the script lein1

21:41 and run it

21:41 kovasb: dnolen: definitely a better idea than attaching event handlers for sure

21:42 cbrozefsky: that's what i do

21:42 wingy you can also just try running "lein deps; lein git-deps"

21:42 but I bet the git-deps will fail

21:42 wingy: yeah there is no such task

21:42 wtf

21:43 i dont get this

21:43 cbrozefsky: Well, CL One goes against the suggestions of the lein maintainers, this is what happens

21:43 wingy: a pity i was looking forward to this

21:44 cbrozefsky: you can also get rid of the git deps, replace them with proper deps

21:44 ad skip git-deps and bootstrap alltogether

21:44 dnolen: kovasb: I suppose there still a bit of a resource problem. (observable x) still needs to mutate x.

21:44 cbrozefsky: wingy: sorry dude

21:44 wingy: cbrozefsky: i dont have the experience to do so

21:44 cbrozefsky: its clojure and domina it wants right?

21:45 wingy: ill just watch for other tutorials

21:45 cbrozefsky: open project.clj

21:45 look, learning your packaging tools it part of it 8)

21:45 I'll walk you thought

21:46 dnolen: kovasb: tho I'm not sure that's actually a real problem ...

21:46 cbrozefsky: open up project.clj, see where the git-dependencies statement is

21:46 remove that, and then see where the :dependencies list is?

21:47 kovasb: dnolen: i don't think its a problem

21:47 dnolen: my problem is not what these things do, its what they don't do

21:47 dnolen: kovasb: ?

21:47 kovasb: dnolen: they don't really help you with higher-level representations

21:48 wingy: cbrozefsky: and next?

21:48 kovasb: dnolen: like, i want the changes to have an effect on a more abstract structure

21:48 dnolen: and then percolate the changes down

21:48 cbrozefsky: add dependencies for domina

21:48 dnolen: kovasb: does Rx not handle that?

21:48 kovasb: dnolen: its just a more elegant way of handling events, not a way of keeping representations in sync

21:50 dnolen: responding to events is different from generating a representation from scratch

21:50 cbrozefsky: and clojurescript

21:51 dnolen: kovasb: what's the simplest example of something you find problematic?

21:52 kovasb: dnolen: representing a hiccup datastructure as a dom element

21:52 wingy: cbrozefsky: https://clojars.org/ibdknox/clojurescript ?

21:52 cbrozefsky: wingy: I'll put my project.clj in a gist

21:52 wingy: why is it on ibdknox namespace :)

21:52 cbrozefsky: it just worked for me

21:52 kovasb: dnolen: you update your hiccup structure.. and then what

21:53 cbrozefsky: https://gist.github.com/3126459

21:53 that is the project.clj I used for one

21:53 replace yours with that

21:53 kovasb: same problem for any higher level representation that needs to be compiled to a lower level one

21:53 cbrozefsky: I then, with lein2, did: lein deps; lein repl

21:53 and it appears to work

21:54 that is as far as I tested it at least

21:54 wingy: good luck 8)

21:54 dnolen: kovasb: right you're talking about the problem that you want to listen at the level of hiccup?

21:55 kovasb: dnolen: thats one way to put it

21:55 dnolen: in the case of the drag and drop example, i would want the coordinates in my hiccup to change

21:55 dnolen: and then the dom would just react accordingly

21:55 wingy: cbrozefsky: it says Could not find artifact org.clojure:clojurescript:pom:0.0-1069 in central (http://repo1.maven.org/maven2)

21:56 and all other

21:58 cbrozefsky: lein2 clean

21:58 lein2 deps

21:58 that is an old version

21:58 and that doesn't appear in that project.clj I gave you

21:59 kovasb: dnolen: if you have that, then you can build higher level declarative stuff, like the thing the drag and drop represents

21:59 dnolen: kovasb: hmm what's the problem with the Pods approach? You can (manipulate immutable-hiccup) -> mutable hiccup which handles synchronization. any attempt to read produces something persistent?

21:59 wingy: cbrozefsky: thats the weird part .. why is it trying to get that one

21:59 i onlu changed clj version to 1.4

21:59 cbrozefsky: old dep data around?

22:00 kovasb: dnolen: yes, but how do you write the synchronization function

22:00 dnolen: thats the missing piece

22:01 dnolen: in a way that is built up from some reasonable constructs, not some ugly hack that is a pain to write every time

22:01 dnolen: and not special-cased to the dom

22:02 cbrozefsky: kovasb: so you don't want to rerender the hiccup and then replace it wholesale in the dom, right?

22:02 wingy: impossible i deleted it and git clone it again

22:02 still the same

22:02 dnolen: kovasb: ? I don't see the problem. The hiccup has to be annotated somehow with events.

22:02 kovasb: cbrozefsky: no, that would be easy, but too slow

22:02 cbrozefsky: wingy: did you copy that project.clj I linked too into the dir

22:03 wingy: yeah i used your one

22:03 cbrozefsky: ok, and when you git clone again you nuked it

22:03 wingy: yeah

22:03 but i checkout the remotes/origin/M003 branch

22:04 perhaps that one is weird?

22:04 cbrozefsky: I have no clue what you are talking about now

22:04 dnolen: kovasb: it doesn't sound like to me for interaction you need the whole structure - only for serialization right?

22:04 kovasb: dnolen: the problem is you are translating between mutable and immutable things

22:04 dnolen: with some fairly involved logic

22:04 cbrozefsky: kovasb: yah, so rendering the whole thing is costly, however, if you know what you changed, and then can ap that to the DOM, like say, via IDs...

22:05 kovasb: dnolen: and you need to update the mutable thing in the correct way

22:05 wingy: fuck this

22:05 dnolen: kovasb: I guess I don't see the problem. Mutating is easy. Annotating is easy. Copying is easy. What else is needed?

22:05 cbrozefsky: kovasb: ok, so your hiccup data structure is manipulated via something using a tree zipper to get around

22:05 wingy: if its that hard to use it perhaps its not meant for me

22:05 kovasb: cbrozefsky: yes, you can do it, but we want to do it not just for the DOM, but at higher levels of abstraction as well

22:05 wingy: i dont even know why i wanna use it

22:06 ill read some other tutorials how to use cljs

22:06 cbrozefsky: kovasb: when you make a change, you san back up the list for your the elements that are tagged with an ID, you make a list of them

22:06 dnolen: kovasb: at no point have I mentioned the DOM - that's part of the event architecture.

22:06 cbrozefsky: you can then render just those fragements and update the same elements in the DOM

22:06 dnolen: kovasb: events are constraints that keep things in sync.

22:06 ibdknox: dnolen: kovasb: I think we need to take a step back, because the FRP discussion seems like 4-5 different problems

22:06 cbrozefsky: or whatever other structure you want to sync with

22:06 kovasb: dnolen: think about how complex the logic is for the hiccup-to-dom function

22:06 ibdknox: and we're conflating their solutions

22:07 kovasb: dnolen: how do you trace through that logic and determine the exact mutation that should occur

22:07 dnolen: when a tiny piece of your hiccup changes

22:07 dnolen: ibdknox: agreed. Events is one thing. Abstracting data structures is another.

22:07 kovasb: you don't need to trace. You have events mutating a mutable thing.

22:07 kovasb: i am ignoring events here

22:07 ibdknox: dnolen: if you guys can wait until after my oscon presentation (thursday) I'll chime in with something

22:08 kovasb: suppose your hiccup changes because you got new data from the database

22:08 cbrozefsky: ibdknox: thanx for noir, jayq, korma 8^)

22:08 ibdknox: cbrozefsky: np :)

22:08 null-: you are still working on noir?

22:08 dnolen: ibdknox: excellent :)

22:08 kovasb: ibdknox: will there be a live stream?

22:08 ibdknox: dnolen: kovasb: but I think we should center the discussion around the code we want to write - it's not clear to me what that is quite yet

22:08 then worry about the "how" ;)

22:09 kovasb: right

22:09 dnolen: kovasb: I think I'm forgetting to say something here.

22:09 kovasb: i want to write high-level tagged literal representations of the UI

22:09 ibdknox: kovasb: I don't think so.. I think they're trying to sell videos or something

22:09 kovasb: ibdknox: self-record your screen and audio :)

22:10 ibdknox: null-: not focusing on it, Raynes has been helping me there, but I use it for Light Table so it's not ignored completely by any means

22:10 dnolen: kovas: in my mind you have annotated hiccup -> DOM. When we put it in the DOM we get back something which we can read which can reconstruct the hiccup (I personally don't see another way).

22:10 kovasb: kind of like working with source code, parse / unparse

22:11 kovasb: dnolen: I'm thinking of e.g., the slider example - you move the slider, a value changes, and then you need to update another graphics based on that new value

22:11 dnolen: kovasb: but all that happens in the mutable world. But you'll get back handles that reconstruct the Hicucp.

22:11 null-: ibdknox: ok cool

22:12 ibdknox: it's safe to assume it's not going anywhere, if that's your concern

22:12 kovasb: dnolen: yeah, i get that. but you need to be able to change your models in other ways as well

22:12 dnolen: kovasb: an example you have in mind you haven't mentioned so far?

22:12 kovasb: dnolen: hiccup is just a very low level example of a model. but it captures the essential point

22:13 dnolen: sure, pretty much every construct in session

22:13 dnolen: the loops, the sub sessions, the session

22:14 dnolen: higher-level widgets of various sort

22:14 dnolen: graphics

22:15 dnolen: those should all be declarative things, that get recursively expanded to lower and lower level representations

22:15 null-: ibdknox: yeah, good to know

22:15 dnolen: kovasb: I don't see how the unparse / parse model doesn't support those as well. Your issues seem to be completely about serialization. But maybe I missing something.

22:16 kovasb: dnolen: a representation may not contain all the info needed to reconstruct

22:17 dnolen: for instance toggling detail level

22:17 dnolen: kovasb: why wouldn't it have that?

22:17 kovasb: dnolen: like, you are zoomed in an an area of the graph

22:17 dnolen: not showing the whole thing

22:18 dnolen: i mean, in general you don't want to have only a 1-to-1 model-view relationship

22:18 dnolen: where you only have exactly one view for the model

22:18 dnolen: kovasb: but something is storing that state, regardless of whether it's on the graph itself or not.

22:19 kovasb: dnolen: yes

22:19 dnolen: @(go! graph-of-constraints) -> copy

22:19 kovasb: not following

22:20 dnolen: kovasb: you start with a data rep + constraints (events), go! realizes it (puts it in the DOM), you need to serialize - start at the root producing the immutable copy.

22:21 kovasb: dnolen: you think we should get rid of models and just store all the data in the dom?

22:21 devth: how would you transform [1 2 3 4] into {1 1, 2 2, 3 3, 4 4}?

22:22 dnolen: kovasb: this is what I mean about a parse / unparse model

22:22 hiccup can parse to DOM

22:22 but DOM can't unparse to hiccup

22:22 kovasb: ok

22:22 dnolen: so make the DOM smart enough to unparse itself.

22:22 brehaut: ,(mapcat (juxt identity identity) [1 2 3 4])

22:22 clojurebot: (1 1 2 2 3 ...)

22:22 kovasb: ok, yes, you can try to do that

22:22 that is basically what mathematica does

22:23 devth: brehaut: ty

22:23 dnolen: kovasb: I guess I don't see any other way. It's also a pretty tried and true way with compilers :)

22:23 kovasb: right

22:24 i mean, fair enough

22:24 I'm trying to invent something new in this department

22:24 :)

22:24 its intuitive to me why i want it, maybe not to others

22:25 dnolen: kovasb: heh, it seems to me a protocols really wouldn't be enough - you'd need some kind of specialized data structure - and I'm not sure it would work for all cases.

22:25 kovasb: though i think its a good argument that 1) you want models distinct from views and 2) you want it to be easy to create layers of abstraction

22:25 dnolen: kovasb: putting things in the DOM is fast - based on your use case you don't need to unparsing all the time.

22:25 kovasb: dnolen: yes protocols are not enough

22:26 dnolen: kovasb: do you need to unparse on every mouse movement? I doubt it. Only at mouse up.

22:26 you've got about 300ms to unparse after a mouseup before a human notices.

22:26 I don't see any challenges here.

22:26 brehaut: devth: a more sensible implementation uses (partial repeat 2) in place of (juxt

22:27 kovasb: dnolen: I'm less worried about going from dom to data than from data to dom

22:27 dnolen: the assumption here is your program is dealing at the level of abstract logic, and updating clojure data

22:28 dnolen: so low level dom events get converted into something with semantic meaning

22:28 dnolen: kovasb: I'm not so sure.

22:28 kovasb: dnolen: and which then in turn changes some data

22:28 dnolen: i mean, thats the backbone way right :)

22:29 dnolen: kovasb: I think you want to bridge the two worlds in a way that's not necessary.

22:29 declare your mutable world - run it - get immutable copies is what I'm suggesting.

22:29 don't make it chatty.

22:29 kovasb: dnolen: its not necessary, since people have been writing apps the old fashioned way forever

22:30 dnolen: i think the update interval is an optimization

22:30 dnolen: kovasb: well gotta run for a bit - let's chat on Wednesday :)

22:30 kovasb: dnolen: cool, talk to you later!

22:39 gnarmis: hey does anyone know where clojure.contrib.string went in the whole 1.3 diaspora?

22:39 aperiodic: clojure.string

22:39 gnarmis: ah really?

22:39 aperiodic: yup

22:40 gnarmis: was just looking for substring? in there

22:41 devth: brehaut: i really just wanted to know the function to use. the value of each item would actually be computed based on the key.

22:41 gnarmis: hmm can't find substring?, maybe it got renamed or deprecated or something

22:41 brehaut: subs

22:41 or .substring

22:42 jweiss: is there a good reason Delay objects don't support metadata? or just that no one has added it yet?

22:42 brehaut: oh, sorry missed the comma there

22:42 aperiodic: i don't thing substring? made the trip

22:43 gnarmis: hmm ok, .substring's there i guess

22:44 aperiodic: (def substring? [needle haystack] (>= (.indexOf haystack needle) 0)))

22:44 s/def/defn/

22:45 devth: brehaut: so if i need to compute the value based on key, would i use this? (map #(hash-map %1 (* %1 %1)) [1 2 3 4])

22:45 brehaut: devth: im not sure what you are doing sorry

22:46 devth: brehaut: ok np. that code works - i just don't know if it's idiomatic.

22:46 ,(map #(hash-map %1 (* %1 %1)) [1 2 3 4])

22:46 clojurebot: ({1 1} {2 4} {3 9} {4 16})

22:46 gnarmis: awesome, was about to do something with indexof

22:47 although re-seq seems even more handy

22:50 devth: actually that doesn't work. i want {1 1, 2 4, 3 9}. arg, so rusty after not touching clojure in several months :(

22:52 brehaut: ,(into {} (map (fn [i] [i (* i i)]) [1 2 3 4]))

22:52 clojurebot: {1 1, 2 4, 3 9, 4 16}

23:02 amalloy: 'into and 'for go together like bagels and cream cheese though, guys! ##(into {} (for [i [1 2 3 4]] [i (* i i)]))

23:03 lazybot: ⇒ {1 1, 2 4, 3 9, 4 16}

23:03 devth: brehaut, amalloy thanks!

23:05 dsrguru: in common clojure style are earmuffs only used for thread-local dynamic vars or do they get used for things like agents too?

23:09 amalloy: earmuffs strongly suggest dynamic vars

23:16 dsrguru: amalloy: so for agents in web app code that get read from and written to by each browser session, don't use earmuffs, correct?

23:16 amalloy: right

23:16 dsrguru: thanks

23:22 iDesperadO: what's the problem of my gcd function?(defn rgcd [a b] (if (= a 0) b (rgcd [(rem b a) a]))). when I call it with (rgcd [24 36]), the repl errs me with a ArityException

23:23 tmciver: (defn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a))) ;; lose the square brackets on the recursive call.

23:24 iDesperadO: (clojure.core/defn rgcd [a b] (if (= a 0) b (rgcd [(rem b a) a])))

23:24 sorry about that

23:25 whamied: The problem is that you're passing in a vector as an argument

23:25 dsrguru: as in call it with (rgcd 24 36)

23:25 whamied: right

23:26 arity is the number of parameters, the problem is you're passing in only one as opposed to the two you specify

23:26 iDesperadO: I've both passed the arguments as vector and as individual numbers...both errs the same error exception

23:26 whamied: right, the recursive call is also a vector

23:26 (rgcd [(rem b a) a])

23:27 dsrguru: it should say (clojure.core/defn rgcd [a b] (if (= a 0) b (rgcd (rem b a) a)))

23:27 whamied: so, lose the square brackets, as tmciver said above

23:28 dsrguru: (you don't need the clojure.core; I was just copying what you wrote)

23:28 (unless you've redefined defn in the current namespace, but I hope you didn't)

23:28 iDesperadO: so..that's the problem of my definition when i call the rgcd passing a vector instead of two actual arguments?

23:28 dsrguru: it would be fine if you had written (defn rgcd [[a b]] ...

23:28 but the parameter list that defn takes

23:28 doesn't create a single vector parameter

23:29 it creates any number of separate parameters

23:29 that's just how it works

23:29 so (defn foo [a] a)

23:29 is a function of single arity

23:29 one parameter

23:29 amalloy: iDesperadO: the problem is that (f x y) is not the same as (f [x y])

23:29 dsrguru: and it returns that one parameter

23:29 amalloy: I think iDesperad0 is confused because in the call to defn, you enclose the parameter list with square brackets

23:30 so iDesperadO might think that the parameter list is specifying something like a destructured vector

23:30 iDesperadO: it's just the grammar of the Clojure language that you put square brackets around the parameters when you define the function using defn

23:31 but that creates a function

23:31 that gets called with those parameters as separate arguments

23:31 so (defn add [a b] (+ a b)) gets called (+ 3 4) not (+ [3 4])

23:32 iDesperadO: then my second wonder is if the calling part is not right, why the repl didn't errs right after my finishing the definition?

23:32 dsrguru: can you paste the definition you're referring to right now?

23:32 iDesperadO: user=> (clojure.core/defn rgcd [a b] (if (= a 0) b (rgcd [(rem b a) a])))

23:33 #'user/rgcd

23:33 user=> (rgcd [24user=> (rgcd [24 36]) 36])

23:33 dsrguru: because the recursive call (rgcd [(rem b a) a]) part

23:33 hasn't been evaluated yet

23:33 iDesperadO: ArityException Wrong number of args (1) passed to: user$rgcd clojure.lang.AFn.throwArity (AFn.java:437)

23:33 dsrguru: when you define it

23:33 so even though the function isn't correct

23:33 iDesperadO: hasn't been evaluated...hmm...lazy evaluation right?

23:33 dsrguru: it generates a runtime error

23:33 not a compile-time error

23:33 well no

23:34 it's just that you haven't called rgcd

23:34 so

23:34 first you type the code in

23:34 the (defn rgcd ...) stuff

23:34 then clojure reads when you typed

23:34 and it assigns the function you defined

23:34 to the name rgcd

23:34 but it doesn't execute the function yet

23:35 then once you try actually running it

23:35 such as (rgcd 24 36)

23:35 iDesperadO: Oh...first read, then compile, then evaluate...

23:35 dsrguru: yes

23:35 well

23:35 iDesperadO: i get it

23:35 dsrguru: it reads defn

23:35 and it evaluates defn

23:35 iDesperadO: thank you guys

23:35 dsrguru: but it doesn't exexute the function yet

23:35 cshell: it defines a function

23:36 and binds it to the sybol rgcd

23:36 dsrguru: evaluating defn just means compile the function and assign it to the name rgcd

23:36 when you type (rgcd 24 36)

23:36 the repl reads that just like it did the defn expression

23:36 iDesperadO: so I should still define a function with parameters in a vector or just list them....I'm afraid I want to vector form....since I can expand the arity using a & when i need it

23:36 dsrguru: and then it evaluates it

23:36 and when it evaluates it

23:36 it tries running the function

23:36 and sees the problem

23:37 yes parameters get defined in square brackets

23:37 you're just listing them

23:37 but in square brackets

23:37 but the way defn is defined, the function created is not taking a single argument of vector type

23:38 but rather as many arguments as you enclosed in the square brackets in your defn expression

23:38 iDesperadO: so ...it's just two phases. read/evaluate(compile and run), right?

23:38 dsrguru: essentially

23:38 yes

23:38 but they're not always separate phases

23:39 iDesperadO: dsrguru: ok, I define with parameters in vectors and call it with individual arguments listed one by one...

23:39 dsrguru: yes

23:39 the reason btw that they're not always separate phases

23:39 iDesperadO: because we can use a macro?

23:39 dsrguru: yes

23:39 so for example

23:40 iDesperadO: to stop evaluation at the moment?

23:40 dsrguru: during the reading of (defn ...)

23:40 the repl says

23:40 oh wait

23:40 defn is a macro

23:40 so let me translate this whole expression into something else

23:40 before evaluating it

23:40 and certain expressions

23:40 like regexp patters

23:40 can be evaluated at read-time

23:40 and you can call the read function

23:40 iDesperadO: Oh

23:40 dsrguru: which reads

23:40 when it is evaluated

23:40 so like

23:41 boundaries are kinda flexible

23:41 unlike non-lisps

23:41 where you can't easily interact with different phases of compilation at runtime

23:42 iDesperadO: hm....code is data is code...as Fogus says in the book The Joy of Clojure

23:42 dsrguru: exactly!

23:43 iDesperadO: ah...my function is right

23:43 dsrguru: good

23:44 iDesperadO: and ... I'm wondering the calling part of rgcd is at tail position?

23:44 it's at the else part of it with is the body of the function

23:44 I guess it is

23:45 so it can be optimized

23:45 dsrguru: yes

23:46 but had you put the recursive call to rgcd inside of the call to rem, it would not be

23:46 iDesperadO: it's at the else part of if statement which is the body of the function...sorry for my typos...

23:46 dsrguru: except

23:46 in clojure

23:47 there's no tail-call optimization :)

23:47 you'd have to use loop/recur

23:47 but it *is* in tail position in your example

23:47 so it would be optimized in, say, scheme

23:47 iDesperadO: so a better implementation of rgcd is to use recur, I guess

23:48 I'm confused by recur...esp. with loop

23:49 dsrguru: it'll be confusing in this example

23:50 let's use an example more suited to loop/recur

23:50 have you seen the factorial function implemented in clojure or another functional language?

23:50 (or recursively in any language for that matter)

23:51 iDesperadO: ah...I can't understand others implementation using loop and recur..but I can't write my own

23:51 dsrguru: so first start with something where tail recursion makes sense

23:51 like

23:51 iDesperadO: I'm writing a better version of rgcd using loop and recur and kinda stuck

23:51 dsrguru: the simplest factorial implementation

23:51 would be:

23:52 (defn factorial [n] (if (= n 0) 1 (* n (factorial (inc n)))))

23:52 iDesperadO: (defn fact [n] (if (= n 0) 1 (fact (- n 1)))?

23:52 dsrguru: *dec n

23:52 should be

23:52 iDesperadO: forget to multiply by n

23:52 dsrguru: (defn factorial [n] (if (= n 0) 1 (* n (factorial (dec n)))))

23:52 iDesperadO: ok

23:52 dsrguru: yeah

23:52 (dec n) means (- n 1)

23:52 lazybot: ⇒ -1

23:52 dsrguru: what you said

23:52 yeah

23:53 so

23:53 if we called let's say (factorial 2)

23:53 we'd be evaluating:

23:53 (* 2 (factorial (dec 2)))

23:53 which itself evaluates to

23:54 (* 2 (factorial 1))

23:54 and then (* 1 (* 2 (factorial 0)))

23:54 iDesperadO: (* 2 (factorial 1) -> (* 2 (* 1 (factorial 0)))

23:54 and it evaluate to base case

23:54 dsrguru: right

23:54 so

23:55 a bunch of stuff has to be evaluated

23:55 before getting to the base case

23:55 of (factorial 0)

23:55 iDesperadO: so how to change that to use loop and recur?

23:55 dsrguru: so what you could do is

23:55 (defn fac [n]

23:56 (loop [new-n n

23:56 iDesperadO: loop to binding variable recur to call from intermediate phases...

23:56 dsrguru: acc 0]

23:56 (if (= new-n 0)

23:56 acc

23:57 (recur (dec new-n) (* new-n acc))))))

23:57 so

23:57 loop sets up temporary let-style bindings

23:57 Raynes: https://www.refheap.com

23:57 dsrguru: but also says everything inside here is a function

23:58 and then it can be called recursively by the keyword recur

23:58 iDesperadO: (defn fact [n] (loop [new-n n acc 0] (if (= new-n 0) acc (recur (dec new-n) (* new-n acc)))))

23:59 dsrguru: you could use n instead of new-n btw since you never need to refer to the old n value

23:59 so

23:59 (defn fact [n] (loop [n n acc 0] (if (= n 0) ...

23:59 should work too

23:59 iDesperadO: I usually don't know what to bind and when to recur

23:59 dsrguru: and then every time you type n

23:59 it will evaluate to the n defined inside loop

23:59 not the old when

23:59 oh

23:59 kk

Logging service provided by n01se.net