#clojure log - Dec 01 2011

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

8:30 chouser: Bah. Failed to log since yesterday afternoon until just now.

8:40 noidi: I have a vector of values, and I need to find the index of a given value in it. What's the best way to do this?

8:41 Borkdude: noidi: I would use keep-indexed

8:42 clgv: noidi: you might have chosen the wrong datastructure if you ant to do that often

8:42 *want

8:44 Borkdude: ,(keep-indexed (fn [i e] (if (= e some-value) i))

8:44 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

8:44 Borkdude: ,(keep-indexed (fn [i e] (when (= e 2) i)) [1 2 3])

8:44 clojurebot: (1)

8:44 noidi: basically I just want to map a set of keywords to sequential integers. the obvious way would be a map, {:foo 0, :bar 1, ...}, but I'd rather let Clojure do the work :)

8:44 Borkdude: I mean (copied the wrong thing)

8:45 noidi: and I want the order to remain stable, that's why I use a vector and not a set

8:46 Borkdude: noidi: a vector of keywords maybe?

8:46 noidi: use map-indexed then

8:46 clgv: noidi: try ##(zipmap [:foo :bar :bla :blubb] (range))

8:46 lazybot: ⇒ {:blubb 3, :bla 2, :bar 1, :foo 0}

8:47 noidi: clgv, brilliant, thanks!

8:48 and thanks for the tips Borkdude

8:48 clgv: I wonder if lazybot could have done it

8:48 $findfn [:foo :bar] [0 1] {:foo 0, :bar 1}

8:48 lazybot: [clojure.core/zipmap]

8:48 Borkdude: noidi: no problem. a somewhat longer version: (into {} (map-indexed (fn [i e] [e i]) [:a :b]))

8:49 clgv: yes he could have :)

8:49 noidi: whaaat?! :D

8:49 Borkdude: clgv: heheh, cool :)

8:49 noidi: that's crazy

8:49 clgv: $inc lazybot

8:49 lazybot: ⇒ 2

8:49 noidi: $findfn 2 2 4

8:49 lazybot: [clojure.core/unchecked-multiply clojure.core/+ clojure.core/* clojure.core/unchecked-add clojure.core/+' clojure.core/unchecked-multiply-int clojure.core/*' clojure.core/unchecked-add-int]

8:50 noidi: $findfn [:foo :bar] {:foo 0, :bar 1}

8:50 lazybot: []

8:50 clgv: noidi: he cant compose functions (yet?) ;)

8:50 noidi: clgv, just checking whether's there's something like that in core already :)

8:51 Borkdude: $findarg map % [1 2 3] [-1 -2 -3]

8:51 lazybot: [clojure.core/-' clojure.core/unchecked-negate clojure.core/- clojure.core/unchecked-negate-int]

8:52 clgv: Borkdude: but thats not really composing them on his own ;)

8:52 Borkdude: clgv: right, just trying out if I remembered how it worked ;)

8:52 clgv: yeah that one is pretty cool as well

8:53 noidi: is that built on clojure.core.logic?

8:53 clgv: noidi: I dont think so. Just plain bruteforce ;)

8:53 Borkdude: noidi: check github, it just trying all fns and see if they work ;

8:53 ;)

8:54 $findarg map % [:a :b] {:a 0 :b 1}

8:54 lazybot: []

8:54 Borkdude: $findarg mapcat % [:a :b] {:a 0 :b 1}

8:54 lazybot: []

8:55 Borkdude: $findarg map-indexed % [:a :b] {:a 0 :b 1}

8:55 lazybot: []

8:55 Borkdude: I give up ;)

8:56 $findarg %1 %2 [:a :b] {:a 0 :b 1} ;; clojure.logic do your thang! ;P

8:56 lazybot: java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0)

9:08 fbru02: hey guys i talked today with clgv about multiple fn sigs .. i have a problem one side i have (fn ([a] (..)) ([& b] (..)) this doesn't work b/c the compiler needs the variadic to be longer than the single parameter

9:08 ways to get around this?

9:09 raek: (fn ([a] (..)) ([a & b] (..)) ?

9:09 clgv: fbru02: no. you have to have at least as many parameters in the variadic sig as in the longest non variadic one

9:09 fbru02: ok will try re disgning then

9:09 clgv: fbru02: otherwise the compiler has no clue which one to take

9:10 fbru02: thanks ! :)

9:13 hcumberdale: Are clojure applications 'really' running in multiple parallel threads in the JVM?

9:13 clgv: hcumberdale: depends how you write them

9:13 Wild_Cat: and how the JVM schedules them. As I recall it has M-N threading, right?

9:23 hcumberdale: Why is there no "default concurrency" ? clgv what are you meaning with "how"? Have I to add explicit commands to get concurrency?

9:24 clgv: hcumberdale: sure. did you ever see a system where thats automatic? I think thats semantically impossible

9:25 kephale: clgv: well, one could rename pmap as map, then call concurrency automatic : P

9:26 hcumberdale: clgv => Haskell ?

9:26 clgv: kephale: lol and get worse performance in a lot of cases... ;)

9:27 hcumberdale: sure? I dont know haskell but I dont think that it automatically tries to do everything in parallel since that would be inefficient due to scheduling overhead if you have only small tasks.

9:27 kephale: clgv: sure, explicit concurrency is definitely the way to go. when it comes to a shared environment you really need it to be explicit unless you use sandboxes everywhere

9:29 chouser: There are languages that have ubiquitous parallelism (a bit like Clojure has ubiquitious lazy seqs) but I don't know that any got past "research language" stage.

9:29 kephale: although i guess that comes back to just being able to control the thread pool

9:32 chouser: GPU languages

9:33 hcumberdale: http://www.haskell.org/haskellwiki/Parallel

9:33 clgv: Haskell supports both pure parallelism and explicit concurrency.

9:33 cemerick: is no one using fortress for real work then?

9:34 hcumberdale: never heard of fortress ;(

9:35 clgv: hcumberdale: but that wikipage seems as if you have to use special "things" as well for pure parallelism

9:36 hcumberdale: I think it does not explain anything about the pure parallelism (which must be switched explicit on by a command line switch if I remember)...

9:37 clgv: hcumberdale: but to answer your question - you have to tell clojure when you want to do something in parallel ;)

9:37 hcumberdale: okay! ... good to know

9:38 http://goo.gl/MCNi8

9:38 Fossi: erlang programs can easily be pretty parallel, but other than that i rarely saw another example

9:38 hcumberdale: "To compile a Haskell program for parallel execution under PVM, use the -parallel option"

9:39 Mhhh Intresting how they do such a parallel execution.... really everything in parallel will lead to a lot cpu time for threat management

9:39 threat => thread ... hmpf, new keyboard

9:39 kephale: hence why GPUs are the best example ; D

9:42 cemerick: hcumberdale: it's a modern fortran, built on the JVM. All operations are automatically parallelized.

9:42 clgv: hcumberdale: I remember that haskell is said to have pretty leight weight internal threads. maybe that avoids overhead.

9:42 cemerick: I'd point at the project's wiki, but it looks like they got migrated to java.net, so it's an impossible mess.

9:48 hcumberdale: Does anyone using clojure for real world projects?

9:48 What are your thougths about scala?

9:50 samaaron: so has anyone gotten avout working?

9:51 I'm getting a run-in-transaction exception when i try to get the example working

9:51 hhutch_: samaaron: I'm interested in hearing how people are going to use it

9:51 cemerick: hcumberdale: a small sample: http://dev.clojure.org/display/community/Clojure+Success+Stories

9:55 hcumberdale: Nice samples, thx cemerick

9:56 cemerick: of course, there's a lot more under the surface

9:56 hcumberdale: Are there tools to profile clojure performance and control flow?

9:56 cemerick: with some fiddling, standard JVM profilers work well with clojure codebases

9:57 yourkit is fairly popular; I've always had good results with the standard jvisualvm toolchain

10:05 jweiss-bbl: when a macro expansion includes a symbol is that symbol resolved in the ns where the macro is defined, or where it's expanded? (looks to be like the latter)

10:06 AWizzArd|work: Lein 1.6.2 ends in an NPE when doing "lein deploy" under Windows. I specified the "releases" and "snapshots" repos in :deploy-repositories. Ideas?

10:08 TimMc: jweiss: A bare symbol?

10:08 jweiss: TimMc: yeah

10:10 TimMc: i'm testing serializable.fn, which uses its own definition of fn. but the unit test tool test.clj uses deftest, which refers to fn. So i'm wondering if the test tool is producing "tests" with the new fn rather than core's.

10:10 TimMc: aha

10:10 So you may actually have an excuse to care. :-)

10:12 (let [x 100] (defmacro bare [& _] (list `+ 'x 3)))

10:12 (let [x 4] (bare)) => 7

10:13 Makes sense.

10:14 This is the opposite of capturing a symbol. What is it called?

10:15 DerGuteMoritz: TimMc: I think this is also referred to as capturing a binding

10:15 jweiss: TimMc: but you're doing all this in the same ns

10:15 DerGuteMoritz: jweiss: x is a local binding!

10:15 jweiss: you'd have to defmacro, then switch ns and 'use' x

10:15 yeah, my issue is not with locals, but def's

10:16 DerGuteMoritz: oh right, defmacro works on ns level only anyway

10:16 TimMc: Well, I think the same stuff applies -- the result of the macro contains an unresolved symbol.

10:16 (eval '(+ 3 3)) works just as well as (eval `(+ 3 3))

10:16 jweiss: TimMc: ok so it does do what i thought, the symbol is resolved in the ns where the expansion happens

10:17 TimMc: the call site of the macro, you might say

10:17 DerGuteMoritz: jweiss: is it clojure parlance to refer to a `let' binding as `ns'?

10:17 jweiss: so if for instance, fn points to serializable.fn/fn then deftest will expand to use that

10:17 DerGuteMoritz: well, a `let' scope

10:17 jweiss: DerGuteMoritz: ns = namespace

10:18 DerGuteMoritz: jweiss: yeah but `x' is not part of a namespace as in clojure namespace

10:18 jweiss: yeah

10:18 so it's not the same kind of example as mine

10:18 DerGuteMoritz: oh I didn't see the part of the discussion before TimMc's example

10:19 TimMc: jweiss: I think I see what you're getting at -- you *want* to (re-)resolve a symbol in the macro's namespace?

10:19 jweiss: hm, so this is rather complicated. who would have thought fn serialization would be so frought with complex issues

10:19 TimMc: heh

10:19 DerGuteMoritz: TimMc: these kinds of macros are also called unhygienic in case you didn't know

10:19 TimMc: very

10:20 jweiss: yeah, but clojure.test's macro isn't unhygenic

10:20 is hygenic i guess

10:22 DerGuteMoritz: jweiss: if it shadows a binding of the environment the macro is expanded it then it is unhygienic

10:22 jweiss: maybe i don't know the exact meaning of hygenic. if a macro expands to a bare symbol, that symbol could be made to resolve to *anything* depending on where the macro is expanded

10:22 DerGuteMoritz: s,expanded it,expanded in,

10:23 jweiss: yes, thus the explicit renaming with #

10:23 TimMc: jweiss: So... you are concerned that in serializeable.fn's test code, deftest may be pulling in core.fn?

10:23 DerGuteMoritz: oh wait, I may have gotten that one wrong

10:23 jweiss: TimMc: i think deftest is pulling in serializable.fn/fn

10:23 * DerGuteMoritz looks up how exactly macro expansion works in clojure again

10:23 TimMc: jweiss: Just do a macroexpand, yeah?

10:23 jweiss: which theoretically should be ok *if* serializable.fn/fn works, but that's what we're testing!

10:24 TimMc: aha

10:24 jweiss: clojure.test i guess didn't foresee that we'd be testing a different fn macro.

10:25 i guess we could get around this by not "use"ing in fn in the test script.

10:25 TimMc: jweiss: :exclude

10:26 I think that exists...

10:26 jweiss: TimMc: you mean refer-clojure :exclude?

10:26 it already does that to avoid the conflict with clojure.core/fn

10:26 i'm saying it should leave that alone so deftest won't use the wrong one

10:27 TimMc: jweiss: No, like (use '[clojure.string :exclude [replace reverse]])

10:27 jweiss: TimMc: oh, hehe there's only one var in the ns that is needed

10:27 TimMc: you could exclude serializeable.fn's fn

10:27 hah

10:27 jweiss: so if you exlcude it there's nothing left

10:28 crap, i think this is a real dilemma.

10:29 if i let fn refer to clojure.core, then the "round trip" testing of serialize/deserialize/serialize/deserialize will fail

10:30 if i let it refer to serializable.fn/fn, then deftest will be using the code it's trying to test.

10:35 ok, i tried just "require"ing serializable.fn, and using fully-qualified symbol fn, so deftest is happy, and the tests pass. so i guess that is the solution.

10:37 but i'm using serializable.fn in a differnt way than intended (which is for it to replace fn)

10:46 kzar: What's the literal equivilent for (keyword "hello world")? (I'm not sure how to type a keyword with a space.)

10:48 duck1123: you can't

10:49 that's why spaces in keywords are fun in #clojure, but not as great in real life

10:52 gtrak: so, say I want to make a DSL, how hard would it be to have a context-sensitive autocomplete facility based on the DSL? I'm thinking like declarative guis a-la mxml, though nicer because it's clojure :-).

10:54 duck1123: it's kind of a shame there is no XSD for clojure forms

10:55 jamiltron: What is XSD?

10:55 duck1123: There needs to be a documented protocol, where you can assign documentation a record's parts

10:55 gtrak: yea, maybe the rules engine would be useful for somethign like that?

10:55 duck1123: XSD is the structure language for xml

10:55 jamiltron: Oh thanks

10:56 gtrak: the dynamicity can work against you though

10:56 duck1123: now that I'm thinking about it, I'm not sure it would work.

10:58 gtrak: I'm just sad flex is dying :-(

10:58 duck1123: it might be kinda cool to have common html tag name completion for [:html ] forms

10:58 gtrak: there were really a lot of nice things about it

10:59 yea

10:59 the mxml approach wasn't too terrible actually

11:00 maybe could just write your stuff in xml and use CDATA for clojure forms :-)

11:01 http://www.sephiroth.it/test/flex/2/checkbox3state/bin/srcview/source/example.mxml.html

11:01 it looks ugly at first, but it's really easy to mess with and learn interactively

11:02 jodaro: flex is dying?

11:02 gtrak: it just got donated to apache a couple weeks ago

11:02 duck1123: I've been using closure templates in my personal project, and while it's nice, I have to save the file, and then go re-eval a coresponding template ns

11:02 gtrak: I'm guessing that means that adobe's not paying people to work on it

11:03 jodaro: oh

11:03 that'll slow it down, for sure

11:03 gtrak: duck1123, does that work for composing guis?

11:04 duck1123: there was an "apache considered harmful" article I read recently that was rather interesting

11:04 jodaro: i guess it depends on the project

11:04 but

11:04 i've had mixed experiences with apache stuff over the years

11:04 like

11:04 did thrift ever get a real release?

11:04 duck1123: gtrak: If I understand your question, you can break it down to a series of small templates and include them

11:05 TimMc: jweiss: I think :require is appropriate for serializeable.fn's testing.

11:05 jodaro: oh i guess it did finally

11:05 duck1123: gtrak: ex https://github.com/duck1123/jiksnu/blob/master/resources/soy/jiksnu/templates/activity.soy

11:05 jodaro: and i guess hadoop and friends have done well

11:06 duck1123: I hate their insistance on SVN

11:06 jweiss: TimMc: ok, it would appear that :use'ing it can have some unintended consequences. serializable.fn *should* be transparent

11:06 since all it does is add meta to the fn object

11:07 duck1123: I've been using the new Abdera 2 code, and when it breaks, I would totally make fixes if I had a git repo

11:07 gtrak: duck1123, I've been doing something similar with stringtemplate

11:08 duck1123: The promise of soy templates (that I haven't used yet) is that I can use these same templates in clojurescript

11:08 hhutch: duck1123: you can't just use git-svn ?

11:08 gtrak: oo, you can call functions from the template?

11:08 duck1123: hhutch: the messed up nature of their repo makes that impossible. I tried

11:08 gtrak: or is that another template? {call jiksnu.templates.user.linkTo data="$recipient" /}

11:08 hhutch: duck1123: fail

11:09 duck1123: You can't call out from the template, you have to keep view and data separate

11:09 gtrak: that's another template

11:09 gtrak: stringtemplate has some annoyances

11:09 i don't really like dynamic scoping

11:09 duck1123: the downside is I had to write special formatter function that converted my model to the limited set of types it supports

11:10 gtrak: doesn't it handle Maps?

11:10 duck1123: but it forces a strict "no logic in views"

11:10 hlship: Is there a link to Clojure's issue tracker anywhere on clojure.org?

11:10 gtrak: ~jira

11:10 clojurebot: to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks

11:11 duck1123: it handles map. it doesn't handle jodatime dates, Mongodb object ids, or even long

11:11 gtrak: ah

11:11 duck1123: wait, it might handle long

11:11 gtrak: does it just do toString?

11:13 duck1123: I don't believe so

11:15 gtrak: if so, you could just implement a new Object

11:16 duck1123: I really only have a few objects in my records it can't handle. When I first started youing it, my thought was "I'll just pass this whole map to the template and be done." not so. :(

11:16 rickmode: I though I saw yesterday that slime could examine a Java class. What was the key combination?

11:16 gtrak: C-S I O or something?

11:17 "technomancy_: leo2007: sure, just use C-S-i and enter a java class, it will list all the methods"

11:19 AWizzArd|work: $seen rhickey

11:19 lazybot: rhickey was last seen quitting 6 weeks and 6 days ago.

11:20 jweiss: I think 'C-c I' will inspect the class at point

11:21 rickmode: gtrak: thanks... it's not working for me though. At ^C-^S and ^C-S are both undefined

11:21 gtrak: I think C is actually the control button

11:22 rickmode: gtrak - it's the slime-inspect command. So ya.. it's Ctrl-C Shift-I

11:22 gtrak: ah ok

11:23 rickmode: gtrak - sweeeet... let time popping between my IDE and emacs

11:23 duck1123: rickmode: just so you know, that's usually written C-c M-l

11:23 er S-l

11:24 I never understood why Shift was more of an S than "super"

11:24 jweiss: C-c S-i

11:25 rickmode: duck1123: ah - the help (C-h m) uses ^C ⇧I and similar. I'm still like a yellow belt at my emacs-fu

11:30 gtrak: hmm, clojure forms schema, pattern matching?

11:36 rickmode: I've been looking for a good overview of what's new in Clojure 1.3. Things like the the newer ^static and ^inline metdata for defs and such.

11:38 duck1123: there's the changelog, but they don't get too in-depth

11:42 gfredericks: dnolen: I wasn't awake 11 hours ago, but I did run the included tests this morning and saw they all passed

11:43 dnolen: gfredericks: excellent

11:43 gfredericks: dnolen: I'll run mine real quick too just to be thorough

11:43 dnolen: great let me know and I'll cut another alpha

11:45 gfredericks: dnolen: all passing

11:46 dnolen: great

11:48 releasing alpha9 now

12:11 jcrossley3: hi, is there any way to define a multifn and declare that all existing multifns that would also match are preferred to it? (if that makes any sense)

12:12 essentially, a wildcard passed to prefer-method, i guess

12:13 michael_campbell: what does it mean to prefer > 1?

12:13 hiredman: if you call methods on a multifn you get back a map of dispatch values to fns, so you could build something like that

12:15 jcrossley3: hiredman: yes, i considered that, but i'm concerned about defmethods occuring *after* that.

12:17 i'd like my method to be a fallback in case a defmethod for *any* of a types ancestors hasn't been defined

12:18 michael_campbell: by "prefer > 1" i meant "prefer any methods defined over this one"

12:20 dnolen: jcrossley3: is that not satisfied by providing :default?

12:21 jcrossley3: dnolen: hmm... maybe! thanks :)

12:23 dnolen: YES! (thanks again) :D

12:28 michael_campbell: jcrossley3: Ah, I see. I was thinking more along the lines of "I prefer blondes", but am unwilling to narrow it down much further. ;-)

12:28 jcrossley3: :)

12:29 dnolen: jcrossley3: np

12:36 kzar: technomancy_: FYI I think this is a Heroku bug, I set a worker to be `worker: lein run -m app-name.worker/-main` which worked locally but on Heroku gave me an exception "Exception in thread "main" java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate _main__init.class or _main.clj on classpath". When I changed the Procfile to ommit the "/-main" it worked both locally and on Heroku

12:41 technomancy_: kzar: that sounds more like a Leiningen bug

12:41 did you end up getting it switched to 1.6.2 or are you still on 1.5.2?

12:42 kzar: technomancy: Hmm I added the buildpack to a different project, I'm not sure which is running on this project ATM but I haven't added a special buildpack

12:43 technomancy: oh, ok; if you haven't changed the buildpack it would be running on 1.5.2.

12:44 I know there were some improvements to the -main handling in 1.6; I'm not sure app-name.worker/-main was ever supported on 1.5.2

12:44 kzar: technomancy: Want me to add it and see if the problem persists?

12:44 technomancy: yeah, why don't you give it a go

12:53 kzar: technomancy: Yea, that fixed it

12:53 technomancy: sweet =)

12:53 kzar: Sorry, should have tried it before

12:55 technomancy: nah, it should be on by default for everyone

12:55 I'll see if I can get a few more people testing it and hopefully make it default next week

12:56 kzar: technomancy: Cool yea, I haven't had any trouble with it. Oh I wanted to ask, am I right in thinking workers are a process that gets left running all the time and can be used for processing things in the background?

12:56 technomancy: kzar: yeah, that's the general idea. usually pulling work off a queue or out of a DB, but not directly exposed to user requests over HTTP.

12:57 I'm working on a devcenter article on the topic.

12:57 konr: How can I use C functions in clojure?

12:58 kzar: technomancy: Cool throw it my way when you're done :) . Gotta run anyway, cya

12:58 technomancy: cheers

13:00 dnolen: konr: JNA or JNI

13:01 konr: dnolen: thanks!

14:01 gfredericks: dnolen: I just updated my deps to alpha-8, and everything looks good. Thanks for the quick fix!

14:04 daniel__1: can anyone tell me why `lein plugin install swank-clojure 1.3.3` is giving me:

14:04 Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.<init>(ILclojure/lang/Keyword;)V

14:05 gfredericks: daniel__1: last time I saw that technomancy said something about clojure 1.3 in the dev deps. No clue how/if that applies to your case though.

14:05 doesn't sound too related :/

14:06 daniel__1: hmmm ok

14:07 technomancy: it could be clojure 1.3 or it could be code compiled with clojure 1.3; one of those is sneaking into the Leiningen process where it doesn't belong

14:07 check dev-deps and user-level plugins

14:10 daniel__1: what am i searching for?

14:10 technomancy: daniel__1: just move your ~/.lein/plugins dir out of the way, and if it still breaks then the problem is in your dev deps

14:11 daniel__1: that did it

14:11 my only plugin was nailgun-server

14:11 duck1123: see if the clojure 1.3 jar is in lib/dev/

14:11 daniel__1: working now

14:12 thank yous!

14:13 beautiful, now i just need to learn how to use emacs

14:13 technomancy: just don't let it get in the way of clojure

14:14 daniel__1: i think all i need to know is how to move back and forward from the swank / code windows

14:14 buffers

14:14 frames

14:14 whatever they're called

14:15 duck1123: if you're using the starter kit shift + arrow

14:15 otherwise C-x o (for other)

14:16 daniel__1: C-x o :)

14:16 what starter kit?

14:17 amalloy: $google technomancy emacs starter kit

14:17 lazybot: [technomancy/emacs-starter-kit - GitHub] https://github.com/technomancy/emacs-starter-kit

14:25 daniel__1: how do i get the repl up if i open emacs again?

14:25 swank clojure is already running so jack-in fails

14:28 patrkris_: which HTTP client library are people recommending for clojure these days? clj-http? contrib.http.agent?

14:28 technomancy: clojurebot: http?

14:28 clojurebot: dakrone maintains clj-http

14:28 technomancy: ~botsnack

14:28 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack>

14:28 technomancy: =(

14:29 patrkris_: :)

14:29 hiredman: huh, thats new

14:30 Raynes: $botsnack because clojurebot couldn't get his doesn't mean you shouldn't get one.

14:30 lazybot: Raynes: Thanks! Om nom nom!!

14:32 gtrak: $botsmack

14:32 hiredman: ~botsnack

14:32 clojurebot: thanks; that was delicious. (nom nom nom)

14:33 Raynes: gtrak: He doesn't respond to violence thankyouverymuch.

14:33 gtrak: he just takes it quietly?

14:34 TimMc: clever bot

14:36 jweiss: is there a way to tell whether a fn call returns a lazy sequence (possibly infinite)? i'm writing a trace function, and when i attempt to trace a fn call like (iterate inc 1) it blows up obviously.

14:36 ,(class (iterate inc 1))

14:36 TimMc: ,(class (range))

14:36 clojurebot: clojure.lang.Cons

14:36 clojure.lang.LazySeq

14:36 jweiss: is (iterate inc 1) a special case?

14:37 or should i just consider Cons the same as LazySeq (don't try to print the return value)

14:37 gtrak: ,(class (iterate inc 2))

14:37 clojurebot: clojure.lang.Cons

14:37 gtrak: Cons is just a cons cell, value and ISeq for rest i think

14:38 it doesn't say anything about its laziness

14:38 jweiss: gtrak: right, but it could be infinite, which would blow up my trace fn

14:38 gtrak: right

14:38 or it could not be :-)

14:38 TimMc: jweiss: Then don't walk down it forever, I guess.

14:38 What is your "trace fn"?

14:39 jweiss: TimMc: https://github.com/weissjeffm/fn.trace/blob/master/src/fn/trace.clj

14:39 gtrak: private final Object _first; private final ISeq _more;

14:39 amalloy: jweiss: if printing it is what's hard, then bind ##(doc *print-length*) and let clojure handle it for you

14:39 lazybot: ⇒ "; *print-length* controls how many items of each collection the printer will print. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum number of items of each collection to print. If a collection co... https://gist.github.com/1419263

14:40 jweiss: amalloy: ah, that's a neat solution :)

14:40 thought i had already set that but I guess not

14:41 amalloy: i'm not sure if you saw the discussing this morning around serializable.fn

14:41 amalloy: no

14:41 jweiss: i think replacing fn with serializable.fn/fn isn't ideal

14:41 i know you did that so the double round trip test would work

14:42 but like the first serialization, any subsequent one should depend on whether the namespace uses serializable.fn/fn in place of fn

14:43 and even weirder, it turns out that clojure.test/deftest expands into fn. so deftest is using serializable fn, which is what it is supposed to be testing.

14:43 so i think that (:use [serializable.fn]) is bad in that test namespace.

14:43 daniel__1: i cant get my repl back after re-opening emacs

14:43 amalloy: no, yuck. if your namespace doesn't work properly unless the client :use-s your namespace, your namespace is broken

14:44 jweiss: amalloy: it still works properly when you just require it.

14:44 you just have to refer to it with the full name

14:45 https://github.com/weissjeffm/serializable-fn

14:45 amalloy: right, unless you make the serialization be fn instead of serializable.fn/fn

14:45 jweiss: that's what i did

14:45 the test namespace is doing really bad stuff otherwise

14:45 amalloy: uhh

14:46 jweiss: deftest expands into (fn ...)

14:46 which in that ns is serializable.fn/fn

14:46 amalloy: okay, so (a) deftest is a little broken, and (b) so what?

14:46 TimMc: Why does that mean deftest is broken?

14:46 jweiss: deftest is broken because it doesn't explicitly say clojure.core/fn ?

14:47 amalloy: yes. macros shouldn't expand to unqualified symbols unless they have a good reason

14:47 TimMc: ...

14:47 * TimMc goes checks

14:48 jweiss: amalloy: but your change to use serializable.fn/fn in the meta, that was so the tests would pass :)

14:48 and the tests fail because deftest is broken

14:48 amalloy: no it wasn't. i added that test

14:48 jweiss: oh

14:48 amalloy: it's because i wanted that feature

14:48 TimMc: amalloy: deftest uses `(fn ...)

14:48 jweiss: i forgot i pulled from your fork

14:49 amalloy: TimMc: i was taking jweiss's word for it that deftest expands to 'fn

14:49 in fairness though deftest is also broken in five or six other creative ways

14:49 TimMc: heh

14:49 jweiss: well in fairness to me, i did ask this channel if that is what was happening :)

14:50 technomancy: amalloy: the special casing of thrown? is particularly wacky

14:50 actually, that's c.t/is, but whatever

14:51 amalloy: technomancy: right, i'm referring to the way it plays hell with macros

14:51 jweiss: TimMc: actually you asked me if it was a bare symbol, i said yes but didn't notice it was ` instead of '

14:51 amalloy: like, you can't use macrolet around (or inside of iirc) a deftest

14:52 y3di: ,(conj [1 2 3] 4)

14:52 clojurebot: [1 2 3 4]

14:52 amalloy: because (deftest x (y z)) expands to something bizarre like putting (y z) into the *meta* of x instead of the body, and macrolet doesn't know to go look inside the meta

14:53 technomancy: what if c.j.shell had a sh! defn that threw exceptions on nonzero exit codes?

14:53 is that bang-abuse?

14:53 amalloy: technomancy: i prefer sh?

14:53 technomancy: but it's not a predicate?

14:53 amalloy: well i made that judgement in ten seconds, gimme a break if it's terrible

14:54 or, haha, call it "ohsh!"

14:54 duck1123: technomancy: I would find that useful (whatever it's named)

14:54 technomancy: amalloy: it's ok; the non-sequitur question mark reminded me of dinosaur comics, and I had some catching up to do.

14:55 y3di: how would i get all the items in a list except the last one?

14:55 clojurebot: Pardon?

14:55 amalloy: &(doc butlast)

14:55 lazybot: ⇒ "([coll]); Return a seq of all but the last item in coll, in linear time"

14:55 y3di: ty

14:55 joegallo: ,(doc drop-last)

14:55 clojurebot: "([s] [n s]); Return a lazy sequence of all but the last n (default 1) items in coll"

14:55 amalloy: dinosaur comics: leading advocate of wikipedia vandalism since, i dunno, a week or two agi?

14:55 joegallo: also

14:56 y3di: ,((fn revvv [x] (cons (first x) (revvv (butlast x)))) [1 2 3 4])

14:56 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.StackOverflowError>

14:57 ggherdov: Hi all. I've heard that Rich Hickey doesn't have a formal background in CS. that's quite impressive. does anybody know more of his bio?

14:57 gtrak: ggherdov, what's a formal background? :-)

14:57 ggherdov: ok. I mean: he didn't do CS at college.

14:57 gtrak: you mean like a degree?

14:58 ggherdov: yeah.

14:58 foodoo: there was a paper on C++ types that he wrote a long time ago...

14:58 gtrak: he did music composition

14:58 y3di: ,(butlast [1])

14:58 clojurebot: nil

14:58 cemerick: He taught C++ at some college in NYC for a while. *shrug*

14:58 ggherdov: what I wander is: how did he became that good,

14:58 foodoo: practise

14:58 gtrak: as far as I can tell, he reads a LOT

14:59 ggherdov: foodoo: a pointer to that paper? pun intended :)

14:59 duck1123: I know he worked with a lot of realtime systems. voting machines?

15:00 foodoo: ggherdov: It was mentioned in a talk. I'll check if I can find that talk

15:00 ggherdov: it was mentioned right at the beginning

15:01 duck1123: it was one of the really old ones

15:01 y3di: ,(cons 1 1)

15:01 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

15:01 ggherdov: I mean, realtime systems. That's hardcore stuff. How can you get involved in such a career w/o training.

15:01 gtrak: he was an independent consultant for 15 years?

15:01 ggherdov: foodoo: thx

15:01 gtrak: or more?

15:01 duck1123: no formal training != no training

15:01 gtrak: ggherdov, it's really not that hard, 3-5 years of deliberate study and you can do lots of things

15:01 Borkdude: isn't it a bit ugly that when you want to "use" core.logic, you have to exclude == ?

15:01 ggherdov: duck1123: sure. but 'formal' is somehow easier to get.

15:02 y3di: ,(butlast [1 2])

15:02 ggherdov: gtrak: sure, but if you have a day job, time is an issue.

15:02 clojurebot: (1)

15:02 ggherdov: \energy too.

15:03 duck1123: what formal training have you had in clojure, you know clojure because you had a desire to learn it.

15:03 was anyone here forced to use clojure?

15:03 y3di: (cons 1 nil)

15:03 ,(cons 1 nil)

15:03 clojurebot: (1)

15:03 ggherdov: duck1123: i see the point, but i was trained to haskell, caml and stuff.

15:03 TimMc: y3di: You can /msg the bots

15:04 y3di: alright, will do

15:04 gtrak: ggherdov, if you do 15% more studying than the average programmer, you'll learn twice as much every 5 years

15:05 or something like that :-)

15:05 joegallo: not quite, i think, but it's a nice idea

15:05 daniel__1: i cant get my repl back after re-opening emacs (swank-clojure) heeeelp

15:05 TimMc: Only a couple of my college courses actually helped me become a better programmer.

15:06 duck1123: daniel__1: M-x slime-connect

15:06 Borkdude: formal training can set you on the wrong path for a long time ;)

15:06 technomancy: daniel__1: if you started swank via jack-in, then the swank server will not outlast emacs

15:06 zakwilson: https://gist.github.com/1415370 <-- ClojureQL seems to be generating unreasonable output here in terms of the order of the joins. Changing the order in the Clojure code doesn't affect the order in the SQL it emits.

15:06 daniel__1: hmm technomancy, ok

15:07 zakwilson: Though if I'm just doing something dumb, I'd like to know.

15:07 duck1123: I think my favorite was the class I took on C++ data structures. I was just getting into my love of Clojure and learning exactly how things like vectors and sets were supposed to work really helped

15:07 daniel__1: error in process filter: error during connect: connection refused

15:07 it worked the first time, now it won't open up

15:08 gtrak: compilers was enlightening for me

15:08 Borkdude: Common Lisp was enlightening for me, but it wasn't taught at my CS faculty

15:09 foodoo: ggherdov: found it! http://blip.tv/clojure/michael-fogus-fertile-ground-the-roots-of-clojure-4519764 (The quote on C++ from Rich's paper is pretty much at the beginning)

15:09 And I really love the way the Clojure community does presentations :D

15:09 Borkdude: The first programming course we got was a functional programming course though

15:10 Miranda

15:10 foodoo: at university? We had Haskell

15:10 Which is a great language but a bad choice if you want to foster enthusiasm in students when it comes learning how to programming

15:11 dnolen: gfredericks: np

15:11 gtrak: i had the scheme class freshman year, i didn't pay too much attention to it but i think it might be responsible for the initial mind-warp

15:11 sadly they're on python now

15:11 jweiss: looking back on my 'formal training' in CS, we used Turing, Java, Perl, C. the only one that's a good learning experience IMO is C.

15:12 duck1123: I wonder how well Clojure does as a introductory level when people have no pre-conceived OOP or procedural notions

15:12 foodoo: jweiss: in the context of your studies at your university?

15:12 Borkdude: maybe Haskell was a bit too new in 99, I don't know why they chose Miranda, I've never used it since

15:12 duck1123: me 2..

15:12 jweiss: foodoo: no, in general, but even in the context of the classes

15:13 gtrak: duck1123, drscheme had various settings of having to know about details, it was helpful, there was a beginner mode

15:13 i think freshmen wouldn't handle clojure's stack traces well

15:14 foodoo: true

15:14 jweiss: scheme would have been a much better choice for first language. i started with BASIC :)

15:14 zakwilson: Yeah, those aren't user-friendly.

15:14 jweiss: not that my commodore 64 had a scheme interpreter.

15:14 foodoo: My personal recommendation as a first language is Lua. It's simple, elegant but not useless.

15:15 aphyr: Having some trouble with the protobuf library. I've added it as a dep in cake, I've got a protobuf-0.5.0-beta4.jar file on my project classpath, but cake test throws "could not locate protobuf__init.class or protobuf.clj".

15:15 jweiss: i once saw a review of langauges based on speed and conciseness, lua won hands-down

15:15 gtrak: I remember scheme just took forever to write, it was demoralizing :-) 6 hours and all you get is 5 lines and a ton of parentheses

15:15 aphyr: Any ideas?

15:15 daniel__1: technomancy: can i get swank-clojure to open automatically when it detects a clojure file? rather than typing clojure-jack-in each time

15:15 mco_: Hi all, I am trying to read a binary file but I am having an issue with signed/unsigned byte..... I need to read at any offset in the file for n bytes. Is there an idiomatic way to do that ?

15:15 Borkdude: the idea that code itself was data really made sense to me, it is an idea so simple, yet brilliant, I still remember when I first discovered Lisp and loved it ever since

15:15 duck1123: I still have my Atari XE. Had to leave it running because I didn't have the tape drive

15:15 technomancy: daniel__1: you could write a hook for that, sure. the start-up time is significant enough that I'd find it annoying to have it invoked automatically personally, but it's possible

15:16 daniel__1: hmm, yeah good point

15:16 jweiss: gtrak: 6 hours of 'find the missing paren'?

15:16 mco_: I am currently using RandomAccessFile. and reading in a byte-array....

15:16 duck1123: I'd love to have the hook that emacs should reconnect and retry if I try to do a slime command and it fails

15:16 gtrak: dude, I got like a 98 in the class, and I remember it took me forever. the insertion sort is forever burned in my retina

15:17 daniel__1: finally my repl came back anyway

15:17 dont know what happened there

15:17 gtrak: jweiss, I think a lot of people would just cheat

15:17 * ggherdov the irc server kicked me off. what?

15:18 foodoo: ggherdov: did you receive the link to the video?

15:18 ggherdov: foodoo: no.

15:18 I got disconnected,

15:18 didn't mean to be rude.

15:18 foodoo: http://blip.tv/clojure/michael-fogus-fertile-ground-the-roots-of-clojure-4519764

15:18 ggherdov: thx

15:19 foodoo: (downloadable with cclive if you don't like flash)

15:19 daniel__1: the repl seems to load in the user namespace, can't i have it load into the current files namespace?

15:19 gtrak: how does the repl know what file you're in?

15:19 duck1123: C-c M-p

15:20 gtrak: neat

15:20 ggherdov: foodoo: cclive ? what's that?

15:20 foodoo: A video downloader

15:20 ggherdov: ok

15:21 daniel__1: duck1123: Command attempted to use minibuffer while in minibuffer

15:22 mco_: :) has anybody done that before ? reding n bytes from an offset in a binary file ? Please ?

15:22 have been googling for ages

15:23 can't be that hard right ?

15:23 raek: mco_: you generally use the Java classes for IO

15:23 duck1123: daniel__1: you already were doing a command when you tried that. hit escape a bunch of times

15:23 raek: RandomAccessFile is good for this

15:23 mco_: @raek: thanks, that is what I did

15:23 I used RandomAccesFile. .skipBytes .read etc

15:24 but the unsigned/signed thing limitation for byte-array is driving me nuts

15:24 duck1123: daniel__1: C-g will also break out of stuff in most cases in emacs

15:24 mco_: first byte outside the limits causes an error

15:24 raek: on the JVM signed and unsigned bytes are stored in the same type

15:24 _ulises: hello all

15:24 mco_: user=> IllegalArgumentException Value out of range for char: -96 clojure.lang.RT.charCast (RT.java:907)

15:25 this is the error I get

15:25 raek: mco_: a character is not the same thing as a byte

15:25 mco_: ahhh sorry, I am a beginner :) surely it is a dumb error :)

15:25 I am using (.read file x 0 n)

15:25 to read in a byte-array

15:26 I allocate before

15:26 daniel__1: duck1123: i lost the repl buffer by pressing escape but i think its still running. how can i get it back?

15:26 gtrak: C-x b

15:26 mco_: (defn read-n-ofs [f n offset func]

15:26 "Reads n bytes from file f at offset and apply func"

15:26 (with-open [file (RandomAccessFile. f "r")]

15:26 (.skipBytes file offset)

15:26 (let [x (byte-array n)]

15:26 (.read file x 0 n)

15:26 (func x))))

15:26 sorry guys

15:27 daniel__1: thanks gtrak

15:27 raek: mco_: ok looks fine (use http://gist.github.com/ next time). you can also use the .seek method

15:27 duck1123: I hightly recommend creating a binding for M-x slime-selector. I have it bound to C-c s so my repl ic C-c s r

15:27 raek: but that .read call should give you an array of n bytes

15:27 gtrak: daniel__1, also check out M-x describe-bindings

15:27 _ulises: duck1123: I think with C-c C-z it jumps to the repl buffer

15:27 TimMc: gtrak: What school did you go to?

15:27 gtrak: georgia tech

15:28 raek: or more accurately: up to n bytes

15:28 daniel__1: having the same problem starting swank again now :(

15:28 clojure-jack-in-sentinel(#<process swank> "exited abnormally with code 129\n")

15:28 duck1123: _ulises: not for me

15:28 gtrak: TimMc, i think we just do whatever MIT does

15:28 :-)

15:28 mco_: raek: but the first byte that is outside signed values causes the Exception I have noticed

15:28 gtrak: but i didn't get a CS degree

15:28 _ulises: duck1123: interesting; that's the binding I get in my clojure-mode

15:29 duck1123: _ulises: I take that back. I had to be on a clojure-mode buffer. The slime selector route is global

15:29 raek: mco_: what do you do with the bytes? to me it does not seem that the error is in the read-n-ofs function

15:29 _ulises: ah!

15:29 y3di: can anyone help me figure out whats wrong with this:

15:29 ,((fn revvv [x] (cons (last x) (revvv (butlast x)))) [1 2 3])

15:29 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.StackOverflowError>

15:30 mco_: raek: I use func to post-process whatever I have read ( build a string or calc an integer value)

15:30 duck1123: y3di: I think you want to wrap that in lazy-seq

15:30 mco_: raek: #(apply str (map char %)) to get a string for example

15:30 raek: mco_: the exception you mentioned means that you are trying to turn a byte into a char incorrectly

15:31 mco_: raek: ah okay, here is the error : (make-byte-array [1 210 3] )

15:31 TimMc: gtrak: Ah, makes sense. I know that MIT switched from Lisp/Scheme to Python for intro, but I didn't think they had used DrScheme before. :-)

15:31 raek: mco_: you should use the classes in java.nio.charset to convert bytes to strings

15:32 mco_: raek: aah thanks !! I will investigate this

15:32 y3di: duck1123: wrap the revvv function in lazy-seq?

15:33 duck1123: i

15:33 duck1123: i'm new to clojure so excuse my lack of understanding

15:33 daniel__1: duck1123: i get Package: evolve.core [no match] when i try and go to this namespace :(

15:33 TimMc: mco_: Why does your function take a function? Just compose.

15:33 easier to test and understand

15:34 duck1123: y3di: I'm having a hard time figureing out why that's overflowing in my head. one sec

15:34 raek: mco_: you first need to create a Charset instance for the encoding your text is in (def charset (Charset/forName "UTF-8"))

15:34 mco_: TimMC: thanks ! I'll look it up

15:34 duck1123: daniel__1: the namespace needs to be required first. C-c C-k to load that file

15:34 raek: mco_: then you can use .decode or .newDecoder

15:34 daniel__1: C-c C-k is undefined

15:34 gtrak: TimMc, yea, the CS and computer engineering guys took the scheme class, other engineerings took matlab.

15:35 daniel__1: sorry, was in wrong buffer

15:35 raek: mco_: these methods also require the input and outputs to be ByteBuffers and CharBuffers

15:35 daniel__1: gotchaaa

15:35 TimMc: mco_: No, I mean just use good ol' function composition. (func (read-n-ofs ...)) is better than (read-n-ofs ... func).

15:36 raek: mco_: but there is also a more minimal way: (String. the-byte-array "UTF-8")

15:36 duck1123: y3di: try checking if x is not empty (when (seq x) (cons ...

15:36 mco_: TimMC: in fact I defined two other functions on top of that one that build either a string or an integer

15:36 raek: just replace "UTF-8" with whatever the encoding of your text file is

15:37 duck1123: y3di: it's recursively (and not the good kind) calling itself even when there are no more elements in the list

15:37 TimMc: mco_: OK, but it's not as clean.

15:38 mco_: raek: ok, thanks !

15:38 duck1123: y3di: generally, you would want this sequence to be lazy, so you would wrap this whole thing in a lazy-seq, and then check that there are still items left and return the cons cell, that way this whole thing will be lazy

15:38 daniel__1: is there an equivalent for cycling through repl history like using the arrow keys in the terminal?

15:39 duck1123: M-p M-n

15:39 those are two commands

15:40 daniel__1: aaah great :)

15:40 duck1123: if you start typing a command and then do that, it'll cycling through matching lines

15:42 TimMc: daniel__1: Analogous to C-p and C-n

15:42 raek: ,(String. (byte-array (map byte [72 101 108 108 111 32 47 32 -50 -109 -50 -75 -50 -71 -50 -84 32 -49 -125 -50 -79 -49 -126])) "UTF-8")

15:42 clojurebot: "Hello / Γειά σας"

15:42 Borkdude: Why doesn't this work? (refer '[clojure.core :exclude [==]])

15:42 foodoo: I wonder how much new stuff I will learn from "The Joy of Clojure" after having read "Programming Clojure". Is the first book much more advanced than the latter?

15:43 raek: Borkdude: you need to do it like this: (ns foo.bar (:refer-clojure :exclude [==]))

15:43 mco_: raek: cool! but change one value to , say, -166 and *boom*

15:43 TimMc: Borkdude: It's too late, you've already included all of core.

15:43 y3di: ty duck1123 i finally got it, im sure my method could be alot better tho for reversing a seq

15:43 raek: mco_: what do you mean?

15:43 y3di: ,((fn revvv [x] (cons (last x) (if (not (nil? (butlast x))) (revvv (butlast x)) nil))) [1 2 3])

15:43 clojurebot: (3 2 1)

15:44 Borkdude: TimMc: not if I didn't use clojure.core right?

15:44 raek: mco_: you will never get a -166 from a byte

15:44 TimMc: Borkdude: (ns) does it automatically

15:44 raek: mco_: since bytes are from -128 to 127

15:44 TimMc: &(byte 166) ; mco_

15:44 lazybot: java.lang.IllegalArgumentException: Value out of range for byte: 166

15:44 Borkdude: TimMc: raek I'm on a repl here, so I don't want to type (ns ...)

15:45 doing the examples of https://github.com/clojure/core.logic

15:45 mco_: raek: yes , that's what I'm having a hard time getting used to it seems :)

15:45 duck1123: y3di: it's recommended to prefer (seq coll) over (not (nil? coll))

15:45 TimMc: Borkdude: Whatever set up your REPL already pulled in core. refer can only add stuff.

15:45 mco_: raek: I gotta read more and understand that charset business

15:45 raek: Borkdude: (remove-ns 'foo.bar) (in-ns 'foo.bar) (refer-clojure '(:exclude [==]))

15:45 Borkdude: TimMc: then how could the example work ;)

15:47 raek: mco_: the jvm is a bit weird in that bytes are represented as a value between -128 and 127 instead of between 0 and 255. you can easilly get to the latter from the former like this: (bit-and some-byte 0xff)

15:47 duck1123: y3di: IIRC (not (nil? coll)) is esentially (not (not (seq coll)) and that's just a waste

15:47 raek: ,(bit-and -127 0xff)

15:47 clojurebot: 129

15:47 Borkdude: raek: still getting the errors, seems to me the example is just not the good way anymore?

15:48 TimMc: duck1123: That's not true for collections in general.

15:48 gtrak: are atoms slow?

15:48 TimMc: not + nil? is cheaper than seq, but seq is *correct*

15:49 raek: Borkdude: you can't you use ns in the repl?

15:49 Borkdude: raek: I can, I'm just not used to

15:49 duck1123: TimMc: Im'm thinking of (not (empty? ))

15:49 raek: Borkdude: another approach could be to do (ns-unmap *ns* '==)

15:50 mco_: :raek + TimMC : *thanks* guys ! I will be programming and reading now ... :)

15:50 raek: if you are in an already existing namespace (like user)

15:50 mco_: a charset defines how bytes correspond to characters.

15:51 Borkdude: raek: I guess (ns my-logic (:refer-clojure :exclude [==])) does it then.

15:51 iLeNsTR: b

15:51 gtrak: $(doc assoc)

15:52 raek: mco_: for instance, what is/are the bytes(s) for the letter "ä"? it depends on which charset that byte stream has.

15:52 mco_: :raek: I got it to work by replacing the last line of that function with (func (map unsigned-byte x))

15:53 raek: looks like str was the cuplrit ...

15:53 raek: in a file that uses ISO 8859-1, "ä" is encoded as the byte 0xE4, but in a UTF-8 file it is encoded as 0xC3 0xA4

15:53 gtrak: i like that rich hickey uses for(; ;), i feel vindicated :-)

15:54 did you guys know java has a do-while?

15:54 raek: mco_: are you turning a byte array into a string without specifying a charset? if so, your code is (probably) broken.

15:56 y3di: ,(doc seq)

15:56 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

15:56 raek: mco_: if your byte array is called "byte-array", then just use (String. byte-array "UTF-8")

15:58 TimMc: duck1123: yup

16:01 y3di: into works differently for vectors and lists?

16:01 TimMc: y3di: Just like conj.

16:02 hiredman: y3di: into uses conj

16:02 ,(conj '(1 2 3) 4)

16:02 clojurebot: (4 1 2 3)

16:02 hiredman: ,(conj [1 2 3] 4)

16:02 clojurebot: [1 2 3 4]

16:02 Borkdude: hmm, now when I evaluate moveo it complains about the symbol pos not able to resolve

16:03 y3di: ok thanks

16:21 TimMc: It is my reasoned conclusion that having first, rest, next, and cons call seq on their argument is just plain confusing to newcomers.

16:21 It hides the fact that an API boundary is being crossed.

16:22 tsally: is there a fucntion to call a function on a arg, and then call the function again on the result, n times ?

16:23 duck1123: TimMc: it would be chaos without though

16:23 TimMc: tsally: iterate, I think

16:23 or similar

16:23 y3di: is there a way to get clojurebot to understand multiline queries?

16:23 i doubt it, but i figured id ask

16:24 TimMc: duck1123: Lots more if-lets and other extra calls to seq, eh?

16:24 duck1123: y3di: I think the assumption is if you can't fit it on a line, then it should be a gist

16:24 y3di: gist?

16:24 TimMc: ~paste

16:24 clojurebot: paste is http://gist.github.com/

16:25 TimMc: but that's if you're trying to demonstrate something to someone on the channel

16:25 y3di: If you want to just find the result, download Leiningen and run "lein repl".

16:26 duck1123: y3di: also tryclj.com

16:27 TimMc: Ooh, that too.

16:27 * Raynes blushes.

16:27 y3di: right

16:27 https://gist.github.com/8d4e4bd76669846874c7

16:28 TimMc: $mail alexbaranosky It just occurred to me, a good project for the meetup would have been to write a "try-cljs" website.

16:28 lazybot: Message saved.

16:28 y3di: that works for [1 2 3 2 1] but not for "racecar"

16:28 anyone knows how I can fix it? I tried to call seq on racecar so that it changes it to a list, but my function still errors out

16:29 hiredman: y3di: your function isn't properly recursive, and (seq [x]) is always true, so your if is badly written

16:30 TimMc: y3di: Technically, it seq provides a sequence over the string, it doesn't convert it.

16:30 y3di: ,(if (seq []) true false)

16:30 hiredman: D

16:30 clojurebot: false

16:30 gtrak: whoa, lazybot does messages?

16:30 Raynes: He does a lot of things people don't know about.

16:31 hiredman: I didn't say (seq []) I said (seq [x])

16:31 which is what you have in your if

16:31 ,(booealn (seq [nil]))

16:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: booealn in this context, compiling:(NO_SOURCE_PATH:0)>

16:31 gtrak: Raynes, I had already decided he was awesome so I stopped exploring

16:31 Raynes: Heh

16:31 hiredman: ,(boolean (seq [nil]))

16:31 clojurebot: true

16:31 hiredman: ,(boolean (seq [:foo]))

16:31 clojurebot: true

16:31 hiredman: ,(boolean (seq [false]))

16:31 clojurebot: true

16:32 hiredman: ,(boolean (seq [true]))

16:32 clojurebot: true

16:32 hiredman: etc, etc, etc

16:32 gtrak: $fortune

16:32 lazybot: I have no fortune cookies. Please feed me some!

16:32 y3di: hmm, ok someone earlier said I can use (seq [x]) to check if a list is empty or not

16:32 Raynes: That plugin is going away.

16:32 TimMc: hiredman: I imagine you saying that in the voice of that character from The King and I.

16:32 gtrak: ah, sad

16:33 TimMc: ~#3

16:33 clojurebot: 3. Syntactic sugar causes cancer of the semicolon. -- Alan J. Perlis

16:33 Raynes: There are a bunch of bastardized plugins that could just be replaced with a decent factoid system.

16:33 TimMc: Raynes: ^ that feature is a tiny bit tricky to use over SSH.

16:33 hiredman: y3di: someone was wrong

16:33 or you misread what they said

16:33 y3di: yea alright

16:33 Raynes: TimMc: I have no idea what you just said.

16:33 hiredman: I am inclined to believe the latter

16:34 duck1123: hiredman: it was a little of both :(

16:34 gtrak: javabot's system seems simple enough

16:34 TimMc: Raynes: Are you connected over SSH?

16:34 Raynes: To what?

16:34 TimMc: Ah. You are not using a command line IRC client.

16:34 Raynes: God no.

16:35 TimMc: Raynes: <Enter>, [~] is the SSH escape sequence. Typing <Enter> [~] [#] prints a list of connections. :-)

16:35 Raynes: Irssi gives me diarrhea.

16:35 tscheibl: @Raynes: and u don't even use emacs or vi?

16:35 Raynes: tscheibl: I do use Emacs.

16:35 rickmode: Why does (def foo ^{:name "Foo!"} [1 2 3]) work but (def foo ^{:name "Foo!"} (list 1 2 3)) not work?

16:35 duck1123: ,(boolean (seq []))

16:35 clojurebot: false

16:36 Raynes: I don't use it in a terminal.

16:36 tscheibl: isn't there e irc plugin for emacs?

16:36 hiredman: rickmode: what does '^' do?

16:36 tscheibl: ah xirc

16:36 duck1123: tscheibl: M-x erc

16:36 technomancy: tscheibl: there are four or five

16:36 only two built-in though

16:36 tscheibl: thought so

16:37 Raynes: erc never worked very well for me.

16:38 y3di: so I got rid of the (seq [x]) check and used empty instead but i still have the same problem

16:38 https://gist.github.com/8d4e4bd76669846874c7

16:38 rickmode: hiredman adds metadata to an object: http://clojure.org/reader

16:38 y3di: it works with the first but not the second

16:38 hiredman: rickmode: what object?

16:39 a related question would be, why does ^:foo [1] add the metadata to the vectore, but ^:foo '[1] doesn't

16:40 rickmode: hiredman: in this case the vector or list. (meta foo) returns the metadata map for vector, but not the list

16:40 hiredman: which vector or list? where do they come from?

16:40 tscheibl: y3di: u mena "empty?" ?

16:40 _ulises: y3di: what does (first (seq ["racecar"])) return?

16:40 tscheibl: mean

16:41 _ulises: y3di: hint, line 13 is your problem

16:41 rickmode: I'm creating a def for a list

16:41 _ulises: or more like 11 and 3 too

16:41 hiredman: but there are really two lists there, right?

16:41 rickmode: in this case it's contant (a list of agents i'm using elsewhere)

16:42 hiredman: the list (list 1 2 3) and the list (1 2 3)

16:42 which one are you checking for metadata? and which one is available for the reader to attach metadata to?

16:43 y3di: oh wow, ty _ulises

16:43 _ulises: y3di: no worries :)

16:43 rickmode: hiredman: you've lost me. (list 1 2 3) returns the list (1 2 3). (1 2 3) attempt a function call on 1 with params 2 3.

16:44 hiredman: right, but this is lisp right? so (list 1 2 3) is a list too, right?

16:45 so you have two lists there, (list 1 2 3) ;; the list the reader creates and (1 2 3) ;; the list the function call results in

16:46 rickmode: I'm assuming with (def a (b c d)), a will be a ref to the result of evaluating (b c d)

16:46 hiredman: in light of the fact there are two lists, which one are you checking for metadata?

16:46 correct

16:46 rickmode: I want to add metadata such that (meta a) returns it

16:47 hiredman: so you have a (list 1 2 3), which the compiler sees as a function call and generates a call to the function list with the arguments 1 2 3, the result of which is (1 2 3)

16:47 so you have two lists, (list 1 2 3) and (1 2 3), which one are you checking for metadata?

16:48 TimMc: hiredman: May I ask a spoiler-ish question?

16:49 rickmode: the list (1 2 3) is what I want.... so the question is... when does the reader attach the metadata? it's not clear

16:49 hiredman: when can it?

16:50 why does ^:foo [1] add the metadata to the vector, but ^:foo '[1] doesn't

16:50 mefesto: ,(doc with-meta)

16:50 clojurebot: "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."

16:50 rickmode: My mental model of Clojure tells me.. after evaluating the expression, before asigning to the Var

16:50 hiredman: the reader is not the evaluator is it?

16:50 rickmode: "Metadata (^) Symbols, Lists, Vector, Sets and Maps can have metadata, which is a map associated with the object. The metadata reader macro first reads the metadata and attaches it to the next form read: ^{:a 1 :b 2} [1 2 3] yields the vector [1 2 3] with a metadata map of {:a 1 :b 2}."

16:51 So that a bit misleading

16:51 hiredman: how so?

16:51 y3di: _ulises: so (first (seq ["racecar"])) returns "racecar" which would be an issue, but based on my code, I don't think i ever call (seq ["racecar"]) its only (seq "racecar")

16:51 hiredman: (1 2 3) is not the form that is read

16:51 rickmode: ^{:name "hi"} (list "hi") doesn't work

16:51 hiredman: (list 1 2 3) is the form that is read

16:51 y3di: unless im misunderstanding something

16:51 _ulises: y3di: are you sure? your fn takes a parameter x and then you call (seq [x])

16:51 rickmode: but ^{:name "hi"} ["hi"]

16:51 does

16:52 hiredman: ["hi"] is the form that is read

16:52 rickmode: right

16:52 I'm getting what you're saying

16:52 however

16:52 hiredman: no, you don't

16:52 y3di: _ulises: yea, but the x that it takes is "racecar"

16:52 not ["racecar"]

16:52 rickmode: Should be : Metadata (^) Symbols, Lists, Vector, Sets and Maps can have metadata, which is a map associated with the object. The metadata reader macro first reads the metadata and attaches it to the next form read: ^{:a 1 :b 2} [1 2 3] yields the vector [1 2 3] with a metadata map of {:a 1 :b 2}..... But you cannot use ^ with Lists

16:52 _ulises: y3di: yes, so you end up calling (seq ["racecar"])

16:52 hiredman: ,(read-string "^{:n 1} (list 2)")

16:52 clojurebot: (list 2)

16:53 hiredman: ,(meta (read-string "^{:n 1} (list 2)"))

16:53 clojurebot: {:n 1}

16:53 hiredman: rickmode: that is not true

16:53 dnolen: rickmode: attaches it to next *form*, not what the next form evaluates to.

16:53 hiredman: ,(meta ^{:n 1} (list 2))

16:53 clojurebot: nil

16:53 rickmode: sure... and so ^ won't do anything useful with a list

16:53 TimMc: rickmode: [1 2 3] is a literal vector. (list 1 2 3) is a function call that produces a list.

16:54 literals evaluate to themselves.

16:54 rickmode: ,(meta {:n 1} [2])

16:54 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$meta>

16:54 rickmode: ,(meta ^{:n 1} [2])

16:54 clojurebot: {:n 1}

16:56 TimMc: rickmode: ^ is used for handing metadata to the compiler -- you don't generally get access to that metadata at runtime.

16:56 with-meta is the safe way to attach metadata to runtime values

16:57 so... it's not really a problem that it is awkward to attach metadata to a list literal.

16:57 rickmode: TimMc: now that makes sense

16:57 hold on while I reattaches the bits of my exploded head. Thanks guys.

16:58 TimMc: Just because ^{:n 1} [1 2 3] leaks down to the runtime doesn't mean you should rely on it. :-)

16:59 (Homoiconicity makes it easy to confuse the levels.)

17:00 rickmode: TimMc: that "^ is normally used to pass metadata to the compiler; with-meta is idiomatic when added metadata to your own objects" tip *could* be mentioned on the clojure.org/reader page.

17:00 TimMc: rickmode: Many things could. :-(

17:01 rickmode: TimMc: word... the clojure.org bits and the API docs are genearlly useful if you know what you're doing. They dont' really stand alone.

17:02 TimMc: I have many complaints about the doc. I should really open a ticket...

17:03 rickmode: Heh... If I complain much more I'd feel obligated to get off my butt and participate... :P

17:05 TimMc and hiredman: so ya.. I need a better mental model of reader-time vs evaluation-time

17:06 TimMc: So do I!

17:06 Clojure also complicates that a bit by doing on-the-fly compilation.

17:07 rickmode: Which is pretty fly

17:08 gfredericks: it's read vs compile vs execute, in my head

17:08 so compile time is when macros get "run"

17:08 rickmode: aren't here really only 2 stages?

17:08 at least logically

17:08 gfredericks: I think it's confused because the compiler can be used at runtime

17:08 gtrak: rickmode, you'll notice there's an init class generated for each namespace, that should be helpful to think about

17:09 rickmode: read time and execute time? compiling is somewhat invisible

17:09 gfredericks: e.g. calling eval invokes the compiler I think

17:09 rickmode: I think distinguishing compile from execute helps understand what macros can and can't do

17:09 rickmode: ya - I know if you put non-def forms in a file, those will be evaluated / executed when you load/use/require the file

17:09 gfredericks: people often want to "apply" a macro

17:10 gtrak: if you run eval, it has to create new classes and load them

17:10 before it can actually execute the code

17:11 rickmode: so in a sense def are not magically - they are "executed" in the order they appear in the file. And thus you can't refer to something defined later in the file (unlike Java)

17:11 gtrak: when you type (defn ...) in a file, you're telling it to create a class for the function, and the init class for the namespace will bind an instance of that class to the var

17:13 duck1123: that's also the reason you can't have circular dependencies in your namespaces

17:13 gtrak: rickmode, that's the dynamic binding, but there's also a more static way, I'm not clear on the details

17:13 rickmode: you can use declare to get circular refs

17:13 gtrak: things can get inlined

17:14 and compiling a ns will compile all the other ns's it depends on

17:15 rickmode, so here's a gotcha, create 2 namespaces in two files, create a fn in 1st that refers to a fn in 2nd, change the 2nd and recompile it, the 1st will still refer to the original function

17:16 if you want the lookup to be dynamic, you have to use (var or #'

17:16 or recompile the 1st namespace too

17:22 TimMc: rickmode, gtrak: It's not defn that creates classes so much as it is fn.

17:23 rickmode: gtrak: I seem to hit redefinition snags doing remote debugging

17:23 gtrak: TimMc, yup

17:24 TimMc: and really fn*

17:24 rickmode: I have my slime connected to a remote machine.. I can use C-c C-k

17:24 gtrak: it's important to superficially know about classloaders when you're talking about this stuff

17:24 rickmode: sorry I can't use C-c C-k

17:27 gtrak: that cadaddadr macro is awesome :-)

17:28 amalloy ^

17:28 amalloy: gtrak: not my original idea, of course, but pretty easy to implement

17:28 gtrak: it's some deep magic nonetheless

17:29 i never thought about encoding semantics into a string and pulling it out with a regex

17:30 TimMc: gtrak: That's probably a good indicator re: your sanity.

17:30 gtrak: necessary but not sufficient to prove sanity :-)

17:30 technomancy: rickmode: that mostly has to do with filename translation IIRC

17:31 easy way out is to use C-c C-r

17:33 amalloy: yes, it's filename issues: such a pain. maybe i'll bind C-c C-l back to slime-eval-buffer

17:33 since i never use the reload functionality (and it didn't seem to work when i tried), but remote-swank matters to me

17:34 gtrak: <-crazy: i wonder if you could do an inline bytecode macro?

17:35 like C's drop down to assembly

17:38 TimMc: wut

17:41 rickmode: technomany: thanks... anothing thing, if I do a slime-connect I don't get a slime-repl window. If I do a clojure-jack-in to start a local session, I do get the slime-repl. And then after that I can hook up to the remote swank and get a slime-repl. Weirdness.

17:42 technomancy: rickmode: yeah, could be that slime-repl hasn't been boottrapped yet

17:42 bootstrapped

17:42 rickmode: technomancy: is there a way to kick it? start it manually? I looked all the slime commands but didn't one to start a repl.

17:43 technomancy: rickmode: you would need to manually install slime-repl if you want to use it without M-x clojure-jack-in

17:43 it's a separate marmalade package from slime for some reason

17:48 rickmode: technomany: ack - well i'm Aquamacs so I'm kinda floating in my own world. The new clojure-mode makes life a lot easier though ;)

17:49 technomancy: ah... well yeah; good luck with that =(

17:49 rickmode: technomany: I still need my training wheel! heh

18:12 amalloy: does it make any sense for a single machine to have multiple private ssh keys? or does it always go the other way - create (at most) one private key per client, and tell the server that these are all acceptable keys?

18:18 TimMc: amalloy: I have multiple keypairs on my laptop. One is passwordless and one is not. I use them for servers of varying importance.

18:20 amalloy: However, at the last Boston Clojure meetup, what's-his-face distributed a private key for everyone to use to log into a shared terminal on an EC2 machine.

18:21 I think of it as group keys vs. user keys.

18:23 amalloy: TimMc: well, atm i'm putting together a simple tutorial on using clojars. i was going to create a new keypair for a new clojars account, but i realized i have no idea how clojars would know which key to use when i try to scp the jar

18:23 ordnungswidrig: in a macro I want to generate a keyword in the *current* namespace. How would I do?

18:23 (defmacro foo ¢ `(keyword o

18:23 ups

18:24 amalloy: ordnungswidrig: *ns*

18:24 technomancy: amalloy: it should just try the first thing on the list that `ssh-add -l` gives you

18:24 amalloy: man, i don't know how to use ssh-agent

18:25 TimMc: amalloy: I use a config file to tell SSH which key to use.

18:25 ordnungswidrig: like in (defmacro foo [bar] `(keyword ??? 'bar))

18:25 Raynes: I'm happy that I'm not as paranoid as you.

18:25 ordnungswidrig: amalloy: *ns* is of type namesapce where keyword expects a string

18:25 amalloy: oh, i see. didn't know you could do that. i already have a bunch of crap in .ssh/config

18:26 TimMc: Host clojars.org\n\tIdentityFile ....

18:26 amalloy: &(-> *ns* ns-name name) ; clojure is trolling us here...

18:26 lazybot: ⇒ "sandbox17152"

18:26 choffstein: Okay -- prepare yourselves -- this may be a very, very stupid question. I've been struggling to fully comprehend moads for a while now. Beside their base properties, I can't see through the fog to their "why". All of a sudden, I have either had a moment of complete enlightenment or complete stupidity. Would it be correct to say that monads give functional languages the ability to control how a function is applied to an value

18:26 controlling the value and not the function? For example, if I wanted to create a hopelessly egocentric value (x s.t. (f x) is x for all f), it is fairly trivial in an object oriented language -- but not so trivial in a functional one. It seems to me, though, that this could be done with a monad … where m-result always returns x. Am I crazy?

18:27 TimMc: amalloy: ^ ignore that, look at this: https://gist.github.com/1420671

18:27 technomancy: choffstein: it's been my experience that if you have to ask if you're crazy, then you probably just figured out how monads work

18:28 TimMc: There's a host alias in there as well as an unrelated directive listing all the keyfiles to try for arbitrary hosts.

18:28 choffstein: technomancy: mental breakthroughs always sort of require the gymnastics that make us think we are crazy, huh?

18:28 technomancy: choffstein: it's that or severe head trauma

18:28 ordnungswidrig: amalloy: thanks. weird but works.

18:29 TimMc: Raynes: How am I paranoid? One of my (2) keys doesn't even have a passphrase!

18:30 amalloy: thanks TimMc. have forked gist and will maim it until it does what i wantr

18:30 TimMc: haha

18:31 being able to type `ssh timmc@nfsn` is pretty nice.

18:31 amalloy: TimMc: you can configure it so that ssh nfsn just works; is there some reason you're using the timmc@ prefix?

18:32 choffstein: I think I'm going to go with "I'm crazy" until I actually figure this out

18:32 TimMc: Yes, I have different accounts there. It's actually phyzome_brainonfire@nfsn.

18:32 amalloy: choffstein: fwiw i think you're crazy but i don't really understand them either

18:33 choffstein: amalloy: Yes, but your thoughts of me are horribly skewed by my previous questions in this channel that you have had to respond to … so, I don't know if this is an isolated case of crazy or just your general consensus of me

18:34 amalloy: TimMc: back when i was dual-booting windows/linux, i had different usernames on the same computer depending on the mode it booted. i gave them different hostnames to avoid that: ssh linux (akm@server), vs ssh windows (Alan@server)

18:34 you might like something similar, or think i'm crazy

18:35 TimMc: I have like 8 logins at NFSN.

18:35 amalloy: okay okay

18:35 dnolen: choffstein: I think it's much harder to see Why Monads unless the language is nearly useless w/o them, aka Haskell.

18:35 TimMc: but good idea otherwise

18:35 amalloy: i don't even know what nfsn is

18:35 it just looks like nsfw

18:35 TimMc: Web hosting. "Nearly Free Speech.net"

18:36 dnolen: choffstein: I think Dan Friedman and Adam Foltzer's explanation is one of the best I've seen - https://www.cs.indiana.edu/cgi-pub/c311/lib/exe/fetch.php?media=manymonads.pdf

18:36 choffstein: dnolen: Yeah … i played around in haskell for a while. I should really spend some more time with it if I am ever going to reach monad enlightenment

18:36 dnolen: thanks, I'll take a look

18:36 TimMc: amalloy: I really like their pay-for-what-you-use model, and I wish I could get the same deal with a JVM-supporting host.

18:37 dnolen: choffstein: the other thing to realize is that they are about as fun as callback spaghetti unless you have compiler support.

18:37 I did see something almost readable in Ruby but it used continuations

18:37 choffstein: dnolen: Yeah -- I haven't seen 'em much in clojure, so I assumed there was an easier way to achieve the same results

18:38 dnolen: choffstein: they aren't so bad in Lisps - you have macros to do the transformations

18:39 choffstein: core.logic is basically a hyped up list monad

18:40 amalloy: interesting, TimMc. it looks like they're bandwidth-priced - i don't really see where they charge you for cpu or anything? seems like a weird hack to use them as a compute-farm

18:41 alexbaranosky: is there a simple way to find all fns vars ?

18:41 TimMc: amalloy: Bandwidth, storage, and number of sites. They looked into charging for CPU but I guess CPU is correlated enough with other factors that they just boost the other prices.

18:42 alexbaranosky: meaning tell me all fns that have been def'd

18:42 TimMc: amalloy: I just like that pricing model in general. It incentivizes the provider to have good uptime and encourage the growth of their users' projects.

18:42 amalloy: &(doc ns-map) ; alexbaranosky

18:42 lazybot: java.lang.SecurityException: You tripped the alarm! ns-map is bad!

18:42 amalloy: okay, i hate you too, lazybot

18:43 technomancy: alexbaranosky: (for [n (all-ns) [_ v] (ns-publics n) :when (and (bound? v) (fn? @v))] @v)

18:43 amalloy: technomancy: probably v, not @v, at the end there

18:44 technomancy: amalloy: yep, misread the question

18:58 TimMc: clojurebot: monads |are| a hoax

18:58 clojurebot: Roger.

18:59 cemerick: TimMc: ouch!

18:59 TimMc: I'm convinced that they don't exist, and people just write about them to make other people confused. :-P

19:01 Hmm, does clojurebot's factoid module collapse plurals and singulars?

19:15 technomancy: weavejester: any further thoughts on representing migrations?

19:16 weavejester: technomancy: yeah, I think hiredman was correct when he suggested a map of functions would be most appropriate.

19:16 technomancy: maps are probably the most flexible. I think I like the aesthetics of multimethods a bit better just for how they lay out on the page, but that's probably not worth it.

19:16 considering that could be addressed with a separate macro if desired

19:16 weavejester: Yeah, the advantage with maps though, is that you can create a map with just an :up and a :down, and add an :id later.

19:17 Since migrations need to have some sort of unique id to be stored in the database.

19:17 technomancy: would ordering be based upon the ID?

19:17 weavejester: No; at least not in Ragtime. I order based on creation order.

19:17 Which does mean I need a (reset-migrations!) at the top of the namespace file...

19:18 But overall it reads better

19:18 The ID is so that the migrations can be stored in the database so you know what has been applied.

19:19 I thought about adding a SHA1 to the ID based on the content of the migration...

19:19 So that if you change the migration definition, it registers the change, but that might be a bit too clever.

19:19 technomancy: functions are too opaque to pull that off well, I think

19:20 weavejester: Yeah. At first I was thinking that there would be no abstraction - the :up and :down would be defined in one place, so one could use a macro to capture the form.

19:20 You could still do that really...

19:21 i.e. (defmigration foo {:up #(blah) :down #(blah)})

19:21 The defmigration macro would be able to pr-str the form and SHA1 hash it.

19:21 technomancy: true

19:21 just a question of what you would do with it

19:22 if a migration changed, you'd want to reverse the old form before re-running the new up

19:22 but by that point it's too late

19:22 weavejester: Well, Ragtime has different strategies of applying migrations.

19:22 technomancy: unless you stored the down action in the DB, which is crazy =)

19:22 weavejester: For production, if there's a conflict (i.e. the database has A B C, but the migration file has A B D), it'll raise an error

19:23 But for development, you could say (:down C) (:up D) in such a situation.

19:23 technomancy: isn't C gone by that point?

19:23 weavejester: That assumes you know C, of course, but if you were fiddling around and still had C in memory...

19:24 I was kinda thinking that you could write a migration, and then maybe it has a small spelling mistake or something...

19:24 If the ID had part of a SHA1 hash, then your spelling correction would be identified, and the old migration could be pulled down, and the new one put up.

19:25 I was playing around with the idea of a migration middleware, so migrations would be applied automatically.

19:25 technomancy: yeah, I'm just thinking relying on stuff that's in memory but not on disk seems a bit sketchy

19:25 weavejester: In development only, of course :)

19:26 technomancy: it could be made to work, but it just goes against what you'd expect

19:26 weavejester: True, but if you're working in development, you can always reset the database completely if you can't find the migration.

19:26 You'd need some way of adding test data back in though...

19:26 Maybe it's all a little too... automated.

19:28 But I kinda think that maybe local development databases should be looked upon as being very temporary.

19:28 And if you want any test data, you should put that in a file so you can reload it.

19:28 technomancy: yeah, that makes me think it's better to make it easy to nuke and pave rather than try to undo stuff from stuff that's hanging around in-memory

19:29 weavejester: True... But nuke and pave might take too long if it was constantly happening.

19:29 I mean, you change a field from "emal" to "email" and suddenly a hundred migrations need to be reapplied from scratch.

19:30 technomancy: true

19:30 weavejester: I dunno - I'd have to see how this works in practise...

19:30 technomancy: but you don't need to hash the content in that case, just reverse the one you notice the typo on

19:31 weavejester: Yeah, but the hash means it happens without you doing anything special.

19:31 You save the file, and the migration is magically corrected.

19:31 Maybe a little too much magic? But I kinda want to experiment :)

19:31 technomancy: yeah, I think there's room for that

19:32 but we should figure out the basics first

19:32 the advantage of one-migration-per-file is that you can get lein to spit it out in such a way that the migration reflects the timestamp at which it was created, which basically solves the ordering problem

19:33 weavejester: The ordering problem can also be solved by adding a (reset-migrations!) at the top of the migration file that clears an atom, and each defmigration adds to it.

19:33 technomancy: i we support (def my-migration {:up #(...) :down #(...)}) then we can't offer a way to impose ordering on it; order has to either be a key in the map or supplied when you perform the migration

19:34 weavejester: It would just be the order in which it was evaluated.

19:34 technomancy: sure, that works if you want to introduce a macro

19:35 it would be nice to support both

19:35 weavejester: Well, one could easily translate a namespace into a map.

19:36 technomancy: what if rather than storing the migration in an atom, defmigration just expanded to (def my-migration {:up #(...) :down #(...) :order 12}) where :order was determined from an atom getting inc'd?

19:36 rather less stateful that way

19:36 weavejester: Hmm...

19:36 jacortinas: that sounds nice, and would allow manual reordering

19:37 technomancy: yeah, you could slap on a manual (def my-last-migration {:order 999999 [...]})

19:37 weavejester: Yeah. Would that solve the reloading problem as well? Or would you still need to reset the atom when the file is reloaded?

19:37 technomancy: I think as long as you didn't care about the value of the :order number, you could reload all you want

19:37 it would just keep incrementing, modulo integer overflow =)

19:38 weavejester: ... yeah, it would.

19:38 That's actually a much better solution.

19:38 I really should hang out here more often :)

19:38 technomancy: IRC is the best!

19:39 weavejester: On another note, does anyone know if there's an alternative to autodoc aside from margarilla (or whatever the exact name is :) ?

19:41 I'm currently building one, and I don't *think* I'm reinventing the wheel, but maybe someone else has solve the problem of API doc generation.

19:42 jacortinas: what does "-?>" do?

19:43 technomancy: jacortinas: it's like -> but short-circuits if there's a nil

19:43 weavejester: It's like -> but it short-

19:43 Yeah, what he said :)

19:43 jacortinas: ahh ok

19:43 that's awesome

19:50 technomancy: weavejester: getting my privmsg?

19:51 amalloy: heh. margarilla. excellent

19:51 weavejester: technomancy: Sorry, didn't notice

19:56 Raynes: weavejester: There is story, a recent addition.

19:56 weavejester: http://jedahu.github.com/story/

19:56 I'm a fan of this one.

19:58 weavejester: Raynes: Ah I see. It's not quite what I was looking for though. It's more a literate programming thing than classic API docs ala Javadoc or YARD.

20:06 alexbaranosky: technomancy, amalloy - thanks for ns-related tips... my internet died back when I asked so I hope I didn't miss anything useful

20:07 I got the for expression from technomancy and the ns-map from amalloy

20:08 weavejester: Bye all

20:09 amalloy: alexbaranosky: lazybot.org/logs/#clojure

20:09 (i don't think you missed anything, but you can find out from there)

20:11 alexbaranosky: thanks

20:21 TimMc: alexbaranosky: Whoa, stuff has been happening in seqs-and-colls!

20:22 haha, it's all after midnight last night

20:22 alexbaranosky: TimMc: I made a couple small commits

20:22 mostly silly stuff

20:26 TimMc: alexbaranosky: Any idea about how to represent "logical true" (and false) with better icons?

20:27 alexbaranosky: TImMc: my thoughts are along the idea of not thinking in terms of icons, but trying to step back and feel out the page from a UX perspective

20:27 TimMc: I was hoping I'd come up with something better if I slept on it, but the best I can do so far is that idealized power on/off icon: http://static3.depositphotos.com/1000244/205/v/450/dep_2055290-Power-yellow-circle-icon.jpg

20:27 alexbaranosky: I think the visual representation is a matter of UX, and, that could come later

20:28 TimMc: specifically http://us.123rf.com/400wm/400/400/ghoststone/ghoststone1005/ghoststone100500027/7028115-close-up-of-isolated-red-power-on--off-switch.jpg

20:28 There needs to be hella more text, too.

20:28 alexbaranosky: Could put a bomb on the ones that blew up, like a Nintendo type of bomb

20:28 TimMc: haha, I like it

20:28 alexbaranosky: and a thumbs down for thefalses

20:28 TimMc: Making a TODO file...

20:29 alexbaranosky: thumbs up for truths

20:29 TODO file's a great idea, I was looking for it last night

20:29 TimMc: alexbaranosky: I was talking about it with tmciver today and I think we need to avoid any icons that have "good/bad" connotations.

20:30 alexbaranosky: your reasoning?

20:33 TimMc: Well, I don't want the viewer to see the red X on seq / nil and think "Oh, I can't call (seq nil)"

20:33 ...which was Rob's first impression.

20:33 I think it works OK for the predicates though, e.g. counted? and associative?.

20:35 More user-testing is required. :-)

20:35 alexbaranosky: I still wonder if the simplest thing isn't just like "T" with a green background, "F" with a red background, "nil" with a some-color background, and Bomb with a xyz-color background

20:36 TimMc: I have Clojure question

20:36 TimMc: shoot

20:36 alexbaranosky: I have a symbol, and want to say that it does not represent any fns that are in scope

20:37 I can access stuf like such: (for [n (all-ns) [_ v] (ns-publics n) :when (and (bound? v) (fn? @v))] v)

20:38 tmciver: TimMc: alexbaranosky: thumbs up for truth, thumbs down for false and middle finger for "can't do that!"

20:38 alexbaranosky: but am having some friction going between var and symbol to compare

20:38 hehe

20:38 TimMc: tmciver: NICE.

20:39 alexbaranosky: tmciver, its hard to think of pictures for true and false because they're so abstract

20:39 TimMc: Worse, it's *logical* true and false. :-/

20:39 alexbaranosky: And that snippet doesn't work?

20:40 alexbaranosky: what do you all think of a triple quote reader macro for Clojure ?

20:40 amalloy: alexbaranosky: well, all-ns hits all namespaces, not just those that are "in scope"

20:40 tmciver: TimMc: I really think simply printing True and False would be fine too.

20:41 amalloy: if you only want to refer to ones that are in scope, just call (resolve sym) - if you get back nil, it's not in scope

20:42 TimMc: alexbaranosky: Remember that Clojure doesn't have reified environments, so you won't get locals.

20:42 alexbaranosky: I don't want local, so I'm good

20:42 :)

20:43 however, I am not sure how to compare a symbol with a var

20:43 &(var string?)

20:43 lazybot: ⇒ #'clojure.core/string?

20:43 TimMc: ,(name '#+)

20:43 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: +>

20:43 alexbaranosky: &(str (var string?))

20:43 lazybot: ⇒ "#'clojure.core/string?"

20:43 TimMc: haha, whoops

20:44 (.sym #'+) -> '+

20:44 alexbaranosky: &(= (str "#'" "string?") (str (var string?)))

20:44 lazybot: ⇒ false

20:45 alexbaranosky: TimMc, why is that last one false?

20:45 &(= "#'string?" (str (var string?)))

20:45 lazybot: ⇒ false

20:45 amalloy: alexbaranosky: i still don't see why you want to compare symbols to vars at all

20:45 alexbaranosky: &(= "string?" (str (var string?)))

20:45 lazybot: ⇒ false

20:45 TimMc: &(= "foobarbaz" (str "foo" "barbaz"))

20:45 lazybot: ⇒ true

20:45 TimMc: hrmf

20:46 amalloy: &(let [in-scope? (fn [name] (not (resolve name)))] (map in-scope? '[inc dec foo]))

20:46 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

20:46 amalloy: ,(let [in-scope? (fn [name] (not (resolve name)))] (map in-scope? '[inc dec foo]))

20:46 clojurebot: (false false true)

20:46 amalloy: oh. heh, got it upside-down, but you get the idea

20:46 alexbaranosky: amalloy, you da man

20:46 amalloy, you're a Clojure machine

20:47 * amalloy has nothing clever to say about that. anyway, ta-ta, i'm headed home

20:48 alexbaranosky: amalloy, doing the binding map substituions for midje tabular tests will infinitely loop in some spots, because it was thinking of fns used as table data as being table variables

20:49 at this point I think I'm just figuring it out for fun, because '?'-prefixed variables might in fact just be more readable than non '?'-prefix vars

20:55 TimMc: alexbaranosky: Mind if I hammer on the deftemplate thingy, or do you have WIP on that?

20:55 alexbaranosky: TimMc, go for it, I have nothing in progress. I gave up on it

20:57 TimMc: Ha, OK. I'll beat my head against it for a bit.

20:59 &(counted (seq "foo"))

20:59 lazybot: java.lang.RuntimeException: Unable to resolve symbol: counted in this context

20:59 TimMc: &(counted? (seq "foo"))

20:59 lazybot: ⇒ true

20:59 TimMc: &(counted? (seq [1 2 3]))

20:59 lazybot: ⇒ false

20:59 TimMc: welp

21:13 cemerick2: /join #clojure-casual

21:13 good grief

21:15 TimMc: ?

21:21 devn: cemerick: is it possible to get fortress?

21:24 Raynes: cemerick: lazybot is in #clojure-casual still?

21:25 It's more appropriate to /query lazybot

21:25 He responds there the same as here.

21:26 cemerick: Raynes: apparently

21:28 devn: sure, why?

21:29 (don't be fooled by the calamatous state of java.net)

21:29 calamitous*, apparently

21:52 TimMc: Does paredit give me a way to kill the entire next form?

21:52 (as opposed to the first "word" in that form)

22:10 devn: cemerick: I was just curious. I've been toying with APL, at this point, why *not* look at fortress? :)

22:11 TimMc: I am pretty sure it does, but my silly way is to have my point in some whitespace previous to the sexp and then I Mark, M-C-f, C-w

22:11 technomancy: TimMc: C-M-k, but it's stock emacs, not paredit

22:11 devn: d'oh

22:11 cemerick: devn: dude, you're outta control ;-)

22:11 devn: I knew technomancy would chime in

22:11 blasted Phil always besting me in emacs

22:12 TimMc: devn: Yeah, that's what I was doing.

22:12 technomancy: Ah, thanks!

22:12 devn: technomancy: yeah, i might avoid carpal tunnel a few thousand keystrokes earlier now

22:12 technomancy: thank you

22:14 technomancy: i heard through the grapevine you heroku guys were working on specifying how your app should be built, any word on that?

22:15 TimMc: $findarg map % [true false 5 nil] [true true false false]

22:15 lazybot: []

22:31 reiddraper: is __meta the best way to deal with metadata for objects created with deftype?

22:32 TimMc: alexbaranosky: Check it out, result values are in the title text.

22:33 alexbaranosky: TimMc: deployed it?

22:33 technomancy: devn: not sure what you mean by that

22:33 alexbaranosky: sweet, I see it

22:33 technomancy: I'm working on an article about how to set up background workers if that's what you mean

22:34 TimMc: need to commit, tho

22:35 OK, done.

22:36 technomancy: devn: oh, you mean http://12factor.net

22:36 yeah, that's good stuff. definitely worth reading.

22:37 TimMc: alexbaranosky: Oh, and add your name (and Rob and Tim too) to the README copyright section.

22:37 if you don't mind!

22:38 tmciver: TimMc: no need to add me; I didn't do anything!

22:38 TimMc: the change you just made isn't deployed yet?

22:43 TimMc: Nevermind, got it.

22:44 harto: having a little trouble with interop here - I'm trying to pass nil to an overloaded constructor

22:44 tmciver: TimMc: Looks good.

22:44 harto: e.g. (TreeModelEvent. source ^TreePath nil) doesn't work

22:45 I get "Metadata can only be applied to IMetas" - any ideas?

22:48 OK, it looks like this works:

22:49 (let [dummy nil] (TreeModelEvent. source ^TreePath dummy))

22:49 is that the best way to do it?

22:49 alexbaranosky: harto: funky... no idea the best way

22:50 cemerick: harto: yeah, you can't hint nil

22:51 I think I've only ever run into that circumstance (needing to pass nil to an overloaded ctor/method) once before.

22:52 harto: cool

22:52 cemerick: harto: I think I did something like ^TypeHint (or nil) — any expression that returns nil will do.

22:54 harto: ah, I see

22:54 thanks

23:20 hhutch: in clojurescript, if I require [goog.dom.foo :as goog-foo] and i want to do the equivalent of (goog.dom.foo.) using my clojure namespace, how would I do that? (goog-foo.) (new goog-foo) .. (goog-foo/.) actually generates "new goog.dom.foo.()"

Logging service provided by n01se.net