#clojure log - Nov 03 2012

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

0:00 brainproxy: the idea being that for dev purposes, it can help you to think more carefully about what you're putting together

0:00 Sgeo: brainproxy, so basically a run-time check that the programmer is using things correctly? Cool

0:01 brainproxy: Sgeo: yep. https://github.com/michaelsbradleyjr/protocol-monads/blob/examples/src/monads/core.clj

0:01 see the fns check-return-type and wrap-check

0:01 not all the monads implement it yet

0:02 also, the warning message / exception thing could use some work, it probably doesn't agrue w/ "best practices" for that kind of thing

0:02 amalloy: AtKaaZ: the question doesn't make sense, and it's not clear whether it would start making sense with more context

0:03 AtKaaZ: amalloy: https://www.refheap.com/paste/6363

0:03 Sgeo: brainproxy, haven't looked too closely, but the argument list of check-return-type could use some work, I think. Haven't thought about it beyond that

0:04 brainproxy: Sgeo: it's a bit long, however, because of laziness it seems best to "catpure" the value of the dynamic vars

0:04 an easy way to do that is to pass them as arguments

0:05 also, it's not a user-facing function, so...

0:05 in which case, I can make it a defn-

0:05 Sgeo: Oh, I see, check-return-type is private

0:05 Didn't realize that at first. Yeah, make that clear.

0:05 brainproxy: yep

0:05 amalloy: AtKaaZ: you should try writing out, long-hand, what you expect a particular call to your macro to expand to. it looks like you're just flailing wildly at the moment, and that will give you some focus

0:06 AtKaaZ: amalloy: I will do that

0:07 brainproxy: Sgeo: the other thing I learned, from working through the lib's test suite and source is that it's not lazy enough

0:08 but I have plans to take apart `plus` and a few other helper functions, and reimplement as macros which carve the pieces up and wrap them in thunks

0:09 Sgeo: Hmm, I feel like I don't entirely follow, but why do you need macros? Oh, to thunkify?

0:09 brainproxy: yeah, because clojure is strict

0:09 except for macros

0:10 and a few other special cases like `if`

0:10 Sgeo: see https://github.com/jduey/protocol-monads/blob/master/test/monads/test/core.clj#L269

0:11 the author's note on that test isn't quite right; the monad isn't the problem, it's that `plus` isn't lazy enough

0:12 Sgeo: Hmm

0:12 brainproxy: the only way to work around the problem is to make `plus` a macro, thunkify, and and then rewrite the various plus-step methods to evaluate sequence member as it chews along

0:12 Sgeo: Do consider that you might confuse people if you're excessively lazy

0:12 brainproxy: well, maybe there's another way, your input will be welcome

0:13 Sgeo: true...

0:13 I guess it seems like laziness would be the "right thing" for the maybe monad

0:13 what do you think?

0:13 Sgeo: Hmm, what happens if...

0:14 Lemme paste something

0:14 brainproxy: k

0:15 Sgeo: Oh, I see, I misunderstood the test

0:16 Wait, oh, I see

0:16 Is the exception thrown from do?

0:16 Erm, m/do?

0:16 brainproxy: yes

0:17 because the arguments to plus are fully evaluated

0:17 before that fn even gets anywhere

0:17 Sgeo: But should m/do evaluate to maybe-zero-val or throw an exception, outside of m/plus?

0:18 brainproxy: outside of m/plus it would throw an exception

0:18 ivan: just discovered https://github.com/semperos/webdriver-logic

0:18 brainproxy: but the definition of m/plus suggests that m/do should just be ignored

0:19 Sgeo: brainproxy, not sure why it should be ignored?

0:19 I imagine it should be ignored in this case https://gist.github.com/4005862

0:19 brainproxy: plus returns the first monadic value that isn't maybe-zero-val

0:19 Sgeo: Ah

0:21 I do wish to note that macroifying plus would severely limit where it could be used.

0:21 brainproxy: hmm

0:22 Sgeo: Not sure if there's a good solution other than some way to do some sort of pervasive lazy thing in Clojure

0:22 brainproxy: can you give an example of a use case?

0:22 Sgeo: Hmm. Honestly, no examples off the top of my head.

0:23 brainproxy: but you're right, if it's a macro then you can't do certain things with it

0:23 Sgeo: It's the reason and and or are macros :/

0:23 Maybe a macro and non-macro version? I think this is unsatisfying somehow though

0:24 The non-macro version that isn't lazy would still be semantically correct bar the issue of exceptions

0:24 And infinite loops

0:24 (Basically, bottom, in Haskell terms)

0:24 amalloy: (map (partial apply m-plus) [[(just 1) nothing] [(just 2) (just 3)]]), right? something you can't do if it's a macro

0:25 or even just (apply m-plus [...]) really

0:25 Sgeo: Could fix the exception half of that if Clojure had a CL-style condition system

0:25 lynaghk`: I'm trying to be a good citizen and namespace my reader literals, but doing so causes reading errors (this is on clojure 1.4): java.lang.ClassNotFoundException

0:25 Sgeo: Such a system is ... fakable, to some extent, but it's been a while since I thought about that, so don't know if that would help

0:25 brainproxy: amalloy: yeah, except the argument to plus is expected to be a vector/list/etc

0:26 lynaghk`: I've tried setting up the symbols in *data-literals* both with (symbol "full/name") and (symbol "full" "name")

0:26 Sgeo: brainproxy, so, trying to refer to something such as a var that names a vector, rather than the literal vector, would break it?

0:26 amalloy: lynaghk`it's just full/name. i don't think that file is evaluated

0:26 brainproxy: Sgeo: not sure

0:27 lynaghk`: amalloy: I'm trying to do it within a (binding [*data-readers* {}] ...) form, not using data-readers.clj

0:27 brainproxy: Sgeo: if it's a macro, i guss so

0:27 Sgeo: If there's a macro version, there might not be much of a point to accepting a literal vector

0:28 Rather than just taking multiple arguments

0:28 amalloy: paste your actual binding form, lynaghk`? seems like it should work like any other var

0:28 brainproxy: Sgeo: there is inasmuch as you can still take apart the vector literal

0:28 but I think I get your point

0:29 Sgeo: okay, let me ask something else; in your opinion should *warn-on-mismatch* and *throw-on-mismatch* both default to false?

0:29 lynaghk`: amalloy: https://www.refheap.com/paste/6365

0:30 brainproxy: or would you want the *warn...* to default to true

0:30 i'm thinking both defaulting to false is the correct thing, with the return checker being completely opt-in

0:31 lynaghk`: amalloy: actually, you want this one: https://www.refheap.com/paste/6366

0:31 Sgeo: Wait, does the return checker need to be explicitely used, or is it used in your library somewhere

0:31 Let me check

0:31 lynaghk`: amalloy: using prn blows up because nil is returned.

0:31 Sgeo: Ah, you're building in wrap-check to stuff

0:31 brainproxy: Sgeo: you would use it like this (binding [m/*throw-on-mismatch* true] (m/do ...))

0:32 though I think in that branch I have *warn...* defaulting to true

0:32 Sgeo: Well, warnings aren't fatal, and it is a rather bad thing to have a mismatch

0:32 brainproxy: and yes, it's by way of wrap-check that the monadic function gets setup to have its return value checked

0:33 Sgeo: So, I think *warn-on-mismatch* true by default does seem reasonable

0:33 brainproxy: Sgeo: well in some cases it's not too bad, e.g. (m/do list [x (range 5) y (range 3)] (+ x y))

0:34 to pass the return checker you would actually do...

0:34 (m/do list [x (into '() (range 5)) y (into '() (range 3))] (+ x y))

0:34 Sgeo: brainproxy, I think in that case it probably should pass the return checker, so make the return checker work with that.

0:35 brainproxy: well ... actualy, I'm thinking the stricter the better, w/ the idea being that once you're satisfied that you're monadic funcs are doing what they should

0:35 then you can relax the checker

0:35 tomoj: lpvb: I haven't, but I think it would be interesting

0:35 brainproxy: even if technically the monadic func is mismatching

0:35 tomoj: plan to try it but don't have time right now

0:36 Sgeo: brainproxy, the list monad isn't really about lists, per se, but about having a monad that captures the idea of returning 0 or more values.

0:36 amalloy: lynaghk`: your tag name can't have . in it. not sure if that's a bug or a feature

0:36 brainproxy: Sgeo: i know

0:38 lynaghk`: amalloy: I checked the EDN spec, nothing about that: "# followed immediately by a symbol starting with an alphabetic character "

0:38 amalloy: so it sounds like a bug to me. I'll try with 1.5 and file a report if it's still borked.

0:38 amalloy: lynaghk`: EDN's spec is a joke though, right? it's fully of holes

0:39 brainproxy: Sgeo: consider this one... (m/do hash-set [x (into #{} (range 5) y (range 3)] (+ x y))

0:39 ignore my checker thing for a sec

0:39 and just consider that even though that example is messed up

0:39 you won't get a compiler or runtime error

0:40 since bind for hash-set uses clojure.set/union, which works just fine w/ non hash-sets

0:40 lynaghk`: amalloy: *shrug*. It's a bug with data-literals then.

0:40 amalloy: clojure's reader lets me put as many slashes in there as I want though

0:40 amalloy: but that is definitely against the EDN spec.

0:40 tomoj: are there associative emtyables besides vectors which may throw errors depending on what you (partial assoc (empty coll))?

0:41 brainproxy: Sgeo: so what we're really facing is the fact that w/o some kind of way to keep straight the type of the protocol-monad vs the type of the monadic fn's return values

0:41 you can get really hard to debug things going on

0:42 amalloy: tomoj: the set of associatives and emptyables are both open, so yes

0:42 brainproxy: so a really strict (even silly strict) checker mechanism

0:42 can help you not shoot yourself in the foot

0:42 tomoj: amalloy: I want a constructive proof :)

0:42 well

0:42 that's easy

0:42 amalloy: indeed. it's just a reify

0:43 lynaghk`: oh, right. Clojure 1.5 blows up swank. great.

0:43 Sgeo: brainproxy, I'm not entirely focused on this, so not entirely processing.

0:43 tomoj: I have a function that takes a map or vector and returns the same

0:43 brainproxy: Sgeo: no problem, sorry to jump all over you with this stuff

0:43 tomoj: but if I get another associative emptyable, it may fail

0:43 amalloy: lynaghk`: only the latest alphas, right?

0:43 lynaghk`: amalloy: only the ones I've tried

0:43 tomoj: just wondering if there are other interesting cases to worry about

0:43 lynaghk`: 4 and 7

0:44 brainproxy: Sgeo: anyway, maybe some other time we can look at it together

0:44 amalloy: i haven't tried since 2 or 3

0:44 Sgeo: brainproxy, ok

0:44 brainproxy: Sgeo: I do appreciate your input thus far, and it's good to see you back online

0:44 lynaghk`: amalloy: yep, the extra dots are still a problem in clojure 1.5

0:44 Sgeo: brainproxy, you're welcome, and thank you :)

0:44 It

0:44 It's good to be back online lol

0:45 amalloy: lynaghk`: it's easy to find the code that makes them break

0:45 clojure.lang.LispReader$CtorReader checks for the presence of . in a #foo tag, and decides it's a defrecord literal if it finds one, or a tagged literal otherwise

0:46 so it's clearly something rich did on purpose

0:47 or...maybe not? all that code was checked in by stuart sierra

0:47 lynaghk`: amalloy: There's java class reader syntax. I still think it's a bug; it should check if it's in *data-readers* first. If not, then try to init a java class.

0:47 amalloy: i agree

0:48 lynaghk`: amalloy: you have a file and line number where this code is?

0:49 amalloy: sure. 1171 of LispReader

0:49 lynaghk`: amalloy: thanks.

0:50 amalloy: good luck with your jira ticket (i assume)

0:59 brainproxy: where is *warn-on-reflection* implemented?

1:00 amalloy: brainproxy: find clojure-src -type f | xargs grep warn-on-reflection

1:01 brainproxy: amalloy: thanks

1:05 tomoj: I presume datomic.db.Db#with gives index performance as good as for Db's acquired from storage?

3:14 yes, it seems Db#with is fast as expected :D

3:15 so you can just Db#with some extra schema for derived indices, then Db#with the data and get much faster queries than joining on the output of query fns

3:15 shachaf: D-flat-sharp?

3:15 tomoj: :) datomic.db.Db, instance method 'with'

3:49 casperc: anyone got a tip for getting a clojurescript browser repl up and running? Seems no matter what I try the repl seems to hang, or not connect properly.

3:50 using cljsbuild btw

3:51 lpvb: what is the difference between clojure-slim.jar and non-slim?

4:16 wingy: what do people mean by redundant storage?

4:17 Raynes: https://www.refheap.com/paste/6380 Yay for first useful Haskell I've written in probably 3-4 years.

5:04 luxbock: has anyone got 'comint' working with nrepl in Emacs?

5:05 I used that with the Python shell and it worked fine, but I don't know how to enable it with nrepl, or if that's even possible

5:06 or if there's any other way to cycle through previous inputs to the nrepl through keyboard schortcuts

5:34 ivan: luxbock: don't want to use nrepl.el?

5:34 shachaf: hi ivan

5:34 Any lenses in your recent past or near future?

5:34 ivan: Haskell lenses?

5:35 shachaf: Or any other kind.

8:18 gensymv: hello, i was searching for the actual version of the clojure.contrib complex-numbers module. a google/clojars search turned out nothing.

8:18 does the module still exist?

8:24 raek: gensymv: it doesn't look like it has been "picked up" by anyone: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

8:30 gensymv: raek, so it's at best obsolete now?

8:34 ejackson: gensymv: in effect, yes.

8:36 raek: gensymv: it is a library that no one has touched for more than two years

8:39 gensymv: thanks folks.

8:53 snake-john: Hi , I wanted to play with clojure.core.reducers. my first try is (reduce + 0 (reducer [1 2 3 4] (map inc)))

8:53 but I get a ClassCastException clojure.core.reducers$folder$reify__966 cannot be cast to clojure.lang.IFn clojure.core.protocols/fn--6051 (protocols.clj:98)

8:53 any hints on what I'm doing wrong?

8:56 ejackson: snake-john: on the whole you don't want to use reducer itself, but the sugar around it

8:57 so something like (r/fold + (r/map inc [1 2 3 4])) should do it

8:58 snake-john: ejackson : ok thank you that works!

8:59 ejackson: check out the talk by rich on it. Its much clearer than the blog posts

9:00 snake-john: the one on infoq Reducers - A Library and Model for Collection Processing

9:01 ejackson: is it an hour long ?

9:01 that' the one you want

9:02 that's the one. yeah

9:04 snake-john: thank you! i get myself a coffee and listen to it!

9:07 ejackson: enjoy - its quite a trip!

11:56 hughfdjackson: to those that recommended clojurebook.com to me yesterday, thanks :D 1/4 of the way through using kindle's online reader, and it's great so far

12:01 octagon: is there a way to override private function defs in clojure?

12:01 i mean i want to be able to access a function defined using defn-

12:04 technomancy: octagon: yeah, you can go through its var

12:05 (#'whatever.ns/f ...)

12:06 octagon: technomancy: that's interesting, thanks

12:28 xeqi: hughfdjackson: awesome; you might consider tweeting @cemerick/@clojurebook that you're enjoying it

12:28 hughfdjackson: ^^ grand idea

12:50 clojure-newb: hey guys, it was a little quiet on the datomic channel, so I thought I'd ask in here... is it possible to assign a new attribute value to all entities matching a given filter ?

12:50 I've only seen updates that use entity id's so far

12:51 or unique attributs values, and I have neither

12:51 redline6561: lein-noir doesn't seem to work with leiningen 2.*. Is there a simple workaround for this?

12:52 Whoops. It's on the lein-noir github page. Nevermind me.

12:52 technomancy: redline6561: I think that plugin just handles skeleton generation?

12:53 (apart from the obvious glib "use compojure" answer)

12:53 redline6561: That's correct. The lein-noir README addresses the issue, it's just not on the homepage.

12:53 Is Compojure pretty dominant usage-wise?

12:53 technomancy: it's the best

12:54 noir uses it anyway under the covers, so yeah, pretty much everyone uses it

12:54 hughfdjackson: "A zipper is not unlike Ariadne's thread; which helps Theseus to find his way out of the Labyrinth after having killed the Minotaur" <- aah, love it when books do that

12:58 redline6561: technomancy: Is there a preferred "here's the clojure web stack" resource?

12:58 technomancy: redline6561: sure, this is a bit old but pretty comprehensive: http://brehaut.net/blog/2011/ring_introduction

12:59 redline6561: Perfect. Thank you.

13:04 hughfdjackson: zip has lift (e.g. z/vector-zip), return (z/root) and bind (or a sort, using generic 'piping' via the `->` macro)

13:04 :p would i be way off the mark if i said i smelled a monad?

13:06 * hughfdjackson still exists in that state of only partially 'getting' monads :/

13:09 gfredericks: hughfdjackson: written a lot of haskell?

13:10 hughfdjackson: nup

13:10 gfredericks: nup = no * yup ?

13:10 hughfdjackson: haha

13:10 sorry, no

13:10 i've read up on it, and played around, but nothing beyond that

13:10 i found it quite inpenetrable

13:11 gfredericks: ah okay; my single datapoint is that doing something nontrivial in haskell brings the monads much closer

13:11 hughfdjackson: clojure seemed a bit of an easier stepping stone to the dark side ;) (from js)

13:11 gfredericks: yeah that's probably true

13:12 hughfdjackson: :D searching around, it seems like i was wrong about zippers anyhow

13:12 (being monads)

13:17 :D even if they don't help me understand monads, they're awesome at least

13:21 octagon: is there a document somewhere describing the hooks available to a plugin in leiningen, and examples of using them?

13:21 gfredericks: I think all lein tasks are simple functions that you can wrap

13:22 octagon: there is a section about "hooks" in the plugin guide, but i can't make heads or tails of it

13:23 gfredericks: in /doc/PLUGINS.md?

13:23 octagon: i'm having troubles with classpath issues in my leiningen plugin, and i think maybe i need to be hooking into a hook

13:23 yes, that one

13:24 gfredericks: so you're not trying to hook anything in particular, you're just thinking that will fix your classpath problems?

13:24 octagon: gfredericks: the first thing would be to see which hooks i can hook into, and see if any of them look promising :)

13:25 gfredericks: all lein tasks

13:25 which `lein help` lists

13:26 octagon: ah ok thanks

13:29 xeqi: octagon: you can hook any function

13:29 as an example, I'm hooking deep into a private method with lein-pedantic; https://github.com/xeqi/lein-pedantic/blob/master/src/lein_pedantic/plugin.clj#L76

13:29 not recommended for private ones, but I think most public things in leiningen-core should be stable

13:30 octagon: xeqi: thanks that's interesting

13:32 xeqi: what's the purpose of that hook?

13:32 xeqi: octagon: best described in the example on https://github.com/xeqi/lein-pedantic

13:33 octagon: xeqi: cool thanks!

13:37 xeqi: octagon: I'm not sure a hook is the right spot for classpath issues in a plugin though. Most plugins that need another dependency in the project usually have a task that modifies the project

13:38 for example, https://github.com/technomancy/swank-clojure/blob/master/lein-swank/src/leiningen/swank.clj#L68

13:39 octagon: xeqi: yeah i am still a little confused by the different environments in which code is evaluated in lein

13:40 xeqi: octagon: might take a look at https://github.com/sattvik/leinjacker as well

13:40 octagon: xeqi: i think i might actually have a simpler problem in my particular case, which looking at your link reminded me of: i have a overruled dependency issue actually

13:41 xeqi: leinjacker looks cool, thanks

13:42 xeqi: I've got to run, hope you can figure out your problem

13:42 octagon: xeqi: thanks for your help!

13:42 xeqi: you could also ask in #leiningen, though I think most people there sit in here as well

13:57 daniel__: what could be causing this error when running lein repl? I/O exception (java.net.SocketException) caught when processing request: Connection reset

14:01 i can launch a lein repl :headless and then connect to it from another window...

14:01 any ideas whats the matter with lein repl anyone?

14:13 Raynes: I love Haskell. "recurseDir "/Users/raynes/code/fsutils" >>= mapM_ print"

14:13 It's like everything is (->> x y z)

14:14 I forgot how much fun it was to write >>= and </> and such.

14:27 muhoo: i sat in a clojure dojo on ztellman's team, and watched him do the whole program using ->> all the way through. i adopted the style immediately afterwards.

14:28 felt comfy, like "ls | grep | sed | awk | tee | foo"

14:34 daniel__: what could be causing this error when running lein repl? I/O exception (java.net.SocketException) caught when processing request: Connection reset

14:34 i can launch a lein repl :headless and then connect to it from another window...

14:42 can i add a dependency to a project with a relative path? i have two separate projects /backend and /api and want them to talk to each other

14:48 anyone here?

14:51 raek: daniel__: you can't with "vanilla" leiningen

14:52 are the projects two parts of the same application?

14:52 daniel__: yep raek

14:52 raek: I think it would be simpler to divide the code into two separate source directories instead

14:53 each project usually has its own release cycle

14:53 and version numbers

14:53 daniel__: hmm ok

14:54 raek: I see some ways to split up the project:

14:54 1) keep code in src/foo/backend src/foo/api (effectively one project)

14:55 2) keep code in backend/src/foo/... and api/src/foo/... (and add :source-dirs ["backend/src" "api/src"] to the project.clj)

14:56 3) actually make two separate projects and develop them in lockstep. use the "checkouts" feature so that uncommitted changes in one of the projects can be seen in the other

14:57 depencency names are not necessarily releated to any path structure

14:59 daniel__: there is also lein-sub (which I haven't tried myself)

15:00 daniel__: source-dirs looks like what i wanted, thanks

15:00 i guess that can be a relative path like "../backend/src"

15:02 devn: muhoo: do you have the program you're referring to hanging out in git somewhere? (the one you said zach did exclusively with ->>)

15:02 id be curious to look at it

15:04 daniel__: i cant find source-dirs in the sample project.clj file, is it an old example? https://github.com/technomancy/leiningen/blob/master/sample.project.clj

15:05 raek: daniel__: leiningen encourages repeatability and does therefore avoid paths pointing "out of the project" or to files "downloaded at the side". consider what happens if someone else needs to check out your code.

15:05 if a project follows leiningen's approach then things will "just work"

15:05 read more at: https://github.com/technomancy/leiningen/wiki/Repeatability

15:06 daniel__: which version of lein? the option was called ":source-dir" in leiningen 1.x

15:06 daniel__: lein 2

15:06 raek: daniel__: oh, sorry. my bad. it should be :source-paths

15:06 daniel__: thanks

15:06 ill consider all the options

15:07 raek: anyway, I would recommend 2)

15:07 daniel__: i dont think anyone will be checking out one project without the other, everything is inside a single git repo

15:07 i also have a sinatra app living under frontend

15:07 raek: or perhaps not splitting it up at all

15:07 daniel__: i'd rather split them up in case i want to experiment with refactoring one component in another project/language

15:08 its also seems like a much cleaner and intuitive directory structure

15:09 maybe i will move the project.clj back to the parent dir though

15:09 and configure that paths like that

15:24 luxbock: is there a way to disable nrepl from spewing the entire error trace when something goes wrong in Emacs? I could do with just a single line error when tinkering around with some stuff

15:34 found it, (setq nrepl-popup-stacktraces nil), seems to do the job

16:04 xeqi: anyone have a prebuilt wrap-contexted-resource ?

16:07 something better than https://www.refheap.com/paste/6384

16:22 twobitsp1ite: good afternoon/etc

16:22 so, I'm going through the clojure tutorial, and I'm a bit confused on the difference between let and binding... anyone mind helping me understand the difference?

16:24 ahh, nevermined... I should have just kept reading... :P

16:44 schaefer: hi. i'm trying my hand at the new core.logic domains. i want to find the largest value in a domain but am stumped. any help?

16:52 dnolen: schaefer: hmm, there's not really a way to do that.

16:53 schaefer: i think the thing i'm struggling with is the conceptual difference between intervals and regular lists/seqs.

16:53 dnolen: anybody tried CLJS w/ latest Closure Lib I think it's the only thing holding up a release.

16:54 schaefer: i want to do something like (membero q interval-lvar). from there, i think writing maxo is straightforward

16:54 i suspect that there's no notion of membero for domains for some reason that i don't yet understand

16:55 Bronsa: da quanto tempo ormai sappiamo che non fa per noi

16:55 wrong chan again.

16:55 dnolen: schaefer: membero is implicit

16:55 schaefer: and no domains are not like lists at all

16:56 schaefer: what does that mean "membero is implicit" ?

16:56 dnolen: schaefer: a var with a domain will range over it's domain

16:56 technomancy: muhoo: how does that work with having "teams" at a clojure dojo?

16:57 is it like a competition where groups independently implement a given exercise?

16:58 dnolen: schaefer: I strongly recommend reading Finite Domain Constraint Programming In Oz, google for the pdf, it's free to download

16:59 schaefer: it'll give you a conceptual model of how the domain functionality is intended to be used.

16:59 schaefer: dnolen: ah, that was going to be one of my next questions

17:00 dnolen: schaefer: be warned you'll likely encounter bugs, implementation details are still in flux and I'm going through that tutorial myself to verify core.logic's behavior.

17:00 schaefer: dnolen: cool.

17:01 dnolen: i'm trying to write a logic program to compute the layout of cells in a table given constraints. a range of cell sizes is possible and, for aesthetic reasons, i want the program to maximize the cell size. right now, i'm expressing the cell sizes as intervals but, perhaps, that's the wrong approach

17:02 dnolen: schaefer: sounds reasonable - bin packing, Oz Tutorial covers it

17:02 schaefer: dnolen: excellent. looks like i've got some reading to do. thanks!

17:07 tomoj: for groups at a dojo, maybe something like speed dating?

17:07 less competitive, you get to work with a bunch of different people and see more of the various solutions people are coming up with

18:16 daniel__: anyone any idea why im ending up with \ characters? is this some weird conversion from Java?

18:16 i mean, they aren't \n or \space, just \

18:19 antares_: clojure-doc.org now has a tutorial on VimClojure: http://clojure-doc.org/articles/tutorials/vim.html

18:21 tomoj: daniel__: give an example?

18:22 amalloy: &(char 4)

18:22 lazybot: ⇒ \

18:22 amalloy: control characters may print oddly based on your terminal

18:32 technomancy: merged the latest nrepl stuff for clojure-test-mode; would appreciate feedback on it before I cut a release

18:46 twobitsprite: ok, some I'm new to clojure and leiningen... but I'm trying to figure out how to get the lein repl command to include my core.clj definitions in the repl...

18:48 I just have (def test 42) in my src/my-proj/core.clj, and I run lein repl from the base of the project tree, and I've tried "test", "my-proj/test" and "my-proj.core/test"... I also tried lein compile, but it says they're not marked AOT

18:48 the lein tutorial doesn't say a whole lot about the repl

18:49 arkx: twobitsprite: did you try to require that namespace in the REPL?

18:51 amalloy: your file needs to be in my_proj/core.clj

18:51 if you create a project with lein new, it names things right for you

18:53 twobitsprite: amalloy: I did create the project with lein, and it put it in src/my-proj/core.clj

18:53 arkx: I did... it gives me ClassNotFoundException

18:54 amalloy: i know for a fact the latest version of leiningen doesn't do that, and i doubt if any version in years has. regardless, you need to rename the directory

18:54 raek: twobitsprite: are you using an old version of lein? it should have created the file in my_proj, not in my-proj

18:54 hyphens in namespace names are underscores in the path

18:55 twobitsprite: ohh... well, it's not actually my-proj... it's something else, I'm just redacting... there are no hyphens or underscors in my project name

18:55 raek: twobitsprite: how does the require look like? (require 'my-proj.core)?

18:55 the error could be from a missing quote

18:56 twobitsprite: ahhh, that's the problem, thanks :)

18:57 amalloy: suggestion: when asking for help about something you don't understand, don't redact: you probably don't know what's relevant and what isn't

18:58 twobitsprite: actually, I think I learned more by doing so :P i.e., I didn't previously know namespaces couldn't have hyphens :)

18:58 arkx: They *can* have hyphens, and often do. :P

18:58 amalloy: well, they can. but the file/directory names mustn't

18:59 twobitsprite: ahh, right

19:00 and I was just thinking to myself that using underscores in symbol names seemed fairly un-lispy

19:00 :P

19:02 ok, so next question... how do I get it to reload the source file? i.e., I edit the file, and want to see the changes in my repl?

19:02 amalloy: (require 'blah :reload)

19:02 twobitsprite: sweet, thanks

19:03 ok, back to tutorial reading :)

19:26 ForSpareParts: So, I have a namespace with a bunch of helper functions that I want the user of my library to have access to, but they assume that a certain function has been defined already -- something the user has to write in the file that'll use these helper functions.

19:27 I was just going to have a stand-in def'd to nil, but the compiler complains about collisions when I bring in the helper functions with use, and then try to override it

19:27 is there a good way to do what I'm trying to do here?

19:30 Sgeo: Sounds like you'e looking for declare, but also sounds like there's likely to be a better solution to your problem

19:30 Have those functions refer to some dynamically-scoped variable, perhaps?

19:36 ForSpareParts: Sgeo, I looked up dynamic scoping, and it seems like it'd do the trick.

19:36 Is that sufficiently Clojure-y, though?

19:36 I'm worried that I'm making my library too stateful.

19:38 Sgeo: Seems more idiomatic than relying on the user to def at a certain name, but if you can find a way to not have the requirement, say, asking the user to pass in the function in question somewhere, that would probably be even more ideal, unless it would cause a lot of repitition perhaps

19:41 ForSpareParts: I think I may have made a mistake somewhere: how does dynamic scoping prevent me from requiring the user to def a specific name? I thought it was just a built-in way to allow a name to be re def'd?

19:47 Sgeo: Well, yeah, it's to a specific name, but it's ... cleaner/less permanent

19:47 (binding [*some-dynamic* some-value] blah blah blah) outside of that form, *some-dynamic* will be back to its old value

19:47 ForSpareParts: OK.

20:06 algernon: suppose I have a map, I want to remove one elment, and add another, which would be more idiomatic? using (assoc (dissoc foo :key) :new "bar") or (-> foo (dissoc :key) (assoc :new "bar")) ? (or perhaps something completely different)

20:08 * algernon finds -> easier to read, but it's considerably longer in this case.

20:22 scottj: algernon: both are fine. using -> is personal preference. I'd say it's only slightly longer in this case.

20:23 algernon: scottj: thanks!

20:31 amalloy: longer or shorter isn't really the point. -> is best here because it keeps the dissoc-related arguments next to the symbol dissoc, and similarly for assoc. it also makes it clear that the "focus" of this operation is the map foo

20:41 muhoo: devn: i'm pretty sure it's in his github/gist history

20:43 technomancy: there's a problem, teams of 3-4 people are chosen @ random, time limit on solution, presentation of solutuions at end of night. fun

20:43 this particular one was barcode scan decoding, IIRV

20:43 gfredericks: disappointing that *print-meta* has no effect on pprint :/

20:43 muhoo: IIRC even (damn gw keyboard)

20:44 g2 keyboard. mofo

20:44 amalloy: muhoo: no, i like the typo. "If I recall verily" makes you sound very posh

21:08 muhoo: indubitably

21:57 brainproxy: so... suppose I have a lazy sequence which is the product of a map, and a few steps into it there is something that will cause it to "blow up"

21:57 ForSpareParts: Is it possible to pull in a function from another namespace with :use and then use that function as my init for gen-class?

21:58 When I try, Java complains that -init isn't there at runtime.

21:58 brainproxy: now suppose that the first member of the sequence is not something that will cause a problem, perhaps a computation that will return the long 123

21:58 it seems that in some cases I can (first mylazyseq) just fine

21:58 and in other cases I can't

21:58 bbloom: brainproxy: that has to do with sequence chunking

21:58 brainproxy: bbloom: i see

21:59 bbloom: brainproxy: in some cases, operations are applied somewhat eagerly to a chunk of the sequence

21:59 brainproxy: bbloom: in both cases when I (class mylazyseq) I just get clojure.lang.LazySeq

21:59 i.e. there is no indication of an innerclass

21:59 i.e. denoting "chunked"

22:00 but maybe that's irrelevant

22:00 in any case, thanks for letting me know; I now have some idea what's happening

22:01 bbloom: brainproxy: sorta irrelevant

22:01 LazySeq wraps a thunk function

22:01 which itself contains the chunks

22:02 brainproxy: `(->> (map (fn [a] (a)) (list #(/ 1 1) #(/ 1 0) #(/ 1 2))) (cons 123) (drop-while #(= % 123)) first)

22:03 bbloom: seems link the default chunk size is 32

22:03 brainproxy: oh it's &

22:03 &(->> (map (fn [a] (a)) (list #(/ 1 1) #(/ 1 0) #(/ 1 2))) (cons 123) (drop-while #(= % 123)) first)

22:03 lazybot: ⇒ 1

22:03 brainproxy: in that case it works fine, no blow up

22:03 but I have something that looks almost exactly like that which does blow up

22:04 and the list containing the thunks has only two things in it

22:04 i.e. it's not very big

22:05 bbloom: brainproxy: size doesn't have much to do with it. if you're getting a chunked seq for fewer than 32 items, you'll have a single chunk

22:05 so up to 32 items will be evaluated all at once

22:06 brainproxy: 32 being the number of??

22:06 bbloom: try #(-> % seq class)

22:06 lazybot: brainproxy: What are you, crazy? Of course not!

22:06 bbloom: ,(class (seq (range 5)))

22:06 clojurebot: clojure.lang.ChunkedCons

22:06 bbloom: ,(class (seq [0 1 2 3 4]))

22:06 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

22:07 bbloom: ,(class (seq (list 0 1 2 3 4)))

22:07 clojurebot: clojure.lang.PersistentList

22:07 bbloom: 32 is the chunk size

22:08 anyway, you can work around the problem by including a try/catch and a sentinel value

22:09 or test against zero

22:09 brainproxy: cool

22:10 bbloom: ,(let [div (fn [x y] (if (zero? y) :zero-denom (/ x y)))] (map #(apply div %) [[5 10] [3 2] [4 0]]))

22:10 clojurebot: (1/2 3/2 :zero-denom)

22:11 brainproxy: bbloom: i gotcha, in this case it's more about figuring out why sometimes something was lazy "as expected" (though naively) and sometimes not

22:11 bbloom: brainproxy: performance :-)

22:11 brainproxy: i actually have a variant of the functionality which is completely lazy, for those times when you just have to have the whole computation be lazy

22:12 bbloom: brainproxy: basically, you're lazily operating on 32-item chunks

22:12 brainproxy: but it was the "non lazy" version, which was sometimes lazy and sometimes not, which was puzzling

22:12 bbloom: item 33 and on won't be computed until needed

22:12 brainproxy: bbloom: i gotcha

22:12 thanks for your help!

22:12 amalloy: try/catch!? that's a pretty unpleasant solution

22:12 just un-chunk the sequence before you start doing dangerous stuff to it

22:12 bbloom: amalloy: hence i suggested the test against zero :-P

22:13 amalloy: is there an operator to unchunk?

22:13 amalloy: no, but a function to do it is trivial

22:13 mudge: hello

22:14 amalloy: (defn unchunk [xs] (lazy-seq (when-let [xs (seq xs)] (cons (first xs) (unchunk (rest xs))))))

22:15 bbloom: amalloy: that calls first on the seq, which causes the first chunk to be traversed, which blows up.... see above converstaion

22:15 amalloy: bbloom: you unchunk *before* you do the dangerous operation

22:16 bbloom: amalloy: *shrug* i'd just rather treat all exceptions as programming errors :-)

22:16 amalloy: (take 5 (map dangerous-function (unchunk coll)))

22:16 bbloom: doesn't matter; you've only solved a sub-problem. what if instead of throwing an exception, f takes an unlimited amount of time and never returns?

22:16 bbloom: non-termination is also a programming error ;-)

22:16 amalloy: or prints something to the terminal that you don't want printed

22:38 Sgeo: I should write a thing to parse Tcl stuff

22:38 Oh hmm this is a thing that exists http://en.wikipedia.org/wiki/Tcl/Java

22:43 slifer: guys i need help

22:43 why do i always get this error

22:43 No 'xpc' param provided to child iframe

22:43 when i try to connect to clojure

22:43 through web

22:44 http://localhost:9000/repl

22:44 i start the repl with this code :set REPL_CLJ="(require '[cljs.repl :as repl])(require '[cljs.repl.browser :as browser])(repl/repl (browser/repl-env))"

22:45 why do i always get this error : No 'xpc' param provided to child iframe

22:47 No 'xpc' param provided to child iframe with repl

22:58 wingy: so sick .. my test file is 2500 lines long

22:58 one single service

22:59 good thing i used midje though .. or it wouldn't even be readable https://www.refheap.com/paste/6393

Logging service provided by n01se.net