#clojure log - Mar 12 2014

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

0:02 ryantm: dissipate, Do you have a gist of code that shows shuffle not working correctly?

0:04 dissipate: ryantm, not off hand. a sufficiently large collection passed to shuffle will cause the problem though. i actually, originally discovered 'shuffle' was improperly implemented in python. then i found out clojure's implementation was just as bad.

0:05 ryantm, you can't write a unit test to reveal the problem because of the size of the permutation space involved. for instance, a deck of cards has 52! permutations.

0:06 ryantm: dissipate, an experiment should do fine

0:07 dissipate: ryantm, you can't set up an experiment to reveal the problem either. you have to just deduce the problem from known limits in the current implementation.

0:08 ryantm: dissipate, why can't you run an experiment?

0:11 awalker_: would rand-nth have the same problem? i can't see a reason to use shuffle.

0:11 dissipate: ryantm, there are 80658175170943878571660636856403766975289505440883277824000000000000 possible permutations in a 52 card deck

0:11 awalker_: nvm, ignore me

0:12 dissipate: ryantm, in order to properly run the experiment you would have to generate a great deal more than that number of permutations to show that statistically speaking certain permutations were not showing up

0:15 ryantm: dissipate, hmm yeah that makes sense.

0:20 dissipate, http://stackoverflow.com/questions/2715423/is-collections-shuffle-suitable-for-a-poker-algorithm

0:23 dissipate: ryantm, one guy made the good point in that discussion. if your seed for your PRNG is only 32 bits, you can't possibly generate all of the possible hands because 2^32 < 52!

0:27 ryantm, omg, it is worse than i thought

0:28 ryantm, Java's 'shuffle' uses a 'Random' object for its seed. it is only seeded once before it is used by 'shuffle'. the seed is only a 64 bit long.

0:29 ryantm, that means java's shuffle can only generate up to 2^64 permutations before it wraps back around. and 2^64 is way way way way less than say 52!

0:30 ryantm, actually, to be more accurate, Java's 'shuffle' uses a 'Random' object to get its random integers to select the random spot in the shuffle algorithm

0:37 ryantm: dissipate, did you read http://www.cigital.com/papers/download/developer_gambling.php ?

0:38 dissipate, the conclusion seems to be that 64bit seeds are good enough

0:38 dissipate, I guess they have different requirements than you appear to have.

0:40 dissipate: ryantm, wow, that is an epic fail. :(

0:41 ryantm, i had read this article: http://www.i-programmer.info/programming/theory/2744-how-not-to-shuffle-the-kunth-fisher-yates-algorithm.html

0:41 ryantm, it has an argument used in that paper. a naive swap algorithm does not generate a proper distribution of permutations

0:42 ryantm, the conclusion from where?

0:42 ryantm: dissipate, That paper at the link I posted

0:43 dissipate, they are only trying to make it so people can't guess the cards with computer help, not make sure every permutation is possible.

0:44 dissipate: ryantm, i see. well, that is just ridiculous because 2^64 is way way way less than 52!. so a huge number of permutations will never occur!

0:46 TravisD: dissipate: Does it really matter? You'll never have enough time to see 2^64 different shuffles... let alone 52!

0:48 amalloy: i don't understand why you're still campaigning on this, dissipate. java.util.Collections/shuffle lets you pass your own Random object, and you can use/make one that has the characteristics you want

0:48 dissipate: TravisD, yep, it does matter.

0:49 amalloy, it does not reseed the Random object. so my argument still stands. it is limited to 2^64 permutations.

0:49 TravisD: dissipate: I would be happy if the 2^64 permutations it generates are more or less evenly distributed among the 52!

0:49 ryantm: dissipate, well, that article was written in 1999. It should be more practical to make a 226 bit PRNG now.

0:50 amalloy: reseeding the Random object would be a disastrously poor choice

0:51 but like, you can use http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html, which is a subclass of Random, or you can subclass Random yourself and use something that only takes free-range grass-fed entropy

0:53 dissipate: amalloy, fair enough. and what about Clojure's 'shuffle'?

0:53 amalloy: don't use it if it's not suitable for your application

0:54 it's suitable for almost everything done by almost everyone

0:55 ryantm: dissipate, also, you could submit a bug report on Clojure JIRA to improve the documentation on shuffle.

0:55 http://dev.clojure.org/jira/browse/CLJ

0:55 dissipate: amalloy, i'm going to make an alternative that blocks on /dev/random

0:57 ryantm: dissipate, http://www.2uo.de/myths-about-urandom/

0:57 dissipate: ryantm, i think there should at least be a warning

0:58 ryantm: dissipate, sounds great

0:59 dissipate, make it happen

1:40 MattAbbott: So within a project, I want to represent pluggable modules (think supplementary books like in D&D or expansion sets for dominion)

1:41 There are several core concepts that each expansion builds upon. Does it make more sense for the namespace to be, e.g., dominion.intrigue.cards/dominion.intrigue.actions or dominion.cards.intrigue/dominion.actions.intrigue?

1:42 (well, cards and actions are very closely related in dominion i suppose; I guess dnd.phb3.class, dnd.phb.race vs dnd.race.phb, dnd.class.phb is a better comparison)

1:44 My personal inclination is that the categories are more fundamental concepts, so they should be at the higher level, with each expansion installing a file in each concept's directory when added

1:46 but from the user side, you're more likely to specify that you want to use expansion3.* than rules.* but only weapons.[base expansion2]

2:04 Any thoughts?

2:48 isaacbw: has anyone here implemented something like wolfram alpha? I'm wondering if there's any good reference material (papers and such) which at least discuss *parts* of the problem

2:49 the NLP for picking out important query terms from a sentence, perhaps

2:49 SegFaultAX: isaacbw: You might be interested in NLTK

2:51 dsrx: or opennlp, which has some clojure bindings

3:30 steckerhalter: so, I figured that the stackoverlow happens in "update-proxies": http://steckerhalter.co.vu/paste/stackoverflow.html

3:30 any ideas why?

3:30 maybe I'm doing atoms wrong :)

3:50 ambrosebs: steckerhalter: stacktrace?

3:55 steckerhalter: ambrosebs: I need to figure out first how I can get that

3:56 ambrosebs: steckerhalter: (clojure.repl/pst)

3:58 steckerhalter: ambrosebs: http://steckerhalter.co.vu/stuff/paste/trace.html

3:59 ambrosebs: 404

3:59 steckerhalter: dang

4:00 rbattula: reading through 'Clojure Programming' having a little trouble with this little bit https://gist.github.com/rajivbattula/9502649

4:02 specifically line 17, the function takes a (CamelCase) string and a number, but why is the string an argument to odd?, and the whole thing works

4:02 steckerhalter: ambrosebs: http://steckerhalter.co.vu/paste/trace.html

4:02 ambrosebs: steckerhalter: try (clojure.repl/pst *e 100000)

4:02 ,e*

4:02 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: e* in this context, compiling:(NO_SOURCE_PATH:0:0)>

4:02 ambrosebs: ,*e

4:02 clojurebot: #<Unbound Unbound: #'clojure.core/*e>

4:06 steckerhalter: ambrosebs: ok, sorry, I just messed the trace up. need to generate a new one

4:07 ambrosebs: ,(map-indexed (fn [i x] [i x]) ["CamelCase" 5 "lowerCamelCase" 3])

4:07 clojurebot: ([0 "CamelCase"] [1 5] [2 "lowerCamelCase"] [3 3])

4:07 ambrosebs: rbattula: does that help? ^

4:11 rbattula: ambrosebs: at first I was confused by where the 0 1 2 3 came from, I understand now

4:11 ,(map-indexed (fn [i x]) ["CamelCase" 5])

4:11 clojurebot: (nil nil)

4:12 rbattula: ambrosebs: how come this ^ was (nil nil)?

4:12 ambrosebs: ,((fn [i x]) 0 "CamelCase")

4:12 clojurebot: nil

4:13 rbattula: ok that make sense, nothing is being done with the arugments

4:13 OH!

4:14 ambrosebs: the 'i' in the function is the position of the list! thank you soo much!

4:15 ambrosebs: ,(doc map-indexed)

4:15 clojurebot: "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

4:15 ambrosebs: yea that's one cryptic docstring

4:15 almost as bad as ##(doc reduce)

4:15 lazybot: ⇒ "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well... https://www.refheap.com/56961

5:54 dsrx: the map-indexed docstring almost looks like a botched copy-paste job

5:54 err, never mind, no it doesn't

6:27 marek__: Hi guys

6:36 wink: oh wow, someone did it 8) http://clojure.sexy/

6:37 beamso: there is also http://emacs.sexy/

6:37 the clojure one simply redirects to planet clojure

6:38 wink: beamso: that's the cool thing - not some random stuff

6:39 like vim.sexy

6:53 steckerhalter: so I found the stackoverflow happens in "update-proxies" in the sexp (if proxies-rest ...) , see http://steckerhalter.co.vu/paste/stackoverflow.html

6:55 it fails either in the (empty? ...) or when returning @all-proxies because it does not do the reset! in that case

6:56 beamso: why are all-proxies and proxies declared differently?

6:58 steckerhalter: proxies is used to walk through all-proxies, and refilled with all-proxies

6:58 pepijndevos: Raynos, refheap seem down http://www.downforeveryoneorjustme.com/www.refheap.com/

6:59 steckerhalter: what do you mean differently?

6:59 beamso: if they are the same starting point i'd have declared them identically

6:59 pepijndevos: uhm, meant Raynes I suppose?

7:00 $mail Raynes is refheap down?

7:10 beamso: also, any reason why you don't just conj to the set?

7:18 steckerhalter: beamso: conj where?

7:18 beamso: add-proxies

7:23 steckerhalter: it would do the same? keep the unique ones?

7:34 beamso: it should.

7:39 eroomde: greetings, in trying to be an academic who makes some effort with code, rather than keep churning out matlab, I have been working through SICP, and wonder why I didn't do it years ago (suspect this happens a lot). Newly excited and confident, I'd like to use something lispy in anger, and Clojure seems like a good choice. I wonder if there's a summary anywhere on clojure for people who know Scheme, specifically any gotchas? Or should I just dive in and see w

7:41 beamso: http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Clojure_for_Scheme_Programmers

7:41 i haven't watched the video, but this guy is pretty cool : https://www.google.com.au/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0CDEQtwIwAQ&url=http%3A%2F%2Fvimeo.com%2F22675078&ei=REcgU9K7LIOpkAWfroDoDQ&usg=AFQjCNGIiRYadAKd9-puQn3JDirHYlrC1A&sig2=UTkxFNV6YUIH1YZ95B4uug&bvm=bv.62788935,d.dGI

7:41 oh, crap.

7:41 http://vimeo.com/22675078 <-- that was what i meant to link

7:42 eroomde: beamso: wonderful, thanks. I/google missed both of those earlier.

7:44 ruzu2: http://sicpinclojure.com/

7:45 eroomde: I saw that, though I was a bit scared off by the health warnings

8:00 gfredericks: amalloy: `returning` is the same as (comp first list) if you assume orderly execution of arguments

8:57 chris-free: Does anyone whether a list of Leiningen templates exists?

8:58 felher: Hello again, folks. Is there a default way to cope with IO-Errors in clojure? Does one just let the IO-Exceptions be thrown or catch it and return multiple values, kindo Go-like?

9:00 beamso: i don't explicitly catch io exceptions in my code

9:00 i do try and use with-open so that resources are opened and closed properly though

9:01 k3ny: test..

9:02 felher: beamso: I see, thanks. :)

9:03 beamso: i'm not advocating what i do as best practice, but in my code an io exception isn't really a recoverable exception

9:04 clgv: felher: if you want to debug it in a long running application you should probably catch it and log the message + stacktrace and maybe additional context

9:06 felher: Yeah. I won't be able to recover from it. I sure like to display an error message, though. So I'll got with some top-level-catch, displaying an error message and logging + stacktrace

9:06 Thanks, folks :)

9:15 iwilcox: eroomde: If you already know Scheme I'd be interested (purely out of curiosity) to know whether http://clojure.org/lisps makes easy sense to you. I never knew any other Lisp variant (before the still vanishingly small amount of Clojure I know right now) so it's a curiosity to me.

9:16 john123: What number of pages are ideal for a GSoc proposal?

9:22 k3ny: test..

9:24 clgv: iwilcox: I learnt another Lisp after Clojure, so it's the other way round. but that page makes sense when comparing both Lisps I know

9:25 iwilcox: Is it easy to read? Are the differences in commonly used, easily understood things, or are they subtle?

9:26 clgv: iwilcox: except from "Clojure is a Lisp-1" most statements are clear.

9:27 for that one you need to do some reading ^^

9:27 iwilcox: Yeah, I spent a while looking into that one ;)

10:01 bbloom: ambrosebs: does core.typed (or something else you know of) have a list of fns that are pure?

10:01 ambrosebs: bbloom: not that I'm aware of

10:01 bbloom: there's no way to express/use that property in core.typed

10:02 bbloom: ambrosebs: hmmm, ok thanks. i guess i'll have to build such a list myself at some point

10:07 gfredericks: ambrosebs: that's a conceivable extension though isn't it?

10:07 ambrosebs: gfredericks: honest haven't thought about it

10:07 *honestly

10:07 ebaxt: Anyone using http-kit with WebSockets together with IE11/IE10?

10:07 teslanick: ebaxt: I don't, but I'm also interested to know how well they work together.

10:10 ambrosebs: gfredericks, bbloom: is a boolean flag required or something more sophisticated?

10:10 bbloom: ambrosebs: higher order functions are pure if their argument functions are pure

10:11 ambrosebs: that's the main complication i can think of

10:11 ambrosebs: and then there is a whole discussion about whether or not laziness counts as purity

10:11 ebaxt: teslanick: I'm testing it now and found an issue where IE10/11 sends pong frames that http-kit don't support. Unless I've overlooked something this is a blocker to use it with IE11/10 and makes me wonder if anyone is using this combination.

10:11 ambrosebs: right

10:11 ebaxt: teslanick: https://github.com/http-kit/http-kit/pull/134

10:12 jcromartie: I think laziness can count as pure

10:12 llasram: As long as the lazy sequence thunk is pure?

10:13 jcromartie: e.g. for (map f x) as long as f is pure

10:13 teslanick: Interesting; It's annoying that it will be at least a year before the dust settles around websockets.

10:15 ebaxt: teslanick: Agree. We're testing http-kit with clj-wamp and autobahn.js, it's working like a charm except for this issue with IE10/11. You can also get IE8/9 support using https://github.com/gimite/web-socket-js

10:15 teslanick: Gross. Flash.

10:16 ebaxt: :)

10:16 devn: Tim Berners Lee /hates him/. Find out how to hack the internet with this "one weird trick". http://downloadmoreram.com/

10:16 sorry, couldn't resist.

10:17 teslanick: Using flash is like leaving your kitchen door open with a sign that says: "Cake inside. Please only take one slice."

10:17 :)

10:19 benmoss: heaven forbid

10:21 clgv: teslanick: well that strategy works in our institute when someone brings cake for his/her birthday ;)

10:22 teslanick: Unless you're Milton, and mumble about never getting any cake.

10:28 jjl`: is there a macro cookbook anywhere? I find debugging macros a bit tedious and i'm sure people have written similar things before

10:33 devn: jjl`: I suggest light table for debugging. If you use the instarepl you can have your (defmacro ...) (macroexpand-1 '(my-macro ...)) on separate lines, and watch it update as you make changes

10:33 it's pretty nice for macro writing IMO

10:33 jjl`: ooh, that's a good idea

10:33 thanks

10:34 devn: jjl`: as for a cookbook, im not sure i know of one. i know there are specific tutorials, like an old one about writing a debug macro. the joy of clojure (1st edition) had a more advanced version that let you inspect locals and gave you a REPL in your REPL kind of thing, which also utilized &env and &form IIRC.

10:34 * jjl` is normally an emacs user, but never made live debugging stuff work

10:34 pyrtsa: jjl`: It's also a good idea to implement macros as much as possible as plain functions that just happen to return lists of symbols and the like.

10:35 jjl`: *nod*

10:35 pyrtsa: Then, you could have a function (defn foo* [...] ...) and a macro (defmacro foo [...] `(...)) calling that function.

10:36 jjl`: yeah, moving the complexity out as much as possible is always good. sadly not entirely possible in this case

10:56 clgv: jjl`: macroexpand-1 in a normal repl scenario helps a lot as well. use it with pprint

10:57 * jjl` uses macroexpand-1 in a repl a lot

10:57 jjl`: lighttable made debugging that easier than usual just now though

11:24 bbloom: dnolen_: https://github.com/brandonbloom/eclj/commit/c1f0081aa34991d2a2ceea4735513e9c116deeed <- much nicer than all that "Disallowing Recur" business :-)

11:24 dnolen_: bbloom: heh nice

11:25 bbloom: i've got enough stuff working at the repl, i think i'm ready to try to bootstrap cljs core

11:31 cbp: (doc pr-str(

11:31 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:31 cbp: (doc pr-str)

11:31 clojurebot: "([& xs]); pr to a string, returning it"

11:31 cbp: hmm

11:33 (doc pr)

11:33 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

11:58 bbloom: ok unit-testing people... help me out here... i want a test "framework" that literally only exposes success/failure reporting functions. i don't want all sorts of assertions or anything like that. i just want to get a nice count of successes/failures at the end and i'll do the rest

11:58 anything like that?

12:02 gfredericks: clojure.core/atom :P

12:02 bbloom: gfredericks: that's basically what i'm doing now :-P but lein integration printing the failures etc would be nice too

12:03 gfredericks: SCOPE CREEP

12:03 koalallama: is there a json writer in clojure stdlib? I found clojure.data.json, but appears to be a separate project

12:03 bbloom: gfredericks: true story.

12:04 gfredericks: fine, you're right. if my test suite takes long enough that on-error-continue is a necessary feature, then my test suite is too big or my app is too slow

12:04 nevermind, i retract my question and i am removing the atom & using assert

12:04 whew, minimalistic over-engineering adverted, thanks

12:04 (inc gfredericks)

12:04 :-)

12:04 gfredericks: haha

12:04 devn: lol

12:10 bbloom: koalallama: if it's on the clojure github account, it's "supported" (basically) and is preferable to bloating the stdlib

12:13 InvidFlower: Hey… is there some way I can take a string of a local variable and run it through something to act as if typed the variable in instead without the quotes? I can do create a map like (def mapping {"foo" foo, "bar" bar} and use (mapping "foo") but would be nice to automate it more..

12:14 I tried (resolve (symbol "foo")) but complains about var not being able to cast to named

12:14 llasram: InvidFlower: You can write a macro to do that, but honestly it's not that useful

12:15 I've got a version kick around, which I used once or twice, then generally found my code clearer w/o it

12:15 I'll dig it up gist it, for pedagogical effect...

12:15 InvidFlower: llasram: Thanks. It is definitely a bit of a hacky thing. Probably good not to do it even for security implications but now I'm curious..

12:16 llasram: Well, no security implications, because it happens at macro-expansion time, not runtime

12:17 https://gist.github.com/llasram/9510281

12:17 This version actually produces keyword-key maps, but easy enough to s,keyword,str, if that's what you really wanted

12:18 InvidFlower: ok thanks

12:18 llasram: Oh man, I know it's old code -- an obvious missed opportunity to use `juxt` :-)

12:18 TravisD: llasram: Heh

12:19 llasram: Much improved

12:25 CookedGryphon: does anybody know if there's a handy thing for automatically resolving java imports like eclipse does?

12:25 I'm doing a fair bit of interop and it's really annoying having to look up all the packages

12:26 surely someone's written something to just search the classpath for java class names matching?

12:26 gfredericks: I don't *think* slamhound does java imports but maybe it does

12:28 CookedGryphon: ooh, looks like it *does*

12:28 according to this screencast anyway

12:29 giving it a go, thanks for the pointer!

12:29 gfredericks: np

12:29 screencast-oriented documentation (SOD)

12:29 CookedGryphon: and a lot more besides...

12:29 :P

12:34 justin_smith: CookedGryphon: (javadoc String)

12:34 maybe?

12:34 though slamhound is probably more convenient

12:35 CookedGryphon: justin_smith: that wouldn't work would it? The whole point is that i don't have it imported yet

12:36 ah, slamhound doesn't seem to play nice with midje....

12:36 I ran it and got a load of test results inserted into my ns form :P

12:36 *but* it did find most of the packages for my imports, got one wrong, but it was ambiguous anyway

12:37 llasram: CookedGryphon: Wrap all your midje tests in deftest forms :-)

12:38 CookedGryphon: ah, good tip, pity it's a problem in the first place, but still...

12:39 InvidFlower: llasram: It turns out I didn't even need a macro. Was testing it the wrong way at first I think. All I needed was this: (defn get-table [tname] (eval (symbol tname)))

12:40 llasram: InvidFlower: macro >>>>>> eval

12:40 If you can use a macro, you should use a macro

12:40 InvidFlower: llasram: True.. let me see if I can modify it for that

12:42 Hah.. so small: (defmacro get-table [tname] (symbol tname))

12:44 Which is really generic now… probably should rename it. "as-symbol" ?

12:44 llasram: Or try to figure out why you need that...? I honestly can't think of when you would

12:45 Anderkent: InvidFlower: I struggle to see why this is useful at all. Why not just type table-name instead of (get-table "table-name") ?

12:45 TravisD: InvidFlower: Is there any advantage to (get-table "foobar") over (symbol "foobar")?

12:45 Anderkent: remember that a macro will not evaluate its arg, so it will only work with literal strings

12:45 gfredericks: TravisD: it's just foobar

12:45 TravisD: True

12:46 sdegutis: o lazybot where art thou

12:46 InvidFlower: Anderkent, TravisD: The reason is that it needs to be dynamic. It is getting the name from another source and then passing to a library that expects the symbol..

12:47 TravisD: gfredericks: Ah, right, it's not a function, so the symbol would be resolved. I was thinking maybe you would need to say 'foobar

12:47 Anderkent: that won't work with a macro than

12:47 or rather, it won't work with the macro you used above

12:48 gfredericks: InvidFlower: might be good to describe what this library is doing; there might be a much simpler solution

12:49 InvidFlower: Anderkent: Yeah you're right. I hadn't tested it with a variable again after changing from a function to a macro

12:49 Anderkent: doesn't (symbol "foobar") do what you want?

12:50 llasram: Anderkent: I think they then want the value the symbol `foobar` evaluates to in the current context

12:50 InvidFlower: Which is not normal, and means there is probably a better way to do whatever you're trying to accomplish

12:52 InvidFlower: llasram: Yeah. Honestly I think I should just make a map of string names to entities anyway since that restricts the items that could be used from the name. Big security issue of being able to just reference any variable in scope by name..

12:53 Just was trying to understand how things work a bit better too since I'm super-clojure newbie

12:54 gfredericks: rule of thumb: super-clojure newbie => don't write macros

12:54 TravisD: rule of thumb: Don't write macros

12:54 with some exceptions :)

12:55 llasram: rule of thumb: experiment with language features to figure out when they are useful and appropriate :-p

12:55 TravisD: Hehe, I guess learning is a different thing all together

12:55 llasram: Yah

12:56 InvidFlower: Yeah..

12:56 llasram: That said, I do tend to write a fair number of namespace-local macros to DRY up repetition

12:56 TravisD: DRY?

12:56 llasram: Don't Repeat Yourself

12:57 It's a thing from... pragprog? Maybe older, but I believe where I first saw it myself

12:57 (the term DRY -- not the idea obvs)

12:57 InvidFlower: And one thing I could do eventually to make my life easier is to add on to the "defentity" macro that Korma uses so if I include an extra flag to it, it adds the name and data to a map for dynamic access. That way I don't have to write the separate map manually and it also restricts which tables can be queried by the dynamic engine..

12:58 TravisD: That's pretty cool. Like how you can also use it as a verb

12:58 I like that. I mean.

12:58 InvidFlower: DRY is pretty old I think…

12:59 llasram: Oh wow, is "notable": http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

12:59 So yeah, pragprog

12:59 InvidFlower: Hmm.. they do claim the prag prog book

12:59 llasram: That book is 15 years old at this point, so may qualify as "pretty old" :-)

12:59 TravisD: Heh, WET is also pretty funny

13:00 I've never read pragprog

13:01 llasram: I thought it was pretty good when I read it just out of college -- haven't read it recently so can't comment either way much on it now :-)

13:01 But it definitely significantly influence unexperience-me

13:01 InvidFlower: Argh… the whole "1990 was 10 years ago wasn't it?" thing always hits me

13:02 llasram: Almost a quarter-century ago, you mean?

13:02 InvidFlower: llasram: exactly.

13:03 TravisD: pragprog is the book by Hunt and Thomas?

13:03 InvidFlower: Doesn't seem that long ago.. hard to make my brain think across the century boundary.

13:03 berdario: Hi, I wrote this piece of code, but I'm not sure that I'm doing things correctly. Especially, I'm unsure about adding a bang (!) to functions like "dispatch" and if wrapping a call to send like that might be a good choice https://www.refheap.com/57118

13:03 InvidFlower: This has to be one of the oldest things still in use from a programming book though: http://en.wikipedia.org/wiki/C_(programming_language)#.22Hello.2C_world.22_example

13:03 llasram: TravisD: Yeah, /The Pragmatic Programmer/, by Hunt and Thomas

13:03 berdario: (not showed there is the definition for add-visit and group-visits)

13:04 TravisD: llasram: Thanks, I may check it out if the library has it

13:04 berdario: Usually you use ! to indicate that a function has side effects. I didn't really look at the code, though

13:05 berdario: TravisD: flush-queue! stores data in redis, but I'm not so sure about dispatch! since it'll call flush-queue! only once out of 5000 times

13:06 also I'm not sure about having the outer functions without the bang, but I don't know of a better way to set it up

13:06 TravisD: berdario: That function is still impure. Although, I find that people are not so committed to it

13:06 like, the random number generating functions are not marked with !

13:06 berdario: I don't know if there's a naming convention for functions that are supposed to be sent to agents

13:07 llasram: nope

13:07 berdario: (I wanted to create an argument-less function that wraps the send to be able to associate it to ring's destroy)

13:07 llasram: I'd mostly go by the "surprise" of a function turning out to have side-effects

13:07 muhoo: wow! org-mode export to html does source highlighting! all my inline #+BEGIN_SRC clojure is colorizeded

13:08 llasram: berdario: For the send-to-agent version, you can always make those local fns w/in the public versions

13:08 hyPiRion: yeah, it's lush like that

13:08 llasram: berdario: Unless you have some reason to expose them globally

13:09 berdario: llasram: I don't, but I have to expose flush-queue! to dispatch!

13:09 (I mean: I don't _have_ to, but otherwise I'd be duplicating code)

13:10 also, my rationale for not having a bang on the functions that wrap the banged ones, is that in-that-thread there're no side effect, the side effects will be executed in/by an agent... but this seems a flaky excuse for a naming choice

13:12 llasram: You may be over-thinking this :-)

13:13 john123: Hiii!

13:14 Would someone please tell me who is responsible for accepting gsoc proposals?

13:14 TravisD: john123: Maybe ask in #gsoc?

13:15 john123: I meant the one from this community TravisD

13:16 TravisD: john123: This strikes me as the sort of thing that is available somewhere online and, if not, it's intentionally private. But I don't know anything about it, so feel free to ask away

13:17 berdario: llasram: you're not the first one to tell me that :)

13:17 john123: Ok, thanks!

13:22 k3ny: test..

13:22 rasmusto: ~test

13:22 clojurebot: I don't understand.

13:34 edw: I'm trying to inspect an expression in CIDER using C-c M-i and I'm being told I need to install the cider-nrepl plugin, but I've already added it to my :user profile. Anyone run into this?

13:34 CookedGryphon: in async, does untap take the result of tap, or the channel fed into tap?

13:35 muhoo: how is cider compared to nrepl.el these days? last i looked, it seemed like there was lots of churn, and nrepl.el was safer

13:36 CookedGryphon: muhoo: that's not been teh case for some time now, cider is definitely the way to go

13:38 ystael: CookedGryphon: I find that edge cider crashes my emacs predictably whenever eldoc tries to render a hint in the minibuffer, so I have to disable it

13:39 somebody told me the most common cause of emacs freezes with nrepl/cider was auto-complete.el, so that's not even loaded

13:39 but eldoc kills the animal too

13:40 edw: C-g C-g C-g is your friend with recent CIDER releases, it seems.

13:46 I'm guessing that my SNAPSHOT of cider-nrepl is out of date and deleting it from the cache will do the trick.

13:46 * edw crosses fingers.

13:48 augustl: any better ways of doing this? https://gist.github.com/augustl/9512228

13:49 Anderkent: augustl: isn't that just re-seq?

13:49 augustl: Anderkent: ah, cool, testing

13:49 hyPiRion: Anderkent: no, it doesn't contain line pos

13:49 Anderkent: hm I guess not quite

13:49 right

13:49 augustl: my endgame is to use this data to replace the occurrences of the regexp with a parsed version

13:49 which is why I need the position :)

13:49 otherwise re-seq is exactly the same it seems

13:50 llasram: augustl: You could make it lazy if you expect lots of matches...

13:50 augustl: s/parsed/processed

13:50 llasram: And having an *earmuffed* local is unusual

13:50 hyPiRion: augustl: Have you checked out clojure.string/replace?

13:50 Anderkent: augustl: I'd look at the source of re-seq then and just adjust the result

13:50 llasram: Only things I see to comment on :-)

13:50 augustl: llasram: yeah I don't remember where I saw that, but since the matcher is mutable it sort of makes sense

13:50 llasram: Well, except earmuffs usually mean "dynamic scope", not "mutable"

13:51 augustl: llasram: also, lazy ftw, that's a good idea

13:51 llasram: yeah I thought the same thing.. But I also liked the idea of making it clear that *matcher* is mutable

13:51 but breaking convention is also bad..

13:51 hyPiRion: hmm, will check that out

13:51 pyrtsa: Anderkent: I've done the same. A lazy re-seq variant that also includes the position information of matches.

13:52 augustl: hyPiRion: seems like pretty much I want, since I can pass in a function. Nice!

13:52 hyPiRion: augustl: yeah, it's very convenient that way :)

13:52 augustl: only downside is that I don't control execution.. Was thinking of doing the processing in parallel

13:52 CookedGryphon: I'm stuck in core async with the error message "Pop without matching push" for some innocuous looking code

13:52 hyPiRion: ,(clojure.string/replace "10 2 3 9" #"\d+" (fn [v] (apply str (repeat (Long. v) "-"))))

13:52 CookedGryphon: anybody got any ideas how to debug that?

13:52 clojurebot: "---------- -- --- ---------"

13:52 augustl: but perhaps clojure.string/replace already auto parallelizes?

13:53 hyPiRion: augustl: I don't think so, no.

13:54 augustl: clojure.string/replace does too many things.. But it's awfully convenient too.

13:54 TravisD: augustl: It seems a bit hard to parallelize it. If you chunk up the string and hand the pieces to different processes, you might split one of the matches in half. If the processing takes time, I guess one process could find matches and then you could do the processing in parallel

13:54 hyPiRion: TravisD: I think he means the function calls, not the parsing itself

13:55 augustl: TravisD: yeah that's why I thought I'd create a data structure that represents the change so I can process that list in as many threads as I want, and then later join it all together

13:55 TravisD: augustl: Ah, I see

13:55 augustl: each replace operation will be one separate call to pygments which makes sense to parallelize imo

13:56 hyPiRion: oh yeah, that makes sense

13:56 TravisD: augustl: Pygments is that python thing that colourizes code?

13:56 hyPiRion: TravisD: yes

13:56 augustl: TravisD: yeah, so it'll create separate processes etc

13:56 TravisD: cool

13:56 augustl: this is completely not performance critical, but I want to get used to parallelize when I can :)

13:56 or, I don't want to do something explicitly in sequence unless I have to :)

13:56 TravisD: hehe

13:57 So is pygments pretty expensive to run?

13:57 edw: Yeah, clearing out the Maven cache didn't work...

13:58 augustl: TravisD: not really, but I do have 4 cores and I intend to use them :)

13:58 TravisD: augustl: Hehe, no harm in that :)

13:59 augustl: and I'm not pragmatic ;)

14:03 hyPiRion: ,(defn get-matches [re s] (map (fn [s m] {:start s :match m}) (re-seq re s) (for [m (repeat (re-matcher re s)) :while (.find m)] (.start m))))

14:03 clojurebot: #'sandbox/get-matches

14:03 hyPiRion: ,(get-matches #"\d+" "10 2 3 9")

14:03 clojurebot: ({:start "10", :match 0} {:start "2", :match 3} {:start "3", :match 5} {:start "9", :match 7})

14:04 hyPiRion: whoops, messed up the order, but that should work otherwise

14:04 Anderkent: CookedGryphon: do you have an example you could post? pop without matching push *shouldn't* happen, but you know how it is

14:06 wait, https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/ioc_macros.clj#L722 looks like the likely culprit?

14:07 shoulnd't the push be outside the try there

14:08 edw: Is there a way to see what middleware is a part of the current nrepl connection?

14:09 amalloy: Anderkent: yeah, that suggestion does look good to me

14:09 and indeed that's exactly how the example usage in the docstring for push-thread-bindings uses it

14:09 Anderkent: I still struggle to imagine how push-thread-bindings could fail though

14:09 CookedGryphon: Anderkent: I think I worked out what the issue was - there was some code throwing an exception inside a dynamic var binding, the push exception was obscuring the actual issue

14:09 amalloy: Anderkent: the call to merge can fail

14:10 or dereffing the var

14:10 CookedGryphon: I moved the binding outside my go block and could see the root cause, fixed that and everything's happy

14:10 Anderkent: which looks like it might be caused by what you just linked to

14:10 wait, why would that be an issue?

14:11 Anderkent: amalloy: push-thread-bindings only ever fails if it tries to change value of a non-dynamic var; LOCAL_ENV should always be dynamic

14:11 unless it NPE's, I guess

14:12 CookedGryphon: i had an npe inside the rebinding

14:12 Anderkent: I guess if the macroexpansion does assymetric pop-push it might not cause the error until the finally is hit ? Ugh.

14:12 CookedGryphon: could you post your code somewhere?

14:13 CookedGryphon: one sec, I'll un-fix it

14:13 amalloy: Anderkent: the point is that push-thread-bindings doesn't have to fail

14:14 if something inside of it fails, like the call to merge, then push-thread-bindings is never called at all

14:14 or, at any rate, never attempts to push anything

14:14 yeah, i guess never called. i wasn't sure if it was a macro or a function

14:15 Anderkent: no but my point is in this case I struggle to imagine a case where merge or defer would fail. The defer is for an internal compiler binding, should always succeed; i don't think merge ever throws

14:16 I mean maybe in some bizzare situation like OOM; but that's not really what is being hit here

14:16 CookedGryphon: Anderkent: so this is the original code, unfortunately it's not easy to reproduce, has library deps, but I can try and make a trivial example https://www.refheap.com/59a163d6549600da8893257b4

14:18 Anderkent: CookedGryphon: could you also put the stacktrace there?

14:20 CookedGryphon: Anderkent: done

14:21 and i added a little info about what happens if I move the binding

14:22 amalloy: Anderkent: i think you're right, it's hard to imagine how that can fail. of course you can *make* merge throw an exception by giving it something which isn't a map, or is a map that behaves badly in some way, but i doubt if that happens in here

14:24 Anderkent: Yeah I think it must be messing up the binding that is in his sources instead

14:29 sdegutis: ~guards

14:29 clojurebot: SEIZE HIM!

14:29 sdegutis: clojurebot: who owns you?

14:29 clojurebot: excusez-moi

14:30 technomancy: clojurebot: what is your secret superhero origin story?

14:30 clojurebot: Cool story bro.

14:30 technomancy: dang it

14:30 sdegutis: Heh that one actually worked out.

14:30 amalloy: oh, yeah. i'd be a little surprised to find that binding actually works inside of go

14:30 ToxicFrog: clojurebot: what?

14:30 clojurebot: what is short for ,(doc ...)

14:31 sdegutis: Sometimes I don't appreciate Clojure enough.. yeah, there are some inconsistencies and some features I'm not a fan of.. but when writing Clojure, I probably sigh a tiny fraction of the amount I used to sigh when writing Ruby.

14:32 Sure, the honeymoon phase is gone, but I'm much more productive and less stressed now than I was when I used Rails. I should remind myself of that more often.

14:35 technomancy: the honeymoon phase is dangerous

14:35 amalloy: clojurebot: the honeymoon phase is dangerous

14:35 clojurebot: c'est bon!

14:35 technomancy: impairs critical thinking

14:38 hyPiRion: and you tend to overuse new concepts too

14:39 devn: http://ticosa.org/

14:39 That looks interesting.

14:39 edw: Odd: (nrepl-op-supported-p "inspect-start") returns nil in Emacs yet the inspector works when manually invoked.

14:40 technomancy: devn: love it

14:42 kencausey: devn: Yeah thanks

14:42 llasram: Oh that's awesome

14:43 sdegutis: devn: I've given up on Julia, can't work on Romeo anymore, sorry.

14:43 devn: it's a fine language, but its stdlib is too focused on scientific computing and not general purpose enough to be pleasant to work with

14:44 kencausey: sdegutis: Hmm, that was one of my concerns in a cursory examination.

14:44 devn: sdegutis: i feel similarly

14:44 i got bored quickly

14:44 sdegutis: and seriously, 1-based indices?

14:44 devn: i think it's neat and all, and i like that it has some lisp roots

14:44 but it's kind of a bummer to work with

14:44 kencausey: sdegutis: Can't agree with you there ;)

14:45 sdegutis: kencausey: (def 0 1)

14:45 devn: haha

14:45 kencausey: I can deal with either choice

14:45 devn: it's a tiny thing, but it was kind of like: wtf? why?

14:45 sdegutis: :)

14:46 devn: yeah, we should obliterate that repo

14:46 technomancy: is it because it's targeted primarily at scientists rather than coders?

14:46 devn: done.

14:46 sdegutis: technomancy: methinks

14:46 technomancy: working only with 1-indexed languages might be ok, but switching between 1 and 0 sounds like a nightmare

14:47 kencausey: perhaps time in Smalltalk inured me to it.

14:47 devn: i dont think that's actually a good argument for why it is 1-indexed (the scientists vs coders thing)

14:47 technomancy: devn: you don't think that's the reasoning behind the decision, or you don't think it's justified?

14:47 devn: both

14:48 if you're smart enough to learn julia, you can handle 0 as 1

14:48 kencausey: I think being FROM scientists/mathematicians has some bearing

14:48 gfredericks: the arabic number system is 0-indexed :P

14:48 devn: yeah, that might be closer to the truth

14:48 sdegutis: well, we did get one thing right with that julia project.

14:48 sdegutis: the name.

14:48 technomancy: devn: course you *can*, but every weird quirk is one more bit of mental overhead that's likely to cause mistakes

14:48 sdegutis: devn: :D

14:49 i figure, enough langs use 0-based, that 1-based is kinda pointless now no matter how correct

14:49 technomancy: sdegutis: it only makes sense if the users of the language don't use any other languages imo

14:50 koalallama: sdegutis: it's not so bad if you use it for sabatoge. I tell all my enemy's to learn it

14:50 technomancy: which is more likely to happen in academia than anywhere else

14:50 sdegutis: koalallama: bwahahaha

14:50 technomancy: trueché

14:50 technomancy: koalallama: you mean once your attempt to get them to learn node fails?

14:50 devn: technomancy: well, julia has an interface to work with python code

14:50 which makes the 1-indexed thing more ridiculous IMO

14:50 llasram: Well, or only use other 1-indexed languages, like R

14:51 devn: i think llasram just nailed it

14:51 it's for users of R

14:51 llasram: Or Fortran

14:51 technomancy: devn: sure; I don't agree with it either

14:51 just trying to understand the justification

14:52 llasram: And a few other odd-balls

14:52 Lua, apparently

14:52 http://en.wikipedia.org/wiki/Comparison%5Fof%5Fprogramming%5Flanguages%5F%28array%29#Array%5Fsystem%5Fcross-reference%5Flist

14:52 gfredericks: odd-balls! get it??!!?!?!!

14:52 technomancy: lawl

14:52 llasram: I win at puns even without trying!

14:52 gfredericks: also multiplicative-identity-balls!

14:52 technomancy: lua was actually the only one I knew

14:53 llasram: lol

14:53 sdegutis: Given a set of [name email] tuples, what's a great way to get a list of just names and list of just emails?

14:53 kencausey: The fact that array bounds in Simula could be chosen may have influenced the choice in Smalltalk

14:53 sdegutis: ('just' meaning 'only' in this case, not 'fair')

14:53 technomancy: juxt?

14:53 clojurebot: juxt is usually the right answer

14:54 technomancy: ~botsnack

14:54 clojurebot: Thanks, but I prefer chocolate

14:54 llasram: ~chocolate

14:54 clojurebot: actually I decided I prefer botsnacks after all.

14:54 llasram: nice

14:54 ~botsnacks

14:54 clojurebot: No entiendo

14:54 llasram: aww

14:55 amalloy: sdegutis: that's just transpose, right? (apply map list names-and-emails)

14:55 technomancy: sdegutis: yeah I don't think clojure has a notion of filtering by justice

14:55 amalloy: returns two lists

14:55 devn: (filter just? ...)

14:55 technomancy: clojurebot: what is justice?

14:55 clojurebot: Pardon?

14:55 llasram: It needs to be a protocol

14:55 technomancy: clojurebot: justice is like a city

14:55 sdegutis: amalloy: ah yes, it is!

14:55 clojurebot: Ik begrijp

14:56 amalloy: &(apply map list '((name email) (name email) (name email) (name email)))

14:56 llasram: So we can support both Platonic and Rawlsian justice

14:56 amalloy: ,(apply map list '((name email) (name email) (name email) (name email)))

14:56 devn: (extend-protocol Justice ...)

14:56 clojurebot: ((name name name name) (email email email email))

14:56 amalloy: Raynes: lazybot is shirking duty again

14:56 sdegutis: amalloy: you win, kind sir

14:56 amalloy: i'd restart him myself, but i need to go teach a clojure class <3

14:56 sdegutis: amalloy: you have my thanks (go ahead, you can keep them)

14:57 I am slightly but only slightly worried about the performance of apply in this case.

14:57 amalloy: sdegutis: don't be

14:57 well

14:57 i guess you are, necessarily, eagerly realizing the whole thing

14:58 but you can't really help it. you have to either do that or walk the list twice (which also realizes it all)

14:58 sdegutis: Oh, one more part of this question that makes it more fun (but don't answer it amalloy, I don't want you to be late to teaching that class):

14:58 I'd also like to be able to map them to some values via some functions, can that be combined with the transposition to make it shorter than doing bolth separately?

14:59 technomancy: sdegutis: just comp it to list

14:59 comp your transformation I mean

14:59 sdegutis: ah yes

15:01 I wonder, if I interpose them, then do the transformation on each item (they're homogeneous) and then partition them back out into two lists, is that sane?

15:02 augustl: are there any solutions out there for parsing only the attrs of an xml/html tag? Example: " foo", " foo=bar", " foo='bar'" etc

15:02 technomancy: sdegutis: interpose name/email into one list?

15:03 sdegutis: technomancy: Yeah, say I just wanted to lowercase all these suckers.. is this technique pure insanity?

15:03 TravisD: sdegutis: It seems potentially hard to maintain. If, for example, you change the representation of emails or something later on

15:03 technomancy: sdegutis: I would just (comp list (juxt lcase lcase))

15:04 sdegutis: Ah yes, good points.

15:04 Thank you, each and all.

15:08 gfredericks: (defn tjuxt [& fns] (fn [args] (mapv #(%1 %2) fns args)))

15:09 sdegutis: This apply map comp list juxt thing is hard to fully grok.

15:12 muhoo: then use for list comps instead :-P

15:13 i found it easier to start with (for [] (-> ....)) type of comprehensions, then go with map/comp/juxt/apply stuff to show off, later.

15:14 and even still will find myself rewriting comp/map/apply stuff to use list comprehensions just to limit the wtf factor for anyone forced to read it later.

15:17 sdegutis: Hmm, can this transpositioning even be done with (for)?

15:17 (Transposing I should say.)

15:17 SegFaultAX: sdegutis: I love using apply map comp list and juxt all in the same expression. :)

15:23 TravisD: sdegutis: You can get something similar like this: (defn tp-with-for [l] [(for [[x _] l] x) (for [[_ y] l] y)]). But this isn't very exciting

15:33 trap_exit: does :optimizations :advanced break "ns-lookup" ?

15:34 since all the namespaces + defs are renamed

15:37 llasram: trap_exit: You can't use namespaces at run-time in CLJS. They aren't reified

15:37 TravisD: CLJS is the clojure to javascript compiler?

15:37 llasram: The good news is that only development tools should be dealing with that at run-time even on JVM Clojure, so there's probably a better way to do whatever you're trying to accomplish

15:37 trap_exit: llasram: yes, sounds like I have the XY problem

15:37 and should think more

15:38 llasram: TravisD: Well, by CLJS I just meant ClojureScript

15:38 TravisD: I love the XY problem

15:38 llasram: Ah

15:39 augustl: here's the finisher result, ref the regex group matching and replacing from earlier https://gist.github.com/augustl/9512228

15:40 trap_exit: real problem: I'm developing a single page application in CLJS. current approach: I want to use one namespace per "page", i.e. a login-page, a help-page, a chat-page, a svg-editor page. These pages need to know about each other [so they can jump between apps] (and I can't have circular dependencies across namespaces). <-- how shoudl I be approaching thi sproblem instead?

15:40 llasram: ^

15:40 dnolen_: trap_exit: just don't organize your program that way

15:40 trap_exit: dnolen_: how should I organize single-page apps?

15:41 dnolen_: trap_exit: use a router

15:41 trap_exit: dnolen_: can you point me to a blog post / tutorial ?

15:41 I'd like to read something in detail

15:41 or even a chapter of a book

15:41 edbond: trap_exit, see https://github.com/gf3/secretary

15:42 dnolen_: trap_exit: I don't have anything specific for you to look at beyond - https://github.com/gf3/secretary. Routing is a pretty well understood problem in client side applications - conventions in the JS world apply.

15:42 trap_exit: I don't understand.

15:42 Is this till a single page app?

15:42 it looks like multiple urls are being used

15:43 dnolen_: trap_exit: after the hash

15:43 trap_exit: the router is based on hash changes

15:44 trap_exit: dnolen_ , edbond , llasram : noted, thanks, I will study this.

15:45 TravisD: Is ClojureScript mature enough to use in production?

15:46 trap_exit: dnolen_ , edbond: is there a link where secretary is used ?

15:46 I see the documentation but no demo

15:47 edbond: trap_exit, googling "clojurescript secretary" and found http://tomconnors.github.io/blog/2013/12/03/how-i-structured-a-clojure-plus-script-web-app/

15:48 trap_exit, there is an example in readme - https://github.com/gf3/secretary#example-with-googhistory

15:49 dnolen_: edbond: huh never seen that post before, that's actually a pretty good writeup

15:49 trap_exit: sorry, I was lazy

15:49 and was looking for a live demo

15:49 but I guess I should be less lazy and set it up myself :-)

15:49 edbond: hah, I never saw it too, google wins

16:07 danlentz: hello clojurians i have a question about creating a "def-like" macro

16:08 def is a special form so i cant source it to see how it parses its lambda list

16:08 but i'd like to create a simple defdynamic macro to wrap it

16:09 without breaking the normal semantics of def

16:09 ie, all i need is to add ^:dynamic to its meta

16:09 maybe i should just do the def and then alter-meta! i think

16:10 is that the general practice?

16:13 gfredericks: danlentz: actually I'm not confident that would work

16:13 ,(def foo 12)

16:13 clojurebot: #'sandbox/foo

16:13 gfredericks: ,(.isDynamic #'foo)

16:13 clojurebot: false

16:13 gfredericks: ,(alter-meta! #'foo assoc :dynamic true)

16:13 clojurebot: {:ns #<Namespace sandbox>, :name foo, :dynamic true, :column 0, :line 0, ...}

16:13 gfredericks: ,(.isDynamic #'foo)

16:13 clojurebot: false

16:14 gfredericks: danlentz: in any case what's wrong with (def ^:dynamic ...)?

16:14 danlentz: well nothing i guess. i just thought it was ugly and it would be a straightforward macro

16:15 in common-lisp the def* forms are all macros and it is trivial to enhance them

16:15 the business of def being a special form is a bit new to me

16:20 and i kind of wanted a decent docstring too

16:20 joelash: (let [test "test"]

16:20 (cond

16:20 (re-matches #"*" test) true

16:20 :else false))

16:20 is there a reason why this doesn't work in clojurescript?

16:20 katratxo: ninjudd: ping?

16:21 gfredericks: ,(doc def)

16:21 clojurebot: I don't understand.

16:21 bbloom: danlentz: how is a general purpose metadata mechanism uglier than a proliferation of extra def macros?

16:21 gfredericks: danlentz: (clojure.repl/doc def) prints documentation

16:22 katratxo: i'm trying to use the lein-protobuf plugin without success, any hint will be apreciated https://dpaste.de/VV07/raw

16:22 olegon: Hello! I need help with LISP (Scheme). Someone? It's about continuations.

16:22 TravisD: Seems like #scheme would be the more natural place to ask?

16:22 kencausey: Yes, and don't ask to ask, just ask the question

16:23 olegon: I need to create a GIST. Wait!

16:24 justin_smith: if people would just ask to ask to ask, they would know not to ask to ask

16:24 olegon: https://gist.github.com/olegon/c27e4692aed1f3dcef99

16:25 I'm confused. Why the second versions of "mmember?" calls "print"?

16:25 kencausey: olegon: Good, not why aren't you asking in #scheme?

16:25 s/not/now/

16:26 joelash: can someone explain this behavior? https://gist.github.com/joelash/9515550

16:26 olegon: I'll join scheme. I learning Scheme thought "The Little Schemer" series to learn LISP, and then Clojure.

16:27 llasram: olegon: My analogy: that's kind of like learning Latin then Spanish because you'd like to learn French

16:29 camelCaseIsUgly: llasram: it would be a better analogy if there were unbelievably fantastic learning materials for latin, but somewhat mediocre materials for learning French

16:30 danlentz: bbloom: well as a general design pattern i have found it useful in other lisps to work toward higher level api and greater abstractions by creating ever more powerful and customized defining forms

16:30 justin_smith: IMHO scheme is more like esperanto

16:30 edbond: joelash, tooMuchTestException?

16:30 bbloom: danlentz: clojure is not other lisps :-P

16:30 danlentz: start with defclass and gradually work toward defdatabase for example

16:30 defdatabase would be an api exposed to the user

16:30 joelash: edbond: haha, the answer .*

16:30 bbloom: danlentz: generally, us clojure folks prefer to use data and functions over macros

16:31 danlentz: i see

16:31 bbloom: danlentz: it's generally not common to see apps generating vars on your behalf

16:31 danlentz: its hard to believe that such a thing is impossible though

16:31 evewn if not ideomatic

16:32 bbloom: danlentz: it's not impossible at all

16:32 it's just unsupported, b/c there is no reason to do it

16:32 justin_smith: in programming everything is "possible" in every language, and usually isn't idiomatic

16:32 bbloom: ,(def asdf 1)

16:32 clojurebot: #'sandbox/asdf

16:32 bbloom: ,(.setDynamic #'asdf true)

16:32 clojurebot: #'sandbox/asdf

16:32 danlentz: of course

16:32 bbloom: ,(do (binding [asdf 2] (prn asdf)) asdf)

16:32 clojurebot: 2\n1

16:33 bbloom: danlentz: there, just did it ^^

16:33 amalloy: (inc justin_smith)

16:33 dangit lazybot

16:33 danlentz: .setDynamic?

16:33 bbloom: danlentz: yeah, that's java interop.... mucking with the internals of vars

16:33 which is a good sign you're not doing it right :-P

16:34 danlentz: nice, though I appreciate the insight as well as the answer

16:34 llasram: danlentz: The ^:dynamic metadata is an indication to the compiler to make the var dynamic when it creates the var. You can make it work in a macro, but adding it after the fact won't change anything

16:34 gfredericks: (inc llasram)

16:34 danlentz: ah

16:34 how about the variables type?

16:34 same thing?

16:34 bbloom: danlentz: what's a "variables type"?

16:35 justin_smith: var does not have a type

16:35 data has types

16:35 llasram: danlentz: Type hints?

16:35 danlentz: yes

16:35 amalloy: (inc justin_smith)

16:35 lazybot: ⇒ 28

16:35 amalloy: (inc llasram)

16:35 lazybot: ⇒ 19

16:35 bbloom: danlentz: type hints are just more metadata

16:35 llasram: Hey, lazybot!

16:35 Well,

16:35 They kind of mean different things in different places

16:35 danlentz: but is there an analogous .setType interop method?

16:35 llasram: Oh, no

16:35 bbloom: danlentz: may i suggest looking at some existing clojure code to get a feel for how it differs from common lisp?

16:37 danlentz: understood. I consider that an essential practice. and i certainly embrace ideomatic coding in the language i intend to use

16:38 but not all practices need to be abandoned in one instant especially as i incrememntally build new ones

16:38 bbloom: danlentz: there are lots of valid reasons for "defwhatever" style macros, and indeed, they are among the most common macros in real projects. however, it's dramatically less common than in common lisp

16:38 danlentz: ok, we agree then

16:38 i thought you were hardcore against it

16:39 :)

16:39 technomancy: I wonder if defwhatever is more common than with-whatever

16:39 bbloom: danlentz: i'm hardcore against defdynamic

16:39 danlentz: the3y are much easier to implement (with macros)

16:39 -wth-macros

16:39 bbloom: b/c if you're defining some many dynamics that you need a macro for it... you're defining N-1 too many dynamics :-P

16:39 technomancy: I like with-whatever because it's usually clearer what they expand to

16:40 well

16:40 they're clearer and they actually clean things up

16:41 defroutes just being def+routes is clear enough, but it doesn't add any value

16:41 danlentz: well it was really just supposed to be a simple prototype as i plan on implementing some more useful defining macros later

16:42 i thought this would be a reasonably easy one to start with

16:42 not that i desperately need a defdynamic macro

16:42 technomancy: sure, as long as you don't subject other people to it =)

16:43 danlentz: actually my main project involves implementation of a context-oriented extension to clojure

16:43 which incorporates a number of new concepts

16:43 deflayer

16:43 layered functions

16:44 some interesting things.

16:44 im actually working on a high performance mechanism for ad-hoc composition of dynamic scopes based on the Patricia Tree

16:45 which has considerable advantages over the way context orienteation is currentluy implemented

16:45 in any langauge

16:45 sdegutis: Offtopic: What OpenID provider do you prefer to sign in with? I've only heard of people using Google, Yahoo, and StackExchange.

16:46 iwilcox: I'm least reluctant to use SE but I'll just always jump to whichever seems smallest and least capable of collating info about me ;)

16:49 danlentz: Rich Hickey was actually aware of Context Orientation when he designed the first versions of Clojure, and it was a motivation for him to add dynamic scoping to Clojure. See for example the transcript of a talk given in 2008 at http://jafingerhut.github.io/clojure-info/clojure-for-lispers-transcript.txt

16:49 So, in dreaming up possible ways to model contextual "layers" in Clojure, I've been considering a Patricia trie, which is an efficiently mergeable integer map that would provide a means of low-cost, on-demand composition of layers into a composite dynamic "context". This is potentially a significant improvement over the other existing implementations of context-orientation, the best of which, ContextL, uses class inheritance and dyn

16:49 generation of class metaobjects to achieve the same purpose. Naturally, that technique carries quite a significant expense as compared to merging Patricia tries, not to mention being extremely multiprocessing unfriendly -- major portions of the metaobject protocol are linearized using giant, global locks. To be fair, ContextL does do a credible job of caching contexts once computed, so the penalty is only paid on the first access o

16:49 given composite context. But even so, with caching being an imperfect art and the very expensive cost of any cache miss, there is some really great potential that developing this improved technique can make a useful contribution to the manner in which very efficient context oriented extensions can be modeled and integrated into clojure and dynamic languages in general. I have been discussing the matter with Pascal and he seems quit

16:49 enthusiastic.

16:50 TimMc: That was... excessive.

16:50 llasram: huh

16:51 danlentz: my apologies, then.

16:51 technomancy: I wonder if that predates his exposure to writing large-scale applications using lazy seqs.

16:52 danlentz: I have been consistently surprised by the versatility, power, expressiveness, and structure that context orientation lends to the programming model, which (for me) typically includes functional and object orientations. Context orientation is quite orthogonal to either of those, almost giving one the feeling of freedom in some "third dimension" if that makes any sense.

16:52 Context orientation provides a first-class representation that one can use in a structured way to model different circumstances and behavior within that hierarchical framework that may vary based on them.

16:53 technomancy: I can barely keep two-dimensional programs in my head as it is

16:53 danlentz: and i thought leiningen was a hypercubical model :)

16:53 technomancy: it's all just maps and functions

16:54 llasram: I prefer to model all my programs as n-dimensional hyperplanes. I then constrain n to 1

16:54 technomancy: one single macro defined in the whole codebase, and it isn't even called internally

16:54 no protocols or records

16:55 danlentz: So the idea is to 1) express these contexts as a first class entity so we can manage, operate, and represent these contexts programmatically. 2) provide for flexibility to adjust the behavior or display based on the dynamic composition of contexts which may be active at a given point in time 3) maintain the structural and lexicographic correlation of code related to the specific app functionality and provide the means to organize th

16:55 implementation according to the logical correlation with the context for which it is needed, rather than scattered around in various places that the execution of the behaviourhappens to occur.

16:56 justin_smith: technomancy: I think clojure code is one dimensional, since the compilation unit is the top level form? not totally sure of that though

16:56 danlentz: an excellent an light reading description "Language Constructs for Context Oriented Programming"

16:56 - http://www.p-cos.net/documents/contextl-overview.pdf

16:56 justin_smith: though two dimensional layout of the one dimensional data is definitely helpful for organization

16:56 TimMc: danlentz: Your messages are getting cut off. Each link in the IRC spanning tree reduces the max message size.

16:56 technomancy: justin_smith: what if compile-time is one dimension and runtime is another?

16:57 danlentz: do

16:57 doh

16:57 TimMc: "to organize th [] implementation"

16:57 justin_smith: technomancy: OK. Hmm. Let me go check my topos theory book and get back to you :P

16:58 danlentz: timmc: organize the implementation according to the logical correlation with the context for which it is needed, rather than scattered around in various places that the execution of the behaviourhappens to occur.

16:58 sorry

16:58 no wonder so few dissertations are authored using irc

16:58 :)

16:59 TimMc: OK, I think it was just the "e" in "the".

17:00 justin_smith: http://esolangs.org/wiki/Befunge <- I am certain this language is two dimensional

17:00 bbloom: danlentz: that was quite the rant, but i'm not in a position to complain about random irc rants.... anyway... i think that's a seriously backwards approach when compared to work on effect systems

17:00 brehaut: justin_smith: yes. its a 2d funge

17:01 justin_smith: i dont know if anyone has made a usable 1d funge or a practical 3d funge

17:01 sdegutis: (inc llasram)

17:01 lazybot: ⇒ 20

17:01 justin_smith: right, but that is not the usage of "dimension" that I assume others were using

17:01 danlentz: perhaps, although i suggest that judgement is somewhat cursory

17:01 bbloom: danlentz: compare with "COLA Kernel Abstraction" on here http://www.viewpointsresearch.org/html/writings.php

17:01 danlentz: and also compare to http://math.andrej.com/eff/

17:01 brehaut: justin_smith: i think it kind of is, its jsut that funges are mind numbingly low level

17:01 bbloom: danlentz: lastly, compare to http://okmij.org/ftp/Haskell/extensible/

17:02 ztellman: danlentz: unrelated to all but the first bit, but for the patricia trie: https://github.com/ztellman/clj-radix

17:02 bbloom: danlentz: might want to read those and reflect a bit before falling down a CLOS inspired rabbit hole

17:03 danlentz: i think you misunderstand the concept, but it is no matter as yet anyway

17:03 ztellman: hey zach. saw it

17:03 justin_smith: brehaut: I feel dum. searching for phrases connecting to "dimensions" and programming languages / models is getting me nothing that looks like this conversation

17:03 danlentz: did you do any further woprk on it?

17:03 bbloom: danlentz: no, i understand it just fine. i've read that paper

17:03 danlentz: it was a bit spartain the last i looked

17:04 ztellman: danlentz: it's completely functional now, I need to add some sugar to have both a clojure hash-compatible and non-compatible version

17:04 danlentz: oh, ok then

17:04 ztellman: because non-compatible ends up being twice as fast

17:05 danlentz: ztellman: i will take another look. i remember there was something that botherted me but now i cant recall for sure

17:05 sdegutis: Isn't Emacs a bit proponent of context-orientation?

17:05 ztellman: happy for feedback

17:05 danlentz: sdegutils in a very unstructured way

17:05 ztellman: bbloom: will you be at clojure/west?

17:05 bbloom: ztellman: yes

17:05 sdegutis: danlentz: are you also TravisD by any chance?

17:05 technomancy: sdegutis: sure, if you count buffer-locals. arbitrarily-defined contexts are more difficult to track in your head though.

17:06 danlentz: the idea is to create a strctured first class representation that can be programmatically manipulated and composed

17:06 the structured model is he crucial bit

17:06 sdegutis: technomancy: maybe I misunderstood context-orientation then, I thought it was basically using dynamic vars to change the meaning of functions (similar to how vim has "iw" or "a{" decide what "d" acts on).

17:07 bbloom: sdegutis: the idea is to do something smarter than dynamic scoping

17:07 technomancy: sdegutis: oh, well... that's a bit different imo. dynamic defuns are very rare in elisp.

17:07 danlentz: no, it goes considerably deeper, but the essence is implemented based on the use of dynamicallyn scoped functions

17:08 but that is a lower level detail abstracted from the user

17:08 mheld: hey y'all

17:08 I have a TCP connection to a server that's spitting messages at me -- how would I use aleph to handle those messages?

17:08 bbloom: danlentz: read the materials i linked you to. they are based on far sounder theoretical footing and yield dramatically simpler solutions to all the same problems as "context oriented programming"

17:08 danlentz: sdegutils: um no?

17:08 technomancy: sdegutis: there are lots of behavioural changes that happen on a per-mode basis

17:09 sdegutis: danlentz: ok just wondering

17:09 ztellman: mheld: what does "handling" look like in your use case?

17:09 danlentz: bbloom: will; do, thanks for the l;ink!

17:09 mheld: would I be creating a tcp-client, connecting to the server, then reading the messages off the channel that aleph creates

17:09 technomancy: but it's all pretty well-defined and well-scoped; once you set a mode upon buffer creation it's very rare to change it at runtime

17:09 mheld: ztellman: I get a stream of messages that look like "!AIVDM,1,1,,A,83`e?lhj2d<d<=MvM@@hChLUp@00,0*6A"

17:09 ztellman: mheld: first you need some way to split the messages

17:09 mheld: ztellman: I need to transform that string into something I can work with

17:09 ztellman: gloss is one way to accomplish that

17:10 remember that TCP is stream-oriented, not message-oriented

17:10 mheld: ztellman: I can do UDP messages, too

17:10 ztellman: that might be easier

17:10 then you can just use receive-all on the channel you get

17:10 and do whatever you need with it

17:10 I can't infer what the format is based one what you pasted there

17:10 mheld: and it'd continue to work as more messages got sent to the socket?

17:10 ztellman: yes

17:11 mheld: beautiful

17:11 ztellman: it's a callback that will get invoked every time a new message shows up

17:14 mheld: ztellman: ha, awesome -- it works!

17:14 ztellman: mheld: great, let me know if you have any other questions

17:14 mheld: what happens if I mis-parse something? would the exception kill the channel?

17:15 ztellman: mheld: no, but it will log the error if you don't catch it

17:15 seg_utils: danlentz: such a computation model seems like it would be hard to hold in your head as you write code

17:15 iwilcox: Hmm, gloss looks handy. Was just looking at dissolve/concentrate for js earlier and thinking a Clojure equivalent would be lovely :)

17:16 * iwilcox bookmarks

17:16 seg_utils: gloss?

17:16 ztellman: seg_utils: https://github.com/ztellman/gloss

17:17 gfredericks: John Hughes

17:18 is his talk scheduled during the time slot where haskell evangelism is allowed?

17:18 seg_utils: Is this nick easier to read btw?

17:18 iwilcox: ztellman: Hmm, and rhizome looks like it'll help with something else. I must pay attention here more often :)

17:19 bbloom: hughes keynoting? that's cool!

17:19 seg_utils: ztellman: that looks quite handy

17:19 ztellman: w.r.t. gloss, the code itself is a bit creaky, though correct

17:19 there's a rewrite brewing

17:20 dnolen_: gfredericks: Erlang QuickCheck evangelism more like it :)

17:22 gfredericks: yeah?

17:26 danlentz: what was the interrop to see if a var is dynam,ic?

17:26 irc clienmt crashed

17:26 dammit

17:26 dnolen_: gfredericks: all the talks I saw him do last year were bout Erlang QC, amazing stuff, want

17:27 danlentz: to verify .setDynamic worked

17:27 ztellman: he's pretty much a professional speaker/teacher about Erlang QC

17:27 or so the Basho guys tell me

17:28 bbloom: Bronsa: or ztellman: or some other clojure-mad-scientist...

17:28 ztellman: ?

17:28 bbloom: any idea how to implement deftype* and reify in my little interpreter thinggie?

17:29 ztellman: dunno what your interpreter thingy is

17:29 bbloom: i've done pretty much every other special form, but punted on those b/c they seem quite hairy

17:29 ztellman: https://github.com/brandonbloom/eclj

17:29 ztellman: bbloom: oh, right, I was going to ask your opinion on https://github.com/ztellman/potemkin/blob/master/src/potemkin/template.clj

17:29 it's a compile-time syntax quote, more or less

17:29 as opposed to read-time

17:29 allows you to eschew gensyms, quoting, etc

17:30 apologies for the lack of doc-strings, wrote it up last night

17:30 bbloom: ztellman: surely you looked at https://github.com/brandonbloom/backtick/blob/master/src/backtick.clj :-)

17:30 ztellman: yes

17:30 this is different, in that it uses the compiler's local context to validate the form

17:30 bbloom: ztellman: compile time? so is this for lack of reader expressions?

17:30 er i mean "feature expressions"

17:31 danlentz: ah never mind. i needed to use (var symbol)

17:31 ztellman: bbloom: this is because I'm tired of writing crap like https://github.com/ztellman/clj-radix/blob/master/src/clj_radix.clj#L175-L197

17:31 it's tedious, and easy to screw up, and difficult to read

17:31 bbloom: ztellman: yeaaah, i hate that

17:32 ztellman: this allows you to use unquote and splicing-unquote, and verifies that declared external variables and arguments aren't shadowed

17:32 so no gensyms, no ~' to do anaphoric stuff

17:32 bbloom: interesting

17:33 ztellman: you can even templatize type hints

17:33 it's going to make my brand of code a lot cleaner

17:33 bbloom: do you have an example usage somewhere?

17:33 ztellman: I will by the time Clojure/West comes around :)

17:33 bbloom: would you describe your brand of code as "HOLY META PROGRAMMING BATMAN"

17:33 ?

17:34 ztellman: eh

17:34 oh, simple example: https://github.com/ztellman/potemkin/blob/041d4bf82850c27ff792468fb1f9ece3b10de6fa/src/potemkin/template.clj#L94

17:34 ignore the misleading name

17:34 dnolen_: ztellman: heh, does that type hint in clj-radix actually work?

17:34 line 188

17:35 ztellman: dnolen: yeah

17:35 bbloom: ztellman: i like the idea of explicitly declaring available names for such hackery

17:35 danlentz: bbloom: thanks for the assist

17:36 (defmacro defdynamic [& [meta? name & value? :as args]]

17:36 ztellman: bbloom in that example, (plus-one 1 2) would fail because there's no 'y' in the lexical scope

17:36 (let [y 3] (plus-one 1 2)) would succeed

17:36 bbloom: yeah, i gotcha

17:36 dnolen_: ztellman: right, futzing around w/ primitives/arrays made me just avoid type-hinting like that.

17:36 amalloy: dnolen_: working with macros makes me avoid type-hinting in any other way :P

17:36 ztellman: dnolen_ it's an utter pain

17:37 bbloom: ztellman: i've only really ever run in to this sort of problem with java interop and (related) wanting to implement core interfaces that i realy wish were protocols

17:37 if they were protocols, extend would be much preferable

17:38 amalloy: hinting values rather than names is just fraught with peril, because of http://dev.clojure.org/jira/browse/CLJ-865

17:38 bbloom: ztellman: in the past, i've just done plain old non-syntax quote b/c i didn't need any lexical context

17:39 ztellman: bbloom: right, but I write stuff like https://github.com/ztellman/clj-tuple/blob/master/src/clj_tuple.clj, which has three levels of unquoting and requires hackery like "unify-gensyms"

17:39 bbloom: ie i wanted to not copy paste an impl for Associative or something, so i'd just write it once, quote it, stick it in a var, then write another macro to splice it in

17:39 ztellman: yeah, you're a mad scientist

17:40 ztellman: bbloom: def-abstract-type can do that: https://github.com/ztellman/potemkin/blob/master/src/potemkin/collections.clj#L54

17:40 bbloom: which is why i asked if you have a good suggestion for dynamically creating a java class w/o having to do all the crazy shit that goes in compiler.java for deftype*

17:40 :-)

17:40 ztellman: for the low, low price of using my code everywhere

17:40 bbloom: haha

17:40 ztellman: yeah, I dunno about the byte-code level of the whole thing

17:41 I tend to stay clear of that level of the machine

17:41 bbloom: i don't need bytecode level beyond emitting an "invoke" instruction to call in to my interpreter heh

17:41 ztellman: hmm

17:41 bbloom: i just need to generate the class, add methods, etc

17:41 shouldn't be too hard, but doing it by hand might be a pain

17:42 it's the hairest part of the compiler from what i can tell

17:42 ztellman: which is saying something

17:42 bbloom: why not just use a macro+eval for this? https://github.com/ztellman/potemkin/blob/master/src/potemkin/collections.clj#L54

17:42 whoops

17:42 seangrove: ztellman: Sure is. I've no idea what it's saying though.

17:43 ztellman: this: https://github.com/brandonbloom/eclj/blob/master/src/eclj/core.clj#L604-L648

17:43 bbloom: ztellman: two reasons: 1) b/c a vim macro did the trick quite fast

17:44 ztellman: and 2) i'm going to be running that file using the interpreter inside that file :-P so i was trying not to do anything tricky

17:44 ztellman: gotcha

17:44 bbloom: and that's my eval, not clojure's

17:45 i've got all this (and more) working: https://github.com/brandonbloom/eclj/blob/master/test/eclj/core_test.clj

17:45 seangrove: ztellman: Was bummed not to see you at the last cljs meetup. You want to bring some of that batman-metaprogramming wizardry to the cljs world sometime and give a talk on it?

17:45 ztellman: well, dunno what the answer for deftype is, but it's a cool project

17:45 seangrove: clj proper keeps me busy enough as it is

17:46 bbloom: ztellman: i suspect BronsAway is the man to ask

17:46 i assume that's Bronsa's away handle

17:46 seangrove: ztellman: Fair enough, the js world probably isn't ready for you anyway

17:46 ztellman: seangrove: maybe once I get through the roughly six projects I have queued up, I can take a look

17:47 I'd like to delve into it, but I'd be starting from close to zero, my frontend knowledge is close to nil

17:47 ptcek: Does anyone have an elegant solution to remove all siblings in zipper?

17:47 bbloom: ptcek: step up to the parent and replace the children

17:48 mdeboard: what did I walk in on

17:51 ptcek: bbloom: thanks, simple enough :)

17:55 bbloom: ztellman: ha! https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/jvm.clj#L250-L259

17:55 seems Bronsa punted :-P

17:56 ztellman: haha

17:56 ain't no one got time for deftype

18:03 cbp: I wonder what's a better way to write this: https://www.refheap.com/57247

18:04 It's basically a function that doesn't let the user translate a window past the boundaries of an image

18:04 amalloy: cbp: isn't that what cond-> is for?

18:05 seangrove: I was thinking as-> in case the conditions weren't mutually-exclusive

18:05 cbp: I have never used cond-> in my life regretabbly :S

18:05 seangrove: cond-> seems better though

18:05 hyPiRion: amalloy: yeah, that's the very reason cond-> exists in the first place

18:05 cbp: ah

18:05 well i feel silly now :P

18:06 amalloy: i've never used cond-> either; i don't need it since useful already has a version i like better

18:06 but this is the poster-child for cond->

18:07 pdk: that is so cond->escending

18:08 stcredzero: cond->ascending?

18:08 pdk: touche

18:09 amalloy: what's it called when you send someone an email snidely suggesting they use cond->? cond-> sending

18:10 justin_smith: works even better with core.logic/conde

18:10 amalloy: nice

18:13 sed-utils: I don't think custom user-macros are a good selling point for Clojure. Functions should generally be used instead unless they're really needed.

18:24 bob2: sure

18:25 taste is important in all aspects of programming :)

18:28 dbasch: ring/compojure question: I'm redirecting the user to / after submitting a form. I'd like to send some status information in the request, but response/redirect doesn't take any parameters other than the path. What's the right way to do this?

18:30 justin_smith: dbasch: if data is meaningful for a longer duration than the current request, it should probably go in the session store

18:31 dbasch: justin_smith: it isn't, it's just a confirmation that the form was processed correctly

18:31 justin_smith: if it is relevant to the current request, the target page should recognize the data as a request parameter

18:31 so you use that data in creating your redirect URL

18:32 dbasch: justin_smith: good point, that makes sense

18:32 justin_smith: (redirect "target/page?form=complete")

18:32 or whatever

18:33 dbasch: gotcha, thanks

18:34 justin_smith: sometimes just checking the referer may be sufficient though

18:48 sed-utils: Although I don't often miss it, it does feel like more convenient functionality is missing from ring/compojure to build up URLs like that.

18:48 Either missing or well-hidden.

18:53 justin_smith: sed-utils: ring.util.codec/form-encode

18:53 turns a map into a query string

18:53 chare: Do you guys use Apache Kafka or RabbitMQ?

18:55 sed-utils: justin_smith: aha

18:55 chare: neither.. should I be?

18:55 bob2: kafka is very good

18:55 cbp: clojure agents eheheheh

19:01 akurilin: Hey guys, does anybody know if it's possible to have Korma's compose (where) with OR rather than AND?

19:29 Bronsa: bbloom: was just reading the backlog, I don't think it's going to be any fun trying to interpret deftype* :/

19:41 gfredericks: what on earth is bbloom up to?

19:43 clojurebot: what on earth is bbloom up to?

19:43 clojurebot: I don't understand.

19:43 gfredericks: clojurebot: what on earth is bbloom up to?!

19:43 clojurebot: 'Sea, mhuise.

19:51 cbp: ~what on earth

19:51 clojurebot: what on earth is bbloom up to

19:51 cbp: :-o

19:58 gfredericks: huh

20:06 isaacbw: anyone played with GATE for NLP using clojure?

20:08 dsrx: isaacbw: i've played around with opennlp a bit, there are some pretty okay clojure bindings for it

20:12 isaacbw: dsrx: people seem to be suggesting that GATE is more "modern" than opennlp

20:18 akhudek: GATE is a very different thing

20:18 more of a framework with pluggable modules

20:19 isaacbw: akhudek: and I'm a bit confused about that. People (on StackOverflow, etc.) are suggesting it as an alternative to Stanford's Core NLP, OpenNLP, and NLTK

20:21 shep-home: Is there a LIFO channel for core.async ?

20:22 akhudek: isaacbw: as far as I've been able to tell, it's a very different thing. It's primarily rules based rather than ML based, but does allow you to somehow plug ML modules in

20:22 isaacbw: also includes a lot of workflow types stuff

20:23 isaacbw: for nlp ML libraries, stanford's is probably the best (though GPL with paid commercial license), followed by ClearNLP and OpenNLP

20:24 isaacbw: wow, that license business really surprises me

20:25 but yea, I think I'll just spend time with CoreNLP for now

20:25 thanks akhudek

20:49 is there a way to reset the repl environment?

20:49 nightfly: stop it and start it again

20:50 isaacbw: that it?

20:50 seangrove: isaacbw: There are some patterns that keep it clean, but that's the basic way, yeah

20:50 isaacbw: alright, thanks

20:50 seangrove: ~reloaded

20:50 clojurebot: It's greek to me.

20:51 seangrove: isaacbw: Check out http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded if you want to go further

20:51 clojurebot: reloaded is http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

20:51 clojurebot: Roger.

20:51 seangrove: ~reloaded

20:51 clojurebot: reloaded is http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

20:52 beamso: i need to look at that

20:52 seangrove: That's the problem with these bots. They're listening to everyone, and they still don't learn anything other than what you explicitly teach them :P

20:52 beamso: reloading a repl that has database pooling in a namespace eventually expires all database connections

20:52 akhudek: beamso: defonce on the connection object

20:53 or pool rather

20:53 though it's not clear to me why the old pool wouldn't be garbage collected

20:53 beamso: i define the database pool once and use it everywhere :/

20:54 akhudek: still, if you bind something else to the symbol via a reload, one would think that the old pool would be garbage collected

20:56 beamso: how would i bust the numbers out of a list if i was doing (max '(1 2 3 4 5)) ?

20:56 amalloy: akhudek: that's wrong in a number of ways. http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx is one good perspective on why

20:57 bob2: beamso, bust?

20:57 isaacbw: why do I need to do this (require '(ring.mock (request :as request))) instead of this (require '(ring.mock.request :as request))

20:57 akhudek: right, of course delayed garbage collection can be very much delayed

20:57 beamso: bob2: reduce (max '(1 2 3 4 5)) to (max 1 2 3 4 5)

20:57 amalloy: isaacbw: because of prefix lists. you want [] rather tahn () for the innermost list

20:57 beamso: so that i can get 5

20:57 amalloy: beamso: apply

20:58 beamso: amalloy: thanks!

20:58 amalloy: or reduce! a word you even used in your question!

20:59 beamso: d'oh

21:00 isaacbw: amalloy: oh! So require handles a [] and () differently?

21:00 amalloy: yes

21:00 isaacbw: cool beans, thanks

21:01 while I was doing that, I discovered that M-[ is undefined. Shouldn't it wrap with [] using Paredit?

21:02 amalloy: isaacbw: you can bind it to do that, of course, but i think the reason it's not bound by default is it's really hard to send a M-[ combination over ssh. ansi escape codes or something

21:02 bob2: other option is M-S-@ to select the sexp then [ to wrap it

21:02 amalloy: i bind C-c [ to paredit-wrap-square

21:02 bob2: ah nice

21:03 amalloy: M-S-@ isn't a keybinding that exists, right? S is shift, so you're just talking about M-@

21:03 and in my emacs setup M-@ is bound to mark-word, not mark-sexp or anything useful

21:04 (whereas C-M-SPC is bound to mark-sexp, so you could use that)

21:04 bob2: erk, M-C-@, you're right

21:04 didn't realise C-M-space was bound to the same thing

21:05 amalloy: C-M-@ sounds like it would be pretty hard to type!

21:06 bob2: with caps-as-ctrl it's not too bad :)

21:06 but suspect I'll be -space ing from now on

21:06 amalloy: it's still three modifiers

21:07 bob2: i'm glad to know about C-M-@ too, though. C-M-SPC doesn't really work over ssh, just like M-[ doesn't

21:07 and since i have my number and symbol keys swapped, C-M-@ is actually only two modifiers for me

21:07 so maybe i'll switch to that

21:08 bob2: ooooh, interesting

21:16 beamso: everyone is using emacs?

21:16 * beamso is using cursive

21:16 stcredzero: Doesn't count unless you also use crayons

21:17 beamso: just mechanical pencils...

21:17 amalloy: emacs is most popular, but #clojure has room for even the wackiest of editors

21:18 iwilcox: I'm a long-time vim user, but only enough to be functional, not good (they say the first ten years are the hardest; I'm past ten) and Clojure from vim seems painful. Was just mustering the motivation to install and configure all the emacs stuff and start over, when I start paying attention here and someone mentions LightTable.

21:19 beamso: oh dear

21:19 * beamso started the editor war again

21:19 akhudek: I am uncool and use cursive too

21:19 beamso: i have used emacs for clojure

21:19 stcredzero: Doesn't count unless you start an editor apocalypse that spans multiverses

21:20 iwilcox: beamso: Very occasionally, in the right room, with the right participants and the moon in the right phase, these discussions *don't* devolve to wars :)

21:20 zspencer: In the beginning was the term, and it was without form and void

21:20 mlb-: iwilcox: there's the fireplace plugin for clojure. It works pretty well for me

21:21 err, for vim, I mean

21:21 stcredzero: iwilcox: actually reality breaks down at the quantum levels, and everyone's consciousness is cast into utter pain and despair for aeons. It's just that in deep time, all realities get reconstituted by trolling Boltzmann brains.

21:21 iwilcox: I took part in a totally war-free, constructive discussion of languages on #bitcoin for about 45m the other day. It does happen.

21:22 stcredzero: zspencer: lies. I've programmed by flipping 8 switches and hitting a commit button

21:23 beamso: i'm assuming stcredzero meant http://en.wikipedia.org/wiki/Altair_8800

21:23 iwilcox: mlb-: I'll add it to my list of Interesting Things to Look Into, thanks. (Although I don't think I'd really miss vim all that much, truth be told.)

21:25 zspencer: stcredzo truly you are the greatest programmer

21:26 isaacbw: akhudek: do you have any idea how much a commercial license is for CoreNLP?

21:27 akhudek: isaacbw: I seem to recall that just one of the components was 6k a year, but wasn't able to find that number when I looked a second time

21:27 clearnlp is a very good alternative for what it covers btw

21:27 and has a good license

21:28 isaacbw: alright, I'll look into it!

21:29 muhoo: you used switches? feh, back when i was a kid we had to use all 0's, didn't even have 1's.

21:29 * muhoo puts on his yorkshiremen accent

21:29 TravisD: Two consecutive zeros meant a one. heh

21:29 isaacbw: only trouble is you can have nothing but consecutive zeros

21:29 TravisD: :D

21:29 isaacbw: that's where you have to be clever

21:29 muhoo: you can phase encode the 0's

21:30 TravisD: An ordering is fixed on the set of all turing machines, and the number of zeros picks out one of the machines!

21:30 muhoo: that's a thing of beauty

21:31 isaacbw: all possible programs exist and are identified by a number

21:31 muhoo: what is this, godel, escher, bach?

21:31 TravisD: Nah, more of an eternal braid. Perhaps made of gold.

21:32 newhack: I think they refer to book http://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach

21:32 isaacbw: which I've still yet to read, despite it being on my shelf for years

21:33 newhack: Well it's been on my 'to read' list for decades so I don't know if that is better or worse

21:35 tomjack: it's probably the reason I am here

21:35 TravisD: Like, here in this channel? Or here in this world?

21:47 dsrx: he means the dynamically bound "I", the one set by the person reading it

21:47 gfredericks: maybe he's at a G.E.B. discussion group

21:48 amalloy: gfredericks: or his parents met at a G.E.B. discussion group

21:50 gfredericks: maybe somebody at the G.E.B. discussion group told him about freenode

21:50 mr-foobar: two om questions (truly a genre bending framework) .... Q1. Can I set :initial-state for the component that I am rendering in om/root ?

21:51 tomjack: no, but my middle school girlfriend's parents met in a GEB college class..

21:51 hiredman: maybe hofstadter finally did it

21:51 tomjack: so you are not an ai built by hofstadter?

21:51 tomjack: I don't think so :(

21:54 gfredericks: it's a tricky one to rule out

21:54 pjstadig: tomjack: that's exactly what an AI built by hofstadter would say!

21:55 hiredman: gfredericks: indeed, how could he prove the negative?

21:56 gfredericks: pjstadig: I dunno I'd expect a lot more puns

21:56 how can you say "I don't think so" using three words that start with G, E, and B?

22:01 bbloom: Bronsa: so it seems

22:01 i may or may not attempt it

22:26 TravisD: Does anyone have comments on my sparse vector implementation? I'm looking for comments on both style and efficiency

22:31 isaacbw: would anyone be interested in mentoring a project to write a clojure for clearnlp?

22:31 *library

22:31 gsoc

22:38 akhudek: isaacbw: what did you have in mind for a library?

22:39 isaacbw: I'm pretty self-sufficient, so most of what I would need from a mentor is API design feedback, as I'm still pretty new to Clojure

22:39 akhudek: I already have some light bindings to clearnlp that I could release as open source

22:40 isaacbw: akhudek: something that exploses nltk-like simplicity for clearnlp

22:40 akhudek: isaacbw: the hardest parts of clearnlp to me are working with the generated trees

22:41 in any case, I might be up for being a mentor

22:41 depending on how much time it would take up

22:41 isaacbw: so maybe part of the project could be coming up with a tree structure that's more clojure-friendly

22:42 tomjack: I wrote something like that for corenlp, which was horrible

22:42 hopefully clearnlp is better..

22:43 akhudek: I haven't worked with corenlp, but clearnlp is "ok" to work with

22:43 the biggest problem I have with it is that the tokenizer doesn't give span information

22:43 so you don't know here in the original string a token comes from

22:44 esp. because the tokenizer sometimes expands tokens or contracts them, e.g it converts the greater-than-or-equal unicode into =>

22:44 or >= rather

22:45 tomjack: http://nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/util/TypesafeMap.Key.html

22:45 akhudek: ok clearnlp is better :D

22:45 tomjack: I used to think this was absurd, now I realize I've considered doing similar stuff lately :(

23:11 amalloy: TravisD: i don't know where i would find that implementation to comment on it

23:18 TravisD: amalloy: Aha! oops :) https://www.refheap.com/57522

23:19 danielszmulewicz: seangrove: ping

23:19 amalloy: (if x nil y) is pretty gross. you should be able to flip the relational operator and get (when not-x y)

23:19 seangrove: danielszmulewicz: Asking about ReactWithAddons? :)

23:20 danielszmulewicz: no!

23:20 * seangrove fails his psychic test

23:20 danielszmulewicz: seangrove: am i disturbing?

23:20 amalloy: v-apply-cwise-indexed strikes me as a terrible name

23:20 seangrove: danielszmulewicz: No, working on an interesting project right now. What's up?

23:20 amalloy: it's both long *and* uses inscrutable abbreviations

23:21 seangrove: amalloy: If it was misleading, it'd be a trifecta

23:21 danielszmulewicz: seangrove: Just a quick something...

23:21 TravisD: hehe :D

23:22 danielszmulewicz: seangrove: I was wondering if I should use an Om component for something like a HTML5 button, or if that would be overkill.

23:22 seangrove: danielszmulewicz: It depends on what you're doing. I can see some use cases for it

23:22 rational`: I'm trying to record some sounds to a WAV file, could someone

23:22 help with with what i'm doing wrong:

23:22 I'm trying to record some sounds to a WAV file, could someone

23:22 help with with what i'm doing wrong:

23:22 https://gist.github.com/rationalrevolt/9521087

23:23 amalloy: otherwise i'd say, seems like a reasonable attempt to write generic math ops for vector types

23:23 seangrove: danielszmulewicz: If you're just doing a basic app with standard css etc., I wouldn't make it a component

23:23 danielszmulewicz: seangrove: I mean, there are parts of my application that could be implemented with OM, but a couple of dommy/jquery type of thingies would do the trick.

23:23 rational`: I'm trying to record some sounds to a WAV file, could someone help with with what i'm doing wrong: https://gist.github.com/rationalrevolt/9521087

23:23 TravisD: amalloy: Thanks for the recommendations

23:23 danielszmulewicz: I'm not sure about the cost of having om components everywhere...

23:24 seangrove: danielszmulewicz: Sure. What're you thinking about doing with Om vs dommy/jquery, and is this in an existing app?

23:24 amalloy: the multimethod approach doesn't seem super-extensible, in that if you introduce N ways of representing a vector, you have to write N^2 add operators...

23:24 that's fine if extensibility isn't a goal

23:25 danielszmulewicz: seangrove: well, I have an initial page that loads when the user is not logged in, there I have links to log-in and authorize, both require an event listener and a handler.That's it. Would an Om component be justified in this case?

23:26 seangrove: danielszmulewicz: Oh I think so, definitely

23:26 TravisD: amalloy: I chose the multimethod thing because many of the algoriths should actually depend on both types

23:27 danielszmulewicz: seangrove: Cool. I was worrying about the cost of introducing Om for this, but I have not checked this. Thanks. I think I'll go with it.

23:27 seangrove: danielszmulewicz: It forces a little bit of a pattern on you, but it's otherwise tiny enough that it's not much overhead. And it's a good start to a SPA especially (the login form becomes a component eventually, etc.)

23:27 danielszmulewicz: Sure, let me know if you have any questions

23:28 danielszmulewicz: seangrove: Yeah, that makes sense. Cool. Thanks again. Sorry for the bother.

23:28 seangrove: No bother at all

23:28 mr-foobar: seangrove: hey can I ask you an om specific question ?

23:28 seangrove: mr-foobar: Sure, but just ask in general

23:30 mr-foobar: seangrove: actually two questions :) 1. Can I set :initial-state for the component that I am rendering in om/root ?

23:31 danielszmulewicz: mr-foobar: according to the documentation, no: https://github.com/swannodette/om/wiki/Documentation#wiki-root

23:32 seangrove: mr-foobar: What are you trying to do with the root component?

23:34 mr-foobar: oh. well I'm trying to secretary routes and I just have two routes that could use the same root component in different states

23:34 seangrove: mr-foobar: In general, the root component should be the same

23:35 Or at least, that's one pattern that works for us

23:35 It should determine which "dominant component" to render - a login screen, settings screen, the app itself

23:35 And secretary routes just send messages to the controller, which updates state, which tells the root component which dominant component to render

23:38 mr-foobar: seangrove: are you suggesting I use a channel to communicate with secretary ? that does sound like it would solve the problem !

23:38 seangrove: mr-foobar: https://github.com/sgrove/omchaya/blob/master/src/omchaya/routes.cljs

23:39 danielszmulewicz: mr-foobar: yes, let your Om component be able to deal with any routes.

23:39 mr-foobar: https://www.refheap.com/56178

23:42 mr-foobar: *_* awesome !! you have code for backbutton too, i was wondering about that.

23:42 how do I give irc karma here :)

23:44 ( map inc seangroove danielszmulewicz)

23:44 danielszmulewicz: mr-foobar: your back button is served: https://gist.github.com/danielsz/8086074

23:45 mr-foobar: enjoy :-)

23:49 mr-foobar: :D Q2) From what I understood from om/wiki/Basic Tutorial and the way I am putting that to code is, I am treating the (go ... recur) in the main-component' IWillMount as the central place for all event handling.

23:51 sound fair enough right ? I have about 8 events that I generate, so far and I'm using a cond in the go block to do the processing

23:51 danielszmulewicz: mr-foobar: sounds good to me.

23:54 mr-foobar: danielszmulewicz seangrove thanks ! om+core.async is definitely giving a new way to reason code. I jquery my code would have already been a noodle bar now.

23:55 seangrove: mr-foobar: I would recommend giving Omchaya a look to see how event routing is handled there. We do it quite differently, and it scales (in terms of code complexity) very well

23:55 mr-foobar: Take a look at the flow diagram https://github.com/sgrove/omchaya#omchaya-design

23:55 mr-foobar: And then what a controller ends up looking like https://github.com/sgrove/omchaya/blob/master/src/omchaya/controllers/controls.cljs

23:57 danielszmulewicz: mr-foobar: always prefer seangrove's recommendation over mine. Omchaya is much more thorough than what I suggest.

23:58 seangrove: I just suggest what's worked for us, it's certainly not gospel :)

23:59 mr-foobar: seangrove *_* seems like a whole new (shift paradigm) you are doing there ...

Logging service provided by n01se.net