#clojure log - Jun 29 2013

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

0:01 derek_c: Does Leiningen support all maven repos?

0:06 gt`: Hi all, I am on ubuntu want to get clojure read MS SQL data using unixodbc. UnixODBC is setup and working already with MS SQL i just need to know how i could get clojure to read data using any useful library . Appreciate any help

0:07 technomancy: derek_c: it should, yeah

0:17 dnolen_: bbloom: what do you mean?

0:17 bbloom: they certainly aren't a problem the way large methods are on the JVM

0:18 bbloom: dnolen_: i was just wondering what would happen if i compiled a gigantic switch statement in a single big function

0:18 dnolen_: something like what parser generators output

0:19 dnolen_: bbloom: never benchmarks such a thing, but I would imagine not a problem

0:19 benchmarked

0:19 bbloom: dnolen_: even on firefox? i thought firefox was a method jit instead of a tracing jit

0:19 dnolen_: bbloom: dunno, I kinda ignore FF as it's performance is often dismal

0:19 bbloom: heh

0:23 dnolen_: bbloom: my main complaint with FF is GC, they are working on it, it seems

0:24 recent JavaScriptCore is amazing, so I expect FF will get there too

0:24 bbloom: still, as far as big fns, I just don't see why that would be a problem given modules in JS are giant closures

0:25 bbloom: ah, good point

0:25 although i guess modules are only ever really loaded once :-P

0:40 dnolen_: in your dbounce example, could you just initialize with (js/Date. 0) to avoid the nil check ?

2:05 ozzloy: how do you unit test functions that return functions? i did (expect #() #()) which didn't work

2:05 (using expectations)

2:06 a quick answer i can think of is to test that applying the returned function to some values gives the desired output

2:06 but that's not the same as testing whether the returned function is what you expected

2:07 bbloom: ozzloy: functions use reference equality

2:07 ,(= #() #())

2:07 clojurebot: false

2:07 bbloom: ,(let [f #()] (= f f))

2:07 clojurebot: true

2:07 bbloom: you can't test the shape of a function at all

2:28 SegFaultAX: Does something other than Friend exist yet?

2:30 amalloy: SegFaultAX: infinitely many such things

2:30 SegFaultAX: amalloy: Something that is already a thing, and that doesn't suck?

2:31 amalloy: SegFaultAX: i was introducing levity by pointing out that you didn't limit your scope: so far cupcakes fit the bill under all three of your requirements

2:31 SegFaultAX: amalloy: Cupcakes already do authentication?

2:32 Does something that does what friend is supposed to do, but in a considerably less shitty way already exist?

2:37 tomjack: what is friend supposed to do?

2:37 SegFaultAX: tomjack: Warden-like authentication.

2:38 tomjack: "already" threw me off

2:42 Raynes: SegFaultAX: In case you didn't totally get amalloy's joke, he was taking advantage of the fact that the scope you were limiting to includes every single quark in the universe that doesn't make up Friend.

2:43 SegFaultAX: Raynes: Yea, but I'm genuinely curious about this pedantry aside.

2:46 pepijndevos: Are go block generally preferred over threads in core.async?

2:46 (on JVM)

2:47 tomjack: they're complementary

2:48 a decent rule of thumb (I think) is to use thread when the body may block

2:49 a go body should do its stuff quickly, not block on IO or whatever, maybe parking on a channel op

2:50 if not, you'll potentially stop up everything since you only have a fixed pool for go blocks

2:50 not sure what fork/join would mean in relation to this

2:50 SegFaultAX: tomjack: I thought go blocks will automatically park?

2:51 tomjack: I wouldn't call it automatic

2:51 if you use <!! in a go block, that's bad

2:51 if you use <! you're saying "park if necessary"

2:51 (and <! cannot mean anything else)

2:51 pepijndevos: Is core.async in any repo? lein doesn;t find it

2:51 SegFaultAX: "go is a macro that takes its body and examines it for any channel operations. It will turn the body into a state machine. Upon reaching any blocking operation, the state machine will be 'parked' and the actual thread of control will be released. "

2:52 tomjack: no, it hasn't been released

2:52 SegFaultAX: that's maybe misleading in this context

2:52 it's not like gevent's insane monkeypatching or whatever

2:52 SegFaultAX: tomjack: Just repeating what the author wrote.

2:52 rhickey in this case.

2:52 tomjack: "blocking operation" there means <! or >!

2:52 (or alt!/alts!)

2:53 if you deref a future or do syncronous IO or whatever it can't automatically make that async

2:55 SegFaultAX: tomjack: I'm still wrapping my mind around core.async. Haven't looked at it deeply enough yet.

2:55 ozzloy: bbloom, oh, bummer

2:56 bbloom: ozzloy: consider the complexity of that for a moment…. are (fn [x] x) and (fn [y] y) equal?

2:56 ozzloy: bbloom, sorry, i left pretty quickly because i thought the channel was sleeping

2:56 amalloy: bbloom: well, that one's not a great example because they'll generate identical bytecode

2:56 ozzloy: bbloom, i'm aware that it would be complex

2:56 in general

2:56 bbloom: amalloy: shhh you :-P

2:56 amalloy: but, eg, #(+ % %) #(* % 2)

2:57 ozzloy: it's provably impossible, in general

2:58 r0bgleeson: are many of you working with clojure in a day job?

2:58 ozzloy: well... provably impossible to determine if two functions will give the same output for all input

2:59 but if they have the same form but different identifiers or something

2:59 anyways, the answer is no, so i'll move on to my next question: how do people in here unit test functions that return functions

3:00 tomjack: pretty much the same way you test a function

3:00 ozzloy: kk

3:00 tomjack: it's just the same problem again

3:00 ozzloy: well kinda

3:01 amalloy: all you can do is call the function with some inputs and verify you get out what you wanted

3:01 SegFaultAX: Haskell explicitly guards against this problem.

3:01 Well, optionally.

3:01 amalloy: SegFaultAX: you mean by not having an Eq instance for functions?

3:01 SegFaultAX: amalloy: Yes.

3:02 amalloy: except you can add one, if you're a maniac

3:02 SegFaultAX: That's the optionally part.

3:02 There's also some caveats to overloading functions due to the no monomorphism restrictions.

3:02 Also optionally.

3:03 But that's more of a failing of the type system.

3:03 amalloy: i recently learned what that means, although i don't see what it has to do with function equality

3:04 SegFaultAX: amalloy: Oh it doesn't. It merely places restrictions on expressions without explicity type information.

3:04 Explicit, even.

3:05 ozzloy: explicity is a fun word

3:05 sounds like a value of how explicit something is

3:06 g'night. thanks for the help

3:06 SegFaultAX: So are most people just rolling their own authentication then?

3:07 callen: SegFaultAX: that or Friend, yeah.

3:08 SegFaultAX: Bummer.

3:08 Raynes: callen: hi

3:08 callen: Raynes: hey

3:08 SegFaultAX: part of the problem is that while there's a common surface area in Ring, there isn't an agreed upon framework so it's hard to write something everybody can use and that will 'just work'

3:09 Raynes: callen: I met muhoo tonight. We had a blast. RAWK n ROLL'd like crazy.

3:09 callen: Ring middleware can realistically only go so far unless you stash a lot of paranoid state somewhere.

3:09 Raynes: Awesome fellow.

3:09 callen: Raynes: yeah I had a good time bumming around SF with him. Very nice guy.

3:09 amalloy: instance Eq (a->b) where (==) x y = True -- muahahaha, what have you done, SegFaultAX????

3:09 SegFaultAX: amalloy: Haha, wut. :)

3:10 callen: SegFaultAX: so until the community decides it's okay with having a Rails/Django'ish solution somewhere, people will keep rolling their own over and over.

3:10 SegFaultAX: Warden does a decent job of providing a solution for this built purely on rack middleware.

3:10 amalloy: SegFaultAX: well, there are only two plausible definitions of such an operator, and False seemed like it wouldn't have caused as much chaos

3:11 callen: SegFaultAX: then use Warden

3:11 SegFaultAX: And lots of the most popular authentication frameworks are built on warden.

3:11 callen: I prefer to write my own middleware because I like using the request context.

3:12 SegFaultAX: Friend seems to be heavily influenced by warden and it says as much in the documentation. But the implementation is... rough.

3:12 callen: sounds like you know what you want.

3:13 pepijndevos: I'm having trouble mapping CSP onto core.async.

3:14 SegFaultAX: What interests (and perhaps confuses) me is that this doesn't seem to be a more well explored area than I would have anticipated.

3:15 Lots of (most?) apps require some form of authentication or another.

3:15 callen: SegFaultAX: User-facing applications that are more likely to have auth aren't the most common use of Clojure at the moment.

3:15 SegFaultAX: lots of people will have a Clojure API hiding behind a Rails app.

3:15 I'm not happy about this, but again, that's why I have my own bag of tricks for this nonsense.

3:16 pepijndevos: In core.async there are clearly senders and receivers, while in CSP there is just "stuff happening"

3:17 tomjack: are you reading hoare?

3:17 pepijndevos: yea

3:17 tomjack: it's like hundreds of pages in iirc before channel-like things are introduced

3:17 pepijndevos: Trying to imagine a vending machine with multiple customers

3:18 ah

3:18 ok, more reading....

3:18 tomjack: I think in CSP you just say that an event can be a pair of a channel and message

3:18 the way it's formulated you don't have to distinguish between send/receive

3:19 pepijndevos: ?

3:19 okay...

3:20 tomjack: because the alphabet is defined such that a sent message could only be sent

3:20 e.g. if the vending machine has a channel, you could say products will always be received and coins always sent

3:21 pepijndevos: yea, that makes sense

3:21 tomjack: and in the formalism 'sent' and 'received' are just meaningless

3:21 pepijndevos: like so? https://www.refheap.com/16190

3:21 tomjack: just us dirty operational dynamic folks need to care about that nasty stuff :)

3:21 pepijndevos: lol

3:22 So that works with one customer, but with 2 it gets strange

3:23 tomjack: why strange?

3:23 pepijndevos: coin -> choc ||| coin -> choc ||| coin -> choc, I think in CSP that would do one coin -> choc, but with channels that would do 2, in undetermined order.

3:24 tomjack: sorry what's |||

3:24 pepijndevos: that lockstep concurrent thig I think.

3:25 SegFaultAX: Whoa netsplit?

3:26 tomjack: VEND = (slot.coin) -> (tray.choc) -> VEND ?

3:28 I don't understand the mapping well either

3:28 pepijndevos: yes

3:29 tomjack: VEND and BUY look exactly the same, though, right?

3:29 SegFaultAX: If you need some comedy in your life, open up the local computer gigs page on craigslist and see the ridiculous things people want for completely insane prices (often free)

3:29 tomjack: BUY = (slot.coin) -> (tray.choc) -> BUY ?

3:29 SegFaultAX: "I want to build a facebook/amazon clone"

3:30 pepijndevos: tomjack, exactly

3:30 SegFaultAX: Price: $250 - $500 depending on how long it will take

3:30 tomjack: because VEND and BUY are tied in a circle, so slot.coin and tray.choc are in the alphabets of both

3:30 then VEND || BUY || BUY

3:30 anyway I think your code should work fine as long as state is an unbuffered channel

3:30 pepijndevos: yes, so if you run the in parallel, they execute coin and choc synchronously.

3:31 tomjack: as you'd get from (chan)

3:31 the vending machine won't accept a second coin until the first choc has been received

3:31 pepijndevos: right, but now add another customer

3:32 tomjack: and a customer can't get a choc until it's put a coin in

3:32 what's the problem?

3:32 pepijndevos: well, that should work with the code, but I think that's different from what CSP does. But maybe I'mwrong

3:33 tomjack: oh, I must have misunderstood you

3:34 pepijndevos: So in Clojure coin -> choc ||| coin -> choc ||| coin -> choc would give each customer a choc.

3:35 But in CSP it's more like 2 people and a mchine together insert a coin and get one choc back

3:35 tomjack: hmm

3:35 VEND and BUY above are wrong I think

3:37 V = (vin . coin) -> (bout . choc) -> V

3:38 B = (vout . coin) -> (bin . choc) -> B

3:38 ?

3:39 then let vc = (vin,vout), you could instead write

3:39 V = (<! vc coin) -> (>! bc choc) -> V

3:39 B = (>! vc coin) -> (<! bc choc) -> B

3:39 ?

3:39 pepijndevos: that's a confusing syntaxt crosover :P le me parse that

3:40 tomjack: (= (<! (vin,vout) coin) (vin . coin))

3:40 (= (>! (vin,vout) coin) (vout . coin))

3:41 but I think you may be right about the problem with multiple consumers

3:41 pepijndevos: yea, it's betetr explained with a different example. I want to program a choir

3:42 tomjack: I think a channel endpoint in CSP should only be read/written by one process

3:43 if you have multiple consumers you have multiple endpoints

3:43 pepijndevos: there is a conductor C = (>! swing) -> (<! note) -> C

3:43 and there are singers S = (<! swing) -> (>! note) -> S

3:43 tomjack: (I was going to mention I never did a thorough read of hoare so take everything I say with a grain of salt)

3:44 pepijndevos: I can;t think of a way to write a program that keeps a choir in sync

3:45 tomjack: C = (>! flute swing) -> (>! tuba swing) -> (<! flute note) -> (<! tuba note) -> C

3:45 as for a program.. hmm :)

3:46 (for completeness, F = (<! flute swing) -> (>! flute note) -> F)

3:53 pepijndevos: this didn't work

3:53 https://www.refheap.com/19c63f1624e70614e2de1309f

3:53 but maybe it will give you some ideas

3:54 oh I see the problem

3:54 problems

3:55 pepijndevos: so you let the players ad themselves?

3:55 tomjack: https://www.refheap.com/22501c69cab3472136ef54f2a

3:56 I think rich indicated once in here that something like this is the solution to this kind of problem

3:56 not sure about the best way to formulate it, the design space with channels/processes in core.async is frighteningly open to me

3:56 don't understand yet how to best organize things

3:56 but I think any solution will be basically isomorphic to this

3:57 you could just pass a coll of player channels to the conductor

3:57 I think? if you know all the players ahead of time

3:58 then the weird subscription stuff goes away

3:58 and passing a coll of player channels seems to map nicely onto the C above

3:58 [flute tuba]

3:59 in retrospect my refheap is quite silly

3:59 I remembered an approach like that for some other thing I tried once

4:00 blz37: I am not asking much. I have em.raynes/conch in my :dependencies. I want to add one more to play around with. Please suggest one.

4:04 tomjack: pepijndevos: https://www.refheap.com/ac1b667140848032ff6b8f642 ?

4:05 pepijndevos: I ned to catch up, was reading hoar

4:05 tomjack: I almost feel like I would rather have ports be the primitive instead of channels

4:06 I guess channels have to be the primitive, but I feel like I want ports

4:06 I'm too stupid to use channels correctly :)

4:08 pepijndevos: tomjack, that works, but no way you can keep 1000 players in sync that way, if you "sync" them sequentially.

4:09 tomjack: I bet you could

4:09 pepijndevos: hm…

4:09 tomjack: light/sound waves are very fast compared to neural impluses and muscle movements :)

4:10 pepijndevos: ...

4:10 tomjack: if you had some broadcast-like channel hiding the doseq from you, what else could it do but a doseq internally?

4:10 if you have so many consumers that doseq'ing them is a problem, I think you're fucked anyway

4:11 pepijndevos: lol

4:11 tomjack: in addition core.async tends to be more useful if there is some inherent delay

4:11 and often these delays are long enough that doseq'ing 10000 consumers or whatever probably won't matter

4:12 pepijndevos: I'm just going to read the book...

4:12 tomjack: good luck, unfortunately understanding CSP is no longer part of my job description :(

4:12 but I don't think you will find implementation tips in hoare

4:17 pepijndevos: tomjack, it was before?

4:18 I want to understand CSP, and then understand core.async.

4:19 tomjack: please give a talk or something when you're done :)

4:21 pepijndevos: lol, I'll at least write a blog post

4:22 an event as an action without duration, whose occurrence may require simultaneous participation by more than one independently described process.

4:22 That's the part i don't see in core.async

4:23 tomjack: that's in CSP?

4:23 I remember looking for something like that and CSP and not being able to find it

4:23 pepijndevos: Maybe this part is orthogonal to channels, and some fancy concurrent state machine might be devised to handle it

4:23 tomjack: but I didn't look very hard

4:24 my impression was that the C in CSP is always one-to-one

4:24 (like in core.async)

4:24 pepijndevos: full quote: In previous chapters we have introduced and illustrated a general concept of an event as an action without duration, whose occurrence may require simul- taneous participation by more than one independently described process.

4:24 that's in chapter 5 or so

4:25 tomjack: hmm

4:25 'but..'?

4:26 pepijndevos: ah P || Q means P in parallel with Q

4:28 as I understand it, if aP = {foo bar} and aQ = (bar baz} then they will together do bar

4:29 tomjack: "We shall observe the convention that channels are used for communication in only one direction and between only two processes."

4:29 I hadn't thought about the fact that without the convention you get broadcasting channels

4:30 if that's a fact

4:31 pepijndevos: right, so channels are just what channels are in CSP

4:31 but core.async just doesn;t have the events described in the first chapter.

4:31 "All the operations introduced in this chapter can be defined in terms of the more primitive concepts introduced in earlier chapters, and most of the laws are just special cases of previously familiar laws. "

4:32 That leads me to think channels are an abstraction over events?

4:33 tomjack: consider the hypothetical V || B || B

4:34 how is it different from V || B

4:35 I think events are the abstraction

4:35 you can implement core.async-style channels inside that abstraction

4:35 but you can't implement events in anything remotely resembling core.async, it just doesn't make sense

4:36 (and you can't really implement core.async-style channels inside the abstraction. you can implement something which is a good model for them?)

4:38 pepijndevos: ..

4:40 tomjack, are you saying CSP and core.async are entirely different things?

4:41 tomjack: in some sense, yes, absolutely

4:41 processes in CSP are mathematical objects

4:41 processes in core.async are presumably clojure functions

4:42 the whole 'events as actions whose occurrence may require..' makes sense in a mathematical model

4:42 I don't think it makes sense in a clojure program, at least not in something remotely like core.async

4:45 pepijndevos: I think it makes a lot of sense in clojure programs, but it's just not implemented in core.async.

4:46 I would like to see a dining philosophers impl in core.async.

4:47 They do that in CSP, and it looks almost trivial.

4:52 tomjack: I could see maybe a core.logic-alike which lets you define process equations

4:53 but really, I don't understand CSP much at all, I hope you enlighten me someday

4:54 pepijndevos: A communication is an event that is described by a pair c.v where c is the name of the channel on which the communication takes place and v is the value of the message which passes.

4:57 but ye , one to one only,, while events can involve many

4:58 yea, i think some sort of state machine could implement this stuff

5:00 tomjack: is A == A || A ?

5:44 dependencies in this pom.xml with no version specified

5:44 mvn should throw an error :(

6:04 samrat: is doing this: https://www.refheap.com/16195 a bad idea? I want to send an HTTP request every minute for a specific three hour interval a day only.

7:07 Mohshi: hi

7:08 when i do (context "/:id" [id] some-routes) how can i access id in some-routes?

7:09 compojure ^

8:38 jtoy_: what is the point of var?

8:39 this is the definition: The symbol must resolve to a var, and the Var object itself (not its value) is returned. The reader macro #'x expands to (var x).

8:39 but im not sure why its used

8:48 callen: jtoy_: vars are foundational.

8:48 Okasu: jtoy_: http://pramode.net/clojure/2010/05/13/story-of-clojure-vars-part-1/

8:49 _ato: jtoy_: as for why you might want to get a reference to one, try (meta (var first))

8:50 jtoy_: thats useful info!

8:53 EiX: hello

8:55 what will happen if i'll make middleware and will set current-user atom to something in that middleware depending on request?

8:55 is it safe?

9:01 jtoy_: im still not sure why one would want to use var though, i see it being used here : https://github.com/korma/Korma/blob/master/src/korma/core.clj#L581

9:18 EiX: guys?

9:28 xpe: I'd like to make a custom exception class. Is http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#Exception_Handling a good way to go? I don't see `gen-and-load-class` in clojure.core

9:30 * xpe is reading http://stackoverflow.com/questions/3835331/custom-exceptions-in-clojure

9:37 dark_element: xpe looks like :gen-class would do the trick

9:47 xpe: dark_element: that works, but it involves a manual compile step, which is part of the reason why people suggest using the alternatives

9:47 dark_element: xpe what are the alternatives?

9:48 xpe: dark_element: they are listed in that SO post. slingshot is probably the best "all in one" solution from what I can tell. ex-info can help too

9:50 dark_element: xpe ohh ok i thought there are alternatives to defining the usual java exception without compile step. yes slingshot and ex-info are great alternatives.

9:50 xpe ex-info is more preferred i guess since it comes with clojure

9:51 xpe: dark_element: I don't know of any alternatives to defining the usual java exception without a compile step. luckily I don't think a recompile is needed very often

9:52 dark_element: xpe all right

9:52 gfredericks: I imagine there's no reason not to use core.async to do database queries in core

9:52 dark_element: xpe go for ex-info if you can

9:52 gfredericks: s/core/java.jdbc/

9:52 xpe: dark_element: thanks

9:53 gfredericks: gotta be careful about resource cleanup though :/

9:54 I'm also curious about channels as ring responses

9:54 or requests too?

9:59 dark_element: gfredericks http-kit uses channels for the streaming response and websockets

10:01 gfredericks though the same channels you are talking about but the same concept. I wonder if they will be replaced by core.async channels in future

10:01 not the same*

10:06 gfredericks: dark_element: what does this replace? jetty?

10:07 ha yes that's what the website says

10:07 * gfredericks rtfms

10:08 dark_element: gfredericks didn't get you?

10:08 gfredericks: huh?

10:08 I'm fine, just reading about http-kit

10:08 thanks for pointing it out

10:09 * gfredericks still doesn't know how people do error handling with streaming results

10:10 dark_element: gfredericks I was saying replacing channel primitives written in http-kit with core.async will be a good idea

10:10 gfredericks that is a very good question indeed

10:10 gfredericks: HTTP 3.0 will let us put the status at the end :)

10:10 er...1.3?

10:10 whatever

10:11 dnolen_: pepijndevos: not sure what you are asking

10:11 dark_element: gfredericks interesting

10:11 gfredericks TIL, thanks

10:12 gfredericks: dark_element: it was a joke

10:12 very little of what I say is constructive

10:12 dark_element: gfredericks and i already googled for it and wonder what i did wrong

10:12 pepijndevos: dnolen_: I was reading the CSP book, and only in chapter 4 or so does it talk about channels, which seems to be what core.async does.

10:13 Before that it's just events, and I don't see those in core.async

10:13 hyPiRion: gfredericks: oh nono, I think our research on Swearjure is very constructive

10:13 gfredericks: hyPiRion: swearjure is certainly not most of what I say :P

10:14 hyPiRion: gfredericks: Hum, well, but logic programming!

10:14 gfredericks: ditto

10:14 why does lazybot not have a random sample command that we can use to actually check this claim

10:14 hyPiRion: oh what, you're talking about all these cool things you do @ miniKandren

10:14 miniKanren*

10:15 gfredericks: I'm not talking about those I'm just spouting nonsense

10:15 * gfredericks feels like he's doing some kind of anti-marketing

10:15 hyPiRion: oh okay, fine. Here I am trying to make you feel valuable, and you spoil everything

10:15 :p

10:15 dnolen_: pepijndevos: it's not clear to me whether events are just part of the formalism

10:15 pepijndevos: the CSP book is really about formalism not a concrete implementation

10:16 about the formalism

10:16 pepijndevos: n previous chapters we have introduced and illustrated a general concept of an event as an action without duration, whose occurrence may require simultaneous participation by more than one independently described process

10:16 gfredericks: hyPiRion: being valuable is different from the majority of my statements being valuable :P

10:17 dnolen_: pepijndevos: core.async approach doesn't seem that different from how CSP has actually been implemented in the past

10:17 pepijndevos: dnolen_: the important part about events compared to messages is that more than 2 parties can be involved

10:17 dnolen_: pepijndevos: most of the improvements are just good taste

10:17 pepijndevos: sure you can model that with primitives

10:18 with the primitives

10:18 hyPiRion: argh, but there is usually a correlation sir.

10:18 pepijndevos: dnolen_: which primitives?

10:18 dnolen_: pepijndevos: the core.async primitives, writing a broadcast channel is easy

10:19 pepijndevos: I should look at the code...

10:20 I'm not sure a broadcast channel is what I want though

10:21 Itn would be really intreresting to see the dining philosophers from the book translated to core.sync, I think.

10:21 dnolen_: pepijndevos: just try it, I'm sure you'll figure it out, it isn't hard to use

10:21 pepijndevos: ok

10:21 dnolen_: I've started going through various JS UI patterns

10:22 it simplifies things in incredible ways so far

10:22 because you can break apart complected code into independent communicating processes

10:22 pepijndevos: hmhm

10:22 dnolen_: honestly prior to core.async, FP + UI programming was a serious joke in my opinion for me.

10:23 pepijndevos: I would mostly agree, although I never really tried anyway.

10:24 dnolen_: this is what a FRP game looks like https://github.com/raimohanska/worzone/blob/master/worzone.js


10:25 pepijndevos: yeah having done UI programming for the last 8 years, core.async just makes sense to me

10:25 stuff I've used in JS, Obj-C, Java, C, C++ - just different flavors of awful

10:25 pepijndevos: It makes a lot of sense, I'm just missing the first half of the book, which alse makes a lot of sense to me\

10:27 dnolen_: pepijndevos: you should read this http://citeseerx.ist.psu.edu/viewdoc/summary?doi=

10:27 pepijndevos: dnolen_: modelling an orchestra or a choir would be really easy with events instead of channels

10:27 dnolen_: I'm sure the Hoare stuff is good, but ^ pdf made things a lot more clear how things work in practice

10:28 pepijndevos: you can keep talking or you can try it ;)

10:28 pepijndevos: haha, ok ok

10:45 tjb1982: anyone using korma who knows how to defentity a schema in postgres that's not public?

10:50 e.g. something like "select * from a_schema.a_table;" I tried to set it in defdb, as well, but it's only looking for the db part and fails saying "a_database.a_schema" doesn't exist.

11:14 callen: tjb1982: grant perms yo.

11:20 tjb1982: callen: both schemmata have the same owner

11:21 *schemata

11:21 callen: tjb1982: why doesn't the owner have access to its own schema?

11:22 tjb1982: it's not that it doesn't have access, it's that it can't figure out how to access the schema because of the dot

11:22 in postgres you have db.schema.table

11:22 defdb needs db

11:22 defentity needs table

11:23 "public" schema is assumed

11:23 but if you have other schemata it doesn't work

11:23 I can't (defentity schema.table)

11:24 and I can't (defdb db (postgres {:db "db.schema" ...})

11:24 neither works

12:11 kmicu: First example with alts!! https://www.refheap.com/16197 prints nothing, but next one with alts! is ok.

12:13 https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj

13:17 igorw: has anyone written an EBNF for edn? keywords are more complex than ":$symbol"

13:18 bbloom: igorw: i just asked the creator of instaparse about that the other day

13:18 he said he didn't know of anyone

13:19 igorw: i'd love to have a pair of robust grammars for EDN and CLJ forms, so let me know if you tackle that

13:32 igorw: bbloom: too bad. I have regex based lexing which is a good starting point, but I'm sure there's lots of unhandled edge cases.

13:33 bbloom: igorw: luckily, clojure's reader is LL(1)

13:36 hyPiRion: igorw: You could probably have a look at https://github.com/hyPiRion/astyx/blob/master/src/astyx.clj, though note that I know of multiple cases where symbol and keyword is wrongly defined.

13:36 Also, ugly regexes. I just patched and patched and ended up with that mess.

13:37 bbloom: it's also worth noting that clojure itself might not correctly implement it's own grammar....

13:37 ie being more or less permissive unintentionally

13:42 tomjack: bbloom: I was wondering, might you implement a reader, analyzer, compiler, in ascribe?

13:43 (I mean not _you_, I'm asking about the problem space ascribe addresses, not your plans)

13:48 igorw: hyPiRion: interesting. but looks like it is not able to read :#foo as a symbol

13:49 bbloom: tomjack: i started to implement a cljs analyzer :-) but it's a pretty low low low priority project & ascribe is *no where near* feature complete enough to really tackle the task

13:49 tomjack: check out the cljs branch

13:49 in the test directory

13:50 hyPiRion: igorw: yeah, exactly. It's messy for symbols and kws

13:50 Okasu: >(\\\\\

13:50 Oh c'mon.

13:52 tomjack: so if you did this presumably the thing you end up with would be more extensible than the clojure reader/analyzer/compiler

13:52 I wonder if it's equivalent in power to CPS'ing them

13:53 bbloom: tomjack: my initial target was ~2X as slow as the existing cljs analyzer prior to goog advanced optimizations

13:53 tomjack: the longer term goal is roughly the same speed as google closure compiler's advanced mode, but doing the same type of optimizations at the clojure level, prior to javascript

13:54 tomjack: an alternative/simultaneous long term goal would be to create an analyzer that supports in-memory incremental "changes" with efficient dependency tracking, cache invalidation, etc. such that being slower wouldn't really matter unless you change the entire repository at once

13:55 tomjack: interesting

13:57 bbloom: but it's a pretty low priority for me, since i've learned the key things i wanted to learn from building the ascribe experiment :-P

13:58 so many project ideas, so little time….

14:36 supersym: bbloom... I think I know that feeling, but additionally, don't fully master the language myself yet - all in due time I guess

14:37 bbloom: supersym: just start making things :-) you'll be an expert in no time that way

14:37 supersym: Btw, I could use some advice, I was thinking about adding zipcode lookup for visitors on a site, fill in your post code and it looks up the street + city....

14:37 its 326000 lines of CSV though... and I intend to use it in a cljs/Luminus built site...

14:38 should I put these in a db? serialize? put them in a trie? I really wouldn't know the best option

14:38 bbloom: supersym: what's wrong with a map?

14:40 supersym: Nothing...thats what I did with the taxes on vehicles lookup it was considerably smaller in size though.

14:41 bbloom: $ du -h zip.csv

14:43 supersym: that was a query for you :-)

14:44 supersym: yeah :) I know du... just that I'm not a CS major and not shitgiggles about optimization and when stuff starts to break...

14:44 I guess one way to find out is try :)

14:44 bbloom: always a good way

14:45 is the file what? 20 megabytes?

14:45 supersym: clojure csv reading/querying data seems easy enough... prolly beats the effort of trying to be smart

14:45 good guess :)

14:45 21M

14:46 bbloom: was an educated guess based on the number of rows & the nature of the data

14:46 supersym: over 12 files, 1 per province...

14:46 yeah

14:46 bbloom: that's probably what? 30 or 40 megs in memory

14:46 maybe less

14:46 supersym: k

14:47 bbloom: 40 megs top, could even be smaller than 20 megs in memory, since there are no quotes and numbers aren't encoded as text

14:47 read the CSV in line by line, use (into {} …) to build up a map, stick that in a var & you're good

14:47 :-P

14:47 supersym: really.. that easy huh :)

14:48 cool... I should also stop second guessing myself all the time

14:48 seems to be INTP trait

14:48 bbloom: the curse of the skilled intermediate programmer

14:48 supersym: really annoying though,... much appreciated, thanks

14:49 bbloom: takes longer to fret over it than it does to just try it

14:50 supersym: well it has a lot of text "Unknown" strings, and geolocs

14:50 I can trim all that bloat out, saves about half I guess

14:50 bbloom: supersym: sounds like a job for awk :-P

14:50 supersym: good thing I recently (finally) learned the syntax

14:54 tomjack: can a macro expand to something that does defs in another namespace?

14:54 nooga: (/j coffee

14:54 oops

14:55 bbloom: tomjack: not without some hackery at the var level

14:55 tomjack: or i guess hackery at the ns form level

14:55 tomjack: I may be OK with hackery

14:55 bbloom: in theory you could push/pop a ns with try/finally

14:55 and in-ns

14:55 tomjack: I'd just use intern but there's some code only accessible via a def* macro

14:55 bbloom: make a with-ns macro :-)

14:56 tomjack: hmm

14:56 I tried this (do (let [ns (ns-name *ns*)] (in-ns 'foo) (def bar 42) (in-ns ns)))

14:56 no luck

14:56 needs moar hack?

14:56 bbloom: (eval '(def bar 42))

14:56 ?

14:56 heh

14:57 tomjack: confusing, so I need my macro to expand to an eval call to a quoted macro call..

14:57 thanks

14:58 bbloom: def is weird

14:58 tomjack: I think I vaguely understand the reason

14:58 bbloom: it's a side effect, but it's quasi analyzed statically, but it's also one of the few remaining interpreted primitives in clojure

14:58 it's a mess :-P

14:58 but it's also a repl-lovers dream

14:58 so wutchagonna do

14:58 tomjack: if the macro could expand out to multiple top-level forms it could work?

14:58 without hacks

14:58 bbloom: tomjack: i think so...

14:59 "the top level is hopeless"

14:59 tomjack: actually, fuck it

14:59 I'll just macroexpand my def* calls and use intern

15:07 wastrel: razmataz

15:21 QSteven: core.logic question: this program returns (_0) while I'm expecting (3). Something must be wrong with pluso but I don't know what

15:21 https://gist.github.com/devijvers/5892294

15:24 tomjack: QSteven: what about false true false?

15:24 QSteven: tomjack, that's handled by :else

15:25 tomjack: exactly

15:25 the :else doesn't do any logic so you just get _0

15:25 QSteven: tomjack, that's what I was thinking too, but how do I solve this?

15:26 tomjack: any reason you're not just using fd? this is pedagogical?

15:26 QSteven: tomjack, what's fd?

15:27 tomjack: (:require [clojure.core.logic.fd :as fd])

15:27 pluso is fd/+

15:28 only thing is, you have to assign domains to variables like (fd/in x (fd/interval 0 100))

15:28 and it only works with non-negative integers

15:28 I think what you're trying to do would be solved by "constraints and modes" which is not implemented yet

15:28 bbloom: hmm presumably it could be made to work w/ negative integers using a slack variable, no?

15:28 tomjack: you'd have to write a constraint

15:29 bbloom: dnolen_: might know ^^

15:29 tomjack: bbloom: (to be clear, wasn't responding to you)

15:29 bbloom: http://en.wikipedia.org/wiki/Slack_variable

15:29 hyPiRion: well, non-negativity can just be flipped around

15:30 QSteven: tomjack, I'd like to get pluso working, indeed for pedagogical purposes

15:30 hyPiRion: x + y = -z --> x + y + z = 0

15:30 bbloom: yeah, essentially, you just have two magnitude variables & then a constraint that implies one of them must be zero

15:30 QSteven: tomjack, but thanks for the fd reference, I'll look into that too

15:30 tomjack: I think you'll have to look into constraint internals then

15:31 grep the sources for IConstraintStep

15:31 actually

15:31 maybe you don't need to

15:31 bbloom: x = y | y > 0 can be expressed: xpos - xneg = y | y > 0, xpos >= 0, xneg >= 0

15:31 tomjack: maybe you can just defer to a constraint that's in core when things aren't ground enough, like maybe predc?

15:32 :else (l/predc [x y s] (fn [[x y s]] (= (+ x y) s))) or something ?

15:32 :else (l/predc [x y s] (fn [[x y s]] (= (+ x y) s))) or something ?

15:33 whoops. (l/predc [x y s] (fn [[x y s]] (= (+ x y) s)) `pluso)

15:34 QSteven: tomjack, shouldn't I call pluso in the predicate?

15:35 tomjack: well

15:35 predc doesn't seem like it will work anyway

15:35 unless only one var is unground?

15:35 QSteven: tomjack, because (= (+ x y) s) won't work when one of them is an lvar

15:35 tomjack: I was hoping (predc [x y s] ...) would wait until x, y and s become ground to run the pred

15:36 but at worst, following e.g. predc's example, you should be able to come up with something I think

15:36 QSteven: tomjack, IllegalArgumentException No implementation of method: :bind of protocol: #'clojure.core.logic.protocols/IBind found for class: clojure.core.logic$cgoal$reify__3741 clojure.core/-cache-protocol-fn (core_deftype.clj:541)

15:36 tomjack, I'll have a look at predc

15:36 tomjack: you need to call it with the substitution, (a in your code, I think?)

15:37 but it won't work anyway afaict

15:37 r0bgleeson: 'found for class:', is that java leaking through?

15:37 QSteven: tomjack, where would I pass the substitution?

15:38 tomjack: predc returns a goal, so if you're inside a goal (fn [a] ...) you'd do (fn [a] ... ((predc ...) a))

15:38 QSteven: tomjack, actually, what I want to return is *something* so that core.logic skips to the next line (== a 7) and then tries the pluso call again

15:38 tomjack, right

15:39 tomjack: yes, that's essentially what constraints are for

15:39 QSteven: tomjack, you're right, predc doesn't seem to have an impact, still (_0)

15:39 tomjack: I'd try a -plusc closely following predc

15:40 instead of just x you have three args

15:40 and you don't need p/pform

15:41 oh and you'll have to do something predc doesn't in the cases where you're able to infer a value

15:41 ext-run-cs/ext-run-csg I think to set the inferred value

15:42 good luck, if you are stuck I may have some time later to help, but gotta get back to work

15:43 QSteven: tomjack, thanks for you help, unfortunately none of this is intuitive :(

15:43 tomjack: yeah it took me a very long time to get the rudimentary understanding of core.logic I have now

15:44 though if you are more diligent it could take less time :)

15:45 in the back of my mind has been the problem of a more friendly interface for defining constraints

15:46 can't help wondering why a constraint can't just be a fn

15:46 guess there are probably good reasons for all the protocols though

15:48 QSteven: tomjack, if only there would be more documentation :)

15:52 Apage43: grumble grumble

15:53 sublime text totally failed at highlighting here :/

16:00 Foxboron: Apage43: i have been considering throwing up a own syntax file in my Enhanced Clojure package for ST, if i recall, it dosn't hilight correctly if you type 1000N and so on

16:17 gfredericks: core.async's README still has the "don't use this" disclaimer which is contradicted by rich's blag

16:17 technomancy: gfredericks: you should submit a pull request

16:19 gfredericks: technomancy: is this your new long term sabotage strategy?

16:19 first you infect contrib with project.clj files, then you bombard them with PRs

16:19 technomancy: gfredericks: war of attrition

16:20 Bronsa: TBH I see nowhere written that contribs cannot accept pull requests

16:20 hyPiRion: oh no, we may get productive

16:20 gfredericks: is the next phase to snail-mail-DDOS them with CAs?

16:20 technomancy: gfredericks: actually snail-mailing printed patch files would be awesome

16:22 gfredericks: I wonder if snail-mail-DDOS is illegal...

16:22 bbloom: illegal? it's the USPS' business model!

16:23 metellus: yeah, you pay postage

16:23 technomancy: this is such a good idea that I'm wracking my brain trying to think of a patch to send.

16:23 bbloom: technomancy: surely there is a typo in a doc string somewhere

16:24 gfredericks: bbloom: spam and DDOS are kind of complementary things

16:25 benkay_: does anyone recommend resources other than the o'reilly book for learning clojurescript + ecosystem?

16:25 hyPiRion: technomancy: I can give you all rights to http://dev.clojure.org/jira/browse/CLJ-1134

16:25 I'll send you a snail mail with my signature on a paper you can send with it

16:25 gfredericks: so core.async isn't in maven yet? folk just installing the snapshot locally?

16:26 technomancy: hyPiRion: haha; no, it should be something that's not in jira yet

16:26 hyPiRion: oh okay

16:26 bbloom: gfredericks: afaict

16:27 QSteven: core.logic: is -inc a thunk wrapper?

16:27 gfredericks: QSteven: yep

16:27 it stands for "incomplete"

16:27 I just found out

16:27 tomjack: oh!

16:27 I always thought it was some pun on mplus

16:27 QSteven: gfredericks, and what does this "incompleteness" do?

16:27 gfredericks: I always thought it was just unknowable

16:27 QSteven: lets you "pause" computation

16:27 so it can try other branches if available

16:28 QSteven: gfredericks, but pauzing only makes sense with branches, right?

16:28 gfredericks: I think so

16:28 well

16:28 maybe it's also a general laziness mechanism

16:29 I was going to say for when there are infinite results, but that implies branching as well

16:29 bbloom: have you guys re-read out of the tar pit lately?

16:29 QSteven: gfredericks, I currently have the situation where I'm in an AND chaining of goals and in some circumstances I want to skip the current goal, go ahead with other goals and later try again

16:29 bbloom: i'm pretty sure rich just implemented this paper & called it datomic :-P

16:29 i know it's an explicit influence, but damn it's entertainingly similar

16:30 QSteven: bbloom, rich mentions "the tar pit" in one of his recorded datomic talks

16:30 bbloom: yup

16:30 gfredericks: QSteven: this sounds like some sort of fair conjunction

16:30 bbloom: i'm re-reading it now b/c i'm particularly interested in derived values

16:30 QSteven: gfredericks, fair?

16:30 gfredericks: $google fair conjunction status report

16:30 lazybot: [Clojure and me » Fair conjunction: status report] http://clj-me.cgrand.net/2012/04/06/fair-conjunction-status-report/

16:31 bbloom: something datomic does well w/ rules, but is tuned for database use cases

16:31 gfredericks: QSteven: ^

16:31 bbloom: datomic has "rules"?

16:31 bbloom: gfredericks: yeah, for disjunction & arbitrary predicate code

16:32 search rules on here: http://docs.datomic.com/query.html

16:32 QSteven: gfredericks, so no luck with sanctioned core.logic?

16:32 gfredericks: bbloom: how have I missed this?

16:32 bbloom: see also http://docs.datomic.com/database-functions.html which discusses "transaction functions" in depth, but non-transaction functions are usable from rules

16:33 gfredericks: QSteven: I imagine not

16:33 bbloom: gfredericks: i dunno :-P

16:33 the more i play with datomic, the more i agree w/ fogus' initial review: "ufo appearing over the national mall"

16:34 QSteven: gfredericks, ok, thanks, I'm going to play with bind for a while, maybe that will work

16:34 tomjack: bbloom: is that a positive or negative review? :)

16:34 bbloom: tomjack: positive. it's advanced alien technology

16:35 tomjack: good way to put it

16:35 technomancy: https://www.zazzle.com/rlv/lisp_made_with_secret_alien_technology_t_shirt-r6820c892f43a4ee295b7316f83372e68_804gs_512.jpg

16:35 bbloom: technomancy: awesome.

16:35 gfredericks: bbloom: I LIKE THIS thanks

16:36 bbloom: gfredericks: indeed.

16:36 gfredericks: yeah I have a hard time summarizing datomic to people in a sentence without leaving out at least 80% of the interesting bits

16:37 bbloom: i feel so conflicted about the closed source nature of it, however. on 1 hand, i'm a big believer in "pay me for my high quality software" and all the people involved with datomic deserve to be filthy stinking wealthy for their hard work

16:37 tomjack: "alien" gets at its inscrutability and conjures an image of people fleeing in fear

16:37 well the "national mall" bit anyway

16:37 bbloom: on the other hand, i've seen first hand what reliance on proprietary databases can do to your budgets....

16:37 on the other other hand, the pricing is relatively reasonable

16:37 gfredericks: bbloom: agreed; I wish there were reasonable/feasible ways to pay people for making digital things.

16:38 bbloom: at my company I'm less worried about budgets and more about what the situation might be like in 5 years

16:38 bbloom: on the other other other other hand, i really like to have the source to things i rely on

16:38 yeah.

16:38 gfredericks: in terms of support; also having the source is nice

16:38 fixing bugs, forking when you need to

16:38 tomjack: the path is clear, create more alien technology

16:38 bbloom: i kinda wish there was some middle ground :-/

16:38 QSteven: gfredericks, the blessing & curse of Datomic is that the competition sucks

16:39 bbloom: is this where we laugh at mongodb agan?

16:39 lolerskates, mongodb

16:39 * QSteven queues the music

16:40 bbloom: i guess if you're a large enough client, you can probably negotiate source code escrow or something

16:40 but for a little startup, that's not really feasible

16:40 tomjack: for e.g. security audits maybe?

16:41 QSteven: gfredericks, the only thing -inc seems to do in a bind-chain is create an endless loop

16:41 bbloom: more like: we have a support contract & if we can prove that you can't meet your end of the deal, this escrow company releases the source to us so that we aren't fucked

16:42 https://en.wikipedia.org/wiki/Source_code_escrow

16:44 QSteven: it's funny, all important bits in core.logic are grouped in ~60 consecutive lines

16:44 gfredericks: QSteven: that sounds a bit weird. but it takes me forever to wrap my head around core.logic code so I don't think I can help in short order

16:44 QSteven: makes it easier to browse, not easier to understand

16:44 bbloom: QSteven: heh, yes. reading the literature first would certainly help :-)

16:45 xpe: I'm looking for a way to unbind a dynamic var. Mostly for testing. (ns-unmap 'a 'foo) isn't quite what I want.

16:45 If I ns-unmap then I'll need to do `def` again. I want to get the var back to where it says #<Unbound Unbound: in the REPL

16:45 QSteven: xpe, (binding [myvar nil] ) ?

16:45 tomjack: xpe: (.unbindRoot var)

16:46 xpe: QSteven thanks. tomjack : that might be it!

16:47 QSteven: gfredericks, it's not -inc, it's my crazy thunk that's creating the infinite loop

16:47 gfredericks: QSteven: you're doing your own thunk?

16:48 xpe: ,(find-doc "unbind")

16:48 clojurebot: nil

16:48 QSteven: gfredericks, I'm trying to convince core.logic to skip this goal for now and continue to the next goal, I'll do anything that works, so far no luck

16:49 gfredericks: QSteven: you'll probably have to mess with the innards of bind at least; I can't imagine it being easy

16:50 if you don't understand the impl of minikanren then it _definitely_ won't be easy

16:50 xpe: tomjack: I haven't figured out where unbindRoot comes from

16:50 gfredericks: xpe: it's a method on Var

16:52 tomjack: QSteven: you really want constraints

16:52 QSteven: tomjack, my kingdom for a constraint

16:52 Ergh: i'm making a game and i want to decouple the GUI from the gameplay. im thinking i should send events between them, so they dont have to know about each other (well, the gui might still have to read some things from gameplay for rendering). like the GUI receives a mouseclick and sends a move-to event to the gameplay or the gameplay send a "combat"-event so the gui switched to another screen. any tips on what i could use to do that in c

16:52 xpe: ,(do (def x 1) (.unbindRoot #'x))

16:52 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:52 xpe: tomjack: I think that ^^ will work

16:53 gfredericks: I'm surprised it does

16:53 what about technomancy's geribaldi paradox?

16:54 tomjack: clojure has its own hack for that

16:54 gozala: cane anyone explain or point to a docs that explain what "&" prefixed arguments are ?

16:54 technomancy: please, it's "gilardi scenario"

16:54 gfredericks: technomancy: that's what I said

16:54 gozala: you mean &env and &form?

16:54 gozala: gfredericks: yes

16:54 gfredericks: gozala: those are magical arguments to macros

16:55 gozala: aha

16:55 gfredericks: &env has info about locals; &form is the entire macro-call form

16:55 lazybot: java.lang.RuntimeException: Unable to resolve symbol: env in this context

16:55 gozala: gfredericks: are they documented anywhere ?

16:55 I have a feeling that's what I need too

16:56 hyPiRion: gfredericks: Closest I can give you is Garibaldi: http://en.wikipedia.org/wiki/Giuseppe_Garibaldi

16:56 gfredericks: hyPiRion: I think that's what I was trying to spell

16:57 gozala: I can't find any

16:57 hyPiRion: oh

16:57 He looks like some logo for a project management tool though, so no wonder

16:57 gozala: gfredericks: so is that just those two names that are special

16:57 gfredericks: gozala: yep; you can see them in the impl of defmacro

16:57 gozala: or any & prefixed args are special ?

16:57 gfredericks: I don't know of anything else prefixed by &

16:58 I think it's a fun idea to use the prefix for anaphoric locals

16:58 technomancy: yeah &env and &form are secret compiler features

16:59 gfredericks: the next macro I make will wrap its output in (let [&& '&] ...)

16:59 technomancy: you monster

16:59 bbloom: (&& this that)

16:59 ;; if you miss C

17:00 gfredericks: somebody at the local meetup asked why not= instead of != and my only guess was something about lisp traditions

17:00 technomancy: there's no single function that's (comp vals ns-publics) is there?

17:00 gfredericks: isn't it more a lack of C traditions?

17:01 https://lh3.ggpht.com/-O2VRBGn3-xE/UUoH6dzgg1I/AAAAAAAAA0A/yIN6zoyrNOM/s400/English-Mother-Fucker.jpeg

17:01 bbloom: and ! means something else in clojure....

17:01 gfredericks: what does it mean?

17:01 hyPiRion: mutation

17:01 gfredericks: wat

17:01 hyPiRion: or side-effects

17:01 Foxboron: gfredericks: set!

17:02 hyPiRion: well, usually. it's not anything you're enforced to do though

17:02 gfredericks: Foxboron: send

17:02 amalloy: gfredericks: because C can't afford to have any of its operators contain letters, and clojure doesn't need any operators

17:02 gfredericks: alter-var-root

17:02 if you cared about marking mutation I thin you'd start with that one

17:03 bbloom: amalloy: doesn't NEED, but it does HAVE some…. all of them unary/prefix :-)

17:03 konr``: Can a program in run time import a .jar and use functionalities from it?

17:03 technomancy: hey-pay-attention-the-var-root-is-gonna-be-altered!

17:03 konr``: jar files are just zip files

17:03 gfredericks: quick quick (defn alter-var-leaf ...)

17:03 amalloy: bbloom: oh, you mean reader macros like quote? good point

17:03 i guess those are basically like operators

17:03 technomancy: konr``: and the compiler is available at runtime

17:03 hyPiRion: I would've expected not= to be /=, then I realized why it isn't.

17:03 bbloom: amalloy: yeah. the most obvious one is @ for deref

17:04 that's strictly sugar

17:04 gfredericks: hyPiRion: haha that'd be another special case in the reader

17:04 amalloy: *nod*

17:04 clojure.core//= :(

17:04 gfredericks: also there's the in-ary ** operator that makes a var dynamic

17:04 hyPiRion: Then I had the idea that you could do \= but then I realized that's also not possible

17:04 bbloom: heh

17:04 hyPiRion: and then I gave up

17:04 bbloom: i don't think clojure has any infix or postfix operators....

17:04 gfredericks: hyPiRion: sure it is just make \equal for the "=" character

17:04 amalloy: gfredericks: it's not prefix, postfix, or infix. it's like...outfix?

17:05 gfredericks: amalloy: yeah I was struggling with the word too

17:05 bbloom: unless you consider ; to be the infix comment operator

17:05 hyPiRion: gfredericks: makes perfect sense!

17:05 amalloy: extrafix

17:05 gfredericks: I like outfix

17:05 bbloom: matchfix

17:05 mixfix

17:05 ^^ actual things

17:05 gfredericks: () is the outfix call operator

17:05 QSteven: core.logic: what's the difference between choice & conde?

17:05 hyPiRion: mastermix

17:06 gfredericks: QSteven: choice is an impl detail

17:06 representing a solution and a function to look for alternatives

17:06 konr``: technomancy: but in the case there is only compiled stuff in the jar, can I somehow use it from the running program?

17:07 QSteven: gfredericks, but isn't that what conde does as well?

17:07 bbloom: oh, you know what…. & is basically an infix operator

17:07 gfredericks: omg the macroexpansion of (go) is 63 lines

17:07 technomancy: konr``: oh, in that case you need to use a classloader. it's more complicated but still possible.

17:07 gfredericks: QSteven: at a much higher level; conde uses choice

17:08 if it finds a solution at some point

17:08 bbloom: binds to the left, so an arg list is parsed: [x y z & more] as (varargs [x y z] more)

17:08 er i mean binds to the rigth

17:09 gfredericks: bbloom: is midje a pile of operators?

17:09 bbloom: i've avoided looking at midje

17:09 technomancy: gfredericks: it's more of a pit than a pile

17:09 * gfredericks too

17:09 gfredericks: look at that steaming pit of operators with limbs hanging out

17:10 konr``: technomancy: interesting! Thanks!

17:10 hyPiRion: technomancy: tar pit?

17:10 technomancy: hyPiRion: maaaaaybe

17:10 hyPiRion: hehe

17:10 QSteven: bbloom, why? midje is good fun

17:10 amalloy: bbloom: you mean & for varargs? that's surely prefix

17:11 bbloom: QSteven: b/c i'm just not interested in test frameworks much & people bitch about it a lot

17:11 gfredericks: midje bitchers

17:12 QSteven: midje bites midjes bitchers

17:12 bbloom: amalloy: if you were creating an AST node for that, you'd basically have two kinds: FixedArity[x, y, z] and VariableArity[x, y, z, more]

17:12 in mathematica notation :-P

17:13 the & changes the meaning of it's predecessors/parent ast node

17:13 meaning it's a binary relation, not a unary one

17:14 in theory, you could represent it ArgList[Arg[x], Arg[y], Arg[z], Args[more]]

17:14 but that would imply you could have something like ArgList[Arg[left], Args[middle], Arg[right]]

17:14 which clojure can't do

17:15 although center splats would be nice in some cases…. but doesn't play nice w/ lazy apply

17:15 but that would allow multiple variadic Args, which basically gets you into full on lexing/parsing of an arg list :-P

17:16 you could have SplatArgs[{left}, more, {right}] which would only allow you a single splat position :-)

17:17 which is what i think coffeescript does in their AST

17:21 QSteven: core.logic: in a bind-chain, when a goal returns an IBind object, the bind method on the object will be called next, correct?

17:22 gfredericks: uh

17:23 danneu: incredible how easy it is to work with bytes when you can just (map int bytes)

17:24 all day

17:25 gfredericks: ,(time (count (map (fn [_] (Thread/sleep 5)) (range 100))))

17:25 clojurebot: "Elapsed time: 516.994697 msecs"\n100

17:25 gfredericks: &(time (count (map (fn [_] (Thread/sleep 5)) (range 100))))

17:25 lazybot: ⇒ "Elapsed time: 593.318556 msecs" 100

17:26 gfredericks: I guess Thread/sleep is not very precise

17:26 not sure why I would expect it to be

17:27 seangrove: What is `alts!` short for?

17:27 tomjack: my guess is "alternatives"

17:27 seangrove: That's what I thought, but I'm not clear on how that applies to what it does

17:27 I'll continue reading along...

17:28 gfredericks: takes the first available option from several alternatives?

17:29 bbloom: (inc gfredericks)

17:29 lazybot: ⇒ 27

17:29 danneu: this pattern shows up all over my code when i want map->map transformation: (into {} (map (fn [[_ v]] [_ (f v)]) pair)) — is there an even more succinct way to map f over k/v and get a map back out?

17:30 * gfredericks cues amalloy

17:30 hyPiRion: (into {} (for [[k v] old-map] [k (f v)]))

17:30 danneu: can you find a way to incorporate juxt?

17:30 i don't mind if it's 2x longer

17:30 amalloy: danneu: juxt doesn't work very well for that

17:30 it'd be more than 2x longer

17:31 danneu: yeah, lame joke

17:31 bbloom: (into {} (map (juxt identity f) old-map))

17:31 or no

17:31 (comp f val)

17:31 gfredericks: I meant to cue amalloy for something different from juxt

17:31 amalloy: but i wrote knit: (defn knit [f g] (fn [[a b]] [(f a) (g b)])), (into {} (map (knit identity f) m))

17:31 bbloom: (juxt key (comp f val))

17:31 yeah mess :-P

17:31 seangrove: danneu: Prismatic has a similar function in their plumbing lib: https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.clj#L32-L37

17:32 danneu: knit looks hot

17:32 tomjack: I quite like (juxt key (comp f val))

17:34 danneu: thanks folks

17:35 seangrove: Ah, and the core.async article falls off of the front page of hn...

17:35 danneu: i like to add a few layers of indirection to my code to counterbalance all the simplicity

17:36 elephantTechno: What's the cleanest way to design sorted stacks ? I think I could embed a PersistentList in a new type with a keyfn and a comparator (like with sorted-map-by), but I'm afraid I'd have to reimplement each functions of the list datatype and delegate them to the embedded list.

17:37 bbloom: elephantTechno: a sorted stack?

17:37 do you mean a priority queue?

17:37 elephantTechno: Yes that's what I mean, but sith only one end and not two unlike regular queues

17:38 gfredericks: why is my channel-based pmap hanging?

17:38 bbloom: elephantTechno: http://en.wikipedia.org/wiki/Priority_queue

17:38 there isn't really "ends" to a priority queue

17:38 you insert somewhere in the middle and pop off the front only

17:38 gfredericks: https://www.refheap.com/16201

17:39 elephantTechno: Another implementation I'v thought of is with a map, having priorities as keys and list of values as values.

17:39 hyPiRion: elephantTechno: could there be multiple equal elements in the priorityqueue?

17:40 elephantTechno: Absolutely

17:40 danneu: what's the name of the concept on macros that forces you to use the octothorpe: (defmacro java-fn [f] `(fn [o#] (~f o#)))

17:40 elephantTechno: It's meant to be used in implementing a branch and bound knapsack solver

17:40 Gensym ?

17:41 danneu: thanks

17:41 gfredericks: danneu: hygiene?

17:41 danneu: what's the simple description of why gensym is necessary

17:41 elephantTechno: actually I think o# expands to (gensym 'o)

17:41 bbloom: danneu: symbol capture

17:41 danneu: ah

17:41 bbloom: http://dunsmor.com/lisp/onlisp/onlisp_13.html

17:42 danneu: great, thanks!

17:42 hyPiRion: ,`o#

17:42 clojurebot: o__29__auto__

17:42 seangrove: Ah, hilarious memories of mistakes with non-hygenic macros...

17:42 bbloom: the gensyming isn't part of the expansion result, it's part of the expanding process

17:43 danneu: now i can stop faking it til i make it with macros i think

17:44 gfredericks: oh I know why; hah.

17:44 async is hard

17:44 hyPiRion: elephantTechno: I would probably use sorted-map-by and let the keys in the map describe the amount of elements with this value

17:45 bbloom: gfredericks: yes, yes it is.

17:45 hyPiRion: unless elements can be equal but different of course.

17:46 bbloom: gfredericks: but somewhere, there is a C hacker who is going NUTS about Golang, but when he encounters some use of higher order functions, he is thinking "functional programming is hard" :-P

17:49 gfredericks: yeah well that guy is wrong.

17:49 but about something unrelated. just because it's hard to not be wrong about at least something.

17:51 elephantTechno: hyPiRion: Ok then I'll try to solve my problem this way. Thank you.

17:51 musicalchair: hmm. is there something funky about document.write? if I eval '(.write js/document "hey") from a cljs.repl.browser, it never returns.

17:52 bpr: musicalchair: maybe your browser isn't connected? try refreshing?

17:52 beyond that, i have no idea

17:52 musicalchair: it's connected. before evaling that I eval js/alert, +

17:52 bpr: ok

17:52 musicalchair: bpr: hmm ok

17:58 it kind of looks like things hang on the browser side. when I do a '(.write js/document "hey") from my cljs repl, it hangs (as I mentioned before). If I force quit the repl, the browser doesn't notice (normally if the cljs repl is exited the browser will complain about e.g. a failed 'POST' request)

18:00 with '((fn [] (js/alert "1") (.write js/document "hey") (js/alert "2"))) I see both alerts (and the write) but control is never returned to the repl

18:06 defn: technomancy: Syme is having some issues. I'm

18:07 In a cab so I can't check it out.

18:08 technomancy*

18:38 ejbs: Would you call '(1 2 3) a "symbol" in Clojure-land?

18:38 Or is it (quote (1 2 3)) which returns the list (1 2 3)?

18:40 hyPiRion: it's not a symbol

18:40 SegFaultAX: ejbs: It's just a list.

18:40 hyPiRion: ,(symbol? '(1 2 3))

18:40 clojurebot: false

18:40 danneu: (class '(1 2 3)), (class (quote (1 2 3))), (class (list 1 2 3)) - all PersistentList

18:41 ejbs: Yeah, that's what I thought, thanks.

18:42 SegFaultAX: ejbs: Just remember that we have to quote lists in particular since the (...) form is most often used for function application.

18:42 Eg ##(+ 1 2)

18:42 lazybot: ⇒ 3

18:43 SegFaultAX: But if I quote that form, I can get a list that contains those elements: ##'(+ 1 2)

18:43 lazybot: ⇒ (+ 1 2)

18:43 SegFaultAX: Perhaps a little clearer: ##`(+ 1 2)

18:43 lazybot: ⇒ (clojure.core/+ 1 2)

18:43 SegFaultAX: clojure.core/+ is the fully qualified symbol.

18:44 jro_: any suggestions for Trie-library for clojure?

18:44 ejbs: SegFaultAX: Oh yeah, I know. I was just reading this page: http://learnxinyminutes.com/docs/clojure/ and I was on my way to issue an issue on Github about it but I just wanted to make sure that you don't call that a symbol in Clojure (which, IMHO, would be totally weird of you to do)

18:46 Thanks for all the help!!!

18:46 SegFaultAX: ejbs: Well I assumed you asked if it was a symbol because of the ', which is obviously incorrect so I was trying to clarify. :)

18:47 ejbs: SegFaultAX: Dude, I'm not complaining, you're awesome for helping out :). I'm just clarifying why I'm asking

18:48 SegFaultAX: ejbs: Sweet! Good luck.

18:48 ejbs: Thanks!

19:02 musicalchair: if I have a protocol P where P is extended to (java) interfaces A and B, how does clojure dispatch if I have an object implementing both A and B?

19:20 arohner: musicalchair: I'm not sure, but it wouldn't surprise me if that follows Java's rules for dispatch

19:24 r0bgleeson: how do Java classes map in clojure?

19:25 ptn777: r0bgleeson: what do you mean by map? do you mean how do you call a java class from a clojure program?

19:25 r0bgleeson: ptn777: kind of, i assume clojure doesn't have a notion of a 'class' in clojure itself, so im just curious how that works

19:27 for example can i create a java class from clojure?

19:29 maybe my thinking is totally dumb, but my comparison is jruby, where concepts map between java + ruby

19:30 ptn777: r0bgleeson: did you read this? http://clojure.org/jvm_hosted

19:30 that's a clojure program using swing stuff

19:31 callen: r0bgleeson: but if you actually want to use swing, please use seesaw

19:33 SegFaultAX: r0bgleeson: There are a great many things in clojure that will generate a new class, gen-class not the least of them.

19:34 r0bgleeson: ptn777: didnt see that, great read though, i had seen the dot notation and not really understood it

21:23 horofox_: can somebody help? http://pastie.org/8095755

21:23 the question is: why does when I hardcode number as "0000000001" works

21:24 and when I use let it doesn't work

21:37 bbloom: horofox_: your problem isn't a datomic one, it's a clojure/lisp one

21:37 horofox_: so, help me :D

21:37 bbloom: consider: ,(let [x 5] 'x)

21:37 ,(let [x 5] 'x)

21:37 clojurebot: x

21:37 bbloom: quoting prevents evaluation

21:37 notice you get a symbol, not a number

21:38 what you're doing is comparing to see if the field is equal to the symbol 'number

21:38 you need to add parameters as a data source: http://docs.datomic.com/query.html

21:39 horofox_: bbloom: so, in my example, how it would be?

21:39 the right way

21:40 bbloom: horofox_: you need to add a :in clause and then add another argument to the q call. see the docs

21:41 horofox_: i can't get it how to use a data source...

21:41 bbloom: horofox_: think of it like template parameters

21:41 (render-template the-template the-template-parameters)

21:42 search that page for "Peer.q" and for ":in"

21:42 horofox_: how do i set the number variable in my case to be $number?

21:43 i feel very dumb reading those docs trying to do something practical :(

21:43 bbloom: are you *reading* them? or are you skimming/scanning them to find the answer to your question?

21:43 the datomic docs are extremely dense

21:43 they are meant to be read top to bottom

21:44 jumping in at any particular spot will have insufficient context to help you

21:44 horofox_: i'm trying to do the simplest thing ever...

21:44 bbloom: which is plainly demonstraited on that page in several places that i pointed out to you....

21:44 teach a man to fish and all that...

21:45 horofox_: i'm trying to find a entity where a key matches a value...

22:02 bbloom: thanks

22:02 bbloom: it worked

22:02 bbloom: horofox_: hopefully you learned a few other good things while you were in there reading

22:02 happy to help

22:06 horofox_: btw

22:07 datomic is awesome :)

22:08 is there any startup that uses diatomic in production?

22:08 datomic*

22:13 echo-area: horofox_: How much capacity can datomic provide? I mean the data-size/QPS etc

22:13 horofox_: echo-area: i don't know, i'm just studying the technology.

22:13 echo-area: horofox_: Is it suitable for the "Big Data"? (I quote because I don't quite like the term)

22:14 Okay

22:57 horofox_: question, i see maps with keys like :user/name, does the / means something or is it just coding style?

22:58 tbaldridge: horofox_: it's the namespace of the keyword. It really doesn't do much, except allow you to have multiple :???/name keywords that are not equal

22:58 horofox_: i see

22:58 tbaldridge: btw, if I am in the namespace (ns myproject.core) then the following are true:

22:59 (identical? ::name :myproject.core/name)

22:59 and if I (:require [clojure.string :as s]) then the following is true:

23:00 (identical? ::s/name :clojure.string/name)

23:00 horofox_: anyway, that's just some random info about keywords :-)

23:01 horofox_: this is good :)

Logging service provided by n01se.net