# #clojure log - Feb 07 2015

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

0:00 sdegutis: Super portable.

0:00 Blake1: But if I get the core right I could move it to different Clojure VMs and see ... stuff.

0:00 sdegutis: I'm currently investigating PureScript.

0:02 Blake1: Int'resting. I thought I would see what untyping this code could do for it.

0:02 sdegutis: Sure go for it.

0:04 Blake1: For example, one of my utility classes was an integer array, where you didn't have to know the size of the integer in advance. Heh.

0:04 Which strikes me as sort of funny now.

0:12 Blake1: Reddit?

0:12 That's...huh.

0:13 Oh, that's interesting...wasn't someone here saying Haskell was rife with bad decisions that made it dangerous to use? Or was that Scheme?

0:13 justin_smith: sdegutis: almost forgot, there is also F#

0:14 sdegutis: Blake1: I imagine that was Scheme.

0:14 justin_smith: lol, someone in #ocaml said the exact same thing almost at the exact same time

0:15 Blake1: So, if I do this thing in Clojure, am I going to get in trouble when it comes to the bit/byte twiddling stuff? Will I have to go into Java?

0:15 justin_smith: Blake1: you can bit-twiddle in pure clojure

0:16 ,(bit-or 7 (bit-shift-left 42 1))

0:16 clojurebot: 87

0:17 Blake1: justin_smith: My system uses a lot of byte-arrays, and treats them as lists of bits. Another thing is I load a byte array and treat it as a 1, 2, 4 or 8 byte integer array, depending on certain meta-data.

0:18 justin_smith: Blake1: you can use ByteBuffer for that

0:20 Blake1: justin_smith: Cool...well, except for being Java. =P (Which isn't really a problem but pure would be nice. OTOH, if I'm going down to the byte level, impure is...likely.)

0:21 tomjack: have you seen ztellman's gloss?

0:22 justin_smith: ,,(.getDouble (java.nio.ByteBuffer/wrap (byte-array [1 2 3 4 5 6 7 8]) 0 8))

0:22 clojurebot: 8.20788039913184E-304

0:22 Blake1: Is that a personal question?

0:22 justin_smith: Blake1: the above treats 8 8 bit bytes as one 64 bit double

0:24 as you might imagine, there are also .getShort, .getInt, .getLong etc. etc. etc.

0:24 also the above is 100% free of mutation

0:24 Blake1: justin_smith: Cool. I feel like this should end up being a lot less code in Clojure than Pascal.

0:25 justin_smith: well .getDouble does advance a read pointer but hey that doesn't escape scope at all :)

0:25 Blake1: tomjack: Thanks for the gloss tip. I'm not doing anything with structures. Everything is the same simple physical shape.

0:25 tomjack: is e.g. the metadata for the integer size encoded in the bytes?

0:26 Blake1: tomjack: Actually, no...it's in the filename. =)

0:26 justin_smith: Blake1: from everything you described so far, you can probably do it all with the bitwise ops plus some very local ByteBuffers that stay local enough for the mutation not to leak (that's why I demonstrated the offset / length args to the constructor)

0:27 tomjack: ah, then your usage of gloss would be even more minimal than I thought. but I think you could avoid touching byte-centric java APIs?

0:27 Blake1: tomjack: Ah...okay, yeah, I'll keep that in mind. It'd be cool to try this out on various VMs.

0:27 justin_smith: tomjack: when your domain is bytes, how is byte-centric API a disadvantage?

0:28 tomjack: might not be

0:28 Blake1: justin_smith: Not the byte-centric API, the Java API.

0:28 tomjack: if I just want to parse an array of integers which is represented weirdly and move on, I'd rather not touch a byte-centric API, though

0:28 Blake1: justin_smith: Well, this code was very functional to begin with, now that I look at it. Which is kind of cool. Everything was as non-mutating as I could make it in Object Pascal.

0:30 justin_smith: Blake1: and as I mentioned, other than the read-pointer state (avoided by using the offset / size args) ByteBuffer is not mutating

0:31 Blake1: justin_smith: Cool. I'll give it a try.

0:32 tomjack: ah, I wasn't reading your messages justin_smith, only Blake1's. that looks better than I assumed ByteBuffer would be

0:32 justin_smith: tomjack: it's quite direct, you hand it the bytes, and ask for a given type, and there it is

0:32 tomjack: (still not as 'nice' as gloss to me, but probably nice enough to make me pause before killing my jvm and adding a dep :))

0:32 justin_smith: heh

0:33 of course you still might end up doing some bitwise ops if you encoding had non-power-of-two sizes or something

0:33 Blake1: justin_smith: I could do that for larfs. Compactness and speed was the point of this library, though, so there'd have to be a damn good tradeoff.

0:34 justin_smith: Blake1: non-pow-of-2 sizes?

0:35 tomjack: I expected to find that gloss couldn't handle that

0:35 Blake1: tomjack: Oh, lol, no! This is for database stuff.

0:35 justin_smith: Yeah.

0:35 This is a DBMS system I developed a few years back. It's sort of like Amazon Redshift.

0:36 sdegutis: Pointed to it.

0:36 sdegutis: Oh.

0:36 Uh.

0:38 Blake1: sdegutis: lol...sorry? It's interesting, no?

0:38 Or am I being naive?

0:39 sdegutis: sure

0:39 justin_smith: he's just lucky he posted it during permitted haskell evangelism hours

0:39 Blake1: hahahah

0:42 I'm intrigued by the backlash against dynamic typing I'm seeing these days. I would've figured it was destiny--well, ten years ago or more, I figured it would take over.

0:54 sdegutis: Blake1: static typing with type inference and reasonable polymorphism has all the same benefits of dynamic typing with none of the drawbacks

0:55 Blake1: you can usually write just as little code, worrying just as little about types, and also have assurance that it won't compile if there's a type error, instead of failing at runtime

0:55 Blake1: oh the other hand, Clojure often fails at runtime for me (while I'm doing TDD) which means I have to wait like 20 seconds while my whole test suite runs just to find out I made a simple typo.

0:56 Blake1: sdegutis: Static typing that you, the programmer, don't actually do, then?

0:57 sdegutis: Blake1: static typing simply means your types can be definitely known by looking at your source files, without actually running them

0:57 Blake1: it doesn't mean you actually *write* the types down in those source files

0:57 Blake1: hence type inference

0:57 Blake1: and yes, writing type names down in source files is annoying; fortunately we don't have to, thanks to type inference

0:59 vas: justin_smith: hey man, thanks for helping me figure out the csrforgery protection stuff. turned out i just needed to change def app to use "wrap-session" and ring does the rest :]]] (def app (wrap-session app-routes site-defaults))

0:59 Blake1: sdegutis: I haven't had any problems with dynamic typing in Clojure, apart from my original feeling of working without a net (when I learned Smalltalk in '92).

0:59 sdegutis: Blake1: welp.

0:59 Blake1: sdegutis: But if you're not stating the type, isn't there still the issue of the compiler inferring a type different from what you meant?

0:59 tomjack: I don't think it has _all_ the same benefits

1:00 sdegutis: tomjack: oh?

1:00 Blake1: that usually doesn't happen

1:00 Blake1: sdegutis: (I ask from ignorance, not having used any tools that did =good= type inference.)

1:01 sdegutis: Blake1: meh, I often end up documenting the argument/return types in my Clojure apps anyway

1:01 Blake1: so it doesn't hurt me any to add it in function signatures

1:02 tomjack: right, if you want to not worry about types, I don't think you go for Haskell :)

1:03 Blake1: sdegutis: Well, I need to play with it, 'cause I'm not getting it. Does core.typed do inference?

1:03 tomjack: But it's so much better, apparently. =P

1:04 sdegutis: Blake1: I never said it's better

1:05 Blake1: sdegutis: Oh! No, I didn't mean you! I was talking about that reddit page.

1:05 sdegutis: Oh.

1:05 Anyway.

1:05 tomjack: sdegutis: basically it's missing the (possible) advantage of "not having to understand how to work with a static type system", I think?

1:06 sdegutis: tomjack: I'd argue that's not a thing in the first place

1:07 tomjack: working with a static type system, in comparison to working with a dynamic type system, just means knowing to look for errors in the console instead of in backtraces

1:07 tomjack: either way, you're still working with a type system, and type errors will surface *somewhere*

1:07 tomjack: yes, understanding the meanings of those errors, and making the requisite changes, is what I meant by "working with a static type system"

1:08 sdegutis: tomjack: sure, but using that definition, there's a huge variance in static type systems

1:08 tomjack: some give horrible errors, some give extremely good ones

1:08 tomjack: but regardless, I need to understand a type system, no?

1:09 sdegutis: tomjack: Not any more than you do with a dynamic type system.

1:09 dynamic system: "error: tried to call method "append" on a string object"

1:10 static system: "error: no method "append" on a string object"

1:10 tomjack: anyway, it's moot to me, because I _do_ want to worry about types, and want something better than Haskell. just confabulating about why I seem to prefer Clojure to Haskell, I guess

1:10 sdegutis: tomjack: In what way do you want something better than Haskell? Also, in what way aren't you satisfied with Clojure?

1:11 tomjack: I want total dependently typed, and Clojure isn't

1:11 though given the choice between Haskell and Clojure (which I am), I seem to choose Clojure for some reason.. hmm

1:11 Blake1: dependently typed?

1:12 sdegutis: tomjack: I do too, to be honest.

1:12 tomjack: re: choosing Clojure

1:12 tomjack: Blake1: my personal confabulation is that haskell's type system is not expressive enough (too restrictive), and Clojure stays out of my way. dependent types are more expressive

1:13 sdegutis: tomjack: that said, I really want to find a new favorite language that isn't tied to the JVM, also a language that's statically typed, which is why I'm not satisfied with Clojure

1:13 tomjack: a Clojuresque LISP, maybe?

1:13 pdk: c++ meets both criteria!

1:14 justin_smith: sdegutis: I don't get why you'd come here looking for it

1:14 sdegutis: justin_smith: I don't think I was?

1:14 justin_smith: oh yeah I totally was, now I remember

1:15 justin_smith: I came here for that cuz when people like you and technomancy are here, I get good answers ;)

1:15 justin_smith: hehe

1:15 sdegutis: (his answer is "OCaml")

1:15 Jaood: tomjack: what language with the dependent types have you use? idris?

1:16 why did techomancy left #clojure?

1:16 he seems to be in the network

1:16 tomjack: Jaood: not yet. I want a LISP so it's mostly Clojure for me for now

1:27 also I want good set/map/vector builtin data structures with literal syntax... :(

1:33 the set and map API should only optionally assume = is decidable for the key type. if it's not, count should be impossible, but one should at least be able to get an upper bound on the number of elements. that bound should be 1 for the set of functions #{(fn [x] x) (fn [y] y) identity}, and probably 2 for #{#(+ %1 %2) #(+ %2 %1)} (though the count of that is actually 1). seq shouldn't work unless you prove that your reduction over the

1:33 seq is idempotent... etc

1:33 this is maybe why I don't use Haskell, I think :)

1:38 Blake1: tomjack: What's the advantage of built-ins here? I thought the point (again, I'm a naif) here, at least in part, is that you can add that stuff in yourself.

1:56 tomjack: well, e.g. {:foo 1 :bar 2} should be in the syntax, and you shouldn't be able to magically define new syntax like {k v ...}

1:57 you could maybe do like Agda and allow the user to bind a datatype with certain operations to that syntax, but that's a mess

1:58 if you have two Agda libraries which bind the same builtin syntax to different data structures, you're, uh, gonna have a bad time

1:58 it's the "batteries-included" principle seen in Clojure and EDN I guess

1:59 Blake1: Sorta the same issue in any language where "you can always roll your own!"

2:03 dagda1_: I've been trying to solve this project euler problem https://www.hackerrank.com/contests/projecteuler/challenges/euler007 to display the nth prime number, I've tried multiple versions and they all work but they time out

2:04 here is my latest which is still too slow https://gist.github.com/dagda1/98caf10b195adda97f27

2:18 Blake1: Jaood: I believe he's doing charity work.

4:24 dysfun: Jaood, Blake1: yes, he's off doing charity work in africa. he wrote a blog post about it recently

4:55 kir: Question about (doc ) : Is there some way to replace the docs with my own notes, without modifying src - explanations provided seem arcane to me?

4:56 dysfun: no, but you can fake it with an atom of alternative docs and a new function that maps one to the other

4:57 but it's probably not the most useful thing

4:57 better to keep a snippets file somewhere to demonstrate how to do things you currently find confusing

4:57 and to ask questions of course

4:58 the docs are a little...behind where they should be right now

4:58 there are some great alternative resources on the internet

4:58 kir: dysfun : I have extensive notes, but those functions (doc ), (find-doc ) are very convenient in the REPL

4:59 dysfun: well you could start with a map inside an atom

4:59 if you want the same calling convention as doc, it'll have to be a macro

5:00 kir: could you provide a brief example please?

5:01 dysfun: ,(def my-docs (atom {}))

5:01 clojurebot: #'sandbox/my-docs

5:02 kir: I get the idea, and I'll need to load that map on reloading of the REPL

5:02 thx

5:03 dysfun: ah well i was going to continue but since you get the idea :)

5:03 the doc things come from an nrepl middleware fyi

5:03 so you can use the same thing to load yours

5:04 kir: great

5:04 dysfun: just remember to map fully qualified symbols as the key

5:04 because otherwise you won't be able to use it without loading all the namespaces

5:05 kir: makes sence, thx.

5:06 dysfun: and hence why it should be a macro rather than a fn, otherwise you'll have to call it like (my-doc 'my-fn)

5:07 you'll need to do some magic to map symbols to the fully qualified form

5:08 kir: I enjoy challenges/magic :)

5:09 dysfun: likewise, although i seem to have bitten off a bit too much magic to chew recently

5:10 the clojure cheatsheet contains most of the functions you'll need though so it should be pretty straightforward

5:11 * kir goes to investigate and test ; thanks dysfun kindly

5:22 dysfun: yw

7:52 justin_smith: ,({+ "adds all the args"} +) ; dysfun: without a macro

7:52 clojurebot: "adds all the args"

7:57 justin_smith: ,(do (alter-meta! #'+ assoc-in [:doc] "adds all the args") (doc +))

7:57 clojurebot: "([] [x] [x y] [x y & more]); adds all the args"

7:57 justin_smith: ^^ you can totally replace the doc strings

7:58 dysfun: also, technomancy isn't in Africa, he's in Thailand

8:02 luxbock: does technomancy still use IRC? I think he might be living in the same city as I do

8:09 hyPiRion: luxbock: yeah, but he recently moved, so he's probably a bit busy right now

9:10 LauJensen: /msg LauJensen test from LT

9:10 ...

9:12 Thingamagik: From Clojure I insert like SET dt = "2015-04-01". Then I get the line "select .... where dt="2015-04-01" and get the same line back with all values intact, except dt which is now "2015-03-31". In SQL its type DATE. Any idea why?

9:14 gfredericks: Thingamagik: smells like time zones

9:14 justin_smith: gfredericks: yeah, that was my first thought too

9:16 expez: repl fails to start, lein deps :tree suggests over 100 exclusions, what's the best way to proceed?

9:16 justin_smith: expez: don't use so many deps?

9:17 (just being glib - I have no idea)

9:18 expez: between the project and the tooling the transitive dependencies a significant fraction of all code ever written for the jvm

9:20 LauJensen: gfredericks, Timezones?

9:21 justin_smith: LauJensen: typically a date is stored as a timestamp for midnight that day

9:21 LauJensen: Ah, so its getting pushed one hour?

9:21 Best way to remedy?

9:22 justin_smith: LauJensen: bad timezone code can erroneously push the timestamp onto the wrong date

9:22 LauJensen: is the db local to your machine?

9:22 LauJensen: Yes

9:24 justin_smith: I was going to suggest making sure the server and host time zones and clocks were set up properly, but everything being on the same machine rules that out

9:55 imanc_: is it possible to use destructuring in a recur func, or is it limited to let/fn etc.

9:56 justin_smith: imanc_: you mean loop? you can destructure loop bindings

9:56 csd_: How can I make CIDER automatically load my test namespaces when I load a project?

9:56 imanc_: I actually want to destructure in the recur bit - but perhaps i'm thinking about it wrong and need an inner (let) block or something

9:57 justin_smith: imanc_: wat

9:57 it makes no sense to destructure the recur call - there is no way that would be helpful

9:57 destructuring is for the binding vector

9:58 you don't need a let block, you need the destructuring to happen where the bindings are

9:58 ,(loop [[a & r] (range)] (if (= a 4) (first r) (recur (rest r))))

9:58 clojurebot: 5

9:58 imanc_: yeh, OK makes sense. Basically I have a func that returns a list of two lists. and I need to input each list back into recur, but I realise I can use (let) inside the loop to destructure the the results into two var to pass back into ercur

9:59 hmm

9:59 justin_smith: imanc_: put the destructuring where the bindings happen (in the arg list of the function in this case)

10:00 ,((fn [[a & r]] (if (= a 4) (first r) (recur (rest r))) (range))

10:00 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

10:00 justin_smith: oops

10:01 ,((fn [[a & r]] (if (= a 4) (first r) (recur (rest r)))) (range))

10:01 clojurebot: 5

10:02 csd_: justin_smith-- do you know if it's possible to have cider load a project's tests when doing cider-jack-in? right now i have to manually load each test clj

10:03 justin_smith: csd_: cider should have a command for that - have you tried emacs' apropos command?

10:04 csd_: i'm looking through the commands listed in the github docs-- they all assume the tests are already loaded into the repl

10:04 figured there might just be something i need to put in my project.clj

10:06 justin_smith: csd_: this is close, but not quite https://github.com/clojure-emacs/cider/blob/master/cider-test.el#L438

10:07 it just runs tests for the current context

10:08 csd_: do you use cider yourself?

10:08 justin_smith: csd_: I did for a while, I gave up on it and just use inferior-lisp now

10:08 csd_: why did you give up on it?

10:08 justin_smith: too frequent breakage

10:09 I'd rather have fewer features

10:09 csd_: i would be a lot less effective using inferior lisp

10:09 justin_smith: rather than updates making things not work

10:09 OK

10:09 I manage alright

10:10 pandeiro: there's no existing feature expression support in master currently right?

10:10 justin_smith: pandeiro: no, it's in the 1.7 alphas

10:10 pandeiro: though cljx is a lein lib

10:11 pandeiro: justin_smith: sorry - that means what? i still need to use cljx?

10:11 justin_smith: pandeiro: or use the alphas

10:11 pandeiro: justin_smith: alphas are fine! trying to find a link to how to enable it

10:12 julianleviston: ooh does that mean stuart might be reworking component for cljs support?

10:12 justin_smith: pandeiro: http://mvnrepository.com/artifact/org.clojure versions are listed here

10:13 pandeiro: justin_smith: thanks, i already am working off alpha5 in my project

10:13 justin_smith: oh, I misunderstood

10:13 pandeiro: julianleviston: no idea but there's a cljs port

10:13 justin_smith: i found this https://github.com/levand/fx-hello-world -- looks like it might be what i need

10:13 i just don't get what i have to do, exactly :)

10:14 justin_smith: got it

10:14 julianleviston: pandeiro: yeah, I did one.

10:14 pandeiro: julianleviston: ah is that yours? sorry

10:14 julianleviston: pandeiro: prolly not the one you’re thinking of...

10:14 i just forked it

10:14 justin_smith: pandeiro: ahh there's a modified leiningen to work with the feature expressions

10:14 pandeiro: julianleviston: there are several yeah, i noticed

10:14 justin_smith: !!!

10:14 *that* is the info i was after -- so it doesn't work w/ regular lein?

10:15 justin_smith: pandeiro: it's listed on the page you linked

10:15 julianleviston: are feature expressions even stable yet?

10:15 I guess so coz there’s a diff… http://dev.clojure.org/jira/browse/CLJ-1424

10:15 justin_smith: they are in the alphas :P - you need a forked lein for lein test or aot to work with feature expressions

10:16 julianleviston: seems to still be heavily under dev.

10:16 seems a bit broken to me.

10:17 I don’t think #+cljs is a feature, is it? lol.

10:17 justin_smith: julianleviston: that's the feature expression syntax

10:17 julianleviston: justin_smith: yeah, but cljs is not a feature, it’s a language.

10:18 pandeiro: julianleviston: guessing the terminology came from common lisp

10:18 julianleviston: pandeiro: yep.

10:18 pandeiro: like interns

10:18 justin_smith: julianleviston: feel free to put in a pr to change them to "semantics expressions"

10:18 julianleviston: justin_smith: that’s a bit broken too

10:18 pandeiro: justin_smith: 'awesome tags'

10:18 julianleviston: justin_smith: language markers would make more sense

10:18 haha :)

10:19 justin_smith: "super pedantic about semantics expressions"

10:21 julianleviston: kind of thought the difference mattered, actually.

10:21 all good, tho. :)

10:21 justin_smith: julianleviston: I suggested "semantics expressions" as a joke, and you set me up to escalate the joke, sorry :)

10:22 julianleviston: justin_smith: oh it was a joke? i didn’t realise sorry :)

10:22 pandeiro: do you guys have a 'feature expressions' branch in your clojure repo?

10:22 justin_smith: the idea being that the expressions describe sementics, and then you are questioning the semantics themeselves etc.

10:22 I found that funny in an odd way

10:23 julianleviston: justin_smith: but the expressions don’t describe the semantics… they name the target (or selected) language. I guess that’s why I missed the joke.

10:24 justin_smith: julianleviston: they aren't just for language switching

10:24 julianleviston: justin_smith: oh?

10:24 justin_smith: julianleviston: the examples also switch code for prod / dev

10:24 for example

10:24 julianleviston: justin_smith: ew.

10:25 justin_smith: really? environment switching? guh that seems like a terrible thing to do

10:25 justin_smith: julianleviston: you list an arbitrary set of "features" as a system property, and that guides the tags turning forms on / off

10:25 julianleviston: justin_smith: ah ok… that might end up being sane.

10:25 justin_smith: I’d be pretty suprised if it wasn’t given who was working on it...

10:26 justin_smith: so anyway, one special case is turning off lines of code that don't work in clj-java/ cljs/ clj-clr, but that is not their only usage

10:26 julianleviston: justin_smith: seems a little open to abuse tho… but time will tell I guess.

10:26 justin_smith: julianleviston: we have so many features that are open to abuse, but we also have good community standards

10:27 julianleviston: justin_smith: the standards protect it from abuse. This seems still open to me. Just my opinion tho, really.

10:27 justin_smith: I mean anything in clojure.core (beyond the reader macros) can be pretty freely mutated and replaced at runtime. But we don't do that, because we aren't idiots.

10:27 the standards are informal

10:28 julianleviston: justin_smith: sure. However here it would seem that people are going to use this by putting runtim selection info in it, which doesn’t seem like it has a very long view of the fture in mind.

10:28 justin_smith: it's trivial to access the underlying array of a persistent vector and mutate it, but once again, we are smart enough to know not to do it.

10:28 julianleviston: runtime selection as in #+cljs / #+clj

10:29 justin_smith: having overloadable symbols/forms for each language would make more sense to me.

10:30 justin_smith: where you can overload on the language.

10:30 justin_smith: but I haven’t been in the hammock… :)

10:30 justin_smith: julianleviston: some things just make sense in cljs but not clj, and to some degree visa-versa

10:30 julianleviston: justin_smith: yeah, I agree…

10:31 justin_smith: that’s in accord with what I reckon would be better.

10:31 justin_smith: julianleviston: I mean, do we replace our current straightforward jvm interop with an abstraction that is guaranteed to work on any backend? that seems foolish

10:31 clojurebot: Titim gan éirí ort.

10:32 justin_smith: julianleviston: though if that's the sort of urge for abstraction one wants, Haskell and friends do aim for that

10:32 julianleviston: justin_smith: mmm

10:33 oh well, it’s night from me. :)

10:33 thanks for the chat

10:33 as always.

10:33 justin_smith: np

10:43 gfredericks: anybody know an easy way to create a bmp/png file from scratch? like specifying each pixel?

10:44 TEttinger: gfredericks: I don't know of any particularly easy ways on their own. AWT has setpixel and you can save a Graphics to a png or bmp

10:44 * gfredericks threatens to write a clojure library that writes the damn bits all by its own self

10:45 TEttinger: setPixel is extremely slow compared to drawing other textures, plus it's software rendered

10:45 justin_smith: gfredericks: setting pixels in png is tricky because it's a compressed format

10:45 gfredericks: justin_smith: sure if I wrote something by hand I'd do bmp

10:46 justin_smith: gfredericks: but you can use the java awt image classes to get the png into an array, and set the pixels followed by exporting again

10:46 but nothing that isn't datamosh is going to edit a png in place without an extraction/ recompression

10:46 gfredericks: sounds likely easier than figuring out the dang bmp header

10:46 TEttinger: I used to use a method in C# that drew a 4x4 pixel texture about 8000 times per sprite I was making. it was very slow. now I write to a byte buffer, and then slap that directly into memory using the Marshal class in C#. which only works because .NET has direct memory

10:46 justin_smith: gfredericks: heh, yeah

10:48 ffwacom: Sup fuckers

11:10 hyPiRion: ,(let [a (atom 0) inc! #(swap! a inc)] #{~(inc!) ~(inc!)})

11:10 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: (clojure.core/unquote (inc!))>

11:10 hyPiRion: my life is shattered

11:11 Well, I guess I didn't even need to syntax-quote that to show the problem.

11:23 gfredericks: hyPiRion: man your life must've been super fragile

11:28 hyPiRion: gfredericks: I realised it's possible to bypass the problem, so I am fine now

11:29 ,#{~(+ 2 3) ~(+ 3 2)}

11:29 clojurebot: #{5}

11:29 hyPiRion: eventually wrap some identities.

11:29 justin_smith: ,(let [n 0] #{n (do n)})

11:29 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: 0>

11:30 justin_smith: err, OK

11:30 ,(let [n 0] #{~n ~(do n)})

11:30 clojurebot: #{0}

11:30 hyPiRion: justin_smith: you must syntax-quote it

11:30 justin_smith: right

11:30 hyPiRion: ,'#{}

11:30 clojurebot: (clojure.core/apply clojure.core/hash-set (clojure.core/seq (clojure.core/concat)))

11:30 justin_smith: the opposite weirdness ;)

11:31 ,#{~@[1 1 1 1 1 1 1 1 1]}

11:31 clojurebot: #{1}

11:32 hyPiRion: hm

11:32 ,#{~@(repeat 1)}

11:32 justin_smith: haha

11:32 clojurebot: Execution Timed Out

11:33 hyPiRion: oh right, that's not at read time

11:35 ,'#(%1e10)

11:35 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

11:35 justin_smith: oh, that's a fun one

11:36 hyPiRion: Hm. I hope I didn't crash the whole thing by doing that :x

11:36 ,1

11:36 clojurebot: 1

11:37 justin_smith: I wonder if that is one of those things, where if you made the mistake of catching throwable you'd be worse off than if you just let the exception go to the top

11:43 hyPiRion: hm, maybe

11:43 depends on how OOM is handled, I guess

11:46 I am confused

11:46 ,(meta ^nil {})

11:46 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata must be Symbol,Keyword,String or Map>

11:46 hyPiRion: ,(meta ^+ {})

11:46 clojurebot: {:tag #<core$_PLUS_ clojure.core$_PLUS_@41996713>}

11:47 hyPiRion: + is not a symbol, kw, string or map

11:48 justin_smith: hyPiRion: clearly the error message should say IObj

11:48 hyPiRion: I guess it makes sense if you consider it at read time.

11:48 ,(let [x nil] (meta ^x {}))

11:48 clojurebot: {:tag nil}

11:48 hyPiRion: not sure if it's sensible though

11:50 I guess it should say Class instead of Symbol to make sense.

12:13 gfredericks: ,(defn uniformize-random-bits [bits] (->> bits (partition 2) (keep {[0 1] 0 [1 0] 1})))

12:13 clojurebot: #'sandbox/uniformize-random-bits

12:13 gfredericks: ^ love how elegant that is

12:23 justin_smith: ,({[0 1] [1 0]} '(0 1))

12:23 clojurebot: [1 0]

12:56 creese: In cider, output from println goes to server log but not to the repl. Is this expected behavior?

12:58 justin_smith: creese: this is because you lost the binding of *out*

12:59 creese: if you had created a future instead of using Thread directly (of if the thing you used did so...) that would be automatic

12:59 but you can make or pass in some binding of *out*, and use that binding explicitly, to make things print to the repl in cider

13:01 creese: the issue is that when a process is created in emacs, its stdio is attached to a buffer (the one cider uses as the *nrepl-output* buffer), but cider overrides *out* with a dynamic binding to make things print into the repl buffer

13:02 creese: but because of how dynamic bindings work, sometimes if you create a new thread, they get the root value of the binding (that stream to print to the hidden by default buffer) instead of the newer thread-local repl binding

13:02 sharms: If I have a file, a.clj which runs fine, and I require it in b.clj, when I run my function it tells me it can't find a variable the function is looking for when called from b.clj

13:03 I can fix it by adding an additional require statement, but could someone explain to me while having the require statement in a.clj isnt sufficient?

13:03 justin_smith: sharms: because we have namespaces, and that's how namespaces are intended to work

13:03 sharms: justin_smith: I am having trouble googling my way to understanding this - but I dont want to duplicate all of my require statements in b.clj, or is that pragmatic clojure?

13:04 justin_smith: sharms: if you are replicating all the required libs, whey are they even separate namespaces?

13:04 why not put everything in a?

13:04 the idea with a namespace is that you can see explicitly in your clj file where the things you are calling come from

13:04 no magic

13:04 no transitive bindings

13:04 brucehauman: guys I’ve struggled a bit with finding good cljfmt settings for Emacs, link anyone?

13:05 justin_smith: brucehauman: cljfmt is super new, right?

13:05 sharms: justin_smith: a.clj is a model file, and b.clj is my swagger file - so I may have like 20 a.clj's and I would hate to take all of that and put them in a single file

13:05 arrdem: justin_smith: yep.

13:05 sharms: I just want to reference each model type without importing all of the things they already import

13:06 creese: brucehauman: doesn't clojure-mode take care of this?

13:06 brucehauman: justin_smith: I’m really not that sure. But I’m definitely not liking how its indenting

13:06 arrdem: brucehauman: cljfmt is new in the last month or so, I'd be amazed if you can find non-default indentation settings floating around.

13:06 justin_smith: creese: I don't think there has been a clojure-mode release since cljfmt was written

13:06 brucehauman: arrdem: thanks !

13:06 arrdem: brucehauman: clojure-mode has a perfectly good indentation engine as well

13:06 brucehauman: I’m using clojure-mode

13:06 justin_smith: arrdem: well, indentation, but not formatting

13:07 arrdem: justin_smith: betweent the style guide, whitespace-cleanup (for which I'm happy to share my config)

13:07 and clojure-mode I don't see what else you need.

13:07 justin_smith: sharms: typically I have between 3 and 10 requires in each namespace. Many of them are the same between namespaces in the same project.

13:07 brucehauman: arrdem: would love to see you config

13:07 t0: What do you think about learning Clojure as a first programming language?

13:08 arrdem: t0: it can be done to be sure but Clojure seems to be a 2nd or 3rd language after some Java.

13:08 justin_smith: arrdem: cljfmt can take a piece of code with any given whitespace weirdness and bad line breaks and reformat, nothing in clojure-mode does that (it just indents) so that's less automatic

13:08 brucehauman: t0: I might suggest Scheme or Racket

13:08 arrdem: justin_smith: sure

13:08 t0: racket definitely

13:08 <3 raket

13:08 sharms: Let me try a different way: a.clj: (defn testfunc [x] (somelib/somefunc x) works fine. b.clj: (:require [core.a :as shortcut]) (shortcut/testfunc x) -- In this scenario calling it from b.clj wont work without importing somelib in the require statement of b.clj - this is as intended and there isnt a better way?

13:09 justin_smith: what?

13:09 clojurebot: what is your favorite number

13:09 arrdem: brucehauman: on windows right now but lets see if I can get this to you...

13:09 martinklepsch: What's the right way to prevent Leiningen plugin deps from leaking into library consumers? using :scope "test"?

13:09 brucehauman: arrdem: thanks

13:09 justin_smith: sharms: after requiring a from b, you can call testfunc without requiring what a does

13:10 b does not need to reference a's deps at all, unless it explicitly uses them

13:10 sharms: ok thats what I thought, but it appears to be my error - it says 'Unable to resolve symbol:'

13:11 I must be just overlooking something

13:11 justin_smith: OK

13:11 noonian: I think Clojure is a fine first language to learn, but not as simple as scheme to be sure.

13:11 brucehauman: t0: The reason Clojure isn’t a good first language is because it is hosted in another language. Racket and or JavaScript are better ways to start.

13:11 justin_smith: sharms: do you literally have (:require ...) at the top level of b.clj?

13:11 because that will silently do nothing at all

13:12 ,(:require ["whatever" "this" "does" "nothing"])

13:12 sharms: justin_smith: its inside of a (ns some.namepsace (:require ...

13:12 clojurebot: nil

13:12 justin_smith: sharms: oh, OK, just double checking :)

13:12 sharms: No I appreciate the help, clearly I am missing something simple and fundamental

13:13 t0: brucehauman: Thank you. I'm interested in learning programming with a functional language first

13:13 justin_smith: sharms: feel free to share a paste on refheap

13:13 t0: racket seems like a good choice

13:13 gfredericks: justin_smith: wouldn't it crash?

13:13 justin_smith: gfredericks: what would crash?

13:13 ahh, unbound symbols in the vector

13:13 yeah

13:13 gfredericks: justin_smith :require at top level

13:14 arrdem: brucehauman: https://www.refheap.com/97032

13:14 brucehauman: t0: Thats a very enlightened perspective.

13:14 gfredericks: ,(:require clojure.string) ;; justin_smith

13:14 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.string, compiling:(NO_SOURCE_PATH:0:0)>

13:15 brucehauman: arrdem: thanks :)

13:15 justin_smith: gfredericks: yeah, good point

13:15 arrdem: brucehauman: I also think you need to setq tabs-<something> nil so that indentation is spaces

13:15 sharms: justin_smith: https://www.refheap.com/97033

13:16 justin_smith: I started learning clojure last week, so I am guessing I am just missing something super simple / core concept

13:16 brucehauman: arrdem: thanks, giving it a try

13:17 sharms: justin_smith: The error itself ends up on the line of (swaggered "businesses" ... which I think I dont need to explicitly import since a.clj already contains it, and I dont reference it directly from b.clj

13:18 arrdem: brucehauman: just to clarify, that's a pasted .dir-locals.el file

13:18 brucehauman: you can't just slap that in your .emacs and have it work.

13:18 brucehauman: arrdem: thanks for the clarification

13:18 justin_smith: err, I missed some parens, sorry

13:19 arrdem: brucehauman: just thought I'd save you some confusion before I buzzed off :P

13:19 brucehauman: I really appreciate it

13:19 sharms: justin_smith: ok so even though b.clj has no reference to Business, because I require a.clj and am calling a function from a.clj that references it, I need to require it in b.clj?

13:19 justin_smith: oh, wait...

13:21 I missed that you weren't even referencing Business

13:22 maybe there is something weird going on with how the defroutes* is being expanded in b.clj

13:23 well no, because it should be fully expanded in the first one

13:23 hmm

13:23 sharms: justin_smith: I havent run into this before so my suspicion is swagger magic

13:23 justin_smith: yeah, could be a bug in their macro

13:24 sharms: I just wanted to make sure I understood the core concepts, being new to clojure, that maybe I didnt understand name spaces

13:24 justin_smith: but you can likely at least prevent the bug from triggering by importing Business in that ns

13:24 sharms: thank you so much for the help

13:24 justin_smith: np

13:24 that's really good for someone so new to clojure, btw

13:24 not your first lisp I assume?

13:25 bacon1989: I was wondering, is there any support for clojureclr within leiningen?

13:25 sharms: justin_smith: I know a bunch of non-lisp languages and I did watch a few videos with SICP before taking a swing at making a test api

13:25 bacon1989: From what I can tell, there isn't as far as I know

13:26 sharms: justin_smith: Also I notice on github that when they do it in the examples, they use :refer :all so swagger must be expecting that

13:26 bacon1989: So I was wondering how difficult it would be to get clojureCLR working in leiningen

13:26 would it be a huge untertaking for me?

13:26 justin_smith: bacon1989: I recall seeing lein plugins that do clr stuff

13:27 sharms: the name "Business" led me to believe that it was a class being generated, and not a var

13:27 sharms: if it's a class it would need to be imported, if it's a var it would need to be referred / used

13:28 sharms: which reminds me, the convention is that capitalization is for things that generate classes, usually (though I am aware prismatic/schema also has its conventions etc.)

13:28 bacon1989: There's this https://github.com/kumarshantanu/lein-clr

13:28 martinklepsch: :profiles {:dev {:plugins [[com.cemerick/austin "0.1.6"]]}} — having this in a library, how can I ensure this does not end up being loaded as transitive dependency?

13:29 sharms: justin_smith: Ok that makes sense thanks

13:29 justin_smith: sharms: yeah, never mind, schema expects caps, but that's weird in the clojure world, so just expect people might misread things

13:29 so it is a var, just capitalized

13:30 gfredericks: ,(def LOWER-CASE? false)

13:30 clojurebot: #'sandbox/LOWER-CASE?

13:30 justin_smith: haha

13:30 gfredericks: ,(def unbound)

13:30 clojurebot: #'sandbox/unbound

13:31 gfredericks: ,(def reflexive #'reflexive)

13:31 clojurebot: #'sandbox/reflexive

13:32 justin_smith: ,(def def def)

13:32 clojurebot: #'sandbox/def

13:33 gfredericks: ,def

13:33 clojurebot: #<Unbound Unbound: #'sandbox/def>

13:33 justin_smith: oh wow, that is better than expected

13:33 gfredericks: is there anything else it could do?

13:34 or did you expect an error?

13:34 justin_smith: I naively expected sandbox/def would be assigned the value of clojure.core/def which is of course wrong, because def creates the var before the form is evaluated so by that time def refers to itself

13:35 Bronsa: justin_smith: also there is no such thing as clojure.core/def

13:35 justin_smith: oh, that's helpful to know

13:35 bacon1989: I remember reading an article on a bunch of security holes taht were patched

13:35 clojurebot: No entiendo

13:35 bacon1989: * on clojurebot

13:38 but anyways, i'm interested in writing some clojureCLR libraries. I'm wondering if publishing .NET clojure code is possible

13:38 there doesn't appear to be anything on it

13:40 justin_smith: bacon1989: does .net have the kind of automatic dep resoltuion with a community repo that we use?

13:40 bacon1989: .NET has nuget

13:40 justin_smith: sounds like there should be a lein-nuget plugin (or maybe that's a candy bar)

13:40 bacon1989: so if need be, I wonder if writing something on top of nuget would make sense, sortof like how leiningen builds on top of Maven?

13:41 justin_smith: bacon1989: also, if you are using lein anyway, there's no reason you couldn't distribute clr code on maven

13:41 /clojars

13:41 bacon1989: justin_smith: hmmm

13:41 yeah, i'd prefer to take the 'less coding' path

13:42 and re-use what's already there

13:42 maybe i'll look through the lein-clr tool, and see if I can use that

13:42 justin_smith: and since much of what lein does is the maven stuff, maybe you'd just want nulein

13:42 bacon1989: there doesn't appear to be much interest in clojureCLR, I wish it could be just as easy to get started as in Java

13:43 justin_smith: bacon1989: the basics are there for sure, I think it's a question of tooling / community (of course that's chicken - egg)

13:43 bacon1989: yeah

13:43 justin_smith: bacon1989: I think the taint of MS keeps some of the sorts of folks that tend to develop free tooling for the community away from clr stuff

13:44 bacon1989: but there's Mono, and the latest Microsoft moves have been grand

13:44 justin_smith: bacon1989: not that clr isn't awesome and now very open, but the culture that leads to things like lein comes from a historical place that has a grudge against ms tech stacks

13:44 bacon1989: yeah true

13:44 justin_smith: not a technical problem at all, but a social one

13:44 bacon1989: but I can see a better adoption of a language that works on the CLR with .NET

13:44 arrdem: is't that how all of the language tooling stuff shake sout?

13:45 bacon1989: when it comes to enterprise

13:45 justin_smith: it's true

13:45 bacon1989: microsoft is still a pretty strong contender when it comes to businesses. The business i'm at right now is only microsoft

13:46 but yeah, no one likes the microsofts taint

13:46 justin_smith: arrdem: yeah. it's just that in my experience, the kind of person who makes a free open source tool that makes building stuff in X easier, either really really really loves X, or is a bit of a GNU / freedom for the sake of freedom / community oriented person (usually it's actually both I think)

13:47 bacon1989: that's the thing though, if microsoft all of a sudden makes stuff open-source, shouldn't we reward them?

13:48 justin_smith: oh sure, but just try using rationality to influence human motivations, see how far that gets you :)

13:48 bacon1989: Sortof push the demographics on what people want, and other companies will follow suit and make their stuff open after they see the benefits

13:48 haha

13:48 gfredericks: is .NET realistically useful outside of windows?

13:50 justin_smith: gfredericks: yeah, big parts of Gnome are built in mono

13:50 well - maybe not big parts, but it is in there

13:51 gfredericks: interesting

13:52 martinklepsch: Somehow only Austin seems to be leaking from :profiles {:dev {:plugins [[lein-pprint "1.1.1"][com.cemerick/austin "0.1.7-SNAPSHOT"]]}}

13:52 justin_smith: I mean, for that matter the ancient windowmaker wm for linux was a port of a big part of next before it became OSX

13:53 bacon1989: gfredericks: idk about .NET, but the CLR runtime is use quite a bit outside of windows

13:53 gfredericks: I don't think I know the difference

13:54 justin_smith: .NET is oracle-jvm, CLR is the java spec

13:54 or something like that

13:54 bacon1989: .NET is a set of core libraries

13:54 justin_smith: ahh

13:54 bacon1989: .NET core was recently open-sourced though

13:54 mono tries it's best to mimmick .NET core and everything else

13:55 that's why the recent .NET core dump was huge

13:55 (to opensource)

13:55 justin_smith: very cool, thanks for the extra context

13:55 bacon1989: yeah, so .NET is a set of useful libraries, it's like Microsoft's Standard Libraries

13:56 sortof like Java's Standard Libraries get updated, C++11 std::, etc

13:56 jwm: opensource = more important than anything

13:57 really monumental that so much is going oss these days

13:58 justin_smith: jwm: at this point, I think it's hard to justify a non-opensource lang for new projects

13:59 hyPiRion: so this is a really funny error https://www.refheap.com/97034

14:00 hyPiRion: regarding the whole "what would happen if you caught throwable" question

14:00 hyPiRion: I still get my usable repl back afterward though

14:01 oh I get it - the exception happens while the form is still being compiled, and somehow when it is caught and things are removed we are no longer in the context of the "try" ? that's weird though, I still don't quite get it

14:07 martinklepsch: wow so my issue with Austin leaking into deps was that "lein install" runs with the :dev profile when I did lein with-profile -dev install, it wasn't there anymore

14:14 gfredericks: martinklepsch: are you installing an uberjar?

14:14 martinklepsch: gfredericks: no

14:14 gfredericks: er...AOT?

14:14 or you mean declared deps in the pom?

14:16 gfredericks: oh something to do with cljs?

14:17 martinklepsch: I dont think it has anything to do with cljs

14:17 * gfredericks gives up

14:17 martinklepsch: gfredericks: the issue I had was that whenever I depend on "pani" as described in the link I get a dependency on com.cemerick/austin as well

14:18 justin_smith: martinklepsch: I would say that's a problem with pani's pom file

14:19 martinklepsch: justin_smith: right. but I expected depencies in :profiles {:dev {:plugins []}} not to end up in said pom file

14:19 justin_smith: is that a wrong assumption to make?

14:19 justin_smith: hmm - does clojars have a way to look at the pom file for an artifact? I guess I can just depend on pani to download it.

14:20 martinklepsch: yeah, so a bug in lein or some lein plugin? clearly a problem with their pom is a problem with the tool that generated it (or how it is being used...)

14:21 martinklepsch: justin_smith: I couldn't replicate the behaviour with other plugins than austin (e.g. lein-ancient) so I thought it might be an issue in austin but then again that shouldn't be possible right?

14:21 justin_smith: the pom file, for reference https://www.refheap.com/97036

14:22 heh, guess I was too slow :P

14:23 justin_smith: martinklepsch: this is terrible, but what if you tried removing the erroneous deps from the pom? better would be to clone the repo and see what change would prevent bad stuff from ending up in the pom, of course

14:24 tomjack: are there good alternatives to the common emoticons which are valid clojure forms?

14:24 justin_smith: tomjack: ;)

14:24 tomjack: oh, :/ is good. :) is all I need I guess

14:24 justin_smith: (comment to end of line)

14:24 tomjack: hah

14:24 martinklepsch: justin_smith: I cloned the repo and that "install" alias was the only way I could come up with that prevents austin from ending up in the pom

14:25 tomjack: of course I would like to be able to write more after the emoticon

14:25 e.g. it should be able to go in the last spot of a one-line list

14:25 using comments is an interesting idea for actual clojure code, though

14:25 justin_smith: tomjack: there are unicode things that look like ) but will be accepted as symbol-constituent by the reader

14:26 tomjack: ah, thanks, good idea

14:26 justin_smith: but at that point you may as well use emojis

14:26 arrdem: what's wrong with using emojis?

14:26 tomjack: yeah, that would satisfy me

14:26 * arrdem sprinkles :doge: around his codebase

14:27 tomjack: unicode just didn't occur to me

14:27 justin_smith: arrdem: they are an upgrade, but you need to accept the whole "unicode you can't easily type in the codebase as var symbols" thing

14:27 martinklepsch: arrdem: do those get rendered on github?

14:27 justin_smith: ,:doge:

14:27 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :doge:>

14:27 tomjack: I somewhat frequently turn on agda-input-mode in clojure-mode :O

14:28 arrdem: I pretty routinely use the TeX input mode in clojure-mode

14:28 \gets

14:28 \to

14:28 \lambda

14:28 justin_smith: haha

14:28 arrdem: I'm perfectly serious

14:28 tomjack: I want to someday patch paredit so that it deals better

14:29 imanc_: (let [collided (filter (fn [x] (> (:x x) (:x obj))) active-list)] Why would this generate a null pointer exception? Strangely if i just delete the > func in the filter pred, the error no longer happens *grrr*

14:29 tomjack: imanc_: clojure is not sql :P

14:30 imanc_: changing the pred to (fn [x] true) or (fn [x] false) also solves it

14:30 tomjack: presumably either (:x x) for some x or (:x obj) is nil

14:30 ,(> nil 42)

14:30 clojurebot: #<NullPointerException java.lang.NullPointerException>

14:30 imanc_: aha!

14:30 that must be it... thanks tomjack

14:31 tomjack: I'm trying to decide how I'd deal with that in the case that the numbers can be negative

14:32 justin_smith: (and (:x x) (:x obj) (> (:x x) (:x obj)))

14:32 you probably want a let block for that :)

14:32 well no - you don't want and

14:32 never mind

14:33 imanc_: and looks like it'd be a solution?

14:33 justin_smith: imanc_: false means either obj had a larger x, or one of the x's or things was nil

14:34 that's a lot of things to encode in one false :)

14:34 imanc_: ah i see

14:34 justin_smith: but if that is correct in your logic, run with it

14:35 (if (and (:x obj) (:x x)) (> (:x x) (:x obj))) :something-was-nil)

14:36 well, those parens are wrong

14:36 kryft: Does anyone happen to know if jdbc/update! can fail without throwing an exception (which would cause the transaction to roll back)?

14:37 martinklepsch: justin_smith: do you have any more input on that deps issue?

14:38 justin_smith: martinklepsch: I would make my own version of the lib that didn't have erroneous deps in the pom

14:38 martinklepsch: and it would be nice to make a pr for that, of course

14:39 "Clojure - Vatican City: Beautiful architecture and power well beyond its size, built over the bones of an ancient empire."

14:39 martinklepsch: justin_smith: sure, sure. I'm less concerned about solving it for me right now than solving it correctly

14:39 justin_smith: that "install" task is a hack so I wonder what would be "the right way" to do it

14:39 justin_smith: hmm.

14:40 figure out which plugin / which part of lein is screwing up there I guess?

14:40 I'm not really sure

15:07 martinklepsch: justin_smith: ok, I'll see what I can do

15:29 expez: I'm trying to spin up datomic with an h2 db and I get a NPE in find-log when it's trying to create a UUID. Do I have to do anything other than create-db before running connect?

15:32 in the docs they just do create-db followed by connect, but that's in the groovysh *shrug*

15:37 damn this works just fine in the groovysh but not at the repl

15:47 justin_smith: expez: it's calling the same bytrcode, so I'd imagine your groovy to clj adaption needs work?

15:49 expez: Peer.createDatabase(ur) => (datomic.api/create-database) and Peer.connect(uri) => (datomic.api/connect uri)

15:50 the problem was modular-datomic depends on datomic-extras which depends on old version of datomic free which wasn't loaded in the groovy console

15:51 justin_smith: expez: yoi passed the uri to create-database, right?

15:52 expez: justin_smith: yes, but the log formats weren't compatible between the old version of datomic which was pulled in by the transitive deps and the one running in the transactor

15:52 it's working now but that was an annoying problem

15:52 justin_smith: ahh

15:53 expez: was trying to save a few minutes by using the juxt/modular components but between all the transitive deps and the complete lack of documentation I'm starting to regret that decision

15:57 AeroNotix: anyone got an up-to-date guide on using protobufs with clojure/

16:21 eugh, protobufs in clojure.

16:21 fraught

16:22 tcrayford____: AeroNotix: can you copy whatever riemann does?

16:22 AeroNotix: I know you're already familiar with riemann haha

16:23 AeroNotix: tcrayford____: oh I forgot riemann uses protobufs. good idea.

16:26 It's... not clear what it does.

16:26 tcrayford____: hahaha :(

16:26 AeroNotix: it just pulls in a package from com.riemann.protobufs

16:26 com.aphyr.riemann sorry

16:27 tcrayford____: ah, welp then :/

16:27 that prolly uses generated java classes

16:27 AeroNotix: indeed

16:27 tcrayford____: as far as I understand things, https://github.com/ninjudd/lein-protobuf is basically the state of the art

16:28 arohner: is there a thing similar to clojure.core/bean for cljs?

16:28 i.e. get a hashmap from the fields of an arbitrary js obj?

16:28 AeroNotix: tcrayford____: Using that now and it's... less than perfect. It generates code that doesn't compile.

16:28 working myself through the forks of it now

16:28 tcrayford____: arohner: doesn't like, into work or something (I don't use cljs though)

16:29 seeing as js objs are just maps anyway

16:29 arohner: if not it seems trivial to write with Object.keys in js land

16:29 arohner: Error: [object Window] is not ISeqable

16:29 tcrayford____: AeroNotix: ah, sorry then, don't think I can help more

16:29 arohner: tcrayford____: yeah, I'm about to do that, was just asking if it existed first :-)

16:31 AeroNotix: tcrayford____: I think the riemann-clojure-client uses the java stuff which uses whatever the java compile machinery uses to compile protobufs

16:31 and not lein-protobufs

16:32 :/

16:32 tcrayford____: AeroNotix: that seems like an reasonable idea to me. It definitely wraps them in records futher inside riemann

16:32 like, you can call assoc on an Event, but I guess aphyr just does that wrapping inside riemann itself

16:32 AeroNotix: yeah

16:32 arohner: js->clj exists, and the source looks like it does the right thing, but it is returning nil on me

16:32 AeroNotix: I'll persevere

16:33 arohner: hrm, looks like js->clj doesn't have a case for things that are native code

16:57 dagda1_: I have been trying to solve this nth-prime problem on hackerrank https://www.hackerrank.com/contests/projecteuler/challenges/euler007 but I just cannot get it fast enough, I found lazy seqs the slowest and this

16:57 is the fastest I can get it and it still fails 2 tests https://gist.github.com/dagda1/9f182549988709c80610

16:58 I'm aghast, can anyone suggest an refinements, using lazy seqs was at least twice as slow

16:58 justin_smith: arohner: I woyld use .keys as a sequence to reduce over

16:58 tcrayford____: dagda1_: type hint function args so they take primitive, use a transient vector given that you're just banging on it

16:59 currently you're boxing/unboxing on every call to is-prime? (I think)

16:59 dagda1_: tcrayford____: what do you mean banging on it?

16:59 justin_smith: arohner: due to inheritance stuff hasOwnProperty is udeful here

16:59 tcrayford____: like, it's single threaded and you're mostly mutating it rather than passing it around etc

17:00 dagda1_: tcrayford____: I've never heard ot type hints

17:00 dagda1_: tcrayford____: use a transient in n-primes?

17:00 tcrayford____: yea

17:00 that might not even be a big win though

17:00 what jvm options are you running it with?

17:00 (hi: I do cleaxjure performance a lot)

17:01 arohner: dagda1_: there are also significantly faster algos

17:01 dagda1_: focus on algo first, clojure overhead is not your problem

17:01 tcrayford____: also that's prolly the real deal haha

17:01 * tcrayford____ is so used to having the correct algorithm

17:01 dagda1_: tcrayford____: that is outside of my control, you paste the code into the site

17:02 arohner: dagda1_: in general, the euler problems are very math heavy, so solving problems typically requires more math knowledge than clojure knowledge

17:02 tcrayford____: arohner: I've seen 5000x perf differences from bad jvm/clojure usage in the past haha. It's not always just the algorithm

17:02 (though it prolly is here)

17:03 dagda1_: this was almost twice as slow than my loop recur but I was twice as pleased with this code :) https://gist.github.com/dagda1/c0165842dce687c6ab16

17:04 sorry, that is from the clojure lazy-seq docs and that got a stack overflow

17:05 justin_smith: arohner: acually (Object/keys j) and that slready filters inherited stuff

17:05 arohner: justin_smith: thanks

17:05 I'll look into that

17:05 dagda1_: this is my lazy version that was twice as slow as using loop reucr https://gist.github.com/dagda1/41141f53b50b06c98094

17:08 this got me a big boost by only checking up to the square root (range 3 (inc (Math/sqrt n)) 2) and also only checking for odd number primes other than 2, I don't know what is left

17:09 I've seen the sieve of erathonese mentioned here http://clj-me.cgrand.net/index.php?s=eratosthenes but I'm not convinced it is faster

17:09 I'll have to try it

17:09 michaelr525: hey

17:09 tcrayford____: dagda1_: learn you some 2 millenia old mathematical optimization

17:10 michaelr525: i wonder why lein cljsbuild clean has been deprecated?

17:10 dagda1_: tcrayford____: I think I need to time travel

17:10 amalloy: dagda1_: the real sieve is a lot faster than the trial division in your poaste

17:10 dagda1_: amalloy: I think I need a sieve, it is all I have left

17:10 amalloy: simply because it involves only addition and array lookups, rathre than division

17:11 dagda1_: pretty depressed about how slow lazy seqs are

17:13 amalloy: dagda1_: they're really not. if you use a bad algorithm, work on that before you complain about the performance of underlying tools

17:13 like, you're doing a ton of work recomputing primes, treating each test case as totally independent, instead of reusing a list of primes between the T test cases

17:14 dagda1_: amalloy: I think it is fair to say that there is a price on a lazy sequence, I don't see how i am dissing the language by saying that

17:14 amalloy: the sieve is a bit harder to use when you don't have the same goal in mine (it's designed for finding all primes less than N, rather than the first N primes)

17:14 of course. there is a price for addition too

17:15 dagda1_: amalloy: I'm just depressed I cannot pass the tests :)

17:15 amalloy: at least not quick enough

17:16 amalloy: I'm coming from the ruby world, I understand slow

17:17 I tried memoising also, I need to try the sieve for myself

17:17 AeroNotix: Does anyone think that when-let could be improved somewhat?

17:17 e.g. it doesn't really work with destructuring

17:17 multiple bindings would be nice too

17:18 amalloy: AeroNotix: when-let works fine with destructuring. (when-let [[x & xs] (seq coll)] ...)

17:19 tcrayford____: AeroNotix: also it should really be called whence-let

17:19 AeroNotix: amalloy: try a map destructure

17:19 amalloy: it only appears not to work because you imagine it doing other stuff like somehow knowing which bindings you want to be testing, rather than what it actually does, which is test the truthiness of the value you bind to

17:19 AeroNotix: amalloy: indeed

17:20 I looked at the macroexpansion, there's no misunderstanding when the code is right there.

17:20 amalloy: you said it "doesn't work with destructuring", which is obviously false

17:20 AeroNotix: There's no destructuring going on with (seq coll)

17:22 justin_smith: ,(when-let [{a :a} nil] true)

17:22 clojurebot: nil

17:23 AeroNotix: The truthiness check is done before the bindings

17:23 amalloy: or indeed if you want to assert that the key :a is present and still destructure, you can write (when-let [{:keys [a]} (not-empty (select-keys m [:a]))] ...). lots of avenues are open to you

17:23 AeroNotix: amalloy: and that's a bit gross. Imho

17:23 amalloy: so write your own macro

17:23 AeroNotix: I'm thinking it could be nice to improve on it a bit

17:23 amalloy: that does whatever you want

17:23 AeroNotix: amalloy: I am thinking about it

17:24 I was hoping either this already exists somewhere :)

17:24 justin_smith: quorum: like when-let but multiple bindings snd all must be non-nil

17:24 amalloy: it probably does

17:25 AeroNotix: justin_smith: that's.. pretty much what I want

17:25 lazybot: [Jay Fields' Thoughts: Clojure: Combining Calls To Doseq And Let] http://blog.jayfields.com/2013/05/clojure-combining-calls-to-doseq-and-let.html

17:25 amalloy: i dunno, that looks like a bad search result

17:25 AeroNotix: hmm

17:26 amalloy: you can also try github.com/egamble/let-else

17:26 AeroNotix: amalloy: did you mean? http://edtsech.github.io/2012/12/and-let.html

17:26 amalloy: well, i haven't read that article

17:26 but i know that the thing you are looking for is called and-let in other languages

17:26 AeroNotix: this only focuses on simple bindings

17:27 turbofail: yeah most of those still won't check for truthiness on all of the destructuring variables

17:27 probably because doing so requires basically parsing the destructuring syntax

17:27 for which cfleming's approach would be nice again

17:28 amalloy: turbofail: well, you don't have to parse it yourself; that's whta clojure.core/destructure is for

17:28 AeroNotix: seems we could steal https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L4045

17:28 yeah

17:28 turbofail: amalloy: oh, didn't know that existed

17:28 AeroNotix: it.. needs to exis

17:28 let is just a macro implemented in clojure

17:28 amalloy: eg i use it in https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L224

17:29 AeroNotix: that's sweet^

17:29 turbofail: AeroNotix: i could totally have imagined it being an internal thing, not actually usable from elsewhere

17:29 amalloy: so that you can write like (let-later [x [1 2 3] [^:delay y] x] ...)

17:29 turbofail: like the `for' parsing

17:30 AeroNotix: amalloy: doesn't Sir Tellman have a similar thing?

17:31 amalloy: are you thinking of riddley?

17:31 no, probably you're not. i dunno

17:32 AeroNotix: hmm, no ztellman had a lib with something like this

17:32 where the binding form would be executed in parallel

17:32 wrapping them in delays and automatically forcing them seems neat though

19:42 sdegutis: Is there a way to specify easily when using assoc-in that one of the keys must simply be the last element of that vector?

19:43 I think I'm using assoc-in all wrong. I have the value of the node I want to update, but not the indexes of how to get to it.

19:43 gfredericks: don't use assoc-in for that

19:43 sdegutis: Is there a better way to solve this?

19:43 gfredericks: use update-in with conj

19:43 sdegutis: Plese help. Thanks in regards.

19:44 gfredericks: well the node already exists, it's a map deep in a nested structure, and I want to update a key in that map

19:44 alandipert: sdegutis: i have a thing for you maybe 1 sc

19:44 gfredericks: ooh I see

19:44 sdegutis: I keep thinking tree-seq may help?

19:45 gfredericks: no you probably just want a special update function for vectors

19:45 ,(defn update-last [v f & args] (apply update v (dec (count v)) f args))

19:45 clojurebot: #'sandbox/update-last

19:45 sdegutis: Or am I supposed to give this function a "path" to the node it represents?

19:46 I'd usually do it by just making sure this function has the path given to it in its entirety.

19:46 gfredericks: ,(def the-data {:tacos [{:flavor 7} {:flavor "juice"}]})

19:46 clojurebot: #'sandbox/the-data

19:46 sdegutis: But that means adjusting a lot of intermediate function parameters.

19:46 But it seems cleanest.

19:46 gfredericks: ,(update the-data :tacos update-last assoc :size "jumbo")

19:46 clojurebot: {:tacos [{:flavor 7} {:flavor "juice", :size "jumbo"}]}

19:47 alandipert: sdegutis: https://gist.github.com/alandipert/ac8e8b77e8660b9f947a

19:48 sdegutis: That is some code.

19:48 alandipert: the idea with the paths thing is it gives you all the paths into a nested map, which you can then filter

19:48 sdegutis: I dunno, I feel like this shouldn't be so special cased.

19:48 alandipert: i’ve been using it together with https://github.com/cgrand/seqexp to do unsound things with mongo records

19:48 sdegutis: Haha

19:49 alandipert: well played sir or madam

19:49 alandipert: it’s sort of xslt-ish

19:49 tyty

19:49 sdegutis: Oh! Maybe clojure.walk can help here?

19:49 gfredericks: don't you just want to update a single thing?

19:49 sdegutis: Yes, but that thing is very deep.

19:49 gfredericks: clojure.walk tramps all over your data

19:50 sdegutis: I'm okay with *walking* all over the data, I just want to find the deep thing.

19:50 I hope ClojureScript has clojure.walk

19:50 Otherwise I can just change my functions to take more parameters so that it can build up a path.

19:50 The context is that I'm writing a budgeting app for myself using Reagent in ClojureScript.

19:51 gfredericks: sdegutis: so if you had a variant of assoc-in that took negative numbers as vector indices, would that solve your problem?

19:51 sdegutis: I'm updating an "actual" field (number) in an "expense" map which is the last key in the "months" vector.

19:52 gfredericks: technically yes, but it would be special casing it such that I can't easily change the thingy.

19:52 I think changing the parameters is the cleanest way to do htis.

19:52 Thanks everyone for your charity.

19:52 gfredericks: good luck

19:52 sdegutis: gfredericks++

20:41 vas: Hello. I am playing with the ring.middleware.anti-forgery/*anti-forgery-token* and am not sure how to embedd it into my form as a hidden field that isn't evaluated until needed. Trying to run my server with lein ring server yields something like "attempting to call unbound fn" ..

20:44 nevermind, i think i just biffed on the enlive html. thanks anyway, shall ping again!

21:32 julianleviston: Hey correct me if I’m wrong, but isn’t this broken because of lazy eval? (defn add-recipes [datas] (map add-recipe datas))

21:34 julianleviston: Oh yeah, nevermind, a commenter pointed it out. all good.

21:35 she’s obviously doing all this at the REPL.

22:08 vas: In using enlive to generate html for a form, i'm trying to incorporate the *anti-forgery-token* field but it is unbound on page access. how do I make sure it gets set? or would it simply be easier to incorporate the anti forgery token into page headers instead?

22:09 justin_smith: vas: how did you go about adding the anti-forgery field to the form?

22:10 vas: you should be able to insert the right vector into the data representing the form from your request handler

22:14 vas: justin_smith: so on the (GET "/pagewithform" [] (renderpage)) you're saying i could pass the token along to renderpage?

22:14 justin_smith: right, and let renderpage insert the token into the form before rendering

22:15 you may want to include more too - eg. if they are coming back from an error after having partially filled the form you could prefill the relevant parts etc.

22:15 (eventually that is)

22:15 sdegutis: What makes Clojure particularly good at writing parsers?

22:15 vas: justin_smith: ah. that makes sense. that is a great direction! thanks a lot (=

22:15 sdegutis: hi justin_smith

22:16 justin_smith: hello sdegutis

22:16 sdegutis: justin_smith: you're so often helpful to me so I thought I'd be friendly to pay my respects

22:16 justin_smith: well thank you kind sir, and a good day to you

22:17 sdegutis: justin_smith: that was slightly humourous

22:17 justin_smith: well done

22:17 What makes Clojure particularly good at writing parsers?

22:17 julianleviston: hey this reminds me of the time a few seconds ago

22:17 … when you asked that.

22:18 justin_smith: maybe because we have first class continuations and that makes parsing so much easier

22:18 oh wait, we don't!

22:18 julianleviston: sdegutis: this? https://github.com/Engelberg/instaparse

22:19 aaelony: what does "good" mean? what does "particularly good" mean?

22:20 sdegutis: julianleviston: right

22:20 justin_smith: right, you don't

22:20 julianleviston: ah okay

22:20 aaelony: I don't know

22:21 julianleviston: sdegutis: and yet, you’re asking the question. What are you trying to ask here, really?

22:21 aaelony: comparatively easier to write? more performant? something else?

22:21 julianleviston: sdegutis: did you just read something someone said, and you’re asking us why s/he said it?

22:21 justin_smith: in all seriousness, I think functional programming is elegant for parsing, but I wouldn't say clojure, among the functional languages, was particularly good at it

22:22 sdegutis: sure

22:22 julianleviston: I think PEGs are particularly good for writing parsers.

22:22 justin_smith: for example parsing can lead to huge stack and heap usage, which are both things clojure has a problem with already

22:22 sdegutis: justin_smith: why not?

22:22 okay

22:22 thanks

22:23 justin_smith: now for a web server back end, or a REST service? I think clojure really excells for that sort of thing.

22:23 julianleviston: He’s gone.

22:23 justin_smith: 'tis his pattern

22:23 julianleviston: haha is it? :)

22:24 justin_smith: he shows up, asks a bizarre (or at least oddly worded) question, and leaves. Sometimes it's trolling, other times I can't prove it is :)

22:24 julianleviston: It did feel like he didn’t actually care about the question. Hence the lack of response, I guess.

22:25 Reminds me of one of my friends who asks impossible questions like “What hat do you think I should get?”

22:25 hueyp: with core async, is there a method to not evaluate a put until a take happens? kind of like (lazy-seq ...) ?

22:26 aaelony: I have a question like that... how much of a performance boost should one expect by converting pmaps over collections to core.async channels?

22:26 justin_smith: hueyp: you could put a delay, and deref it on the other end I guess

22:26 julianleviston: hueyp: sure… wrap a go block around a blocking take and a put after it.

22:27 justin_smith: aaelony: core.async isn't actually a perf bonus usually (not that pmap tends to have great perf for most tasks either...)

22:27 ~pmap

22:27 clojurebot: pmap is not what you want

22:27 justin_smith: julianleviston: I was imagining he meant the take and put were in separate go blocks

22:27 julianleviston: justin_smith: oh… ok. It was a very general question.

22:27 hueyp: e.g. I have a lazy-seq of blocking http requests ... no request happens if you don't take from it

22:27 aaelony: I have had good success by simply using pmap, but I'm considering adopting channels for future endeavors, any thoughts?

22:28 vas: there's gotta be a simpler way to play with this csrf token... anybody have any good resources on schoolin' a neophyte on how to ring.middleware?

22:28 hueyp: not sure how to translate that into non-blocking without evaluating at least 1 http request

22:28 julianleviston: aaelony: future endeavours?

22:28 justin_smith: hueyp: I think you would use pipeline, and evaluate each request as they are put on the channel

22:28 julianleviston: vas: oh god… it’s so simple that it’s complex.

22:28 aaelony: the next time I need to write something that will generate a lot of heat

22:28 justin_smith: either that, or send delays or functions that get evaluated or forced on the other end

22:29 julianleviston: aaelony: it entirely depends on what you’re trying to do. Ask when you have the problem, I reckon.

22:29 vas: julianleviston: hahah i feel like i am finding icebergs every time i'm trying to pick up an ice cube, but it's good practice i s'pose

22:29 aaelony: is there any general guidance?

22:29 justin_smith: aaelony: core.async is great for organizing otherwise complex interactions between different logical flows of code

22:30 aaelony: it won't always make things blazing fast, but it does tend to help with clarity and correctness

22:30 julianleviston: aaelony: generally, … no.

22:30 aaelony: justin_smith: I have used pmap for that in the past.

22:30 julianleviston: aaelony: it always depends… always.

22:30 Speaking of parsers, I really liked OMeta….

22:30 aaelony: julianleviston: that isn't a strong case to shift from the premise of avoiding pmap then

22:31 justin_smith: aaelony: yeah, if you only have one producing logic pmap can make sense (as long as there is a relatively large work load per item in the mapping) but once you have more complex flow between parallel processes core.async really starts to shine

22:32 vas: i got the token to print to the browser!! jello shots for everyone!

22:32 julianleviston: aaelony: but if you have something that generates a lot of heat, it might be for various reasons… inefficiency (due to needing to rework your program into a more understandable state), or it might just be because it needs more or less parallelizing.

22:32 justin_smith: WOO

22:32 julianleviston: vas: woo!

22:32 aaelony: justin_smith: I'm currently using it with two nested pmaps, it seems to work pretty well. For example, one pmap over choices of files to process and another pmap over the lines of a particular file

22:32 julianleviston: haha jynx

22:32 justin_smith: julianleviston: well, of course shots mean WOO what else would they mean?

22:33 julianleviston: justin_smith: oh I was wooing coz he did the thing. I don’t drink.

22:33 amalloy: lazybot: what do you say to free shots?

22:33 lazybot: It's AWWWW RIGHT!

22:33 vas: hhaha

22:33 justin_smith: haha

22:33 julianleviston: aaelony: does pmap allow you to specify the concurrency?

22:33 I should know this

22:33 * julianleviston goes to look

22:33 aaelony: julianleviston: the size of the box, right?

22:33 justin_smith: julianleviston: it's automatic based on physical cores and magic numbers

22:34 aaelony: julianleviston: in effect, yes, because I spin up a box size I need to run it on :P

22:34 julianleviston: LOL

22:34 aaelony: but it depends on the task, right? sometimes you don’t want that particular part of the program to get all that bandwidth...

22:35 aaelony: (of processors)

22:35 aaelony: so the idea is that a channel approach with core.async would provide better control?

22:35 julianleviston: aaelony: I feel like CSP gives you more control over your “concurrency”.

22:35 aaelony: I see

22:35 julianleviston: aaelony: exactly.

22:35 justin_smith: my favorite is always the calculation of the core.async pool size https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/exec/threadpool.clj#L21

22:36 I mean if I just dropped that factoid, you'd likely think I was joking if you hadn't read the source already

22:36 julianleviston: aaelony: As the programmer, you actually know how much concurrency you’d like, often… at least, in proportion to the other parts of your program. Some things are more important than others…

22:36 aaelony: I thought it had to do with the threads in async being more lightweight due to better scheduling or something like that

22:36 justin_smith: thanks for that link.

22:36 julianleviston: aaelony: well it can use sharing, whereas I don’t think pmap can, right?

22:36 justin_smith: aaelony: the core.async threads are real OS threads (or they don't exist, in cljs) but in each one there is a state machine

22:36 julianleviston: 42!!!!!

22:36 justin_smith: aaelony: hilarious, isn't it?

22:37 aaelony: funny stuff.

22:37 justin_smith: and the state machine picks up go blocks when they have been parking but are now ready to do work

22:37 aaelony: douglas adams would be proud

22:37 justin_smith: indeed

22:38 justin_smith: blame says we have tbaldridge to thank for that calculation

22:38 we have other reasons adams can be proud

22:38 julianleviston: hehe

22:38 justin_smith: (+ 41 1)

22:38 clojurebot: *suffusion of yellow*

22:38 aaelony: I didn't realize there was a term "pronic"

22:38 justin_smith: ^ like that

22:38 aaelony: funny

22:39 justin_smith: the number of rooted ordered binary trees with six leaves

22:39 aaelony: well, at some point I'll try to invoke the same functions I use with pmap in a core.async setting and compare notes.

22:40 justin_smith: the number of ways in which five pairs of nested parentheses can be arranged

22:41 aaelony: sounds like a knuth xmas lecture on trees with imaginary numbers being called imagin-ary trees...

22:41 justin_smith: haha

22:48 vas: my 404 page says "it is better to light a candle than to curse the darkness" .. just thought i would share, as it has stopped me from pulling hair out :)

22:49 julianleviston: vas: it’s also substantially harder.

22:53 wow… I’d never connected DSLs to protocol composition, but of course.

22:57 justin_smith: julianleviston: care to elaborate?

23:01 julianleviston: justin_smith: I guess Ruby burnt me out about DSLs for quite a while… (coz we’re mad about them in Ruby, but they’re not really DSLs, they’re more subsets of Ruby), and so I’d consequently not given this talk the time of day it probably deserved: http://www.infoq.com/presentations/DSL-Clojure (Jim Duey))… but really, they should be more like the VPRI POL (problem-oriented languages), where they’re actually

23:01 potentially completely different languages, which necessitates protocols and their composition…

23:02 julianleviston: astar: huh?

23:02 astar: do you mean I should learn Haskell because of the types system? I’ve learned some Haskell… not fully in depth enough to be able to code in it...

23:03 oh… he was trying to join #haskell lol

23:03 justin_smith: julianleviston: I think he meant to do /join haskell but made a typo

23:12 julianleviston: funny, so far he is showing DSLs that I have intentionally stopped using because they don't compose as well in higher order code than regular clojure would

23:12 *as

23:12 julianleviston: justin_smith: yeah it’s pretty ironic… in a way, clojure (being a lisp) is the ultimate DSL..

23:16 I’m still super keen on POLs, but I couldn’t easily understand OMeta because I didn’t understand PEGs enough… I think now I should probably revisit it… I wonder if someone’s done a port to clojure… so far all I can find it something by someone “inspired” by OMeta. There’s Ometa/js so that might be cljs portable I guess. It’s very interesting!

23:16 so much to learn.

23:33 justin_smith: oh wow, another monty cantsin

23:33 is karen eliot around too?

23:34 also, of the places I hang out this is the last one where I would expect to see a monty cantsin

23:35 montyxcantsin: me are legion

23:40 julianleviston: montyxcantsin: it’s oddly appropriate… “join haskell” ;-)

23:40 jwm: heh subethasmtp has left 300k tmp files in my temp folder

23:41 justin_smith: woah

23:43 julianleviston: I really wish commutativity was a first class programming construct rather than an afterthought, like core.async or somesuch.

23:44 justin_smith: julianleviston: like a metadata that tells you if primitives commute, and then you could derive whether a function commutes based on what it calls?

23:46 julianleviston: justin_smith: no, more like… as it stands, everything is assumed to NOT be commutative… it’s assumed that each “line” of code is non-commutative… assumed to be sequential and that prior lines have already been executed. I’d like that not to be necessarily the case. The standard should be that lines execute commutatively (ie order doesn’t matter) unless you mark them as non-commutative…

23:47 montyxcantsin: you should dig occam

23:48 julianleviston: justin_smith: because non-commutivity is really only a requirement sometimes… bindings indicate most of the non-commutivity, and for the side-effecting cases, it should be pretty trivial to mark them.

23:49 montyxcantsin: thanks I’ll take a loo

23:49 look even ;-)

23:50 I *do* very much like CSP.

Logging service provided by n01se.net