#clojure log - Jan 12 2016

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

1:45 turbofail: there should really be a transducer version of group-by

1:45 unless there is and i've missed it

2:18 amalloy: er, what would that do?

2:20 turbofail: it would return a reducing function that looks a lot like the one that's in group-by already, but with `conj' replaced by the argument reducing function

2:21 it'd probably also have to be able to receive some kind of default value to use in place of []

2:22 i use a similar function in my personal elisp library and it's super convenient, though it's slightly hampered by the fact that hash tables in elisp are mutable

2:26 blt: i feel like there is a better way to do this... https://www.refheap.com/113557

2:29 perhaps reduce

2:41 WickedShell: Is there a hint that can be passed to the compilier that tells it to strip the docstrings on AOT compilation? I've been looking but can't find anything similar to that

2:43 turbofail: blt: here's how i'd do it - http://sprunge.us/PQMi

2:43 blt: turbofail: hey, that's nicer!

2:45 turbofail: gotta love destructuring

2:59 turbofail: amalloy: here's an example implementation and usage of what i had in mind

3:00 it's a pretty powerful tool, i think. though on further inspection, i'm not sure how it would fit into the existing group-by function, because that "default" argument is pretty important

3:06 amalloy: turbofail: it looks like you said "here's an example" but didn't actually link to it?

5:03 qsys: What about core.async publisher and timeout? I have a core.async/pub, but would like to perform a 'default' action if nothing happens during xx milliseconds. (If something happens, timeout timer should reset.) I thought of using alt! somewhere, but can't figure out exactly where...

5:06 the publisher being: (def messagepub (async/pub messageq first)) I'd need a message that's added to the messageq (core.async/chan) when nothing else is added during xx milliseconds

5:09 or do I need a timer which is reset everytime a message is received?

5:33 ... or put (alt! messageq ([msg] (publish-message msg)) (timeout :timed-out)) on a channel before the publishing

6:00 tomekd789: Does anything happen on this channel, aside of people joining and leaving? The reason for asking is I'm looking for clojure "hot spots", or "vibrant societies", for general discussions.

6:01 * the_frey has left IRC

6:16 mpenet: it's more active a bit later in the day

6:17 but yes, there is life

6:17 as shown there: http://clojure-log.n01se.net/

6:19 qsys: sounds like an alts! in a loop/recur with a receiving chan and a timeout chan is the way to go yes

6:23 tomekd789: @mpenet: thx

6:25 SevereOverfl0w: tomekd789: Make sure you check out the slack, really active there.

6:37 tomekd789: SevereOverfl0w: Can you expand 'slack'? Will be happy to join.

6:40 scottj: tomekd789: https://clojurians.slack.com/

6:40 SevereOverfl0w: ^^ beat me to it

6:40 aurelian: can I access that via my IRC client?

6:41 SevereOverfl0w: I think so actually.. but the web client is really very neat imo.

6:41 scottj: aurelian: I think so, slack has an IRC gateway

6:42 aurelian: yeah, I know but it has to be activated by community admin or something

6:42 is not enabled by default AFAIK

6:42 anyway... how do I get an invite to slack?

6:42 mpenet: it's accesible via a normal irc client yes

6:43 aurelian: sweet

6:43 mpenet: I used to do just that

6:43 scottj: aurelian: auto inviter http://clojurians.net/

6:46 tomekd789: scottj: thanks!

6:53 qsys: @mpenet (12:19): thx... saying it 'loud' (on irc) made me realize it's rather obvious

6:57 turbofail: amalloy: doh. here's the link http://sprunge.us/SGXa

6:57 aurelian: so how do I get into that slack thing?

7:10 tomekd789: scottj: got there, tx again.

7:18 aurelian: start with the auto-inviter mentioned above by scottj, i.e. http://clojurians.net/

7:18 aurelian: then you'll be guided by hand

7:19 aurelian: ah, okay for some reason I was accessing clojurians.slack.com

7:25 cool stuff, I'm in :)

7:55 ustunozgur: I recall seeing a lein plugin that adds the dependency to the dependencies list from the command line, kind of the equivalent of npm install foo --save.

7:55 does anyone remember the name or the technique?

7:56 found it

7:56 https://github.com/johnwalker/lein-plz

12:25 justin_smith: aurelian: http://clojurians.net/

12:25 oops, I was scrolled and did not realize it

12:34 lokien: Hey, does someone here use cursive?

12:38 TimMc: ystael: Did you figure out the Luminus thing from the other day?

12:39 Kamuela: lokien: I tried but settled on night code

12:40 lokien: Kamuela: did you do that licence thing? my friend's having issues with that

12:40 Kamuela: lokien: nah just the trial

12:41 lokien: Kamuela: damn, so we're screwed

12:41 Kamuela: Contact support if there's an issue

12:42 justin_smith: lokien: cfleming is often here - he might be able to help

12:42 kwladyka: lokien just register on cursive site, it is easy

12:42 but you have to wait for accept

12:43 Kamuela ^

12:43 lokien: kwladyka: we've got the key, but every time we enter it, there is "invalid certificate" message

12:44 kwladyka: lokien oh are you sure you copy whole key the beginning to the end?

12:45 sdegutis: Is there a shorter way to map an array of keys to their values in a map, than this? (map #(get m %) ks)

12:45 lokien: kwladyka: yeah, with ----begin licence---- and without

12:46 kwladyka: lokien you can always write to cursive@cursive-ide.com with your problem

12:46 justin_smith: sdegutis: (map m ks)

12:46 sdegutis: Oh!

12:46 kwladyka: lokien he will answer

12:46 sdegutis: Sweet! Thanks justin_smith :D

12:46 lokien: kwladyka: and we've tried to enter just this big chunk of code, didn't work also. I guess he'll just switch to linux

12:46 kwladyka: thanks for help

12:46 sdegutis: I forgot maps are functions of themselves.

12:47 Mainly because it's /generally/ bad practice, in the event it's nil.

12:47 justin_smith: (map (or m {}) ks) ?

13:00 sdegutis: In my case it's fine.

13:00 I definitely know m is some?.

13:04 justin_smith: for extra safety you could check ifn? instead

13:04 ,(ifn? {})

13:04 clojurebot: true

13:04 justin_smith: ,(ifn? "")

13:04 clojurebot: false

13:07 sdegutis: I imagine Compojure's source code is very high quality Common Lisp.

13:08 And if I ever finish my Lisp-like language, it will absolutely not have macros. All things that would be macros will be built into the compiler as internal AST transformation phases.

13:08 j-pb: why have s-expressions if you cant extend the compiler?

13:09 sdegutis: j-pb: because they're still the superior syntax

13:09 Writing Clojure in Emacs using Paredit is always really easy for me, much easier than other languages.

13:11 * sdegutis replaces [compojure "1.4.0"] with [clout "2.1.2"]

13:21 sdegutis: Does core.match have something like {:keys [...]} ?

13:24 Never mind, using the work-around.

13:45 Oh man.

13:46 compojure.core/GET is a macro that doesn't return a syntax-quoted form.

13:47 justin_smith: sdegutis: eh, it calls a function that returns a syntax-quoted form, what's the difference?

13:47 sdegutis: Touche

13:47 I'm trying to piece apart what it does so I can reverse-engineer it in order to build up my own list of routes as data, which I can then turn into a Compojure router.

13:48 So that I can do [:get "/" #'home/landing-page]

13:48 justin_smith: sdegutis: have you looked at bidi or polaris? those are two examples of routing libs that basically do that

13:49 sdegutis: Ah.

13:49 Yeah I was trying bidi out, but I don't understand why {foo bar} is equivalent to [[foo bar]] rather than [foo bar].

13:49 That fact scared me away from it.

13:49 justin_smith: ,(vec '{foo bar})

13:49 clojurebot: [[foo bar]]

13:50 sdegutis: Oooh, right.

13:50 So it's just like when you put {} through for and destructure with [k v]

13:50 That makes more sense.

14:03 jmonreal: hello, does anyone know where can I find two sigma satellite irc channel or where to discuss this project?

14:06 sdegutis: justin_smith: also my brain has the most impossible time parsing ["/" {"blog" {:get {"/index" (fn [req] {:status 200 :body "Index"})}}}]

14:06 (One of the examples on the main page.)

14:07 And separating it into different lines with their own indentations doesn't help one bit.

14:07 justin_smith: sdegutis: then make up your own way of arranging the data, and a function that turns it into the other one?

14:07 it's just data

14:07 sdegutis: But I can't even *understand* the other one.

14:07 So I can't transform anything into it.

14:07 It literally seems like a bunch of nonsense data with no apparent structure.

14:08 This is probably my 7th time reading the readme in two weeks, and I still just have no idea what's going on with this data.

14:08 cfleming: $mail lokien mail me at cursive@cursive-ide.com and I'll help you out with that.

14:09 sdegutis: His BNF doesn't really help either. In fact I think it kind of proves my point, that this data format is practically opaque.

14:09 cfleming: ,(+ 1 2)

14:09 clojurebot: 3

14:09 justin_smith: cfleming: different bot

14:09 cfleming: lazybot does $mail, and is not around

14:09 cfleming: Ok, just checking - is the mail bot...

14:09 darn

14:10 Oh well

14:10 They know where to find me, I guess

14:13 sdegutis: Wow.

14:13 bidi is surprisingly difficult to use

14:13 and silk has very little traction, so it's going to die and be consumed by bidi

14:14 I have half a mind to fricken write my own router at this point. All the major options are unworkable.

14:16 DomKM: sdegutis: Lot's of people seem to be using Silk without issue. I won't let it die; I just don't have time to finish v1 right now.

14:17 sdegutis: DomKM: I don't mean any offense. It's just the nature of open source. Over time, projects get re-prioritized, and those which don't make money, directly or indirectly, are gradually abandoned, and its userbase is consumed by the next best thing.

14:18 DomKM: take weavejester's for example; it's probably the most inferior of all the routing libs, but it helps him get contract work, and it's got strong name recognition in the community, so it's become the de facto router

14:18 DomKM: It's also the oldest

14:18 sdegutis: And he's going to continue to have time to update it as the Clojure ecostructure evolves, so it'll be around the longest.

14:18 justin_smith: yeah - to replace the first mover, you need to be at least 10x better, anything less is overcome by resistence to change

14:19 sdegutis: Yep.

14:23 Which also explains why people still use Java and C++.

14:23 DomKM: sdegutis: Either what I am working on will become profitable and some of that will be put toward growing Silk (because we use it), or what I am working on will fail and I will have a lot more time to work on OSS, which means I will be going back to Silk. Either way, I'll get back to it (I just hope it's under the former condition). So, yes, it is a

14:23 prioritization issue but I expect the priorities to change, one way or the other.

14:23 sdegutis: DomKM: well, best of luck to you then sir :)

14:23 DomKM: Thanks :)

14:23 sdegutis: DomKM: although I'm sure luck will play a small part in your success considering your talent ;)

14:24 DomKM: Anyway, sorry that Silk hasn't worked well for you thus far.

14:25 princeso: why would be that postwalk isnt respecting the metadata of lists?

14:25 ,(clojure.walk/postwalk (fn [x] (prn (meta x) x) x) '^:meta(list x))

14:25 clojurebot: #error {\n :cause "clojure.walk"\n :via\n [{:type java.lang.ClassNotFoundException\n :message "clojure.walk"\n :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}]\n :trace\n [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366]\n [java.net.URLClassLoader$1 run "URLClassLoader.java" 355]\n [java.security.AccessController doPrivileged "AccessController.java" -2]\n [java.net.U...

14:26 justin_smith: ,(require 'clojure.walk)

14:26 clojurebot: nil

14:26 princeso: the bot has a session for every user?

14:27 ,(require 'clojure.walk)

14:27 clojurebot: nil

14:27 princeso: ,(clojure.walk/postwalk (fn [x] (prn (meta x) x) x) '^:meta(list x))

14:27 clojurebot: nil list\nnil x\nnil (list x)\n(list x)

14:28 justin_smith: princeso: no, there are no per-user sessions

14:28 princeso: ,(clojure.walk/prewalk (fn [x] (prn (meta x) x) x) '^:meta(list x))

14:28 clojurebot: {:meta true} (list x)\nnil list\nnil x\n(list x)

14:28 princeso: prewalk works good

14:29 sdegutis: DomKM: like I said in the github issue a few years ago, it's not that silk isn't right for my needs, it's that I don't understand how to use it from a routing perspective, since the readme seems to focus on it from too abstract a standpoint, rather than how to use it in real life

14:29 DomKM: I looked at it again a few weeks ago to see if that was addressed, but I still couldn't really see how to use it as a router.

14:30 DomKM: the "Strings only match themselves." and "Keywords are wildcards." and "There are also built in patterns for common use cases." don't explain how this has to do with routes at all; it's very confusing

14:31 justin_smith: princeso: the issue is in the source of clojure.walk/walk - if the item is a seq, it calls map, and map does not preserve metadata

14:31 sdegutis: DomKM: if those were addressed, I'd love to take another look at silk

14:31 justin_smith: princeso: though it would be easy to make a version of clojure.walk/walk that preserves metadata of seqs

14:32 DomKM: sdegutis: What specific routing context? Backend with Ring (Compojure replacement)? Frontend (Secretary replacement)? Both? If frontend, do you want to route with the history API or with hashchange?

14:32 sdegutis: As a Compojure replacement.

14:32 I think I see the issue here. Is there a programming thing called generality-syndrome?

14:33 DomKM: sdegutis: Gotcha. Okay, well Silk isn't specific to Ring, Compojure is.

14:33 princeso: justin_smith: that sounds interesting, i searched for a way to make a walk, with no look

14:33 sdegutis: Like, when you try to become so abstract that you're everything to everyone.. that thing

14:33 justin_smith: princeso: (clojure.repl/source clojure.walk/walk)

14:33 DomKM: Hah, I don't know if it's a syndrome but yeah, it's quite general.

14:34 justin_smith: princeso: if you look at the source of postwalk, it's just a simple call to walk

14:34 DomKM: To use Silk with Ring, you need to generate your own Ring responses (status, body, etc.). Compojure does that for you. Silk only handles the URL matching part, not what you do after. That's why I was asking what context you were trying to use it in.

14:34 sdegutis: DomKM: I don't even mind if it's not specific to Ring. As long as I can give it "/articles/:title/edit", match it to "/articles/foo/edit", and it gives me a positive match along with {:title "foo"}, that's good enough for me.

14:35 That's what I'm looking for in the beginning of a readme for a router.

14:35 Clout seems to do that mostly well enough, so I'm trying that now.

14:35 DomKM: It does that, except you'd write ["articles" :title "edit"]

14:36 princeso: justin_smith: thx. let me watch closer ... i see prewalk calls walk even

14:37 Bronsa`: sdegutis: have you looked at bidi?

14:37 justin_smith: Bronsa`: he said he was confused by it

14:38 Bronsa`: https://github.com/juxt/bidi#route-patterns

14:38 it's pretty straightforward and does exactly what he's describing

14:39 sdegutis: DomKM: Hmm, I like that.

15:04 SevereOverfl0w: DomKM: Bidi is a pretty good example of how to talk about the generic router, but also mention ring, in my opinion.

15:25 orz: If, in an interop situation where I'm grabbing an object from a java iterator, do I need to cast it explicitly still?

15:38 sdegutis: Also, Compojure seems to do a lot of transformation stuff with various kinds of params.

15:47 justin_smith: orz: why would you cast it?

15:47 orz: also, instead of grabbing an object from an iterator, you can use iterator-seq

15:52 orz: Im trying to use an ImageWriter to control the quality of a saved jpeg image.

15:52 justin_smith: OK

15:52 orz: To do that I need to call ImageIO.getImageWritersByFormatName("jpeg"); and take the first element from the iterator it returns

15:53 And the java docs Im using tell me I have to cast it since the iterator it has dosen't use generics

15:53 justin_smith: orz: generics are fictional

15:53 they don't exist

15:53 we don't have casting because we don't have generics (since the vm doesn't have them either, this isn't a problem)

15:54 orz: So I can just take the object and try calling the method I need from the subclass?

15:54 justin_smith: right

15:54 you can use a type hint to avoid runtime reflection when calling the method, but that's not the same as a cast

15:55 orz: So I could use something like (let [^ImageWriteParam iwp (.next iter)]) right?

15:55 justin_smith: right

15:55 well, the name comes before the hint, but yeah

15:55 I think? maybe I misremember that.

15:56 never mind, you have it right

15:56 orz: The docs for iterator-seq say I can just use seq directly on an iterator. So does that mean I could just write "(let [iwp (first (seq iter))])"?

15:57 justin_smith: orz: or (first iter) - first calls seq on its arg

15:57 ,(doc first)

15:57 clojurebot: "([coll]); Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil."

15:57 orz: that's even better. Thanks!

15:58 justin_smith: orz: so iterator-seq says for Iterable you don't need iterator-seq - TIL

15:59 orz: Yeah but the way I get the iterator is from a static ImageIO method, so I thought I needed the iterator anyway

16:01 justin_smith: Yeah in clojure it shouldn't matter where your Object came from, as long as it has the Interface or Class you need.

17:12 sdegutis: Oh man.

17:12 Compojure -> Clout -> Instaparse.

17:12 https://github.com/weavejester/clout/blob/master/project.clj#L7

17:14 Compojure indirectly uses Instaparse, heh!

17:30 Is it possible to discover an anonymous function's arglists? For example, from (fn [a b] ...), end up with '[[a b]]

17:31 justin_smith: I think you'd need some black magic for that

17:32 sdegutis: Hmm.

17:32 Tried looking into AFn.java to see if there could be some fields I could examine.. but nope

17:32 justin_smith: I guess you could use serializable-fn

17:32 sdegutis: Ahhh haha yeah maybe.

17:33 justin_smith: that means using the special serializable version of fn though

17:33 or replacing fn with that one?

17:33 sdegutis: Right.

17:33 Yeah I'm not gonna go that route.

17:34 amalloy: justin_smith: and also having to do some data wrangling to *find* the arglists in the list representation of the functino

17:34 justin_smith: oh, that too, yeah

17:34 amalloy: like you have to handle '(fn [a b]) as well as (fn '([a] [a b])) as well as '(let [x 1] (fn [a b]))...

17:36 justin_smith: sdegutis: you could promise not to do side effects, then use try/catch to find out via trial and error which arities it accepts

17:36 lol

17:36 sdegutis: Haha.

17:36 Oh you.

17:37 amalloy: you laugh, but i would estimate there are a countably infinite number of people who have decided this is a good idea

17:47 sdegutis: I'm mostly leaning toward (defn ^{:method :get :path "/"} home-page [db user] ...)

17:54 justin_smith: sdegutis: or the thing where everything takes exactly one arg, a hash map

17:54 I mean that's what ring does anyway

17:54 sdegutis: Yeah, that's what I'm doing right now.

17:55 But I'm trying to meta-program away the [{:keys [db user]}] so I can just write [db user]

17:55 Because that gets old after the 240th time.

17:55 justin_smith: feels like a lot of effort for a minimal convenience

17:55 sdegutis: You may possibly be right.

18:08 In fact, you *are* right.

18:09 TimMc: All my fns take exactly two arguments: The first is a lookup table of names to fns, and the other is an argument map. It makes dependency injection so easy! /s

18:10 justin_smith: haha

18:11 SevereOverfl0w: Heh. I've been doing something like that for templating, where my functions return either a ring map, or a hashmap for the templates. So my enlive fns must take only one arg or die.

18:11 I do wish there was a simple way to use something like Plumbing's fnk with Enlive (& other macro-based things)

18:12 I do wonder if we've over-encouraged macros for the fn problem, when really we should have been accepting anonymous functions as arguments.

18:18 sdegutis: DI well is hard.

18:20 SevereOverfl0w: * well is hard.

18:21 TEttinger: hard * is, well...

18:22 sdegutis: Ha. ha.

18:22 haaaaaa....

18:24 blake__: Trying to send-message with postal and...going postal.

18:24 justin_smith: dealing with time zones and feeling pretty wibbly-wobbly about things

18:24 blake__: In the docs for the google example it has this for the ssl key: ":ssl :yes!!!11}"

18:24 hiredman: while reading "Going Postal" I hope

18:24 blake__: (And playing postal.)

18:25 But the ":yes!!!11" doesn't seem to actually work. No keywords work. Nor does "true", as I found elsewhere. It apparently needs to be a string.

18:25 justin_smith: blake__: guessing it accepts anything truthy, so they just threw in something silly

18:25 oh

18:26 blake__: justin_smith: Yeah. I get a "boolean can't be converted to string" or "keyword can't be..."

18:27 Oh, crap, never mind. Just a typo. =P

18:28 sdegutis: blake__: you using AWS SES?

18:29 blake__: sdegutis: Not currently. Might, though, later on.

18:29 sdegutis: ok

18:47 nanuko: is it possible to create a random object in clojure such that i can perform `(.randomMethod random-object 1 2 3 4)`?

18:48 justin_smith: nanuko: how random does the object need to be?

18:49 nanuko: justin_smith: essentially an object that mocks out one called for a side effect

18:52 justin_smith: nanuko: that doesn't sound random at all - you can reify the interface which defines .randomMethod

18:52 amalloy: bet you a dollar it's not in any interface

18:53 justin_smith: OK, you could proxy the calss

18:53 *class

18:53 nanuko: amalloy: yup, it’s a class

18:53 amalloy: unluckily, the class (or method) is final

18:54 nanuko: the class is method

18:54 final*

18:54 sorry

18:54 amalloy: java unreasons

18:54 nanuko: this is the class i’m trying to mock https://github.com/tim-group/java-statsd-client/blob/master/src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java

18:55 amalloy: nanuko: you just need to reify StatsDClient

18:56 which is the actual interface this class implements

18:57 nanuko: would i need to reify the whole interface?

18:58 amalloy: well, supposedly yes

18:58 but in practice you can reify just one method and as long as none of the others are called you get away with it

18:59 nanuko: oh sweet! so something like (reify StatsDClient (incrementCounter [arg] (prn arg))?

18:59 amalloy: sure, as long as this function you're calling on doesn't rely on its StatsDClient to do anything meaningful

19:02 nanuko: nope, just checking that the function is called in a test

21:10 kenrestivo: what's that clojure equivalent to chef, puppet, and ansible?

21:11 iirc chef and puppet are ruby. ansible is python. and ___ is clojure?

21:16 amalloy: kenrestivo: you're thinking of pallet

21:17 but i think the puppet folks said some publicly nice things about clojure a while ago, claiming they were "switching to it" somehow, but i don't remember the details. probably in some way that doesn't end up affecting users who write plugins in ruby or whatever

21:32 kenrestivo: amalloy: thanks, pallet it is.

21:32 oh did they? hmm...

21:32 * kenrestivo smells acquisition talks...

21:32 amalloy: https://puppetlabs.com/blog/new-era-application-services-puppet-labs

21:32 april 2014

21:54 Sgeo_: WHat's that pastebin that uses Mozilla Persona?

21:57 TimMc: Sgeo_: refheap, but it's going read-only and persona is going to the farm

21:58 Sgeo_: I just saw the thing about Persona, which is why I was wondering, but why is RefHeap going read-only?

22:07 TimMc: Sgeo_: Raynes didn't have the time and energy to deal with takedown requests for credit card numbers and other stuff that was being posted illegally.

22:09 Sgeo_: Ah

22:16 kenrestivo: the farm?

22:16 what farm?

22:17 justin_smith: amalloy: puppet is heavily invested in clojure, they host all the portland clojure meetups, and clojure and c++ are the two parts of their backend right now

22:18 amalloy: kenrestivo: the farm upstate, i presume

22:18 the big doggy park in the sky

22:19 kenrestivo: oh. bummer. it was the best system around. of course it wouldn't last.

22:19 instead we get authentication grafted onto an wildly-un-interoperable authorization system. yay.

22:20 * kenrestivo grumbles like an old man

22:28 TimMc: Persona was persistently close to being good, but never really reached it.

22:29 I saw an interesting post by someone at Mozilla who said that the design was fatally flawed due to (IIRC) too-rapid development and not enough resources.

22:29 something like that

23:15 virmundi: hello.

23:15 is edn replaced by Transit?

23:16 TEttinger: no, they have different purposes

23:17 virmundi: aside from configuration with edn, as an interchange document, what’s the difference?

23:17 I thought edn targeted Java, iOS and JS by wayof ClojureScript

23:18 amalloy: isn't transit illegible to humans?

23:18 TEttinger: edn is considered a data format like XML or JSON, all 3 are human-readable

23:19 hence why clojure uses a superset of edn for source

23:19 (if it wasn't human-readable it wouldn't be very useful!)

23:19 virmundi: so Transit is a mostly better because it’s a binary format?

23:19 TEttinger: again, different purposes

23:19 there is not a better here

23:20 is a carrot better than an orange

23:21 virmundi: if I was making a new REST-ish service, would I want to use Transit or edn, with the possiblity that I’ll eventually expose my service to iOS and Android?

23:21 justin_smith: transit has better portability to other languages

23:22 amalloy: better than edn? i was not aware of that

23:22 justin_smith: and unlike regular edn you can use a locally scoped data structure to describe the encodings (instead of a magic file on the classpath)

23:22 TEttinger: clojure can run on iOS and android but not as quickly as it does on the desktop/server

23:23 so justin_smith is right about the portability being a good thing

23:23 virmundi: is there a clojure->Swift transpiler?

23:23 TEttinger: guh?

23:23 why on earth would someone transpile to swift?

23:23 virmundi: well, I thought the way clojure works on iOS presently is via JS/Clojurescript.

23:23 TEttinger: I think it's via robovm, let me check

23:24 justin_smith: amalloy: I don't have a clean cite, but I can say that transit comes from the folks who made edn, and is meant for cross-language data sharing

23:24 amalloy: i mean, so was edn

23:24 TEttinger: https://github.com/oakes/lein-fruit

23:24 there may be other things like this

23:24 amalloy: my understanding was that the difference is edn is human-readable, transit is compact

23:25 justin_smith: amalloy: I'm looking at the cognitect repos and not finding any edn libs for other languages

23:25 amalloy: https://github.com/relevance/edn-ruby

23:25 TEttinger: robovm has become commercial since that was made, though certain things still get free licenses

23:25 amalloy: there are edn libs all over, some more official than others i guess

23:26 justin_smith: right, but there are official transit libs from cognitect for python, ruby, java, javascript

23:26 TEttinger: well the reason you wouldn't want to transpile to swift is because it makes more sense to generate bytecode that iOS can run natively (LLVM) AND that every other LLVM platform can run (including the web via emscripten)

23:27 amalloy: https://github.com/edn-format/edn/wiki/Implementations

23:27 justin_smith: interesting

23:27 amalloy: i think they want(ed) both of these things to be portable

23:27 TEttinger: but clojure (and to a lesser extent clojurescript) is not something that someone can magically write a transpiler for overnight. clojure has a non-trivial amount of java source

23:28 amalloy: whether they achieved that is another question

23:28 i certainly would not use transit in real life, where i would consider edn

23:28 justin_smith: amalloy: I use transit extensively, and at the code boundary it becomes edn

23:29 amalloy: the code boundary?

23:29 justin_smith: the point where it goes from being an opaque container I pass around, to a value I use

23:30 probably there's a better way to say that

23:30 virmundi: justin_smith: you unmarshal it from the wire to edn internal.

23:30 justin_smith: right

23:30 but if I consumed it from js it would become standard js datatypes

23:30 hiredman: you don't unmarshal antthing to edn

23:31 anything to edn

23:31 virmundi: aside from the compactness, I think transits’ linking might make it a better REST data format.

23:31 hiredman: edn is marshaled

23:31 amalloy: yeah i was about to say the same thing hiredman is

23:32 you don't unmarshal to edn internally, you unmarshal to clojure data types

23:32 edn is string representations of data

23:32 virmundi: I kinda thought so.

23:34 thanks.

23:53 domgetter: Is it possible to make a macro that expands to more than one form?

23:53 justin_smith: no

23:58 neoncontrails: I have a postrgresql server up and running, and I'm following the instructions here to connect it to my luminus app: http://www.luminusweb.net/docs/database.md. I'm following along up until the part where it binds a raw SQL query to a function called create-user! and passes a bunch of fields to it. How do I call this function from my app?

23:59 domgetter: neoncontrails: that link didn't work

23:59 neoncontrails: Is the idea to require the myapp.db.core namespace in myapp.core, and use the fully-qualified myapp.db.core/create-user! syntax to invoke?

23:59 domgetter: hmm, let me try again

23:59 domgetter: nvm, i removed the trailing period

Logging service provided by n01se.net