#clojure log - Jul 19 2012

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

0:01 noidi_: I find (dorun (map ...)) cleaner when I have to iterate over multiple sequences in parallel, but doseq is generally preferable

0:01 kenneth: hey if i want to create a dynamic doc string on a function, how would i do that?

0:01 noidi_: what do you mean by dynamic?

0:01 kenneth: i'm creating a function using (fn) and returning it as the return value of another function

0:02 i'd like to give that function a doc string that's computed

0:02 noidi_: doc strings are bound to symbols, not fn objects

0:02 kenneth: oh they are? i guess it's impossible then

0:03 i thought when you did (doc something) it would check the doc of the function something, not the doc stored as the doc of 'something

0:03 noidi_: &(:doc (meta #'inc))

0:03 lazybot: ⇒ "Returns a number one greater than num. Does not auto-promote\n longs, will throw on overflow. See also: inc'"

0:04 noidi_: &(meta inc)

0:04 lazybot: ⇒ nil

0:04 akhudek: kenneth: you can give it a name I think

0:04 that way you can identify it in a stack trace

0:05 noidi_: there's nothing stopping you from assigning metadata to the fn object, though

0:05 &(with-meta inc {:doc "foo"})

0:05 lazybot: ⇒ #< clojure.lang.AFunction$1@afa3f>

0:06 noidi_: you just can't check it using the `doc` macro, since it looks up docstrings for vars and special forms, not objects

0:06 akhudek: &(meta (with-meta (fn [a] (inc a)) {:hello :world}))

0:06 lazybot: ⇒ {:hello :world}

0:07 kenneth: ah i see

0:07 okay

0:07 alright thanks guys heading home

1:50 hiredman: so, uh, does incanter just not work?

1:51 I am trying to actually use it to chart data and it seems to ignore various documented options

2:02 all I want is a legend for my chart :(

2:03 amalloy: hiredman: 4clojure uses incanter to generate charts, which have axis labels but not legends, if that code is helpful to you

2:04 hiredman: amalloy: axis labels, while also being broken have any easy work around

2:04 have an

2:06 ah, if I switch to a scatter plot I get a legend

3:00 notostraca: what does the prepended - in -main or -init do?

3:02 TEttinger: does the - only have to do with gen-class or is there another use?

3:56 kral: namaste

3:59 asaleh: Somebody to help me \w creating custom lein task?

3:59 already tried https://github.com/technomancy/leiningen/blob/stable/doc/PLUGINS.md

4:00 and http://nakkaya.com/2010/02/25/writing-leiningen-plugins-101/

4:01 but putting stuff inside src/leiningen does nothing a.f.a.i.c.t.

4:18 clgv: lpetit: ping

4:20 lpetit: clgv: hello :)

4:20 clgv: lpetit: had a question but found it in the ML. there is a lately updated wiki page for CCW development setup, right?

4:21 lpetit: clgv: right

4:22 clgv: people succeeding in setting up their dev with the page, nothing buried in obscure mailing lists, etc.

4:22 clgv: lpetit: I still miss the repl search feature badly and want to try to implement it during the next weeks. so gotta setup the projects one of the next weekends :)

4:22 lpetit: clgv: Man, how terrible is the new Juno GUI :-(

4:23 clgv: lpetit: I just gave it a short try at home. which didnt result in much positive or negative experiences. what don't you like?

4:23 lpetit: clgv: ok :). The REPL has been Chas' territory historically, and he's working on it when he can afford to do so, that's why I haven't tried to do this in his behalf (among other things). Better ping him to ensure synchronization.

4:24 clgv: lpetit: I will let him know. I think when I can manage to navigate in the project, the feature should be easy to implement on top of the current functionality

4:24 lpetit: clgv: the look of it. On my Mac, I can barely tell active from inactive forms, worse on Ubuntu, the rounder borders look wrong, etc.

4:25 clgv: lpetit: but thats customizable afair. there should be a shipped classic theme

4:25 lpetit: clgv: probably so. I haven't looked that much into the deep inners of REPL history management.

4:26 clgv: i just find it a shame that such a major announce "Switching from 3 to 4" comes with a bad first approach. GUI counts.

4:26 anyway

4:26 clgv: thats right

4:27 I didnt dare to switch "in production" yet. just for a little pet project at home ;)

4:28 petit: is the keyboard shurtcut page up-to-date?

4:28 lpetit: Well, hopefully they can find a designer able to fix it and show the real potential of the new way of skinning it through CSS

4:28 clgv: at 90% rate I think

4:28 clgv: for which commands do you have a doubt?

4:29 clgv: lpetit:none, I just wanted to check now for some tasks I really could use the shortcuts ^^

4:30 lpetit: clgv: I think no feature is missing from the page. More so, maybe one or 2 have had their defaults changed and not updated

4:30 clgv: lpetit: this page is one of those where it would be awesome to be able to autogenerate it from the project ^^

4:30 lpetit: clgv: tell me that ! I've been thinking about it from almost the start :)

4:31 but never found the time :(

4:32 clgv: ah shift+alt+* is the key for selection features ^^

4:33 lpetit: clgv: yeah, and for me it's a game changer

4:33 clgv: right. thats why I was looking for the key binding :)

4:33 lpetit: clgv: note that you can tweak this for your taste. I know e.g. that Christophe experimented with Alt+UP/RIGHT/LEFT. I did not chose those as a default because they already have a meaning for text selection

4:34 s/text selection/text navigation/

4:34 clgv: I just needed to know which commands therfore exist at all ^^

4:35 I am getting more used to paredit mode, although there are some edit task where I like to switch to unrestricted

4:36 lpetit: clgv: note that while in the paredit mode, you can disable it for the next keystroke bit hitting the Esc key.

4:36 clgv: really interesting when you have a problem with an extra paren but it keeps trying to jump over it instead of deleting it

4:36 clgv: ah great.

4:38 lpetit: so the "Add Leiningen support" only shows up if there is a project.clj in a Clojure project already?

4:39 lpetit: that could be the reason for my observation then

4:39 lpetit: indeed

4:40 clgv: in my pet project leiningen support went smoothly :)

4:41 lpetit: clgv: great :)

4:42 clgv: lpetit: I had to change eclipse monospace font since Ubuntu 12.04. to have a real monospaced font.

4:42 lpetit: it looked quite odd with bold syntax highlighting^^

4:43 lpetit: oh

4:45 clgv: lpetit: just a hint if someone asks on the ML about bold highlighting being not monospaced ^^

4:45 lpetit: I installed and now use "Bitstream Vera Sans Mono"

4:46 lpetit: clgv: that's weird. Is it a problem rooted in the Eclipse/Ubuntu 12.04 combo, or do you think it's a CCW problem ?

4:47 clgv: lpetit: sole Ubuntu 12.04. I think. I read some explanation that the "bold" is interpolated instead of being a part of the font.

4:49 lpetit: clbv: there we are : http://code.google.com/p/counterclockwise/wiki/FAQ

4:52 clgv: lpetit: good, hopefully saves some people the google time which was around 5-10mins ;)

4:59 ro_st: i know i can use [& {:keys [arg1 arg2]}] to do named optional params

4:59 how about… oh. nevermind

4:59 clgv: ro_st: you want something more comfortable?

5:00 ro_st: forgot i can do (defn my-fn ([] (my-fn some-default) ([arg] …))

5:00 clgv: ro_st: that does solve it in a small number of cases ^^

5:01 ro_st: if you need more parameters with default values and propagating parameter documentation, you can use [clojure.options 0.2.0]

5:02 ro_st: https://github.com/guv/clojure.options/ ?

5:02 clgv: yes

5:02 ro_st: that looks nice

5:04 clgv: ro_st: internally it uses destructuring as well

5:09 ro_st: i want to be able to call an fn with no args as well as something-or-nil for arg 1. i want no-arg's behaviour for nil-for-arg-1.

5:09 does that mean doing a nil check in the [arg] case and calling the fn with no args?

5:10 that's what i'm doing now, just checking if perhaps there's a cleaner way

5:11 clgv: ro_st: can you show an example?

5:12 ro_st: https://www.refheap.com/paste/3682

5:12 this is so i can compose this fn with other fns that might return a valid item or nil

5:12 i have cases where i know there's no item to pass, so i don't want to explicitly pass nil in those instances

5:13 (something nil) smells bad to me

5:13 samrat_: how does this work: https://www.refheap.com/paste/3683 ?

5:17 clgv: ro_st: looks sane to me. although I would change it to (if item <use item to find value> (next-item))

5:17 ro_st or is "false" a valid item?

5:17 ro_st: no

5:17 it's either nil or a map

5:18 i tried not using (nil? item) but that didn't do what i thought it wold

5:18 clgv: samrat_: you have to ask a more specific question

5:19 ro_st: sure? not using `nil?` works if false has the same interpretation as nil to your code

5:19 there are special cases when you want to treat false different than nil, were you should explicit check nil?

5:22 ro_st: i'll try removing the explicit nil checks and see

5:33 ernestas: /c/r

5:45 ro_st: clgv: all works with simple if value instead of if-not (nil? value)

5:45 yay regression tests

5:50 asaleh: Anybody here could help me \w lein 1.7.1 custom task writing?

6:14 clgv: asaleh: there should be information in the leiningen repo on the 1.x branch

6:14 there is a whole textfile about that

6:39 ro_st: i have to implement undo/redo in cljs. i'm toying with the idea of fn's for the 'do' and jamming an undo-fn into that fn's metadata

6:40 the issue is that some fns need to keep some state to be able to process the undo, and i'm not sure where to keep that

6:40 actually, scratch that, i do know.

6:42 i'm going to use a vector in an atom, and each element of that vector will be a map of the fn (along with its undo fn in metadata) and whatever state is required to process both the do (or redo) and the undo fns.

6:42 clgv: ro_st: hmm if the function does not need to return the mutation, you could let it return the undo function with the appropriate parameters

6:42 ro_st: new user actions add stuff to this vector. undo pops the vector, calls undo, and moves that element to the redo atom vector. redo reverses that.

6:43 ah, you mean as a closure?

6:43 clgv: yes

6:44 and the undo function could return the "re-do" function ;)

6:44 ro_st: yes

6:45 clgv: I don't know if that really is a good layout in practice. but seems to have neet properties

6:46 ro_st: um, how do i pop the last element off a vector? (let [item (last @vec)] (swap! vec (pop @vec) … handle item) ?

6:46 missing close parens for swap! there

6:46 ifesdjeen: mknoszlig: ohai

6:46 mknoszlig: ifesdjeen: point taken :P

6:48 clgv: &(let [v [1 2 3]] (println v)(swap! v pop)(println v))

6:48 lazybot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Atom

6:49 clgv: &(let [v (atom [1 2 3])] (println v)(swap! v pop)(println v))

6:49 lazybot: ⇒ #<Atom@11ed63b: [1 2 3]> #<Atom@11ed63b: [1 2]> nil

6:51 ro_st: when-let has an implicit do form, whereas if-let does not, because of the else clause, right?

6:55 here's a completely untested first pass

6:55 https://www.refheap.com/paste/3684

6:56 the (apply …) will probably change

6:57 the cool thing is that my document persistence will simply store whatever's in the undo-events list, and on loading the doc, it'll replay the stack in order

6:57 no having to serialise view state

6:57 of course, everything meaningful the user does will be undoable

7:25 rahcola: &(do (defrecord Foo [a]) [(type (dissoc (map->Foo {:a 1}) :a)) (type (dissoc (map->Foo {'a 1}) 'a))])

7:25 lazybot: java.lang.ClassNotFoundException: clojure.core.Foo

7:26 clgv: &(defrecord Foo [a])

7:26 lazybot: java.lang.ClassNotFoundException: clojure.core.Foo

7:27 clgv: wrong error description for a user. he probably cannot define the record due to sandbox rules

7:27 rahcola: oh well, the question was, that why the first (type ...) returns clojure.lang.PersistentArrayMap and the second Foo

7:30 clgv: rahcola: you will always get a map if you remove one of the defined attributes of a defrecord

7:30 ro_st: what's the right way to add arbitrary metadata to a defn?

7:30 clgv: rahcola: since the defrecord needs to have its attributes.

7:30 ro_st: (defn ^{:foo "bar"} fn-name [args] (body)) ?

7:30 rahcola: ok, yeah, that makes sens

7:30 clgv: ro_st: yes

7:31 rahcola: *sense

7:31 ro_st: i can't put it after the fn-name?

7:31 clgv: ro_st or as simplem map after the name

7:31 ,(doc defn)

7:31 clojurebot: "([name doc-string? attr-map? [params*] prepost-map? ...] [name doc-string? attr-map? ([params*] prepost-map? body) + ...]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata. prepost-map defines a map with optional keys :pre and :post that contain collections of pre or post conditions."

7:31 clgv: ro_st: `attr-map?` marks the spot

7:31 ro_st: ahh, attr-map?

7:31 neat!

7:31 rahcola: clgv: would (into {} <record-object>) be an idiomatic way to turn a record into a map?

7:32 clgv: rahcola: no. since a defrecord can have more than his own attributes

7:32 rahcola: tried to implement write-json for a record and got an infinite serialization :D

7:32 clgv: rahcola: uff misread you

7:33 that creates a map with the same key-val pairs as the record

7:37 alexyakushev: Is there a way to AOT-compile a project with only those Clojure namespaces that are used? Seems like that automatic resolving mechanism is far from perfect

7:41 noidi_: alexyakushev, the dependencies of AOT-compiled namespaces are also AOT-compiled

7:43 alexyakushev: noidi_: Yes, I also thought so before I tried. But clojure.core doesn't want to be compiled. If I add it to compiled namespaces manually, then it does get compiled, but clojure.java.io is not and so on

7:44 noidi_: that's odd

7:49 clgv: alexyakushev: as far as I reme,ber you can define patterns in that config as well

7:50 alexyakushev: clgv: Sorry, not quite sure what config you are talking about

7:52 clgv: alexyakushev: like :aot [#"clojure.*"]

7:52 or :aot [#"clojure\..*"]

7:53 alexyakushev: cglv: Well, I guess it could work, but then all Clojure namespaces would be AOT-compiled, and I want only necessary to be

7:54 clgv: alexyakushev: ah so you cant give a precise pattern? you want the ones that are use determined automatically

7:55 alexyakushev: clgv: Yes, exactly. Like it is automatically determined when AOTing projects and libraries (which works OK for what I saw so far)

7:55 clgv: alexyakushev: is it possible that aot compilation for dependencies has problems in general?

7:56 alexyakushev: clgv: I don't know but when I AOT-compile a project with library dependencies, and have the whole Clojure compiled - it works OK. But when I try to AOT-compile Clojure from scratch - necessary namespaces are missing

7:57 clgv: alexyakushev: maybe thats something for the ML or even the Dev ML

7:58 alexyakushev: Perhaps, I should try writing there. Thanks for helping

8:29 ro_st: how do i get the metadata of a function?

8:30 from within a higher-order function that gets passed the function whose metadata i want to read?

8:31 Bronsa: (meta (var f))

8:32 ,((fn [f] (meta (var f))) identity)

8:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: f in this context, compiling:(NO_SOURCE_PATH:0)>

8:32 Bronsa: oh.

8:32 ro_st: yup. that's what i get

8:36 Bronsa: well makes sense

8:36 clgv: ro_st: you dont get it directly since the metadata is on the symbol

8:37 ro_st: so the answer is, "no." ?

8:39 sorry i'm tired and i'm not quite getting it

8:39 clgv: ro_st: no, the answer is, it is more difficult

8:40 ro_st: you can do it like that ##(->> map meta ((juxt (comp name ns-name :ns) (comp name :name))) (apply symbol) resolve meta)

8:40 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

8:40 clgv: ok not in the sandbox ^^

8:40 the above resolves the metadata for `map`

8:41 ro_st: the double # at the beginning is important?

8:41 hxiao: Calling var on the function first should do it in most cases, I have a working macro that just does (meta (var ~fn))

8:41 clgv: ro_st: no, that is the trigger for lazybot

8:41 hxiao: but those are in the same namespace

8:41 ro_st: hxiao: ah so passing (var f) into the HOF?

8:42 hxiao: ro_st: yeah it works for me, but the function i'm getting the metadata off of is in the same ns as the macro, so ...

8:42 clgv: ,(->> map meta ((juxt (comp name ns-name :ns) (comp name :name))) (apply symbol) resolve meta)

8:42 clojurebot: #<NullPointerException java.lang.NullPointerException>

8:42 hxiao: also i think since it's a macro it may behave differently than what you're trying to do

8:43 clgv: lol clojurebot still tries to throw differently ^^

8:43 it works on my repl^^

8:44 ro_st: ok, thanks guys. let me muddle

8:45 fforbeck: identify test

8:46 wjlroe: If I have #'something/something-else how do I get something/something-else ? I basically want (unvar ... )

8:46 ro_st: deref

8:46 or @

8:46 wjlroe: ro_st: oh that simple, thanks!

8:46 ro_st: which is shorthand for gimme-the-damn-thing

8:46 wjlroe: :)

8:47 fforbeck: clear

8:51 wjlroe: I should be clear - I want something I can pass to (var )

8:51 so this doesn't work: (var (deref (var clojure.core/keys)))

8:54 samrat_: I'm trying to use nrepl.el but its not working because I've lein2 set up as just lein

8:55 how can I fix it to make it work? a zsh alias didn't help

8:57 duck1123: could you just copy lein to lein2, so they both work?

8:57 I have lein, lein2, and lein1.7 where lein is also lein2

9:02 samrat_: duck1123: thanks, that worked

9:04 stain: any ring users?

9:04 hi - in https://github.com/wf4ever/workflow-runner/blob/master/src/workflow_runner/core.clj#L26 I try to generate a 'full-url' for links

9:04 duck1123: ~anyone

9:04 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 ..."

9:04 stain: however when using ProxyPass through Tomcat I end up with http://localhost:8580/ instead of the external host name..

9:05 so what is the best way to get this right? I feel like I'm reinventing what should ahve been an existing wheel here

9:05 duck1123: just to set a topic for my large question!

9:06 duck1123: yeah, you were pretty quick on the question, that just seemed a good time for that response

9:07 In my case, I store my canonical hostname in config, but I think there's a better way

9:07 stain: in a different java app, we store the hostname somewhere on the first request - stealing it from some other servlet header thingies

9:07 so you have to be careful on the first request there!

9:08 don't debug with wget first..

9:08 I would hope for a better way! ;)

9:09 nDuff: The Host header doesn't have what you need?

9:09 ...if mod_proxy isn't passing it through, that's a thing that can/should be fixed.

9:09 duck1123: do you have the x-forwarded-host header in your request?

9:10 * nDuff nods; actually _look at_ the headers, if you haven't.

9:10 duck1123: nDuff: with nginx, the host is set to my ip (what it's proxying to)

9:11 nDuff: duck1123: And it doesn't give you a way to change that? I'd be very surprised (and disappointed) for such a major piece of software to have that large a failing.

9:11 duck1123: ie. ask nginx's support forums.

9:13 duck1123: I have x-forwarded-server and x-forwarded-host in my headers, not sure what the difference is

9:13 of course, I have other reasons for needing to know what the current domain is

9:23 cemerick: FYI: The 2012 State of Clojure survey is on! Please participate if you use Clojure in any way, and share/RT/reblog/etc. http://wp.me/p10OJi-dN

9:32 * nDuff grumbles about the URL shortener use -- if he didn't know/trust cemerick, he wouldn't be following that link.

9:33 cemerick: Sorry, that's me being lazy and copy/pasting the tweet :-|

9:33 http://cemerick.com/2012/07/19/2012-state-of-clojure-survey/

9:39 * nDuff (while filling out the survey) looks on master to see if any of his patches have been merged... negative; phooey.

9:39 antares_: cemerick: thank you, this years questions are all very good

9:41 speaking of news, http://clojureelasticsearch.info is up (another clojurewerkz.org project that now finally has initial doc guides)

9:46 zerokarmaleft: cemerick: shouldn't the clojurescript envs questions have check buttons instead of radio buttons?

9:46 question*

9:48 michaelr`: cemerick: If Clojure disappeared tomorrow, what language(s) might you use as a "replacement"?


9:48 cemerick: zerokarmaleft: fixed, thanks

9:48 michaelr`: cemerick: how is this rellevant to anything?

9:49 cemerick: antares_: thanks :-)

9:49 michaelr`: It's interesting to see how people's language choices progress over time.

9:49 And, it was in the survey the last two years as well, and didn't entirely suck.

9:50 cshell: michaelr`: I'd just quit software development

9:50 zerokarmaleft: heh

9:50 michaelr`: cemerick: ok. but it sounds a bit irattional

9:51 cshell: michaelr`: scala has some similar things but a lot more complex - so I'd probably look at that - the jvm is a strong argument for it too

9:51 cemerick: That's a good point. We are, after all, entirely rational.

9:51 michaelr`: cemerick: maybe it could be rephrased differently: such as: which other language would you happily use if your organization forbids clojure usage?

9:52 zerokarmaleft: the 'if' makes the question applicable to only a subset of respondents

9:53 cemerick: The survey to gauge organizational faffery will run next week.

9:53 ToxicFrog: zerokarmaleft: 'if your organization were to forbid' then

9:54 michaelr`: hehe

9:54 why would a language disappear?

9:54 ToxicFrog: Or maybe just a more general 'if you were unable to use clojure'

9:54 michaelr`: ToxicFrog: +1

9:54 ... but were given the option to chose any other language.. :)

9:56 edoloughlin: Taking the plunge into Emacs and trying to set it up. M-x package-list-packages shows lots of stuff but clojure-mode isn't there. Any thoughts?

9:57 zerokarmaleft: edoloughlin: have you added melpa?

9:57 edoloughlin: Um, no?

9:57 zerokarmaleft: edoloughlin: http://melpa.milkbox.net/

9:58 edoloughlin: Ok. Will have a look. Thanks

9:58 sduckett: zerokarmaleft: is that the new tromney?

9:59 zerokarmaleft: sduckett: more like the new marmalade

10:02 edoloughlin: zerokarmaleft: Putting the code in the "Installing' section of the melpa site results in an error: "Symbol's value as variable is void: package-archives". I don't know Emacs Lisp, I'm afraid.

10:02 …Putting it into .emacs.d/init.el, of course

10:04 zerokarmaleft: edoloughlin: perhaps you haven't loaded package.el? https://gist.github.com/3144144

10:05 those are the surrounding lines in my config, which the melpa docs imply but don't explicitly state

10:06 edoloughlin: Ok. No errors this time. And clojure-mode is in the package list! Thanks.

10:08 No slime-repl???

10:08 lazybot: edoloughlin: Oh, absolutely.

10:09 edoloughlin: No swank-clojure…. I'm trying http://data-sorcery.org/2009/12/20/getting-started/

10:09 5 mins in and I'm ready to run back to CCW with tail between legs.

10:09 Anyone have a better set of instructions?

10:09 llasram: So many old blog posts...

10:10 nDuff: edoloughlin: Believe me, it's worth it.

10:10 llasram: edoloughlin: https://github.com/technomancy/swank-clojure/

10:10 * nDuff has tried to use CCW, multiple times -- and coming from paredit-mode, its equivalent was just too painful.

10:11 edoloughlin: <sigh> here we go again. Thanks.

10:13 llasram: edoloughlin: There's been what I perceive as a reasonably-concerted effort spearheaded by technomancy to make the official docs for these sorts of things succinct, up-to-date, and canonical

10:13 * nDuff is reminded to hunt around for an Emacs 24 package (to support Emacs Live)

10:14 edoloughlin: llasram: Where might these be?

10:14 nDuff: edoloughlin: What's your OS? If you're on an Ubuntu derivative, I can give you the instructions that work for me (since I'm in the middle of a reinstall).

10:14 jkkramer: official, best instructions (I think): http://dev.clojure.org/display/doc/Getting+Started+with+Emacs

10:14 edoloughlin: I'm on OS X

10:15 lpetit: nDuff: I'd be more than happy to have more detailed feedback on what was painful in the paredit mode of CCW

10:16 llasram: edoloughlin: Spread out a bit, so you have to know the thing you need, but then you can go to its own docs. So https://github.com/technomancy/clojure-mode#clojure-mode for clojure mode, and ^^ for clojure-swank etc

10:16 lpetit: nDuff: is it just adjusting to the different mapping for key bindings (almost all paredit keyboard shortcuts in CCW can be changed by the user), or somethinng else ?

10:16 nDuff: lpetit: Specifically, my normal workflow for code editing involves very frequent use of paredit-forward-slurp-sexp

10:16 lpetit: ...I couldn't find that at all.

10:16 lpetit: ...though as often as I use it, having a convenient keybinding is also an important thing, in addition to having it exist.

10:16 llasram: s,clojure-swank,swank-clojure,

10:16 lpetit: nDuff: Indeed, ~ 10-20% of paredit-el hasn't been ported, and I guess paredit-forward-slurp-sexp hasn't

10:17 nDuff: convenient as in … "familiar" ? :)

10:17 nDuff: *shrug* -- I can relearn something, but needing to move my fingers to somewhere too far from the home row wouldn't be fun.

10:18 The IDEA bindings have it as something like ctrl+shift+0

10:18 lpetit: have what ?

10:18 zerokarmaleft: edoloughlin: as i understand it, swank-clojure bundles a frozen version of slime...so i don't install slime-repl from ELPA or melpa

10:18 lpetit: nDuff: IDEA has paredit-forward-slurp-sexp ? Argh :)

10:19 ToxicFrog: "cannot have two overloads with same arity" dammit

10:19 llasram: zerokarmaleft, edoloughlin: Yeah, the swank-clojure doco calls that out

10:19 nDuff: lpetit: ...yes, but it puts it somewhere inconvenient enough that I just fall back to emacs. :)

10:19 ToxicFrog: I was trying to do a pattern match :/

10:19 zerokarmaleft: edoloughlin: quicklisp does the same thing for common lisp except it grabs the latest CVS snapshot (b/c the slime devs don't believe in cutting releases for some reason)

10:19 lpetit: nDuff: btw, I'd also be interested in a real to-the-metal use case for paredit-forward-slurp-sexp, please.

10:20 nDuff: and also, I find it quite hilarious, tbh, that coming from emacs with the possibility for you to tweak every part of it, you stop at the first problem with e.g. IntelliJ while I'm quite certain it is possible to rebind the command to another keyboard shortcut :-p

10:20 nDuff: lpetit: Sure. I want to wrap some code in a conditional. I place the cursor at the front of it, type (if something, activate paredit-forward-slurp-sexp, and my code is inside the conditional.

10:22 ToxicFrog: What is 'CCW'?

10:22 zerokarmaleft: ToxicFrog: counterclockwise

10:22 beffbernard: lpetit: my common use case is to wrap a bunch of sexp's in a let after the fact

10:22 lpetit: nDuff: oh. For the record, with the current state of the art in CCW, here's what I'm doing: I place the cursor at the front of it, select it via the structural selection command (one command, just as paredit-forward-slurp-sexp is one command), and then type (if (note that typing the first paren in "(if" automatically wraps the selection within parens)

10:23 ToxicFrog: zerokarmaleft: in the context of the discussion between lpetit and nDuff

10:23 zerokarmaleft: ToxicFrog: it's a clojure plugin for eclipse

10:23 lpetit: ToxicFrog: it's an Eclipse plugin for Clojure, which I'm developing.

10:23 ToxicFrog: Aah

10:23 I was hoping it was an IDEA plugin for Clojure based on your mention of IntelliJ

10:23 zerokarmaleft: ToxicFrog: intellij has la clojure

10:23 ToxicFrog: Since I wouldn't mind something a bit more customizeable than the reference one

10:24 lpetit: ToxicFrog: there is an IDEA plugin for Clojure, named "LaClojure"

10:24 ToxicFrog: Yes, I'm using it right now

10:24 lpetit: ToxicFrog: shameless plug = Counterclockwise / CCW allows you to rebind the shortcuts for its editor commands

10:24 ToxicFrog: Yes, but then I'd be using Eclipse.

10:25 And it's more the syntax hilighting and indentation I want more control over

10:26 lpetit: nDuff: to be honest, I like my workflow best, because the code to be wrapped in the if is, well, wrapped, sooner: you wrap it in parens, and you start typing if <condition>. With paredit-slurp-forward-…, you first create 2 isolated forms, and then you slurp one into another.

10:26 nDuff: given that in the end both have the same number of keystrokes ...

10:26 duck1123: It would be neat if CCW had support for injecting nrepl into a debugged/running java process

10:27 lpetit: ToxicFrog: Syntax highlighting in CCW has been totally revamped recently. Highly customizable.

10:27 duck1123: Yep, this is something I have thought about previous month. But it was, then, a feature waiting for a user. If you think it'd be of real use for you, please by all means file an issue for this

10:27 ToxicFrog: lpetit: sadly, I dislike Eclipse in general; furthermore, IDEA's support for Scala and Lua, my two main languages, is overwhelmingly superior.

10:28 My issues with laclojure are minor gripes at worst, so.

10:29 In happier news, \o/ update-in

10:29 lpetit: ToxicFrog: I won't open this door. If you're stuck with IDEA for other reasons, I see no point in trying to convince you. I know Eclipse has its flaws. I also know IDEA is good.

10:30 ToxicFrog: ,(split #"," "a,b,c")

10:30 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: split in this context, compiling:(NO_SOURCE_PATH:0)>

10:30 ToxicFrog: ,(string.split #"," "a,b,c")

10:30 clojurebot: #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: string.split, compiling:(NO_SOURCE_PATH:0)>

10:30 edoloughlin: nDuff: No experience of clojure-mode, but I like CCW's way of doing your use-case: Cursor on the top level of the form you want to 'slurp', (on OS X) press CMD-SHIFT-<UP> to select the form and type "(if "

10:30 raek: ,(clojure.string/split #"," "a,b,c")

10:30 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern>

10:31 raek: ,(doc clojure.string/split)

10:31 clojurebot: "([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."

10:31 ToxicFrog: raek: I got the arguments backwards too, this is not my day

10:31 ,(clojure.string/split #"," "a,b,c")

10:31 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.regex.Pattern>

10:31 ToxicFrog: ,(clojure.string/split "a,b,c" #",")

10:31 clojurebot: ["a" "b" "c"]

10:31 ToxicFrog: ,(clojure.string/split "abc" #",")

10:31 clojurebot: ["abc"]

10:31 zerokarmaleft: curse you, fingers of meat!

10:31 ToxicFrog: Ok.

10:32 raek: :)

10:33 nDuff: lpetit: Is that actually fewer strokes? I count one fewer in the slurp-forward case, but perhaps that's misunderstanding.

10:33 lpetit: in any event, it's good to know what that workflow is; I was trying to figure out how to do what I wanted swiftly, and ended up giving up.

10:34 lpetit: nDuff: I count the same number of chars, and same number of commands (number of strokes will depend on the exact keyboard bindings for triggering the commands, which is user-rebindable)

10:35 nDuff: I'd be interesting in other kinds of use cases beyond the "if(" one. If forward-backward slurp is superior to the current feature set of CCW, I'd be more than happy to add the missing commands.

10:35 whoops, did I just write "if(" instead of "(if" ? Please ban me from this channel forever :)

10:36 ToxicFrog: whoops, into swap we go :(

10:37 zerokarmaleft: appropriate smileys should also be (:, not sure what to do with the sad face...

10:40 ToxicFrog: There! A working SFS reader in 120 lines, most of which is actually a library for generalized regex-based lexing.

10:42 hyPiRion: zerokarmaleft: >= is legal clojure.

10:42 That should do for sad faces.

10:52 TimMc: ,:-<

10:52 clojurebot: :-<

11:01 avshalom: hi all: I'm working on getting clojure/emacs/swank/slime up and going. I'm using kjhealy fork of eschulte fork of technomancy E.S.K. Everything "works" in that I can clojure-jack and then C-x C-e on (defn sqr [x] (* x x)) and (sqr 2) yields 4 at the very bottom. But, if I follow page 409 of `Clojure Programming' it indicates that C-c C-c should be available as slime-compile-defun. But if I do C-c C-c (slime-compi

11:01 le-defun) all hell breaks loose : error in process filter: Wrong type argument: characterp, nil

11:01 is C-c C-c germane for Clojure?

11:03 ToxicFrog: ,(doc map)

11:03 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

11:04 wjlroe: avshalom: well I'm using vanilla starter kit stuff and I use C-c C-c all the time without troubles. Before using starter-kit (setting everything up like clojure-mode manually) I had those problems

11:06 avshalom: wjlroe: thanks. it's good to know that it works for you -- maybe I need to roll back to vanilla starter kit.

11:07 wjlroe: avshalom: yeah give that a go - and if you just use the emacs starter kit and nothing else so you don't have stuff hanging around, that can narrow down the possible variables

11:13 * nDuff installs Emacs Live, and... oooh, shiny.

11:15 duck1123: I didn't like the look of emacs live. Is it better with different themes?

11:15 ToxicFrog: ...huh. I thought println'ing a lazy seq forced it and printed the contents?

11:16 But my test here (which, ultimately, boils down to (println (str ...lots of stuff here...))) is outputting "clojure.lang.LazySeq@86550ee4clojure.lang.LazySeq@1afd061f"

11:16 nDuff: ToxicFrog: Perhaps you should be using pr-str?

11:16 * nDuff experiments.

11:17 llasram: `str` Just calls `toString`, which for LazySeqs just gives you the object address fun times

11:17 duck1123: it looks good, but maybe a little less neon. (I'm judging only by screenshots)

11:17 nDuff: *nod*; pr-str will do more what you're looking for than str

11:18 llasram: `println` without calling `str` first will work too

11:18 ToxicFrog: nDuff: I thought pr-str was for printing data objects in a manner clojure can parse back in?

11:19 Aha. I think I found the problem; I have a bit where it's going (str (map ...) (map ...)) and the maps, of course, return lazy sequences of strings

11:19 Whereas what I actually wanted was the concatenation of those strings

11:20 nDuff: ToxicFrog: pr does that by default, but can be tweaked contrarily via setting appropriate dynamic vars

11:21 ToxicFrog: My fundamental goal here is basically to go from a map to a "key = value\nkey = value\nkey = value" string, with some decoration (indentation, surrounding metadata required by the format, etc)

11:23 nDuff: where is this documented, and is it preferable to just going (reduce str (map f foo))?

11:32 joegallo: ,(apply str (flatten (interpose "\n" (map #(interpose "=" %) {"a" 1 "b" 2}))))

11:32 clojurebot: "a=1\nb=2"

11:32 joegallo: yay

11:35 llasram: I think str/join is a better fit

11:35 &(let [data {"k1" "v1", "k2" "v2"}] (->> data (map (partial str/join "=")) (str/join "\n")))

11:35 lazybot: ⇒ "k1=v1\nk2=v2"

11:36 llasram: er, clojure.string/join ; names!

11:36 joegallo: yeah, shorter, bit more natural.

11:36 good call.

11:38 mprentice: ok this might be a bit on the obscure side... in paredit-mode, can i turn off backslash inside a string if the string starts with a single quote?

11:41 llasram: mprentice: What do you mean by "the string starts with a single quote"?

11:43 mprentice: llasram: it's actually in javascript, a string can start with '. i ask here because, well, y'all <3 paredit

11:43 i also <3 paredit, i just want to tweak it to be a little friendlier in javascript

11:44 paredit helps a lot with nested functions in objects in functions in objects in... :P

11:46 yonatane: In the core.logic talk from EuroCloj2012 he mentions a tool that tells you if you write non-idiomatic code. What's the name of that tool?

11:46 the-kenny: kibit

11:46 llasram: mprentice: Hmm, interesting. I've never tried to get it working for non s-exp languages :-)

11:47 yonatane: the-kenny: thanks

11:48 mprentice: llasram: i started with it in common lisp, then clojure. but it's also really great for any languages with a lot of nesting.

11:48 llasram: it's not uncommon in javascript to get a line that looks like })})});

11:48 clojurebot: trampoline is the clenched fist in the gauntlet of letfn

11:49 llasram: clojurebot: Cool story, bot

11:49 clojurebot: clojurebot is not very good at indicating the difference between a return value and an exception

11:53 duck1123: mprentice: If all else fails, you can use C-q to force the insertion of the character

11:58 ToxicFrog: ,(doc clojure.string/join)

11:58 clojurebot: "([coll] [separator coll]); Returns a string of all elements in coll, as returned by (seq coll), separated by an optional separator."

11:59 Bronsa: http://kimochi.ath.cx/up/39c897a2bfc64662cc2deff491aed613.jpg we are pair programming

11:59 he's the mind

12:06 mprentice: duck1123: that's what i've been doing, but i want emacs to work my way, darnit! i'll figure it out, was just wondering if you guys had pointers where to start.

12:07 ToxicFrog: I really, really wish that compile errors didn't generate a complete stack trace of the compiler's internals.

12:08 * ToxicFrog bonks his head against the wall a few dozen times

12:08 ToxicFrog: how the hell do I :use only specific symbols from a library

12:09 Bronsa: (:use ns :only [a b ..])

12:09 llasram: ToxicFrog: Are you using Clojure 1.4 ?

12:09 ToxicFrog: llasram: yes

12:09 Bronsa: (:use [ns :only [a b ..]])

12:10 llasram: Bronsa's will work, but starting with 1.4 use and (ns ... (:use ...)) are semi-deprecated. Instead, just add a :refer [<symbols...>] argument. To your require/:require. Ex:

12:10 (ns example.refer (:require [clojure.string :as str :refer [join]]))

12:11 ToxicFrog: That looks a lot uglier :/

12:11 Bronsa: right, :require with :refer is preferred

12:11 ToxicFrog: Also, turns out I'd actually been using the correct form, I had just forgotten to fix one file

12:11 llasram: ToxicFrog: Uglier how?

12:11 ToxicFrog: And since the compiler didn't tell me which file the error was in I missed it.

12:12 Bronsa: ToxicFrog: you can just use (:require [ns :refer [a b ..]]) that is equivalent and not much longer than the use form

12:13 llasram: Yeah, the error messages are my biggest ongoing issue with Clojure, as a PR problem if nothing else. You learn to figure out the relevant parts pretty quickly, but they're pretty ugly and daunting to a newcomer

12:14 ToxicFrog: So something like: (ns ca.ancilla.kessler.writer (:require [clojure.string :refer [join]])) is the preferred form in 1.4?

12:14 Bronsa: yes

12:14 ToxicFrog: As for uglier - I don't really have a preference between :use/:require, but :use :only or :require :only both read a lot more naturally to me than :require :refer

12:14 Bronsa: I guess at some point in the future use will be removed?

12:16 ToxicFrog: llasram: for this specific case there does not seem to be any way of figuring out which file it's referring to, actually

12:16 Although I admit I could have missed it somewhere in the 80-line error message, 79 lines of which are compiler internals of no relevance.

12:18 llasram: ToxicFrog: Got distracted and didn't finish typing, but yeah -- then there are occasionally a few of those :-/ Certain top-level errors don't seem to get annotated with file/line info.

12:22 ToxicFrog: I am rapidly coming to hate ns now that my project is spread over several files and pulling stuff in from string

12:22 It feels like it does too much stuff and the differences between the things it does do are too subtle

12:22 It also doesn't help that all of the documentation for it is out of date

12:24 llasram: ToxicFrog: That's one reason to get rid of ':use' -- does less. There is still a lot crammed into one form, but it's pretty contained to defining the namespace and it's relationship w/ other namespaces

12:26 How do you think it could be improved?

12:30 ToxicFrog: llasram: for starters, it seems awkward that everything is crammed into the all-singing all-dancing (ns) macro and is not meant to be called as individual functions; what's the reasoning behind that?

12:31 Apart from that, I generally find myself in two situations - needing all of the symbols from a library that exports a small number of them, or needing just a few from a library that exports a huge selection

12:32 The former used to be (:use foo) and is now (:require foo :refer :all), which seems like a step backwards, kind of - it's longer, uglier, less immediately obvious what it does and exposes more internal workings

12:32 technomancy: cemerick: OCaml isn't Irish =)

12:32 ToxicFrog: The latter is (:require foo :refer [x y z]), which isn't that much worse than (:use foo :only [x y z]), I guess

12:33 Have to say, though, I find the ns blocks a lot more readable when :use is used in place of :require :refer :all

12:34 llasram: ToxicFrog: Side-ish note, I think refering all symbols of a namespace is discouraged. More idiomatic seems to be giving the other namespace a short local name, like (:require [clojure.string :refer str]). I definitely feel like it's easier to follow, and personally do that for everything except small numbers of "utility" functions

12:34 er, `:as str` obviously enough

12:35 cemerick: technomancy: huh, didn't it used to be (the apostrophe forming the contraction of Objective Caml)?

12:35 ToxicFrog: llasram: that seems kind of at odds of the Clojure stdlib approach of having a huge flat namespace of Stuff loaded by default, though?

12:35 cemerick: Clearly, it's not anymore, in any case. :-|

12:35 eggsby: what's the go-to logging lib for clojure? just tools.logging ?

12:36 technomancy: cemerick: I've never seen the apostrophe in official places, though I guess you could have argued it from an English language perspective =)

12:36 llasram: ToxicFrog: I don't think so. clojure.core is stuff you almost certainly always want. Everything else is much less special and gets a prefix :-)

12:36 technomancy: eggsby: println!

12:37 cemerick: ok, whew, I'm not insane; the contraction has been used reasonably widely… https://encrypted.google.com/search?hl=en&q=%22o%27caml%22

12:38 I'll definitely fix for next year (changing it now would botch the tally)

12:38 ToxicFrog: The division seems kind of arbitrary; I use split/join a lot more than I use to-array-2d :P

12:38 eggsby: just println fed into a logfile, eh technomancy? What about stderr or loglevels?

12:38 technomancy: eggsby: in Leiningen I just have a function that checks the *debug?* flag, and that covers levels

12:38 and a *silently?* flag that covers disabling info-level

12:39 that way it's much easier to change levels at runtime on a per-thread level

12:39 llasram: ToxicFrog: As far as everything being crammed into the 'ns' macro, I mostly agree, but: (a) It actually is composed of different individual facilities, and you could invoke those facilities individually yourself if you wanted to; and (b) it gives a common structure to the common task of "setting up a namespace," flattening the boiler plate of naming and importing external definitions in one form and file position.

12:39 technomancy: it's possible (but super annoying) to change level at runtime with log4j, but not on an isolated per-thread level

12:40 and since it's not supported by other logging backends, tools.logging doesn't let you do it

12:40 ToxicFrog: In typical code I'm already using (unprefixed, because they're in core) functions for manipulating strings, sets, maps, seqs, vectors, and functions; it feels wrong to be using str and count and format and subs and re-find and re-pattern and...string/split

12:40 Like they should either all be prefixed or none of them

12:41 As for (a), I thought invoking them individually was strongly deprecated?

12:43 llasram: I think it's just not considered idiomatic. The docstrings for e.g. `require` or `in-ns` don't mention anything, but I'm not plugged into clojure/core or whatnot

12:44 ToxicFrog: Thinking on it further, I think the fundamental reason this bothers me is that, from the structure of the standard library and other clojure code I've read, I've inferred a certain code style

12:44 llasram: As far as some functions being prefixed and some not -- I think there is some suboptimal separation. Some things are in core which IMHO would have been in other namespaces if those namespaces had existed when the functions were added. So my perception is that the inconsistency runs the other way

12:44 ToxicFrog: And (ns) both violates that and actively works against it in a way nothing else I've used yet does

12:48 llasram: also, having everything crammed into (ns) makes it harder to macro :use back in when it finally goes away :P

12:50 llasram: Well, I'm not sure what else to add. I'm sorry it bothers you so. And there is ever that with macros, although since you'd need to report a replacement 'use' macro anyway before you could use it...

12:50 s,report,import,

12:54 acristin: cemerick: Is there a reason you didn't go with a checkbox poll for the "which version of the JRE do you target?" question? If I use more than one, should I pick the one I like more?

12:55 cemerick: acristin: The objective is to get a sense of the lower bound that people require. So, if you deploy to 1.6 and 1.7, pick 1.6.

12:55 acristin: cemerick: Thanks, will do

12:55 cemerick: I guess I should have phrased that one slightly differently.

13:43 ToxicFrog: hrm

13:44 So if I want to :use a bunch of namespaces in the same long prefix, I can: (:use [ca.ancilla.kessler parser writer])

13:44 However, if I do (:require [ca.ancilla.kessler parser writer]), it accepts that, and parser shows up, but writer doesn't.

13:45 I get "no such namespace: writer" when I attempt to use it.

13:45 llasram: ideas?

13:46 yonatane: What's the best way to define a set of functions and leave an opening for injecting another implementation, without clients having to change code, other than maybe declaring which implementation they want?

13:47 lancero: I have some function which has multiple arities. Is there a way to invoke the function with a varying number of parameters based on some condition? I want something like: (foo x (when something y)).

13:48 technomancy: lancero: you could use apply for that

13:50 yonatane: is there a way to evaluate an expression into nothing, so it won't be counted as a parameter?

13:50 *considered

13:51 technomancy: yonatane: only in macros

13:52 llasram: ToxicFrog: I believe that is the correct syntax. Also, I don't think I've seen that error before -- wasn't "Could not locate ... on classpath"?

13:52 yonatane: would a 'nothing value be great or screw everything up?

13:52 ToxicFrog: Nope

13:52 raek: ToxicFrog: vectors are for options and lists are for the prefix shorthand

13:52 ToxicFrog: Same error using a list

13:52 raek: so (:require (ca.ancilla.kessler parser writer))

13:52 ToxicFrog: Exception in thread "main" java.lang.RuntimeException: No such namespace: writer, compiling:(ca/ancilla/kessler/core.clj:8)

13:53 (:require (ca.ancilla.kessler writer parser)))

13:53 llasram: raek: No, it doesn't matter. I use lists that way all the time

13:53 er, vectors

13:53 ToxicFrog: Replace :require with :use and remove the parser/ and writer/ prefixes from things and it works fine.

13:53 Also, the line it's reporting the error on is the first line where I use writer/something, not the line with the (ns)

13:53 llasram: Oh!

13:54 It doesn't create short alias for you

13:54 ToxicFrog: Oh

13:54 llasram: The namespace is required, but only available by the full name

13:54 ToxicFrog: So I need something like: (:require (ca.ancilla.kessler [writer :as writer] [parser :as parser]))?

13:54 Or is there a more convenient shorthand for that?

13:54 llasram: Exactly

13:54 That's what I do

13:55 If there's a shorthand for that, I'm not aware of it

13:55 lancero: technomancy: hmm I guess I don't know how to define the function correctly then. This doesn't work with apply when using 2 parameters: (defn foo ([x] 1) ([x y] 2)).

13:56 jsabeaudry: (:use [ca.ancilla.kessler :only [writer parser]]) ?

13:56 lancero: technomancy: anyway... this isn't my real problem (sorry, I thought it was). I'm trying to call clojure.java.shell with apply... and getting errors about missing keys.

13:56 jsabeaudry: sorry was not following the whole thread

13:56 ToxicFrog: jsabeaudry: writer and parser are namespaces containing functions, not functions themselves

13:57 Will that still work?

13:57 jsabeaudry: I dont think so

13:57 ToxicFrog: Oh, here's a question. Can I have multiple files that all contribute functions to the same ns?

13:58 Eg, multiple files starting with (ns ca.ancilla.kessler.sfs) that all get coalesced into a single namespace at runtime?

13:59 llasram: ToxicFrog: I think you might be able to using `load` from a "central" namespace file following the standard convention, but it's not something I've seen anyone do. What's the use-case?

13:59 lancero: I see that this fails as well: (apply + 1 2 (when nil 3) 4).

14:00 dnolen: ToxicFrog: this can be done with load. clojure.core does this.

14:00 jsabeaudry: ToxicFrog, reading back, you get an error that says writer is not a namespace but writer is a namespace?

14:01 ToxicFrog: llasram: I have a bunch of code related to manipulating SFS files that is, conceptually, a single library; I'd like to be able to load it as a single namespace and access it as (say) sfs/load, sfs/save, sfs/children, sfs/ephemeris

14:01 technomancy: ToxicFrog: please don't

14:01 it's possible but really annoying

14:01 ToxicFrog: Rather than needing to :use each file and use sfs-load, sfs-save, or :require them and sfs-loader/load, sfs-writer/save, sfs-content/children, sfs-content/ephemeris

14:02 Since it is, in fact, a single logical library

14:02 But I'd still like to keep it split into different files for my own ease of use when working on it

14:02 technomancy: why?

14:02 llasram: I believe the more common approach is to have a single api namespace which then itself loads various internal implementation namespaces

14:02 technomancy: being able to look at a file and see all the vars it defines is really valuable

14:02 lancero: sorry, (apply + [1 2 (when nil 3) 4])

14:03 technomancy: am I using apply wrong?

14:04 technomancy: ,(apply + (concat [1 2] (when nil [3]) [4]))

14:04 clojurebot: 7

14:04 ToxicFrog: technomancy: ok, but now I'm back to either "the entire library should be one huge file, making it a pain to work on" or "the library should be a bunch of little files and the user needs to load each fragment of the library separately"

14:04 llasram: so I would have, say, .sfs, which loads .sfs.parser, .sfs.writer, .sfs.content, etc, and makes the public sfs API available?

14:05 lancero: technomancy: thanks!

14:07 llasram: ToxicFrog: Yep! Since this is something you need mostly for complex libraries, I'm having trouble of thinking of simple examples, but I think lamina and aleph show the idiom fairly well

14:09 dnolen: ToxicFrog: organize your library based on how you want it to be used. I personally see nothing wrong approaches including load that work towards that end.

14:10 lancero: is there some built in function/macro that takes a bucnh of parameters and returns a coll with all the parameters that evaluate to non-nil? I know I can write it, just wondering.

14:11 llasram: lancero: ,((partial keep identity) [1 2 nil 3 nil 4 nil 5 nil nil nil 6])

14:12 &((partial keep identity) [1 2 nil 3 nil 4 nil 5 nil nil nil 6])

14:12 lazybot: ⇒ (1 2 3 4 5 6)

14:12 lancero: llasram: awesome, thanks!

14:13 amalloy: also (remove nil? coll)

14:14 llasram: Oh, yeah. Er. That's probably even better.

14:14 lancero: amalloy: thanks!

14:17 jsabeaudry: Is there anything special required to use a macro in another namespace? (When I load (C-c C-l) a file using a macro inside another namespace it fails yet I can run the project just fine)

14:24 dnolen: jsabeaudry: nothing special is necessary

14:28 jsabeaudry: dnolen, thanks, any idea on what could differ from loading the whole project vs reloading a file? I was under the impression that a file could not influence how their dependencies would load (as in C for example)

14:30 emezeske: jsabeaudry: C, the language? You can screw with your deps all you want in C.

14:31 jsabeaudry: emezeske, Exactly, I was under the impression that the same was not possible in clojure

14:32 emezeske: jsabeaudry: Oh, heh, I read what you said backwards :)

14:33 jsabeaudry: It was ambiguous, the proper way to write it would have been "I was under the impression that a file could not influence how their dependencies would load as it could in C for example" or something similar

14:35 dnolen: jsabeaudry: I've never encountered that problem so I can't say.

14:39 amalloy: you could probably do it if you put your mind to it

14:39 require file A, then muck with its vars, then require B, which sees the wrong stuff in A

14:58 ro_st: so i'm tackling undo/redo state management. here's what i have: https://www.refheap.com/paste/3689

14:59 my question is, is there a better way to do the concrete undo/redo-able action as defined lines 24-32?

14:59 it returns a fn that does the undo. the undo fn returns a fn that does the redo. using closures to trap the relevant data.

15:00 my solution has to work with clojure script primarily

15:04 emezeske: ro_st: Your solution looks reasonable to me. Is there something about it that you don't like?

15:07 ro_st: i guess i'd like it to be more clear what's happening in the concrete fn

15:07 i guess i can letfn them by name and tie em together at the end

15:08 emezeske: are you aware of any issues with cljsbuild and lein2? for some reason, crossovers didn't work when i tried

15:08 work 100% with lein1

15:12 i'm building all my cljs app's model code in clj with the repl and midje and having cljsbuild crossovers make the js for me

15:12 livin' the dream :-)

15:13 is there a way to get a reference to the function from within its own body?

15:14 amalloy: &((fn f [] f))

15:14 lazybot: ⇒ #<sandbox71428$eval80315$f__80316 sandbox71428$eval80315$f__80316@d48fef>

15:14 rplevy: are Bagwell's RRB trees (enabling faster concatenation) something that is in a Clojure lib that can be used presently?

15:16 ro_st: amalloy: of course. but a generic way without using the fn's name

15:18 rplevy: amalloy: do you know if any util lib contains zencat2 from Joy of Clojure?

15:18 amalloy: wat

15:18 rplevy: it's a concat function that is faster because it uses transients

15:19 XPherior: Can someone help me figure out why this macro won't compile? https://gist.github.com/e98ea7d7f16377a96c50

15:19 amalloy: XPherior: ~@body

15:19 XPherior: What's the @ sign do when conjuncted with ~?

15:19 Ah, thank you so much amalloy :)

15:20 rplevy: XPherior: it's a splice

15:20 amalloy: &(let [x [1 2 3]] `[(foo ~x) (foo ~@x)])

15:20 lazybot: ⇒ [(clojure.core/foo [1 2 3]) (clojure.core/foo 1 2 3)]

15:20 XPherior: Oh, that makes sense.

15:20 Thanks man!

15:33 Is Korma's DSL capable of truncating a table?

15:34 I guess via a delete would work

15:35 Yep. (delete entity-name) did the trick

15:39 amalloy: rplevy: i don't have JOC handy, but a "concat that uses transients" sounds like nonsense. would be happy to see what you mean

15:40 devth: anyone know of a fn or lib that provides a "throttle" function to limit the frequency a wrapped function can be called?

15:40 looking for the equiv of http://documentcloud.github.com/underscore/#throttle

15:41 amalloy: devth: yes indeed! https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L142

15:41 devth: amalloy: nice, thanks!

15:42 rplevy: amalloy: it's not nonsense and it's really fast. it's probably not the only time someone will need a concat and need it to be fast (still much slower than avoiding having to ever concat of course)

15:43 it's a two-arg concat and it uses conj! to get all the things from src into target

15:43 amalloy: rplevy: that's just ##(doc into)

15:43 lazybot: ⇒ ------------------------- clojure.core/into ([to from]) Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. nil

15:43 cemerick: rplevy: you mean something more than into?

15:43 oh, nm :-)

15:44 amalloy: well, in fairness it's not *quite* into

15:44 since into doesn't work with a transient as a dest; it converts persistent dest into a transient

15:44 rplevy: hmm interesting

15:45 thanks!

15:45 I of course knew about into, but didn't know it worked that way

15:46 yeah now that I'm looking at it could be exactly what I need

15:48 dnolen: rplevy: no one has tackled RRB, would be sweet.

15:48 rplevy: dnolen: yeah, that would be awesome

15:50 amalloy: rplevy: (but converting transient to/from persistent is O(1), so into should be just fine)

15:50 speaking of which, how in the hell does that conversion manage to be O(1)? transients are still beyond me

15:51 S11001001: amalloy: you still lose on the next conj!

15:51 amalloy: S11001001: ?

15:51 S11001001: (conj! xs x) versus (conj! (transient (persistent! xs)) x)

15:52 the latter is guaranteed to allocate on either the transient or conj! call, whereas the former may or may not allocate

15:52 amalloy: of course. but that doesn't address my question in any way that i can see

15:52 emezeske: ro_st: I try to keep cljsbuild working against lein2, but lein2 tends to change kinda quickly

15:53 ro_st: It's been a little while since my last "try everything on lein2" run

15:53 amalloy: why is the allocation O(1) time instead of O(n), for example?

15:53 S11001001: amalloy: because you only need a new container for the existing blocks

15:54 the tree root has constant size, so

15:54 amalloy: but doesn't a transient's conj! sometimes mutate nodes other than the root? shouldn't it have to copy those also?

15:54 S11001001: only the ones it actually mutates

15:55 and therein lies the cost of the intermediate persistent! call

16:12 lpetit: New Counterclockwise Beta released: more code completion enhancements, etc. (full list: http://code.google.com/p/counterclockwise/issues/list?can=2&q=next%20status%3AFixed-to%2Cdeliver )

16:12 scriptor: hmm, a 3rd mongo lib

16:13 lpetit: As usual: http://ccw.cgrand.net/updatesite-betas/ for the Software Update Site

16:13 technomancy: I'm helping a co-worker get running on vim; it sounds like lein-tarsier is the way to go for that, but it doesn't really describe what to do on the editor side.

16:13 if I just point him at vimclojure will it be relatively obvious what to do?

16:15 scriptor: vimclojure's pretty straightforward

16:15 rplevy: technomancy: my vim-using colleague Alan says yes it is easy enough

16:15 emezeske: technomancy: As long as he follows the installation at https://bitbucket.org/kotarak/vimclojure/ he should be fine

16:15 technomancy: The trickiest bit is installing nailgun

16:15 Raynes: technomancy: Yes, but I'd personally advise avoiding the nailgun stuff like the plague.

16:16 technomancy: Raynes: is tarsier a nail gun?

16:16 thing?

16:16 clojurebot: RickInGA: of course :-) *everything* is in Clojure

16:16 Raynes: technomancy: Looks like it, but it doesn't help with the editor side of things.

16:16 technomancy: I wonder why it doesn't just use netcat if it needs to do socket communication

16:17 scriptor: I guess lein-tarsier uses the same vimrc settings as vimclojure?

16:17 technomancy: Raynes: tarsier:vimclojure::swank:slime maybe

16:17 ?

16:17 Raynes: technomancy: I expect so.

16:20 technomancy: ok, that helps

16:20 hopefully the nrepl integration gets implemented soon

16:20 Raynes: He was working it a while back. Not sure if he still is./

16:23 emezeske: scriptor: Yes, lein-tarsier is just a nice packaging for vimclojure

16:23 scriptor: So vimrc/plugin stuff is the same

16:24 technomancy: whoa; I think I just successfully invoked paredit-convolute-sexp

16:24 aperiodic: slimv gets you the same stuff without mucking about with nailgun

16:24 technomancy: aperiodic: but without line numbers, from what I hear

16:24 aperiodic: uh, what?

16:24 Raynes: aperiodic: Yeah, I couldn't get that to work at all. In fact, it somehow managed to ruin my highlighting.

16:24 technomancy: aperiodic: according to sjl anyway

16:25 aperiodic: i can see line numbers just fine. i have only been able to get it to work by putting it directly in my runtime path (doesn't work under pathogen, though sjl says it does for him)

16:26 sjl: technomancy: aperiodic: yeah, doesn't have line numbers sometimes, and never has locals. But then again when I tried clojure-mode in emacs I didn't get locals either so who knows

16:26 aperiodic: I also manually start the swank server with lein swank -- I don't like slimv/clojure-mode doing it behind the scenes magically

16:27 aperiodic: sjl: same here.

16:27 sjl: i was helping somebody in here a few weeks ago who also couldn't get it to work under pathogen, FWIW, though i never did hear back if dropping it in the runtime path solved his issues

16:28 sjl: aperiodic: hmm, strange. what about it doesn't work

16:28 (I have my own fork that's an unholy combination of slimv with Vimclojure's indent/syntax files, so it's entirely possible vanilla slimv wouldn't work under pathogen...)

16:29 aperiodic: it just doesn't. doesn't appear to be loaded. leader-c, etc. do nothing at all, and don't produce any error messages

16:29 sjl: oh, i'm using your fork; not sure if this other fellow was

16:31 sjl: aperiodic: I do have some special settings in my vimrc that you may not have: https://github.com/sjl/dotfiles/blob/master/vim/vimrc#L588

16:31 bpr: In this code https://www.refheap.com/paste/3692, I have a macro that includes (System/getProperty "foo") in the expansion. Yet when I macro-expand it, it looks like (getProperty "foo"). Is there a reason for that, or am I making some mistake in my macro?

16:31 sjl: but I don't think not having them would prevent slimv from working under pathogen...

16:31 amalloy: wtf, is it still not possible to (try ... (catch Exception e (loop [] ... (recur))))?

16:31 Raynes: amalloy: I did that a few days ago.

16:31 Apparently it is not.

16:32 bpr: and clearly, it's not behaving properly when run

16:33 sjl: aperiodic: to be honest I'm kind of surprised any of this setup manages to work at all though -- it's held together with duct tape and angry patches basically

16:33 amalloy: bpr: unrelated: (if-let [x y] x z) is just (or x z)

16:33 bpr: amalloy: sure

16:35 llasram: bpr: I can't remember what causes that, but I believe you can work around it by using the more macro-friendly direct-. form: (. System getProperty "example")

16:35 amalloy: and (fn [{:keys [type]}] type) is just :type

16:35 bpr: yes

16:35 aperiodic: sjl: i don't have those set, but i also don't see why those would change anything. i'll experiment with those this evening, though, when i can conscionably faff around with editor plugins for a bit

16:35 bpr: amalloy: i was just gunna mention that too lol

16:36 llasram: ah thanks, I will try

16:36 sjl: aperiodic: yeah. I should actually be home tonight for a change so feel free to poke me if you think my fork has broken something

16:36 scriptor: sjl: jesus christ that's a long vimrc

16:36 amalloy: tbh i can't imagine what is causing this getProperty thing to not have System/ in front of it. i kinda suggest restarting your jvm because multimethods have spooky properties

16:36 sjl: scriptor: yep.

16:36 Raynes: amalloy: Agreed. I don't see anything that could cause this.

16:36 We have spoken.

16:36 bpr: haha

16:37 aperiodic: sjl: is there any way to open issues on bitbucket? i'd like to have some place to track this to see whether or not i'm being crazy here, or if i do indeed have some company in this

16:37 sjl: aperiodic: not for the main slimv, no. the author only accepts issues through email :(

16:38 aperiodic: I'm with you 100% on wanting an issue tracker somewhere though

16:38 Raynes: ...

16:38 sjl: aperiodic: but then again the dude works on this thing like every single day according to the changelog, so I can put up with some quirkiness

16:39 aperiodic: sjl: how about your fork? i don't see an issues button, but i'm also bitbuck-tarded

16:39 sjl: aperiodic: I didn't have one because I didn't expect anyone but we would use that mess, haha

16:39 *me

16:39 Raynes: sjl: You are legion.

16:40 sjl: I'm hesitant to add one because I feel like the issues wouldn't make it back to the original dev, who can actually fix them

16:40 technomancy: could you use it to convince him to man up and accept issues the right way? =)

16:40 sjl: lol

16:40 aperiodic: well, i'll see if i can actually reproduce with vanilla slimv and then figure out what to do from there

16:41 sjl: Actually the ideal solution in my world would be for Vimclojure's indent/syntax files to get absorbed into Slimv officially so I caould ditch this fustercluck of a fork.

16:41 technomancy: sjl: I'd be wary of hitching your hopes to swank-clojure

16:42 sjl: technomancy: why?

16:42 aperiodic: sjl: i do really appreciate your throwing that fork online

16:42 technomancy: sjl: because I want nothing more than to abandon it

16:42 sjl: technomancy: is there a replacement?

16:42 technomancy: sjl: the future belongs to https://github.com/kingtim/nrepl.el

16:42 supposedly kotarak is working on a vim frontend to nrepl

16:42 using Haskell

16:42 aperiodic: whaaaa

16:43 sjl: oh god

16:43 technomancy: the idea that swank-clojure is maintained is largely an illusion

16:43 amalloy: (let [handle-catch #(loop [] ... (recur))] (try ... (catch Exception e (handle-catch)))) ;; what a joke

16:44 * Raynes holds amalloy.

16:44 Raynes: It's okay.

16:45 amalloy: otoh, it gave me an excuse to factor out some common code from the try-body and catch-body into a shared function they both call. so maybe it's a feature

16:45 sjl: technomancy: welp I'll probably continue using swank-clojure until it stops working, then shave whatever new yaks have been born at that point

16:46 technomancy: the nrepl stuff should work out of the box with lein repl

16:46 sjl: technomancy: yeah but the editor-side stuff would be different

16:46 Raynes: sjl: package-install RET nrepl

16:46 sjl: I only use a bare lein repl for sanity checking certain things

16:46 Raynes: That's pretty much it.

16:47 Oh, Vim.

16:47 sjl: Raynes: ln /usr/bin/emacs /usr/bin/vim

16:47 or vice versa

16:47 Raynes: Yeah, I keep trying to love emacs but until it gets sane modal editing I'm stuck to Vim

16:48 Raynes: sjl: I use evil-mode.

16:48 sjl: Raynes: Evil would be nice if it would actually work everywhere

16:48 Raynes: I've yet to find a place where it didn't work.

16:48 amalloy: i dunno, man. if you're not holding down at least one key at all times how do you know you're really using an editor?

16:48 technomancy: yeah, it seems like if you're going to change something so fundamental you'd run into composability issues with third-party code

16:48 sjl: but then you open a help window or sldb window and it chokes

16:49 Raynes: I'm not sure why I'd want evil-mode in a help window.

16:49 *shrug*

16:50 sjl: Raynes: because you want your "move to the left window" shortcut to continue to work?

16:50 or the "close this window" key to actually close the window?

16:50 Raynes: I guess.

16:50 sjl: The nice part of Vim is that *everything* works pretty much everywhere. There'

16:51 s not special cases for different kinds of buffers, and if there are they're (hopefully) isolated behind leader/localleader

16:51 Raynes: I don't understand how people use editors, I guess.

16:51 technomancy: I probably would have tried to switch to modal editing years ago if it could be implemented in a way that would work consistently

16:51 sjl: technomancy: it's pretty consistent in Vim... heh

16:53 technomancy: you should probably just mentally append "in a way that keeps me as far away from vimscript as possible" to everything I say =)

16:53 sjl: heh

16:54 vimscript actually has its charms, though once you get past the basics it's pretty horrifying

16:54 Raynes: I couldn't find any charms, lucky or otherwise.

16:55 technomancy: "It distinguishes between statements and expressions; HOW ADORABLE."

16:56 sjl: being able to do things like 'nmap <localleader>ef mzvab:call SlimvEvalRegion<cr>`z' is nice

16:56 which I still can't figure out how to beat emacs into doing

16:56 grr

16:56 Raynes: Being able to understand what that does is nice too.

16:57 sjl: "map <localleader>ef to: place a mark, highlight the current parens, eval the region, and go back to the mark"

16:57 ToxicFrog: Calls forth Yog-Sothoth, which is both the Key and the Gate that lies beyond the bounds of time.

16:57 Oh well, I was close.

16:57 sjl: Mapping in the same language as the one you *actually use* is really nice.

16:58 One of the most painful parts of trying emacs is "okay I want to map a key to do these things, now I need to look up the functions those things call and figure out how to make a function that calls those"

16:58 whereas with Vim it's 'nnoremap K :q<cr>'

16:58 technomancy: sjl: you mean the fact that not every function is a command?

16:58 Raynes: The most painful part of elisp is its http client.

16:58 I wanted to kill myself while writing refheap.el.

16:59 amalloy: don't forget regexes, Raynes

16:59 Raynes: Yeah, those too.

16:59 sjl: technomancy: no, more like "what's the thing that happens when I press C-M-A-H-S-x M-x?"

17:00 technomancy: sjl: oh, you mean you want to compose many commands into one simply by naming the keys they're bound to?

17:00 sjl: technomancy: yes

17:00 technomancy: that's a keyboard macro

17:00 but it would be nice to be able to describe it from lisp

17:00 sjl: it works well in Vim because a lot of the keys are mnemonic

17:19 m0smith: hi all

17:20 I have a question if anyone is awake

17:20 emezeske: ~anyone

17:20 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:22 akhudek: What is the difference between clojurebot and lazybot?

17:22 m0smith: I have a small project (<1K lines of code) that has 26 functions that all take one to 3 similar arguments

17:23 My question is: It there some why to have those functions "close" over the arguments rather than pass them in? I do not want a global that is shared or "bind"ed

17:24 Instead, something like defining the functions just before they are called

17:24 sjl: m0smith: can you give an example? You may be able to use partial to make little helper functions

17:24 m0smith: Or a use of partial

17:25 sjl: Where is the best place to post an example

17:25 ?

17:25 pastebin?

17:26 sjl: m0smith: any pastebin -- cljbin.com is pretty and will run some types of code

17:28 m0smith: k

17:29 sjl: http://cljbin.com/paste/50087be2e4b0a3fa2f1a89fc

17:29 Raynes: sjl: You're dead to me.

17:30 m0smith: sjl: There are 4 functions there that are part of a simple game engine. When it is a player's turn those and a bunch of other functions are called with the current state of the world and the player

17:32 my thought is for some way to define those functions so they close over the "world" and "player"

17:32 but all the ways I think of are ugly

17:32 emezeske: m0smith: If you literally make those close over world and player, the world and player will never change

17:32 m0smith: You'd have to close over something mutable, e.g. an atom

17:34 m0smith: emezeske: At the end of a player's turn, the current functions defs would be abondanded and re-closed (or re-bound)

17:34 sjl: m0smith: one option is to combine world and player into a single vector, like game-state

17:34 m0smith: at the beginning of the next players turn

17:34 sjl: m0smith: and then use one of the threading macros to do updates to it nicely

17:35 m0smith: slj: I like that except then I have to start each function with some call to fetch the world and the player from the game-state

17:35 sjl: m0smith: just destructure them

17:36 (defn place-piece? [[world player] piece]...)

17:36 though then you *do* need to return a [world player] pair, which is a bit annoying

17:38 m0smith: slj: what about destructuring a map instead? That might get around the annoyingness of the return

17:38 sjl: m0smith: not really...

17:39 you might be able to do something like http://cljbin.com/paste/50087e5fe4b0a3fa2f1a89fd though

17:40 m0smith: slj: but return game rather than world

17:41 sjl: m0smith: well you're update-in'ing the game, so it would return the game

17:41 m0smith: slj: That might be a workable solution. I'll chase it down

17:42 slj: Oh, I was looking at the true branch of the if

17:42 sjl: oh right, I didn't see that since it was on the same line

17:45 m0smith: slj: I think your idea will work but I still wonder if there is a clean way to define and redefine functions (maybe like letfn) in a high-level closure. letfn is not good for 2 dozen functions used in various places

17:48 sjl: m0smith: yeah, I'm not sure. I'm doing much the same thing in a game I've been working on and I pretty much just type out all the arguments

17:48 clojurebot: datatype is see datatypes

17:50 emezeske: m0smith: But, wouldn't you have to re-bind the parameters any time any of the functions changed their states?

17:52 m0smith: emezaske: yes

17:53 slj: It is easy enough to do with letfn but that can easily get unwieldly. I guess I want letfn on a namespace or something similar

17:53 emezeske: m0smith: Okay, I must be missing something, I have no idea why you'd want to do that. Oh well!

17:54 m0smith: emezeske: I think the motivitation is that everytime I type the same parameters over again I think "wouldn't this be a good use case for a closure"?

17:58 emezeske: m0smith: If you decide on a solution, be sure to mention it here! I'm curious what you come up with.

18:02 m0smith: emezeske: will do

18:29 evildaemon: How do I use the API outside of clojure.core?

18:31 emezeske: "The API" ?

18:32 Frozenlo`: Outside?

18:35 amalloy: use?

18:35 clojurebot: Only use :use with :only.

18:35 S11001001: I open up every clojure file with an unqualified use of every clojure.* library including excontribs

19:12 Gnosis-: how do I make indentation correct in SLIME?

19:28 Aderius: hi

19:33 I'm quite new to clojure and had some (i think) question. What is the easiest way to get element from a vector using a negative index (is possible in some othere language like python) I couldn't find a solution by googling. Thanks

19:36 technomancy: Aderius: I proposed that, but it was refused

19:36 apparently it's a "goofy" idea

19:37 * nDuff uses negative indexes all the time in Python, but for some reason hasn't yet felt the need for them in Clojure.

19:37 emezeske: technomancy: I think I actually agree that it's a goofy convention. I do find it useful, though.

19:38 amalloy: i've never used a language (maybe matlab?) that supports negative indexes, and my gut reaction is that clojure doesn't need them, but i've written quite a few things that would be nicer with them

19:38 Aderius: I dont find it that goofy. I hoped I could do it with lazy seq but it only works in one direction (indice larger then the vector size)

19:38 amalloy: or maybe i've always wanted the very-last item, so that pop/peek wound up being fine

19:40 Aderius: Mjah, I need it actually for a very specific usercase, so maybe it's not very needed in general

19:41 TimMc: I really enjoy having negative indices available in functions that support that.

19:41 especially substring

19:42 Gnosis-: has anyone been able to get Clojure-style indentation working in the SLIME REPL?

19:43 Aderius: Maybe the overhead (checking each time if there is a negative index) is to expensive to support it in core

19:43 amalloy: Gnosis-: https://gist.github.com/7ddfc2eaacd9988cb57e

19:44 nicholasf: hi - I want to create a namespace (mongo) that internally uses another namespace (congomongo) and exposes all of its functions on a (ns blah (:require [foo.mongo :as mongo])) call. Is this possible?

19:44 Gnosis-: amalloy: should I put that in my .emacs?

19:45 amalloy: only if you want the repl to indent like a clojure buffer :P

19:45 Gnosis-: I... think so?

19:45 amalloy: i have it in mine

19:45 Gnosis-: well, thanks!

19:46 amalloy: it might matter where you put it, i dunno

19:47 creese: is it possible to get clojure-mode.el quality indentation in vim?

19:50 Raynes: creese: If you enable fuzzy indent in Vim, mostly.

19:51 There are small differences (see how cond is indented in both editors), but mostly insignificant.

19:51 technomancy: there's no good way to indent cond

19:51 Raynes: Compare both of them to ST2 and laugh at its terribleness.

19:51 technomancy: See my whining in #leiningen.

19:52 technomancy: *more* whining? but I don't liiiiiiiiike whining =(

19:53 creese: do I need a plugin?

19:53 Raynes: Yes, VimClojure.

19:54 creese: can you use vimclojure without nailgun?

19:56 Raynes: Don't do any of the nailgun stuff.

19:56 They're entirely separate.

19:59 emezeske: Raynes: How do you use vimclojure without nailgun?

19:59 Raynes: emezeske: You simply don't use the nailgun portion...

19:59 emezeske: Raynes: Isn't nailgun the only way that Vim can communicate with the vimclojure server?

20:00 Raynes: Yes, but that is in no way necessary for highlighting.

20:00 And indentation.

20:00 emezeske: Oh, that's hardly "using vimclojure" though

20:01 By far the most useful parts of it are the nailgun/repl integration

20:01 Raynes: I strongly disagree.

20:01 emezeske: How do you evaluate things in your repl?

20:01 Raynes: VimClojure is two things: highlighting and indentation for Clojure and an integrated repl.

20:01 I open lein repl and type.

20:02 emezeske: Dear God, man, there's a better way! :)

20:02 Raynes: I've only had disaster with nailgun crap.

20:02 Also, I don't use Vim these days, I've been using Emacs and evil-mode.

20:02 emezeske: These days, nailgun's not bad really. lein-tarsier takes care of the server and makes that easy

20:03 Well, sure, if you're not using Vim, I don't recommend vimclojure

20:03 ** When I say nailgun's not bad, I mean setting it up isn't bad. Nailgun itself is stupid.

20:03 Raynes: stuarthalloway: How dare you come into my channel.

20:04 * stuarthalloway ducks

20:05 technomancy: emezeske: you still have to compile a C program though, right?

20:06 emezeske: technomancy: Yeah, I don't know why that's so hard, though. Maybe I just happen to be on a system where it compiles cleanly, and on others it doesn't?

20:07 technomancy: emezeske: it's not that it's particularly hard, it's just Yet Another Thing that gets in the way

20:08 emezeske: technomancy: Oh, I totally agree, and would prefer not to have to do that

20:08 Aderius: I use only the inferior-lisp mode. Keep simple things simple.

20:09 technomancy: it sounds like with the nrepl stuff he's working on you'd still have to download a binary client, but it would be precompiled for all platforms

20:09 emezeske: technomancy: *for all popular platforms

20:09 technomancy: Yeah, that would be an improvement

20:10 technomancy: heh; right

20:10 emezeske: technomancy: As it stands, though, IMHO the benefits of hooking up vim and the vimclojure server is totally worth the hassle of a "make install" command

20:10 technomancy: emezeske: it's just a lot to ask for newcomers

20:11 emezeske: technomancy: You win on that point! :)

20:11 technomancy: I was helping out a co-worker get set up and found myself apologizing a bit on that front

20:11 emezeske: I'd like to see the client-side stuff just implemented in Python, which vim has native support for

20:12 technomancy: doesn't that depend on how you compiled vim though?

20:12 emezeske: AFAICT, running Python from Vim is Fast Enough™

20:12 Yeah, but all the major distros have python-enabled vims

20:13 creese: but then you have to have the same version of python install on your computer

20:13 emezeske: creese: I'm pretty sure that's not true

20:13 Raynes: I'm pretty sure it is. actually.

20:14 At least, I spent at least two weeks dealing with Vim + Ruby crap because I had RVM installed.

20:14 emezeske: Well, I mean, you need the headers or whatever if you want to recompile Vim

20:14 Raynes: I expect the same problems would exist with Python.

20:14 emezeske: Raynes: Why was it anything other than "apt-get install vim" done?

20:14 creese: isn't it gvim?

20:14 emezeske: creese: If you want gnome support sure

20:15 creese: in my distro, regular 'vim' isn't compiled with ruby support, don't know about python

20:15 emezeske: Vim just depends on libpython or libwhatever, it doesn't actually exec Python in the shell or something

21:06 Seo007: Is your website on page 1 of Google? http://bit.ly/LYh99L

22:01 clj_newb_28gnos9: anyone here familiar with using clojure + CSS/DOM, but _without_ clojurescript? i.e. I like Clojure. I like JavaScript's HTML/DOM/CSS GUI setup. I'm not a very big fan of debugging clojurescript.

22:05 dnolen: clj_newb_28gnos9: I'm sure quite a few, seeing as CLJS is pretty new.

22:32 ToxicFrog: Is there a good way to require other stuff 'in the same namespace'?

22:33 metellus: isn't it already loaded and accessible if it's in the same namespace?

22:33 ToxicFrog: Eg, if I do (ns ca.ancilla.kessler.core), is there a shorthand for (require ca.ancilla.kessler.sfs.parser) that drops the ca.ancilla.kessler - a "relative require" kind of thing?

22:33 Yeah, "in the same namespace" isn't really the right way to describe it but I'm not sure what is

22:36 metellus: http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html look at the more complicated example here (search for "my-great-project")

22:39 ToxicFrog: I already know about (:require (ca.ancilla.kessler.sfs parser writer)) and whatnot

22:39 Not really what I'm looking for, I want the ability to :require and :use relative to the caller's ns

22:40 metellus: no idea, sorry

22:41 ToxicFrog: Aah well

22:43 gfredericks: ToxicFrog: I can imagine a macro doing that. rrequire and ruse :)

22:46 duck1123: ToxicFrog: Would this help you at all? https://github.com/ztellman/potemkin

22:46 this is more at where you define it than at the require site

22:47 no, reading back, probably not

22:47 gfredericks: heck I guess there's no reason it should be a macro

22:48 metellus: you could do some terrible things with (symbol (str *ns* ".foo.bar"))

22:49 duck1123: I've wanted something like that to make my ns use easier. I have a lot of namespaces and they're all named according to certain patterns and are required in a certain way

22:49 ToxicFrog: Yeah, this is my first experience splitting a project into multiple files and loading a bunch of external dependencies and I am really not enjoying it :/

22:50 duck1123: Even though the ns form isn't really much special, I like the peace of mind of having all my namespaces up there at the top where they belong

22:50 gfredericks: (defmacro ns' ...)

22:51 waitaminute

22:51 there's not really any easy solution to this is there? even if you made a lib with (defmacro ns' ...), you couldn't use it without requiring that lib first

22:51 ToxicFrog: gfredericks: yep

22:51 gfredericks: so you'd have to at least (require such.and.such) (ns' ...)

22:51 aw crap. so much for "macros can solve anything"

22:52 * gfredericks switches back to ruby

22:52 ToxicFrog: noooooooooooo

22:53 Ok, away from (ns) for the moment, I want to ask for naming advice

22:53 The opposite of read is write; the opposite of load is save.

22:53 What's the opposite of parse?

22:53 What do you call the AST -> source operation?

22:54 duck1123: I have 180 files named *.clj in my source folder. That's a whole lot of namespaces

22:54 gfredericks: esrap

22:54 metellus: ToxicFrog: (require (symbol (str *ns* ".foo.bar"))) would work, it's just ugly and probably terrible

22:54 ToxicFrog: I have 'stringify' as a working name, but don't really like it

22:54 hiredman: gfredericks: there are various ways around that

22:54 .win 15

22:54 ToxicFrog: metellus: yeah, that's ugly enough that the ugliness I'm trying to avoid is less ugly than that

22:54 gfredericks: hiredman: I was wondering

22:56 hiredman: clojure unconditionally loads the first user.clj it finds on the classpath

22:56 gfredericks: ah ha

22:56 so you define clojure.core/ns'

22:56 hiredman: when you load a file, it the current namespace generally starts as clojure.core, the ns form changes to your namespace

22:57 etc etc

22:57 gfredericks: (inc hiredman)

22:57 lazybot: ⇒ 11

22:58 gfredericks: hiredman: do you happen to know if that kind of hackery is the purpose for user.clj?

23:01 hiredman: gfredericks: ask rich

23:03 amalloy: ToxicFrog: unparse. and the reason it doesn't have a name is it's not something that gets done often

23:04 ToxicFrog: Really? It gets done all the time - every time you have an AST-based prettyprinter, every time a configuration is loaded from disk, modified, and written back...

23:05 I was actually contemplating "print" but that has connotations of writing to *out*

23:05 Or maybe just load/save for files, read/write for strings, and keep parse internal

23:07 kenneth: hey guys, what's the most efficient way in clojure to prefix match a string

23:07 i want to know if an arbitrarily long string starts with "something"

23:08 i have the string as a byte array, and i'd preferably want to avoid converting the entire byte array to a string

23:09 should i figure out length of my match string, take that many bytes, toString it, and check for equality?

23:09 brehaut: ,(.startsWith "abc " "ab")

23:09 clojurebot: true

23:09 brehaut: oh

23:10 amalloy: bytes aren't characters, man

23:10 kenneth: in ascii

23:10 i have no unicode in my situation

23:11 brehaut: ,(byte 128)

23:11 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Value out of range for byte: 128>

23:11 amalloy: converting just a subset of a byte[] to a string is probably more expensive than converting the whole thing

23:12 kenneth: you think so?

23:12 amalloy: if you do it by allocating a smaller byte[], that's not cheap

23:12 that is, allocating a smaller one and copying to it

23:14 kenneth: yeah, i can see that. i can't just compare the head of the byte[] without having to allocate the smaller chunk of memory?

23:14 brehaut: i think you should just convert it to a string and .startsWith it and not worry about performance till you need to

23:14 amalloy: you asked: should i figure out length of my match string, take that many bytes, toString it, and check for equality?

23:15 AustinYun: hm, can you call seq on the string?

23:15 brehaut: ,(seq "abc") ;; AustinYun

23:15 clojurebot: (\a \b \c)

23:15 AustinYun: talking to kenneth

23:15 amalloy: but seriously, agree with brehaut here. in addition to a suspicion that you've done something wrong earlier if you think the best way forward is to search a byte[] for some characters, you are worrying about performance too soon

23:16 clojure already allocates a gajillion objects a second, probably larger than the String you're worried about creating

23:17 AustinYun: like just (take 9 (seq myString)) and see of that seq matches "something"

23:18 oh wait he's already got it as a byte array

23:18 well jeez, why do you have a byte[]

23:20 brehaut: AustinYun: if you wanted to do i with just seq abstractions #(every? (partial apply =) (map vector "abc" "ab"))

23:20 if you have strings then the java method is the best way

23:21 amalloy: brehaut: that doesn't really work, because you wind up saying "f" starts with "foo"

23:21 brehaut: true

23:21 amalloy: i'd rather write it as (every? true? (map = "abc" "ab")), btw

23:21 brehaut: oh yeah

23:22 got so caught up being point free i forgot to just use the functions

23:26 ToxicFrog: awesome, got the compiler to NPE

23:26 I hate it when that happens

23:27 kenneth: wait, so would this work?

23:27 (every? true? (map = (seq my-head-str) my-byte-array))

23:28 brehaut: if you are worried about object allocation times, using seqs is going to comically bad for you :P

23:29 map implicitly seq's its arguments too

23:29 kenneth: yeah probably not a good idea

23:29 i mean i don't want to prematurely optimize, but also this is supposed to be executed a quarter million times per second or so

23:33 amalloy: kenneth: no, because characters never compare as equal to bytes

23:33 &(= (seq "0") [\0])

23:33 lazybot: ⇒ true

23:34 amalloy: &(= (seq "0") [(byte 48)])

23:34 lazybot: ⇒ false

23:35 kenneth: oh lame

23:35 is there a way to convert byte arrays to lazy sequences so i can do that?

23:36 acristin: kenneth, you said you're going ot be doing this 250k times per second... which is going to be changing; the head string, the byte[] or both?

23:36 kenneth: will (seq (.getBytes string)) do what i think it will?

23:36 the byte[] will be changing, the head stays the same

23:37 amalloy: why not just write it in C?

23:37 kenneth: the head is something like 15 bytes max, probably more like 5, and the byte[] could be any size, realistically up to 500-1k

23:37 acristin: I'm trying to remember what my friend did when we were comparing clojure vs. common lisp for file carving; I don't remember if he used seqs or just called out to java for the byte[] comparison

23:38 kenneth: i probably should have :) would have been easier too

23:38 might have to at some point

23:38 amalloy: C lets you just use memcmp too, which is usually hardware-optimized

23:40 kenneth: no way i can rewrite this in time for my deadline, but will probably do it in c for round 2

23:40 it's a pretty simple program

23:41 acristin: Anyway, my advice would be to do a one time conversion of your string to a close-enough byte[] and then do something like BM string comparison on the two

23:41 * ToxicFrog throttles the compiler

23:41 acristin: But I'd be surprised if there isn't already a good library that does this

23:41 brehaut: ,(String. (.getBytes "abcdefg") 0 4)

23:41 clojurebot: "abcd"

23:42 brehaut: the String constructor already provides a way to convert only a portion of your byte array into a string if things are really too slow

23:43 ToxicFrog: I wonder if this is any better in the nightlies /

23:43 :/

23:43 kenneth: oh awesome

23:43 sounds like just what i wanted

23:43 brehaut: ,(.equals (String. (.getBytes "abcdefg") 0 (count "ab")) "ab")

23:43 clojurebot: true

23:44 brehaut: the javadoc is your friend. you could have found this yourself in the same time it took me

23:44 amalloy: $javadoc java.lang.String

23:44 lazybot: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

23:44 brehaut: see you can do it faster; i used google

23:45 AustinYun: well

23:46 if you're going to re-write it in C anyway, I know Go has HasPrefix(s, prefix []byte)

23:46 *shrug*

23:47 ToxicFrog: This was all working fine before I tried to move from :use to :require, and now the compiler just crashes unhelpfully

23:52 aaaaaaaaaaaaa

23:53 I can enter this code into the repl

23:53 But when I pass it to clojure using -e, I get an "EOF while reading" error

23:54 brehaut: paste it up somewhere

23:55 ToxicFrog: Actually this may be an error in my launcher script

23:56 Yeah, it is, false alarm

Logging service provided by n01se.net