00:00:01  * ircretaryquit (Remote host closed the connection)
00:00:10  * ircretaryjoined
00:00:25  * ferossquit (Quit: feross)
00:02:52  * thlorenzjoined
00:07:24  * thlorenzquit (Ping timeout: 246 seconds)
00:08:03  * calvinfojoined
00:09:04  * ferossjoined
00:12:48  * calvinfoquit (Ping timeout: 252 seconds)
00:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 99]
00:29:41  * jergasonjoined
00:31:13  * Wraithanjoined
00:31:40  <Wraithan>Interesting `#include <cmath>` is not namespace compat but `#include <math.h>`
00:31:49  <Wraithan>Which means you can't use cmath with dotc
00:32:10  <Wraithan>unless it is in your top level file
00:38:13  * calvinfojoined
00:42:50  * calvinfoquit (Ping timeout: 264 seconds)
00:48:34  * maksimlinjoined
00:51:26  * ednapiranhajoined
00:53:20  * yorickquit (Remote host closed the connection)
00:57:58  * jergasonquit (Quit: jergason)
01:01:33  * calvinfojoined
01:03:22  * mikolalysenkojoined
01:06:31  * calvinfoquit (Ping timeout: 272 seconds)
01:08:50  * tilgoviquit (Remote host closed the connection)
01:08:59  * jiangplusjoined
01:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 49]
01:17:50  <rowbit>substack, pkrumins: Encoders down: 50.57.103.135 (free2)
01:21:44  * thlorenzjoined
01:21:54  * AvianFlujoined
01:22:54  * Aviaphonejoined
01:26:15  * AvianPhonequit (Ping timeout: 245 seconds)
01:26:30  * thlorenzquit (Ping timeout: 252 seconds)
01:27:14  * jxsonquit (Remote host closed the connection)
01:27:42  * jxsonjoined
01:27:44  * jxsonquit (Remote host closed the connection)
01:27:50  * jxsonjoined
01:39:02  * ednapiranhaquit (Quit: Leaving...)
02:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 24]
02:22:21  * thlorenzjoined
02:22:21  <rowbit>substack, pkrumins: Encoders down: 50.57.103.135 (free2)
02:27:17  * thlorenzquit (Ping timeout: 268 seconds)
02:29:07  * AvianFluquit (Remote host closed the connection)
02:29:38  * AvianFlujoined
02:29:38  * Aviaphonequit (Quit: Bye)
03:04:36  * defunctzombie_zzchanged nick to defunctzombie
03:09:45  * thlorenzjoined
03:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 15]
03:33:08  * thlorenzquit (Remote host closed the connection)
03:38:20  * jcrugzzjoined
03:38:41  * jxsonquit (Remote host closed the connection)
03:39:07  * jxsonjoined
03:44:19  * jxsonquit (Ping timeout: 272 seconds)
04:03:10  * jergasonjoined
04:04:41  * thlorenzjoined
04:09:19  * Maciek416quit (Remote host closed the connection)
04:09:54  * Maciek416joined
04:10:28  * jcrugzz_joined
04:12:44  * jcrugzzquit (Ping timeout: 268 seconds)
04:13:09  * thlorenzquit (Ping timeout: 253 seconds)
04:14:35  * Maciek416quit (Ping timeout: 268 seconds)
04:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 16]
04:30:15  * jcrugzz_changed nick to jcrugzz
04:44:40  * shamaquit
04:56:05  * DTrejoquit (Remote host closed the connection)
04:56:38  * DTrejojoined
05:00:42  * DTrejoquit (Ping timeout: 246 seconds)
05:09:34  * thlorenzjoined
05:14:15  * thlorenzquit (Ping timeout: 272 seconds)
05:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 17]
05:23:08  * sidoraresjoined
05:33:56  * dguttmanquit (Quit: dguttman)
05:39:09  * dominictarrjoined
05:41:51  <rowbit>substack, pkrumins: Encoders down: 50.57.103.135 (free2)
05:48:59  * dguttmanjoined
05:53:58  * dguttmanquit (Quit: dguttman)
05:56:37  * defunctzombiechanged nick to defunctzombie_zz
06:03:01  * mikolalysenkoquit (Ping timeout: 272 seconds)
06:10:13  * thlorenzjoined
06:13:00  <dominictarr>
06:13:08  <dominictarr>hey whats up?
06:15:03  * thlorenzquit (Ping timeout: 272 seconds)
06:16:45  <rowbit>Daily usage stats: [developer: 14, free: 1641]
06:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 26]
06:22:04  * thlorenzjoined
06:26:27  * thlorenzquit (Ping timeout: 246 seconds)
06:29:02  * mikolalysenkojoined
06:33:24  * mikolalysenkoquit (Ping timeout: 240 seconds)
06:39:54  * jxsonjoined
06:41:34  * ralphtheninjajoined
06:44:49  * jxsonquit (Ping timeout: 272 seconds)
07:05:46  * AvianFluquit (Remote host closed the connection)
07:06:16  * AvianFlujoined
07:10:33  * AvianFluquit (Ping timeout: 246 seconds)
07:13:03  * sidoraresquit (Quit: sidorares)
07:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 41]
07:21:39  <timoxley>dominictarr that "Again with the modules" thread is painful
07:21:52  * jergasonquit (Quit: jergason)
07:23:59  <timoxley>I might be wrong but it seems those arguing against the npm pattern really understand what they're arguing against other than 'node'.
07:24:09  <timoxley>*don't really
07:26:53  * ralphtheninjaquit (Read error: Operation timed out)
07:29:44  * mikolalysenkojoined
07:31:50  <Raynos>meh
07:34:45  * mikolalysenkoquit (Ping timeout: 272 seconds)
07:38:14  <timoxley>Raynos: it just bothers me, like, node has this pretty solid pattern and everyone's just "Yeah, well, that's just, like, your opinion, man."
07:42:49  <Raynos>they seem to think that async loading cant be done
07:42:54  <Raynos>or that file size is like really important
07:45:35  <timoxley>and completely ignore the benefits of code/dependency encapsulation
07:48:39  <dominictarr>timoxley: Raynos and they seem to think that asyncloading is like super important too,
07:48:50  <dominictarr>when really, it's a kinda rare case
07:49:54  <Raynos>i made a comment about the async loading
07:50:06  <Raynos>saying its kind of bloody trivial for the edge case where its important
07:51:17  <timoxley>dominictarr and it's also very application specific. I'm not even sure if it should be the responsibility of the import mechanism at all
07:51:20  <dominictarr>but really, when you dig into arguments like these you always discover that the sides are actually trying to do different things
07:51:38  <dominictarr>timoxley: agreed
07:51:58  <dominictarr>we have talked about ways to get browserify to do async loading nicely
07:52:57  <dominictarr>like maybe a asyncRequire(['m'], function () { require('m') })
07:53:37  <dominictarr>browserify would just have to detect that the code inside async require should not be parsed until after
07:53:54  <dominictarr>... or maybe it would be easier to put that in another script
07:53:59  <timoxley>yeah
07:54:28  <timoxley>async dependency loading: just inject a script element
07:54:32  <timoxley>listen for load
07:54:34  <timoxley>done.
07:55:10  <dominictarr>yeah, that is the way most people do it
07:55:33  <dominictarr>it would be nice to have an elegant way to do it, but it's not a pain point.
07:55:55  <dominictarr>the biggest reason would be just to make people shutup about it.
07:56:29  <timoxley>yeah, sure, package it up so it looks like an import or whatever but it's not a good reason to break compatibility with npm
07:57:02  <timoxley>it's like shooting someone over some loose change
07:58:48  <timoxley>which is exactly what the stupid es6 module syntax is doing
07:58:50  <timoxley>wtf
07:59:49  <dominictarr>timoxley: well, that is like getting blood out of a stone
08:00:12  <dominictarr>thing is, we will still use bundling for browsers even with es6
08:00:45  <dominictarr>because it's the roundtrips that are the expensive thing, not the downloading
08:05:21  <timoxley>dominictarr I have a vague memory that was one of the things http2 was trying to solve
08:06:13  <timoxley>maybe they're right. maybe by the time all this stuff gets adopted browsers and protocols will be smart enough to avoid those issues
08:09:32  * dominictarrquit (Ping timeout: 268 seconds)
08:11:30  * thlorenzjoined
08:14:26  <Raynos>ugh
08:14:28  <Raynos>es6 ;/
08:16:16  * thlorenzquit (Ping timeout: 260 seconds)
08:16:26  * jiangplusquit (Ping timeout: 264 seconds)
08:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 34]
08:19:57  * ferossquit (Quit: feross)
08:30:35  * mikolalysenkojoined
08:31:34  * jiangplusjoined
08:36:18  * mikolalysenkoquit (Ping timeout: 246 seconds)
08:41:04  * mirkokieferjoined
08:52:22  * chilts_joined
08:53:58  * cubert_joined
08:54:51  <rowbit>substack, pkrumins: Encoders down: 50.57.226.209 (free4)
08:55:08  * jaz303_joined
08:56:48  * sidoraresjoined
08:58:34  * owen1quit (*.net *.split)
08:58:35  * chiltsquit (*.net *.split)
08:58:35  * cubertquit (*.net *.split)
08:58:35  * jaz303quit (*.net *.split)
08:58:35  * cubert_changed nick to cubert
09:06:58  * owen1joined
09:12:08  * thlorenzjoined
09:15:54  * sidoraresquit (Quit: sidorares)
09:16:22  <rowbit>substack, pkrumins: Encoders down: 173.203.67.76 (free3)
09:16:24  <juliangruber>substack: is there a browserify transform that adds NODE_PATH suport?
09:16:29  <juliangruber>defunctzombie_zz ^
09:16:43  * thlorenzquit (Ping timeout: 272 seconds)
09:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 39]
09:19:30  * ferossjoined
09:26:19  * jcrugzzquit (Ping timeout: 272 seconds)
09:33:07  * mikolalysenkojoined
09:35:33  * kevino80joined
09:35:55  <jiangplus>、quit
09:35:59  * jiangplusquit (Quit: leaving)
09:37:55  * mikolalysenkoquit (Ping timeout: 260 seconds)
09:52:53  * jcrugzzjoined
09:59:58  * kevino80quit (Remote host closed the connection)
10:00:24  * kevino80joined
10:01:21  * jcrugzzquit (Ping timeout: 246 seconds)
10:05:13  * kevino80quit (Ping timeout: 272 seconds)
10:06:27  * maksimlinquit (Quit: ChatZilla 0.9.90.1 [Firefox 25.0/20131028113308])
10:12:46  * thlorenzjoined
10:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 25]
10:17:38  * thlorenzquit (Ping timeout: 264 seconds)
10:33:51  * mikolalysenkojoined
10:38:38  * mikolalysenkoquit (Ping timeout: 264 seconds)
11:12:00  * dominictarrjoined
11:13:24  * thlorenzjoined
11:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 32]
11:17:48  * thlorenzquit (Ping timeout: 256 seconds)
11:21:30  * dominictarrquit (Ping timeout: 246 seconds)
11:31:33  * ferossquit (Quit: feross)
11:34:34  * mikolalysenkojoined
11:36:22  <rowbit>substack, pkrumins: These encoders are STILL down: 50.57.103.135(free2)
11:39:02  * mikolalysenkoquit (Ping timeout: 240 seconds)
11:48:57  * dominictarrjoined
12:04:20  * dominictarrquit (Quit: Lost terminal)
12:09:54  * yorickjoined
12:14:00  * thlorenzjoined
12:16:45  <rowbit>Hourly usage stats: [developer: 62, free: 10]
12:18:31  * thlorenzquit (Ping timeout: 260 seconds)
12:35:18  * mikolalysenkojoined
12:39:35  * mikolalysenkoquit (Ping timeout: 240 seconds)
12:43:41  * thlorenzjoined
12:51:33  * kevino80joined
12:53:49  * thlorenzquit (Remote host closed the connection)
12:56:10  * thlorenzjoined
12:56:43  * thlorenz_joined
12:57:28  * thlorenzquit (Remote host closed the connection)
13:00:35  * thlorenz_quit (Remote host closed the connection)
13:13:50  * mirkokieferquit (Quit: mirkokiefer)
13:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 16]
13:22:15  * jcrugzzjoined
13:23:06  * Maciek416joined
13:27:39  * jcrugzzquit (Ping timeout: 265 seconds)
13:27:41  * jiangplusjoined
13:36:07  * mikolalysenkojoined
13:40:38  * mikolalysenkoquit (Ping timeout: 240 seconds)
13:57:47  * thlorenzjoined
14:01:41  * thlorenz_joined
14:03:18  * thlorenzquit
14:03:37  * thlorenzjoined
14:06:15  * thlorenz_quit (Ping timeout: 272 seconds)
14:08:45  * defunctzombie_zzchanged nick to defunctzombie
14:09:56  <defunctzombie>juliangruber: isn't NODE_PATH deprecated?
14:14:25  <juliangruber>defunctzombie: doesn't say so here http://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
14:15:02  <defunctzombie>juliangruber: do you use this to use local libs?
14:15:10  <juliangruber>yes
14:15:26  <juliangruber>so I can write require('foo') instead of require('../foo')
14:16:45  <juliangruber>because require('node module name') also works from any location in my app
14:16:45  <rowbit>Hourly usage stats: [developer: 12, free: 30]
14:17:54  * thlorenzquit
14:18:10  * thlorenzjoined
14:18:17  <defunctzombie>juliangruber: I had a better solution to that was hoping to eventually implement
14:18:29  <defunctzombie>juliangruber: it has been vetted by st_luke and isaacs I think
14:18:50  <defunctzombie>juliangruber: in the package.json allow a "file://path/to/local/js/or/folder" value
14:18:56  <defunctzombie>for a dependency
14:19:11  <defunctzombie>this would only be allowed for "private: true" projects
14:19:38  <defunctzombie>but would solve the issue people have of wanting to think about something being a separate module but not yet publishing it as such
14:20:11  <defunctzombie>juliangruber: having said that.. I don't think it would be a transform issue.. I think it would be a browser-resolve module issue
14:20:21  <defunctzombie>and in turn a resolve module issue
14:20:25  <defunctzombie>to lookup in the correct pahts
14:20:27  <defunctzombie>*paths
14:21:09  <juliangruber>ok I see
14:22:38  * kevino80quit (Remote host closed the connection)
14:23:15  * kevino80joined
14:23:32  * jaz303_changed nick to jaz303
14:23:43  * kevino80quit (Read error: Connection reset by peer)
14:24:15  * kevino80joined
14:25:28  * thlorenzquit
14:25:46  * thlorenzjoined
14:29:39  * kenperkinsquit (Quit: Computer has gone to sleep.)
14:29:59  * mikolalysenkojoined
14:31:14  * kenperkinsjoined
14:31:26  * mirkokieferjoined
14:35:10  * AvianFlujoined
14:42:02  * ednapiranhajoined
14:43:53  * mirkokieferquit (Quit: mirkokiefer)
14:49:53  <rowbit>substack, pkrumins: These encoders are STILL down: 50.57.226.209(free4)
14:52:38  <mikolalysenko>sat solvers! https://github.com/mikolalysenko/2-sat
14:52:47  <mikolalysenko>next step is horn sat. any takers?
14:53:45  * AvianFluquit (Remote host closed the connection)
14:54:14  * AvianFlujoined
14:58:12  * tmcwjoined
14:59:05  * AvianFluquit (Ping timeout: 272 seconds)
14:59:11  * dguttmanjoined
15:02:16  * thlorenz_joined
15:06:44  * thlorenz_quit (Ping timeout: 265 seconds)
15:11:23  <rowbit>substack, pkrumins: These encoders are STILL down: 173.203.67.76(free3)
15:13:03  * mikolalysenkoquit (Ping timeout: 260 seconds)
15:14:37  * mikolalysenkojoined
15:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 32]
15:26:47  * thlorenzquit
15:28:12  * thlorenzjoined
15:45:06  * jcrugzzjoined
15:45:56  * kevino80quit (Remote host closed the connection)
15:46:32  * kevino80joined
15:47:11  * kevinswiberjoined
15:51:23  * kevino80quit (Ping timeout: 272 seconds)
15:51:47  * AvianFlujoined
15:54:37  * shamajoined
15:58:35  * calvinfojoined
16:03:02  * jcrugzzquit (Read error: Connection reset by peer)
16:04:54  * jcrugzzjoined
16:09:59  * mikolalysenkoquit (Ping timeout: 260 seconds)
16:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 40]
16:16:59  * jergasonjoined
16:29:15  * calvinfoquit (Quit: Leaving.)
16:30:21  * st_lukejoined
16:34:12  * jcrugzzquit (Ping timeout: 260 seconds)
16:34:28  * jcrugzzjoined
16:37:15  * kenperkinsquit (Quit: Computer has gone to sleep.)
16:38:42  * kenperkinsjoined
16:44:00  * jiangplusquit (Quit: leaving)
16:48:06  * kevino80joined
16:54:32  * brianloveswordsquit (Excess Flood)
16:55:57  * brianloveswordsjoined
16:57:28  * ralphtheninjajoined
16:58:57  * DTrejojoined
17:01:28  * calvinfojoined
17:16:45  <rowbit>Hourly usage stats: [developer: 1, free: 25]
17:16:59  * mikolalysenkojoined
17:18:05  * AvianFluquit (Remote host closed the connection)
17:20:33  <Domenic_>creationix: so yeah, streams work all day tomorrow and Sunday.
17:20:49  <Domenic_>I could almost certainly use some help, cuz there's a lot to do
17:21:03  * mikolalysenkoquit (Ping timeout: 240 seconds)
17:21:20  <Domenic_>Your experience implementing js-git on top of your streams is pretty valuable
17:21:47  <Domenic_>Although it needs to be tempered by a desire for performance, which might mean sacrificing on simplicity or purity.
17:22:26  <Domenic_>But I am definitely interested in doing as much via layering of small primitives as is possible
17:23:05  <creationix>yay, I have irc again. It's been a while
17:23:08  <thlorenz>Domenic_: maybe there could be a more low level API to allow optimizing for performance and a higher level one for normal use?
17:23:09  <creationix>ITC on chromebooks generally sucks
17:23:12  <creationix>*IRC
17:23:26  <Domenic_>My current thinking is that promise-returning read() is not the lowest level; a sync read() plus a promise-returning wait() [equivalent to node's on('readable')] seems lowest-level
17:23:49  <creationix>Domenic_, did you see my latest proposal
17:23:49  <creationix>it's somewhat like that
17:24:04  <Domenic_>actually I was thinking sync pop() as the name, then read() could be promise-returning
17:24:12  <Domenic_>creationix: I'm not sure I did, link please :)
17:24:15  <creationix>https://gist.github.com/creationix/6587060
17:24:34  <creationix>dominictarr seems to like it. Also he's started a new thread somewhere. Let me find it.
17:24:41  <thlorenz>Domenic_: pop() would give away implementation details (i.e. its an Array Buffer)
17:25:21  <thlorenz>read() as low level and maybe next() as higher level?
17:25:28  <Domenic_>thlorenz: well it's supposed to invoke array feels. it pops off the internal buffer, and the think popped is no longer in the internal buffer
17:25:32  <Domenic_>thlorenz: that's nice too
17:26:00  <Domenic_>although actually I guess I mean shift() not pop
17:26:00  * AvianFlujoined
17:26:10  <Domenic_>whatevs, names not horribly important
17:26:10  <creationix>basically my interface has a .pull() method that tells the underlying stream I'm ready for data, and then it later calls my .ondata handler
17:26:37  <Domenic_>creationix: pull() returns buffer contents?
17:26:48  <creationix>no, pull doesn't return anything
17:26:56  <Domenic_>I keep seeing "return input.pull()" :P
17:26:57  <creationix>except maybe return true if it dispatched the data sync
17:27:05  <creationix>oh, I tend to tail call
17:27:13  <creationix>in hopes tha VMs optimize it
17:27:21  <Domenic_>so ondata is zalgo-ish?
17:27:31  <creationix>zalgo?
17:27:36  <Domenic_>sometimes sync, sometimes async
17:27:49  <creationix>I prefer that in my APIs
17:27:54  <creationix>it's simpler to implement
17:27:58  <creationix>(though harder to consume)
17:28:00  <Domenic_>oh, yeah, that's not really ok :-/
17:28:19  <creationix>but for a W3C spec, I'm find with all data events being on their own tick
17:28:25  <creationix>makes usage a lot simpler
17:28:39  <Domenic_>the inherent conflict, as laid out by isaacs, is that read(cb) is an extra nextTick if data is already available, but much simpler. so some kind of readCurrentBufferSync() + tellMeWhenMoreDataIsHereAlwaysAsync(cb) is what you want
17:28:57  <Domenic_>with the idea that you only ever call tellMeWhen... once readCurrentBufferSync() returns undefined or something
17:29:03  <creationix>the streams2 / go / other platforms way right?
17:29:11  <Domenic_>yeah pretty much
17:29:21  <creationix>right, that's the idea with .pull() returning true if it was sync
17:29:36  <creationix>so you can do while (stream.pull());
17:29:47  <Domenic_>tbh, also, moving away from promise-returning read() helps us differentiate from the existing W3C streams proposal (the one with no backpreessure)
17:30:47  <creationix>so in the streams1 writable API, there was the write return value and the "drain" event
17:30:47  <creationix>we could do the same for readable
17:30:50  <Domenic_>creationix: if you want to open an issue explaining your proposal (with words :P), especially how it compares to read(cb) and readCurrentBufferSync(), that would be helpful. It sounds slightly different, and there's probably something to learn there.
17:30:51  <creationix>read would return undefined if there was no data
17:30:51  <creationix>but otherwise return the data sync
17:30:52  <creationix>and have "readable" event
17:30:54  <creationix>(which actually is basically what streams2 does right)
17:31:03  <Domenic_>yeah that's the idea i think
17:31:27  <creationix>My main goal is to keep confusion out of the bare API
17:31:30  <Domenic_>although promises (or cbs) instead of events makes more sense since you really want a one-time notification to start re-reading
17:31:34  <creationix>but still have the nessecary primitives
17:32:08  <creationix>Domenic_, so in practice, there are cases where callback/promise based read streams are natural and other cases where event handlers are naturan
17:32:10  <creationix>*natural
17:32:22  <Domenic_>right, yeah, passive data listening being the obvious event case
17:32:28  <creationix>hence why node now supports both types
17:32:49  <creationix>and not all streams need backpressure
17:32:51  <Domenic_>isaacs is pretty insistent (as is most of node core) that making EEs part of the stream abstraction was a mistake
17:33:00  <creationix>agreed here
17:33:05  <ogd>for perf reasons yes
17:33:14  <creationix>though I feel the same way about promises
17:33:22  <Domenic_>well if you don't want backpressure I think you'll want something simpler, e.g. a generator of promises or something I think.
17:33:27  <creationix>but is promises were a fast primitive in the language itself, that may be different
17:33:44  <Domenic_>right, that's the decider, is would they be fast enough. i am hopeful.
17:33:54  <creationix>can we use generators in this proposal?
17:34:01  <Domenic_>it would be nice to be able to do `while (data = yield stream.read())` though
17:34:05  <Domenic_>yes definitely
17:34:13  <Domenic_>but it is harder to make use of them than you'd think
17:34:22  <Domenic_>because once a generator is "empty" it can never become un-empty
17:34:23  <creationix>that's the interface I've been pushing for years with lua coroutines and js generators
17:34:25  <thlorenz>Domenic_: but now it's a push again
17:34:35  <Domenic_>thlorenz: ???
17:34:38  <thlorenz>i.e. it'll keep yielding (pushing) values
17:34:41  <Domenic_>so e.g. you can't start out with an empty stream that starts filling with data
17:34:56  <thlorenz>I'd keep read simple
17:35:11  <Domenic_>thlorenz: you have a very weird conception of "pull" vs. "push", but yeah, I remember from yesterday.
17:35:25  <thlorenz>it should by sync and have no (promise, callback, yiedld, future) whatevs API
17:35:29  <Domenic_>thlorenz: to me pull vs. push means "data is buffered until you ask" vs "data is thrown at you and you might miss it"
17:35:45  <thlorenz>that's not how it works
17:35:54  <Domenic_>thlorenz: well it needs to be async at some level, so you know when new data is available to read synchronously
17:35:57  <creationix>Domenic_, not sure I understand the problem?
17:35:59  <thlorenz>push buffers data for you if you don't handle it fast enough
17:36:24  <rowbit>substack, pkrumins: These encoders are STILL down: 50.57.103.135(free2)
17:36:27  <creationix>Domenic_, push can work just fine as long as the stream starts paused
17:36:28  <thlorenz>Domenic_: yes, something to replace on('readable'
17:36:31  <creationix>and it stops emitting data the instant you tell it to pause
17:36:46  <Domenic_>creationix: well a naive model of streams is a generator of promises. but if you ever call .next() before the previous promise is fulfilled, you kill the generator and can't recover.
17:37:03  <creationix>Domenic_, then don't do that?
17:37:12  <creationix>in mine I throw an error if that's done
17:37:19  <creationix>I only allow one read at a time
17:37:36  <Domenic_>creationix: i mean yeah that is part of it. feels fragile though. why use generators at all in that case?
17:37:47  <creationix>right, I don't use generators *in* the stream
17:37:48  <Domenic_>you can't consume with for of
17:37:57  <creationix>I just consume the stream with generators
17:38:04  <Domenic_>what does that look like in code
17:38:09  <creationix>the stream just returns promises from the read
17:38:27  <creationix>while (data = yield stream.read());
17:38:32  <Domenic_>sure ok
17:38:44  <creationix>and yield goes to gen-run or something that resolves the continuable/promise
17:38:51  <Domenic_>i misinterpreted what you meant by "use generators" I guess.
17:38:53  <substack>Domenic_: events should still be part of the stream api
17:39:05  <thlorenz>Domenic_: creationix I stick to my stance that read should never delay - mixing these concepts make things unnec complex
17:39:10  <Domenic_>you seem to have meant "design an API so that it is nice to use when consumers have generators"
17:39:15  <creationix>all of js-git can be used with node style callbacks or continuables
17:39:18  <Domenic_>substack: interesting, why.
17:39:20  <substack>if I'm consuming a stream I want to know when it's done giving me data
17:39:24  <creationix>so you can use generators to consume the streams if you want
17:39:30  <substack>this is one thing I really dislike about the current streams
17:39:45  <substack>even if you're consuming a stream, you have no way from outside to know when it's done
17:39:52  <substack>and that's such a common use-case
17:39:54  <Domenic_>substack: sample use case?
17:40:07  <creationix>substack, that's what the end event is for right?
17:40:09  <substack>a.pipe(b); b.on('end', function () {}) only works if b is in flow mode
17:40:12  <substack>er sorry
17:40:22  <substack>a.pipe(b); a.on('end', function () {}) only works if a is in flow mode
17:40:24  <creationix>oh, pipe right
17:40:32  <substack>creationix: only in flow mode
17:40:33  <Domenic_>hmm
17:40:43  <creationix>when I design stream interfaces I make them simple enough that you don't need pipe
17:40:47  <Domenic_>why do you care when a has no more data
17:40:52  <substack>having good consistent semantics for "hangup" kinds of events would also be really good
17:40:59  <substack>for when the stream gets destroyed
17:41:04  <substack>to unregister listeners
17:41:17  <creationix>js-git streams are readable only and treated like primitive values
17:41:23  <substack>Domenic_: because often I want to do something like this:
17:41:27  <creationix>you write to things by handing a stream to a sink
17:41:30  * jxsonjoined
17:41:40  <substack>a.pipe(fs.createWriteStream('output.txt')); a.on('end', function () { do the next thing... })
17:41:51  <Domenic_>substack: my current plan for that is that the stream constructor gets passed a function to call when the stream is aborted and/or done.
17:42:04  <creationix>substack, with js-git style APIs, you do output.sink(input, callback)
17:42:14  <creationix>where the callback gets called for error or end of stream
17:42:24  <substack>Domenic_: but if I didn't create the stream myself, that doesn't help
17:42:32  <Domenic_>substack: yeah.
17:42:35  <substack>if I got `a` from some existing function for example
17:42:58  <Domenic_>one interface that other languages have I think is a.pipe(b).then(callThisWhenPipingIsOver, callThisIfPipingFails)
17:43:21  <substack>Domenic_: what about having a 'close' event that ALWAYS fires when a stream is "done"
17:43:24  <Domenic_>this output.sink(input) vs. input.pipe(output) thing is curious.
17:43:31  <substack>whether done by being destroyed, ended, or errors
17:43:33  <Domenic_>substack: the problem is that then streams are EEs and isaacs will be sad.
17:44:17  <substack>I think isaacs's "event emitters are always bad in streams" is too broad of a prohibition
17:44:33  <substack>event emitters are really good for hooking up state changes that are immediate
17:44:43  <substack>'data' and 'end' are not immediate was the problem
17:44:56  <Domenic_>I am tempted to throw more promises at the problem (stream.end.then(noErrors, thereWereErrors)). That is probably slightly better. But kind of silly also.
17:45:01  <substack>but other kinds of events like disconnects and 'close' are
17:45:06  <Domenic_>substack: what do you mean by "immediate"
17:45:26  <substack>events fire immediately
17:45:44  <Domenic_>stream.end promise is pretty useful (eg. you can subscribe after the stream is already over) but still feels weird...
17:45:45  <substack>but data and EOF fire when you read, which is not immediate
17:45:45  <creationix>substack, I'm not sure the stream interface should worry about things like close
17:45:45  <creationix>node conflates too much imho
17:45:52  <creationix>streams should care about "data", "end", "error", backpressure, reading, writing
17:46:04  <substack>Domenic_: will I have to use promises to get at these events :/
17:46:25  <substack>because if so the first thing I am going to do is wrap everything in an event emitter so I don't have to look at them ever
17:46:30  <Domenic_>substack: one-time events which you often want to subscribe to after they've already fired should generally be promises (e.g. document.ready), so yeah.
17:46:42  <Domenic_>substack: that's a shame, feels close-minded of you.
17:46:51  <Domenic_>substack: but if something has real EE semantics then of course it'll be an event emitter
17:47:07  <creationix>substack, just imagine he says callback when you hear promise
17:47:08  <creationix>same behavior
17:47:09  <Domenic_>e.g. if it can occur more than once
17:47:15  <Domenic_>creationix: yes thanks :)
17:47:26  <substack>promises use callbacks
17:47:41  <substack>promises are like forcing everybody to use your wonky flow control library
17:47:56  <substack>instead of the base thing that every async abstraction has in common
17:48:05  <Domenic_>they're like forcing everyone to use weird higher-level primitives like "functions" when everyone has this base abstraction of gotos and labels in common.
17:48:26  <Domenic_>but let's please set aside our differences on this issue ... it's pretty tangential.
17:48:36  <Domenic_>the sematnics are what's important: one-time vs. recurring.
17:48:46  <creationix>like I said, don't focus on callback vs promise vs continuable
17:48:54  <creationix>they are all the same thing from a design point of view
17:49:04  <creationix>I obviously prefer continuables, but whatever
17:49:06  * st_lukequit
17:49:17  * st_lukejoined
17:49:47  <substack>streams should just have a way of firing some code when they are done being consumed
17:50:08  <substack>because then you can pipe 2 streams together without having had to create them yourself
17:50:11  <Domenic_>+1, that is a big takeaway
17:50:33  <substack>it's very often to pipe 2 things together and then to want to do something else when that finishes
17:50:38  <creationix>substack, so your goal is to know when each piece of a stream chain is done individually?
17:50:44  <substack>whatever isaacs says about EEs always being bad
17:50:45  <Domenic_>substack: what do you think of a.on('done') vs. a.pipe(b, function (err) { ... })
17:51:09  <substack>Domenic_: I think 'done' is cleaner but both would work
17:51:43  <substack>the cb arg might get in the way of other arguments to .pipe() like opts
17:51:56  <substack>like whatever { end: false } is in the w3 streams
17:52:40  <Domenic_>ah wow i totally forgot that w3 streams missed { end: false }
17:52:42  <Domenic_>that's an important one
17:52:47  <Domenic_>should have busted their balls for that
17:52:47  <chrisdickinson>creationix: do your sinks still return continuables?
17:53:13  <Domenic_>BTW everyone: W3C streams = current proposal from those two guys = bad. WHATWG streams = my (our) proposal = good
17:53:16  <chrisdickinson>(would it be possible to phrase "end" as "output.sink(input).then(…)" in promise-land?)
17:53:37  <Domenic_>chrisdickinson: well the promise version would be equivalent to the function (err) { ... } version I did above
17:53:39  <creationix>chrisdickinson, right
17:53:57  <Domenic_>but that's different semantics than the on('done')
17:54:44  <creationix>WHATWG vs W3C, fight!
17:55:42  <Domenic_>(WHATWG = open to anyone, works on real "living standards", CC0, mostly GitHub these days; W3C = pay to play, DRM, copyright, copies and pastes WHATWG standards into their repos and then shoves them through this crazy multi-year editor's draft -> working draft -> etc. -> recommendation process.)
17:56:13  <chrisdickinson>wouldn't returning a promise give the writable streams / sinks / destinations a single point at which to say "I'm done", and "I had an error" or "I was successful"?
17:56:31  <Domenic_>chrisdickinson: not sure, what do you mean more concretely?
17:56:33  <creationix>chrisdickinson, that's what I use the continuables
17:56:41  <creationix>continuable == promise
17:56:43  <chrisdickinson>creationix: right
17:57:14  <creationix>I really, *really* like the idea of treating a stream like a primitive
17:57:20  <chrisdickinson>was seeing if that would be an amenable way to solve the "tell me when this stream is done" problem (vs. making it an eventemitter)
17:57:23  <creationix>transforms accept streams and return new streams
17:57:38  <creationix>sinks accept streams and return promise for "done" or "error"
17:57:40  <chrisdickinson>and was suggesting promises over continuables since that's the way things seem to be moving in the browser.
17:57:48  <chrisdickinson>ok, cool
17:57:59  <Domenic_>creationix: Raynos: why do you guys find the idea of sink.accept(source) better than source.pipe(sink)
17:58:17  <creationix>Domenic_, because it's less code
17:58:26  <creationix>lesss code == less complexity generally
17:58:28  <Domenic_>creationix: for who
17:58:41  <creationix>everyone
17:58:59  <creationix>dest.sink(source) vs source.pipe(sink) is the same code
17:59:00  <Domenic_>creationix: be more specific then. how?
17:59:14  <creationix>but to implement it, only writable things need to implement sink
17:59:30  <creationix>most the links between a source and a dest are transforms
17:59:35  <creationix>and they have a different interface
17:59:41  <creationix>transform(stream) -> stream
18:00:01  <creationix>where sink is sink(stream) -> promise<end/done>
18:00:04  <Domenic_>i find node's .pipe really ergonomic
18:00:08  <chrisdickinson>anecdotally, using simple-streams (the spec that preceded what creationix linked) was easy to follow, easy to write new transformation streams, and made it easy to encapsulate logic
18:00:50  <creationix>all of js-git is still simple-streams for reference
18:00:50  <creationix>the new idea is still just an idea
18:00:53  <creationix>to try to solve some of the pain points in implementing simple-streams
18:00:55  <creationix>in particular error reporting
18:01:02  <Domenic_>substack: you love pipe, how do you react to all this talk of dest.sink(source) intead of source.pipe(dest), and gzipTransform(source) vs. source.pipe(new GzipTransform)
18:01:06  <creationix>I hate it that I have to wait till the next .read() call to emit an error
18:01:27  <Domenic_>creationix: how do errors get emitted in the new idea?
18:01:28  <creationix>I agree that source.pipe(dest) is more natural
18:01:39  * rxgxjoined
18:01:41  <creationix>in the new idea, part of the stream interface is an error event
18:01:43  <chrisdickinson>what I found I liked best about it was that it was simple enough to write a stream sans any supporting infrastructure -- vs. node streams, which always involve subclassing or using another library to create a base stream for you.
18:01:47  <Domenic_>creationix: would love a promise explanation of the new idea, code is not easy to figure out which parts are profound vs. which are just details.
18:01:54  <Domenic_>s/promise/prose
18:01:58  <Domenic_>(O_o)
18:02:02  <creationix>lol
18:02:21  <creationix>chrisdickinson, yes, that was my main goal!
18:02:27  <Domenic_>hmm yeah
18:02:29  <creationix>simple-streams don't need a library to be usable
18:02:35  <Domenic_>everyone uses through anyway
18:02:40  <creationix>you just create objects that conform to some simple interface
18:02:46  <creationix>I don't
18:02:48  <creationix>:P
18:03:11  <creationix>also remember I'm not node-centric with js-git
18:03:15  <creationix>most my platforms are non-node actually
18:03:26  <Domenic_>the constructor pattern in whatwg/streams seems to help some, i.e. you will have to subclass less and just use the constructor with different onRead functions instead.
18:03:36  * thlorenz_joined
18:04:38  <creationix>Domenic_, ok, so lets start with the bare abstract goals
18:04:38  <creationix>1. we want a data stream with back-pressure
18:04:45  <creationix>2. we want a way to signal the end of the stream
18:04:55  <creationix>3. we want a way for the consumer to notify the source it's done consuming (abort)
18:05:02  <creationix>4. we need sane error reporting
18:05:09  * defunctzombiechanged nick to defunctzombie_zz
18:05:37  <Domenic_>let me add some others that we need, probably not in the base layer:
18:05:43  <Domenic_>5. multi-destination pipe
18:05:44  <creationix>so we want readable *and* writable interfaces?
18:05:50  <creationix>or stick with readable only using sinks for writable?
18:06:17  <Domenic_>creationix: definitely want writable. So e.g. <video> tags can implement writable and you can start writing frames to them.
18:06:53  <creationix>for file-streaming situations, I like readable-only
18:07:01  <creationix>not sure about the <video> case, that's gray
18:07:25  <Domenic_>WebWorkers: duplex streams, write data in, read data back out
18:07:40  <creationix>to me a duplex stream is just two streams
18:07:50  <creationix>they can be the same object if the interfaces don't conflict
18:07:57  <creationix>but it's really two streams
18:07:59  <Domenic_>Future awesome world (TM): getXHRStream().pipe(webWorkerToDoComplexProcessing).pipe(videoTagStream)
18:08:06  * thlorenz_quit (Ping timeout: 245 seconds)
18:08:10  <Domenic_>creationix: agreed.
18:08:35  <chrisdickinson>.pipe(webglTexture)?
18:08:35  * st_lukequit (Read error: Connection reset by peer)
18:08:37  <creationix>as far as multi-destination pipe, I think that's just a custom transform
18:08:46  <creationix>it shouldn't be part of the core stream API
18:08:57  * st_lukejoined
18:09:04  <creationix>unix streams don't have that, you use the tee program
18:09:14  <Domenic_>creationix: as long as that can be done performantly, seems good.
18:09:20  <Domenic_>although the base API will probably have it
18:09:34  <Domenic_>but, implemented in terms of a simpler API + a T stream
18:09:39  <Domenic_>(both of which will be exposed)
18:09:52  <creationix>tee(source, 2) -> [output, output]
18:09:57  <creationix>or something like that
18:10:29  <Domenic_>I really liked what Raynos did at https://github.com/whatwg/streams/issues/1#issuecomment-27545472
18:10:34  <creationix>in js-git I have multiplexers and demultiplexors
18:10:42  <creationix>parse(stream) -> { pack: stream, progress: stream, error: stream, line: stream }
18:10:50  <creationix>encode({streams...}) -> stream
18:11:03  <creationix>all custom connectors
18:11:26  <creationix>oh heh, that's the github link I was looking for
18:11:35  <creationix>I should have remembered you've seen it
18:11:42  * creationixslaps forehead
18:12:35  <creationix>so basically, include some generic helpers as builting
18:12:39  <creationix>*builtins
18:12:42  <creationix>I'm find with that
18:12:58  <creationix>as long as they are truly generic *and* useful
18:13:41  <Domenic_>we are trying to make this as much "extensible web" as possible
18:13:57  <Domenic_>it's a bit tricksy because the community hasn't finished experimenting and settled on something perfect yet
18:14:08  <Domenic_>so we can't just rubber-stamp node streams and say "good to go"
18:14:34  <Domenic_>but we want streams as a low-level primitive, not just a magic part of XHR and a magic part of web filesystem APIs and so on
18:15:15  <Domenic_>and to be most useable by others who are building their own custom streams, yeah, small useful and generic helpers that compose the higher-level API that we want to expose
18:15:52  <creationix>yes
18:15:52  <creationix>since we still haven't found the perfect API, I say we should err on the side of simple
18:15:55  <creationix>better to do too little than too much
18:16:21  <Domenic_>yeah. modulo the fact that we need to actually solve all the problems.
18:16:29  <creationix>pipe in streams1 was unusable for voxer, so they never used it and had a custom pipe
18:16:45  <rowbit>Hourly usage stats: [developer: 5, free: 34]
18:16:49  <creationix>which problems should we optimize for
18:16:54  <Domenic_>would still really like a creationix vs. substack fight on source.pipe(dest) vs. dest.sink(source). maybe with commentary from isaacs.
18:17:16  <creationix>dominictarr likes .pipe too I think
18:17:29  * chrisdickinsontoo
18:17:34  <creationix>I like it, I just can't justify the complexity it entails to implement
18:17:43  <creationix>I hate APIs that require me to use complex tools
18:17:56  <Domenic_>creationix: all of node's use cases + https://dvcs.w3.org/hg/streams-api/raw-file/tip/Overview.htm#consumers seems like a start.
18:18:10  <chrisdickinson>is it still a matter of `dest.sink(transformC(transformB(transformA(source))))`?
18:18:16  <Domenic_>why is .sink easier to implement than .pipe
18:18:17  <chrisdickinson>(re the `sink` version?)
18:18:52  <creationix>chrisdickinson, that's the simple way, yes
18:18:59  <creationix>pure functional programming
18:19:05  <creationix>parallels map functions
18:19:13  <creationix>var object = JSON.parse(json)
18:19:15  <isaacs>Domenic_: i'm more insistent than that. I maintain that EEs should not be in node *at all*
18:19:30  <Domenic_>creationix: how do transform functions work with non-chunkwise transforms (e.g. gzip)
18:19:32  <creationix>var messageStream = websocket.parse(inputStream)
18:19:33  <isaacs>Domenic_: event emission *as such* is almost always a bad idea, and node *way* overuses it
18:19:45  <Domenic_>creationix: maybe they are more like .flatMap than they are like .map?
18:19:53  <creationix>Domenic_, it's higher level
18:20:01  <creationix>you consume a stream and return a stream
18:20:09  <Domenic_>creationix: I guess I should look at the gist's examples.
18:20:15  <creationix>there is no constraint that events in the source stream must match 1:1 with the output stream
18:20:36  <Domenic_>isaacs: so how do you solve cases like passive data listening or "tell me when the stream is done so i can clean up."
18:21:19  <creationix>passive data listening, by definition is event based
18:21:27  <creationix>but you don't need multiple listeners
18:21:29  <creationix>.ondata = function () {} is fine
18:21:53  <Domenic_>mehhhhh
18:22:05  <creationix>it
18:22:22  <creationix>it's a lot simpler *and* faster than inheriting from some EE library and routing every event through the library code
18:22:44  <creationix>but that's like continuable vs promise vs node-callback
18:22:48  <creationix>it's the same behavior
18:23:17  <creationix>also with .ondata = fn, you can short-circuit stuff
18:23:26  <creationix>like use a reference from 3 layers deep
18:23:27  <creationix>no routing needed at all
18:23:32  <Domenic_>hmmmmm
18:23:47  <Domenic_>isaacs: agree/disagree?
18:24:25  <isaacs>i don't like .ondata=function
18:24:27  <isaacs>either
18:24:44  <isaacs>i'm *less* offended by .ondata(function)
18:24:58  <isaacs>one problem with .on('data',fn) and .ondata=fn is that it's not discoverable
18:25:17  <isaacs>and you have this stateful side-effecty change, for something that should be idempotent
18:25:43  <creationix>right, it's terribly awkward to use .ondata = fn
18:25:44  <creationix>it's the most simple/performant option I think
18:25:51  <Domenic_>isaacs: by that do you mean flowing vs. non-flowing mode?
18:26:24  <creationix>so .ondata(fn) would internally set this._ondata = fn or something right?
18:26:29  <creationix>or would it support multiple listeners?
18:28:25  <creationix>the problem my new interface has is I have no way of knowing when .ondata and .onerror were set
18:28:37  <creationix>I assume they set it right away (same tick), but that's tricky
18:28:40  <creationix>and fragile
18:28:43  <isaacs>creationix: .ondata(fn) is like Raynos's Event thing
18:28:54  <isaacs>creationix: this.ondata = new Event();
18:29:04  <creationix>haven't seen that
18:29:07  <isaacs>creationix: yeah
18:29:12  <isaacs>creationix: it is still brittle
18:29:26  <isaacs>the Observer pattern is only good if the observer is strictly JUST an observer, and not a Consumer
18:29:36  <isaacs>this is what sucks about node's "evented" io
18:29:56  <isaacs>and this, really, is why i get annoyed at most people who criticize node. they don't cut deep enough.
18:30:20  <isaacs>in order to truly have crippling criticism, you have to know a system so well you fall in love with it.
18:30:54  <isaacs>and most trolls dont' ahve the grit to do the work, or the empathy and compassion required to fall in love with something that deeply that you can shape your mind to it, and feel where it's broken
18:31:02  <Domenic_>haha aww <3
18:31:16  <Domenic_>Ender's Game-esque
18:31:25  <isaacs>yeah, but without the militarism or homophobia
18:31:29  <isaacs>;)
18:32:11  <isaacs>i'm wiling to bet that nearly *every* system is deeply flawed. when people don't cop to their systems' flaws, either they're liars, or they don't know what they're talking about.
18:32:24  <isaacs>because all computers are shit.
18:32:41  <isaacs>it's just that some systems are better in certain circumstances at not showing their flaws.
18:32:50  * creationixpretty much agrees with isaacs
18:34:29  <creationix>isaacs, would it be a terrible mistake to have pull-streams only for whatwg streams?
18:34:29  <creationix>it sure simplifies things
18:34:33  <creationix>stream.read() -> promise<value/end/error>
18:34:48  <creationix>stream.write(data/end) -> promise<written/error>
18:35:15  <Domenic_>two arguments have me moving back in favor of sync readCurrentBuffer
18:35:30  <Domenic_>one is, the extra nextTick.
18:35:37  <Domenic_>(if data is already available)
18:36:11  <creationix>I know bruno has been pushing this style for a long time using node-fibers and streamline transforms
18:36:25  <creationix>are promises slow if the data is already available?
18:36:26  <creationix>or are we going with A+ which assumes nextTick?
18:36:37  <creationix>(continuable promises, for example, don't have this guarantee)
18:36:38  <Domenic_>the other is, write streams already need a dual API of .write(data) -> promise<written/error> PLUS .tellMeWhenReadyToWriteMore() -> promise
18:36:51  <Domenic_>yeah ES6 promises guarantee end-of-microtask
18:37:13  <Domenic_>which is pretty damn fast, but, meh, we're at a pretty low-level, probably should be careful
18:37:18  <Domenic_>but to finish the thought
18:37:27  <creationix>why do writable streams still need "writable"?
18:37:35  <creationix>if you have a promise for write, it can block till writable
18:38:08  <Domenic_>creationix: um, hmm. But, node .write() already has a callback, but also has 'drained' event, right?
18:38:22  <creationix>that's because the callback is rarely used
18:38:28  <creationix>and write has a sync return value
18:38:43  <creationix>the "drained" is to go along with the return value to write
18:38:53  <Domenic_>what is the callback communicating anyway...
18:39:03  <creationix>the readable parallel is sync read with "readable" event
18:39:17  <Domenic_>yes
18:39:26  <creationix>I think it communicates drained, not sure exactly
18:39:38  <Domenic_>i think this is important knowledge :)
18:39:48  <Domenic_>isaacs: halp, what does the callback to .write() actually do
18:39:55  <creationix>my point is most node code I've seen doesn't use or rely on that callback
18:40:02  <creationix>it's quite optional and unused in my experience
18:40:30  <Domenic_>most node code doesn't rely on anything but .pipe ;)
18:40:43  <creationix>right, but that's another level
18:40:50  <Domenic_>bah i have to lunch
18:40:55  <Domenic_>be back in 20-ish
18:40:58  <creationix>ok
18:52:26  * creationixis writing up ideas in a gist for easier reading...
18:59:02  * defunctzombie_zzchanged nick to defunctzombie
19:00:10  <defunctzombie>substack: ping
19:09:12  * calvinfoquit (Quit: Leaving.)
19:12:56  <thlorenz>defunctzombie: substack I just removed an entire feature from browser-pack and no tests failed
19:13:05  <defunctzombie>amazing
19:13:12  <thlorenz>the PRs are gonna be forthcoming within the hour though
19:13:20  <defunctzombie>thlorenz: means one of two things... useless feature or we don't test enough hahhaha
19:13:22  <thlorenz>defunctzombie: scary actually -- how dit that make it in
19:13:53  <thlorenz>defunctzombie: it actually changed behavior, but didn't work fully , so not useless ;)
19:16:45  <rowbit>Hourly usage stats: [developer: 2, free: 32]
19:16:53  * kevinswiberquit (Remote host closed the connection)
19:20:26  <defunctzombie>well, deleting code is always good
19:20:32  <defunctzombie>so +1 for that
19:20:59  <thlorenz>:)
19:23:46  <thlorenz>substack: defunctzombie: https://github.com/substack/node-browserify/pull/512 and https://github.com/substack/browser-pack/pull/24
19:24:31  <defunctzombie>thlorenz: if nomap is set
19:24:40  <defunctzombie>thlorenz: will that mean the duplicate won't have a source map?
19:24:41  <thlorenz>yep, browserify sets it
19:24:49  <defunctzombie>if you get an error in it.. what will happen?
19:24:50  <thlorenz>you won't need it
19:24:54  <defunctzombie>will we not have good debug info?
19:24:56  <thlorenz>how?
19:25:04  <thlorenz>it's just a generated require
19:25:05  <defunctzombie>oh.. cause it always load the other one
19:25:08  <defunctzombie>gotcha!
19:25:09  <defunctzombie>cool stuff
19:25:11  <thlorenz>:)
19:25:15  <defunctzombie>I like the nomap flag much better
19:25:17  <defunctzombie>than the other name you had
19:25:24  <defunctzombie>more generic
19:25:25  <thlorenz>yep, it's more generic
19:25:26  <thlorenz>:)
19:46:15  * mikolalysenkojoined
19:47:47  * tilgovijoined
19:48:06  <substack>thlorenz: that commit is from https://github.com/substack/browser-pack/commit/45b153aa1c3035ff346f04776176ce1b82fe3ab4
19:49:17  <substack>https://github.com/substack/browser-pack/pull/17
19:49:23  <substack>https://github.com/substack/node-browserify/issues/465
19:49:28  <substack>thlorenz: please put those lines back
19:49:46  <substack>unless that issue can be addressed
19:50:58  <thlorenz>substack: has been addressed: https://github.com/substack/node-browserify/issues/497#issuecomment-27446743
19:51:15  <thlorenz>ef4 who put it there told me to remove it ;)
19:51:49  <thlorenz>substack: and this: https://github.com/substack/node-browserify/issues/465 is a duplicate of the issue I just linked
19:52:25  <thlorenz>I'm surprised: https://github.com/substack/browser-pack/pull/17 made it in substack
19:52:31  * timoxleyquit (Remote host closed the connection)
19:52:56  <thlorenz>I mean its sloppy, no tests, indentation messed up and only made the issue harder to repro instead of fixing it
19:53:06  * timoxleyjoined
19:55:01  <creationix>what is a good way to emit events for streams?
19:55:15  * rxgxquit (Quit: timeout)
19:55:20  <creationix>I've been using bare .ondata = fn references
19:55:24  <creationix>which is very simple and fast, but it has it's problems too
19:55:51  * jxsonquit (Remote host closed the connection)
19:56:18  * jxsonjoined
19:56:43  <substack>thlorenz: ok great!
19:56:54  <substack>just making sure that we weren't regressing over any old issues
19:57:16  * timoxleyquit (Ping timeout: 245 seconds)
19:58:38  <defunctzombie>thlorenz: substack: I think the new tests added will prevent that for this case in the future.
19:58:48  <Domenic_>creationix: .setDataListener(fn) seems like a slightly nicer bikeshed.
19:58:49  <thlorenz>substack: yeah I was a bit worried at first too, since I didn't know exactly why that seenSourceFiles thing was in there
19:58:52  <defunctzombie>thlorenz: substack the fact that other fix had no tests makes it scary
19:58:56  <thlorenz>which is why I got the confirmation on the issue
19:59:28  <thlorenz>defunctzombie: yeah, but I got at least confirmation from author that it was attempt to fix same issue
20:00:25  <defunctzombie>yep
20:00:27  * jxsonquit (Ping timeout: 240 seconds)
20:00:46  * jxsonjoined
20:01:41  * kevino80quit (Remote host closed the connection)
20:02:05  <creationix>Domenic_, I'll use something like that in my examples then. I don't want the events to distract
20:02:17  * kevino80joined
20:02:21  <Domenic_>creationix: yeah seems reasonable.
20:02:45  <creationix>Domenic_, the writeup in progress is at https://gist.github.com/creationix/7270104
20:03:52  <creationix>Domenic_, should "end" events be held back if a stream is paused?
20:03:56  <creationix>they don't need backpressure
20:04:00  <creationix>there is only one
20:04:21  <creationix>same for error events
20:04:30  <creationix>I don't like queueing them
20:04:36  <creationix>causes late error notifications
20:04:41  <Domenic_>creationix: seems like they should... if i pause, i don't want anything to happen until i resume
20:04:50  <isaacs>Domenic_: the cb to write() is called when either the write is successful or failed
20:05:01  * jxsonquit (Remote host closed the connection)
20:05:06  <Domenic_>isaacs: to the underlying data sink, you mean
20:05:27  * jxsonjoined
20:05:48  <isaacs>Domenic_: yeah
20:05:58  <isaacs>Domenic_: but it's... weird.
20:06:02  <Domenic_>isaacs: what is the difference between waiting for the cb to call back with success and waiting for 'drain'
20:06:15  <isaacs>Domenic_: 'drain' will only be emitted if the write() returned false
20:06:25  <isaacs>Domenic_: write(cb) MAY call the cb as early as nextTick
20:06:26  <creationix>Domenic_, right, the question is should "pause" affect *all* events or just the "data" events that need the backpressure?
20:06:26  <creationix>I would prefer if they only paused data events
20:06:33  <creationix>also I like to group "end" and "error" into the same handler for simplicity
20:06:43  <isaacs>creationix: 'end' events also need backpressure!
20:06:44  <creationix>"error" is just a special case of "end", there won't be more data after it
20:06:48  <Domenic_>creationix: I feel like if it's named pause it should pass all events.
20:06:52  <Domenic_>s/pass/pause
20:06:55  <mikolalysenko>one more step closer to prolog.js: https://github.com/mikolalysenko/horn-sat
20:07:00  <creationix>isaacs, why?
20:07:09  * kevino80quit (Ping timeout: 272 seconds)
20:07:15  <isaacs>creationix: well, consider the case of an empty stream
20:07:42  <creationix>isaacs, I'm also proposing that all streams start paused
20:08:01  <isaacs>creationix: createServer((req,res)=>{ setTimeout(() => { req.pipe(upstream); upstream.pipe(res); }) })
20:08:19  <Domenic_>isaacs: so, the reason for the callback vs. 'drain' separation is if you need to know ASAP whether your write succeeded. otherwise you could just have the callback delay success notification until the drain has already happened. seem right?
20:08:20  <isaacs>creationix: if req emits 'end' right away, you miss it, and upstream never gets ended
20:08:37  <creationix>right, but that's a special case, not a general case
20:08:45  <isaacs>Domenic_: this is another case where we could make some epistemic decisions
20:08:53  <creationix>the initial pause can be a hard pause that pauses everything
20:08:59  <isaacs>creationix: well, sure, if you consider HTTP GET a special case of streams
20:09:00  <creationix>but later pauses only pause data
20:09:08  <isaacs>creationix: imo, GET is a pretty common streaming case
20:09:18  <creationix>isaacs, no, I mean there is a difference between setup and flow-control
20:09:24  <isaacs>creationix: in streams3, 'end' is not emitted until you read() *past* the EOF chunk
20:09:29  <creationix>setup is done once and nothing should emit till setup is done
20:09:41  * isaacssounds the "COMPLICATIONS" horn
20:10:17  <isaacs>creationix: so, you're back to the wonky nutso stuff we have in node, with flowing=(true/false/null)
20:10:25  * jxsonquit (Ping timeout: 272 seconds)
20:10:30  <creationix>setup is the reason that .ondata =fn is a problem
20:10:35  <isaacs>yeah
20:10:44  <Domenic_>isaacs: ah i see we have the same unnecessary-nextTick problem. if we counted on the cb to notify us when it was safe to write again, we couldn't write twice in quick succession, we'd need to wait a tick between writes.
20:10:45  <isaacs>also the reason that "evented" is a problem
20:11:37  <creationix>I still don't see why would want to buffer "end" and "error" events once a stream had started
20:11:45  <creationix>they have listeners and there will only be one ever
20:11:54  <isaacs>Domenic_: right
20:11:55  <creationix>the issue with data events is that there are many
20:12:03  <creationix>hence the need for back-pressure
20:12:21  <isaacs>creationix: i'd suggest that read() should be required to get the 'end' event to happen
20:12:36  <isaacs>even if "end event" is just "that time when read(cb) calls the cb with null" or something
20:12:52  <isaacs>i'd like to stop speaking in "events" actually
20:12:57  <isaacs>that's THE problem with node streams
20:13:18  <creationix>but they are events of a sort
20:13:28  <creationix>things that happen over time
20:13:31  <isaacs>creationix: yes, but "events" means a thing
20:13:40  <creationix>right, I don't want EE
20:13:45  <creationix>way too much power and complication
20:13:55  <isaacs>creationix: exactly. and .onf=fn is still EE, effectively
20:13:57  <isaacs>just simpler impl
20:14:04  <isaacs>but still bad (in some ways worse)
20:14:21  <creationix>.read(onData, onEndOrError)?
20:14:47  <creationix>or .read(function (err, data) { .. }) with special sigil for EOS
20:15:06  <Domenic_>^ that is my current design, but it has the unnecessary-nextTick "problem."
20:15:34  <creationix>I just worry about the recursive problem with that if you allow sync callback
20:15:34  <creationix>and the performance proglem with nextTick
20:15:35  <creationix>right
20:15:43  <creationix>it's certainly the simplest solution
20:15:46  <isaacs>creationix: sync callback releases zalgo. no.
20:15:52  <creationix>what basically what simple-streams in js-git are
20:15:52  <creationix>but is has real issues that have driven me crazy
20:15:54  <isaacs>creationix: the only way to do that is to guarantee nextTick
20:16:05  <isaacs>creationix: yes, it drives EVERYONE crazy
20:16:13  <creationix>What if you could return value *or* promise
20:16:25  <isaacs>creationix: when zalgo reaches his dark pony tentacles into our world, no one's sanity is safe.
20:16:31  <isaacs>creationix: no, "promise or value" is zalgo
20:16:38  <isaacs>just as zalgo as "cb now or later"
20:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 20]
20:16:55  <creationix>no, my issues with simple-streams is not sync callbaks
20:16:59  <creationix>it's having to buffer error and end events
20:17:02  <creationix>especially error events
20:17:10  * tmcwquit (Remote host closed the connection)
20:17:20  <isaacs>if we were talking about a language with native coros, and syntax for wrapped values that let them be treated just like regular values (ie, E-rights), then we could talk.
20:17:29  <isaacs>creationix: yeah, buffering error events sucks big time.
20:17:40  <Domenic_>isaacs: please explain why it sucks big time
20:17:48  <Domenic_>it seems fine to me
20:17:49  <creationix>ok, so assuming you're willing to accept the performance hit is containing zalgo...
20:17:58  <isaacs>Domenic_: when an error occurs, you should emit it now, and probably crash, or at least throw that stream away
20:18:25  <isaacs>creationix: read my zalgo post: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
20:18:30  <creationix>Domenic_, do suppose I have a transform that has N:M relationship between input and output
20:18:37  <isaacs>creationix: i'm willing to accept the performance hit RATHER than release zalgo
20:18:38  <Domenic_>isaacs: really? i mean, if the HTTP response cuts off in the middle, sure i should get notified if i'm piping that somewhere, but if I didn't pipe it anywhere yet, it seems fine not to tell me until the piping happens
20:18:40  <creationix>Domenic_, happens *all* the time with protocol parsers
20:19:06  <creationix>Domenic_, right, no events should fire if the stream hasn't been turned on
20:19:09  <isaacs>creationix: but, if we assume that releasing zalgo is off the table, because we are sane, then really, it's trading a cleaner API for a perf hit.
20:19:16  <creationix>and by turned on, I mean there are active event listeners
20:19:17  <isaacs>creationix: the cleaner API is desirable.
20:19:27  <isaacs>creationix: simpler to implement, etc.
20:19:42  <isaacs>creationix: and, if the perf hit is rare, then it's worthwhile.
20:19:51  <creationix>isaacs, by cleaner do you mean read() -> promise<value/end/error>/.
20:19:55  <Domenic_>well ok. but what if i consumed three chunks and the fifth chunk is a buffered error. why is it bad to save that error until i try to consume?
20:20:11  <isaacs>creationix: i mean read(function(value/end, error){})
20:20:12  <isaacs>but yes
20:20:28  <creationix>late errors are a royal pain
20:20:42  <creationix>isaacs, right same thing. When I say "promise" I mean all the syntax variants
20:20:50  <isaacs>creationix: ok.
20:21:01  <isaacs>Domenic_: when errors happen you want to handle them asap, generally
20:21:13  * rxgxjoined
20:21:27  <creationix>I don't actually like or use promises
20:21:29  <Domenic_>why. i don't care about the second half of the http request data (yet, or ever). why should i have that error pushed at me.
20:21:38  <creationix>Domenic_, so on late errors..
20:21:40  * tmcwjoined
20:21:56  <creationix>in js-git I've had several real bugs that were terribly hard to track down because of late errors
20:22:10  <creationix>suppose I'm implementing a protocol parser and I have a state-machine
20:22:14  <creationix>I implement it one step at a time
20:22:29  <creationix>when means there might not be the next READ to trigger the queued error
20:22:39  <creationix>so it just hangs and I don't know why till I implement the next step blindly
20:22:47  * rxgxquit (Client Quit)
20:22:55  <creationix>also it greatly complicates my event queues if I have multiple types of events to queue
20:23:00  <creationix>if it's just data events it's much easier
20:23:28  <creationix>in practice, I consider "end" and "error" two variants of the same event
20:23:34  <creationix>it means there won't be anything else from this stream ever
20:23:39  <creationix>the value tells me why
20:23:43  * timoxleyjoined
20:23:48  <creationix>either it was EOS or the socket disconnected or something else
20:24:49  <creationix>But yeah, there have been multiple times that my process silently died with no error when the cause was an Error instance stuck in some queue waiting for a read that never came
20:25:00  * timoxleyquit (Read error: Connection reset by peer)
20:25:02  <creationix>to me that's also Zalgo
20:25:33  * timoxleyjoined
20:26:28  <Domenic_>isaacs: do you agree?
20:26:44  <isaacs>creationix: i dunno, that's definitely some madness-inducing shit, but i'm not sure it's zalgo. some other demon, for sure :)
20:27:07  <isaacs>creationix: the thing about Zalgo is that in induces craziness even when everything's "working"
20:27:14  <creationix>for me it's more maddening than sync callbacks
20:27:25  <creationix>I've rarely ever been bitten by sync callbacks and I use them all the time
20:27:33  <isaacs>creationix: you are lucky :)
20:27:45  <creationix>maybe it's because of where my strengths are
20:27:49  <creationix>not everyone thinks like me
20:28:01  <isaacs>creationix: i've had to debug some gnarly production node stuff, where things are happening in the completely wrong order, and traced it to some zalgo stuff
20:28:03  <creationix>back in the early node days I would literally dream in callbaks
20:28:19  <isaacs>creationix: most of your code is mostly yours
20:28:20  <creationix>yeah, out-of-order is nasty
20:28:25  <creationix>isaacs, yep
20:28:41  <creationix>that's why I use mostly my code. I understand it
20:28:59  <creationix>anyway, I'm find with not allowing sync callbacks
20:29:06  <isaacs>creationix: zalgo is worst when it's person X's app, running on a framework written by person Y, on top of some bit of Node, which is like a hodgepodge of ryah, me, bnoordhuis, bert, tj, et al
20:29:42  <isaacs>zalgo callbacks are only acceptable in purely declarative languages
20:29:44  <creationix>isaacs, right, and my perspective is writing nasty nested statemachines for all kinds of crypto and git stuff by myself
20:29:46  * timoxleyquit (Ping timeout: 245 seconds)
20:29:55  <isaacs>creationix: your js is usually almost purely declarative
20:30:18  <isaacs>btw: node-glob is HEAVILY zalgo under the hood
20:30:31  <isaacs>but the exposed API is very carefully zalgo-containing
20:30:38  <creationix>right, to avoid zalgo
20:30:38  <creationix>never assume order
20:31:14  <creationix>so isaacs, Domenic_ do you agree that "end" and "error" are two values of the same thing?
20:31:21  <creationix>or are they fundamentally different?
20:31:34  <isaacs>creationix: yes, i think that they are similar
20:31:43  <Domenic_>creationix: I don't really know what the implications of that statement are, so I'm afraid to say yes.
20:31:47  <isaacs>creationix: in fact, you could just define some specific kind of sigil, and let it have different states or whatever.
20:32:18  <isaacs>creationix: one of my earlier sketches of a non-EE readable had a `stream.error` field, and if you called stream.read() and stream.error is set, it'd just return that error, forever.
20:32:39  <isaacs>so, a stream in an error state is a "stream of error objects" until the error is cleared.
20:32:42  <creationix>in simple streams I encode "end" as (falsy, undefined), "error" as (truthy, doesntmatter) and "data" as (falsy, not-undefined)
20:33:14  <Domenic_>it's not great for object streams to reserve special sigils (like undefined)
20:33:16  <isaacs>creationix: node streams use `null` s teh sigil
20:33:31  <isaacs>but yeah, it's nicer to object streams to not have some value be "end"
20:33:31  <Domenic_>the only real way to do that is with a separate "state" property, or with { done, value } tuples.
20:33:35  <creationix>Domenic_, but really, "undefined" as a stream value?
20:33:42  <isaacs>creationix: yes.
20:34:03  <creationix>of course all my streams are either data streams (binary/string) or object streams
20:34:07  <isaacs>creationix: imagine if you have a stream of objects, and most of them have "name" fields, and you want to convert that to a stream of names.
20:34:10  <creationix>undefined is never a value
20:34:12  <isaacs>creationix: "undefined" isa value
20:34:19  <isaacs>creationix: it means "this object doesn't have a name"
20:34:28  <isaacs>creationix: in fact, it may even be EXACTLY what yor'e looking for
20:34:34  <creationix>isaacs, true, I could see that
20:34:41  <isaacs>(speaking from experience using null/undefined in node, and causing some headaches for people)
20:34:51  <creationix>but there are other ways to encode
20:35:26  <isaacs>you could do the sync read() + state approach, and have read() thrwo on error.
20:35:50  <isaacs>try { data = s.read() } catch (er) { ohnoes }
20:35:55  <isaacs>but.. ugh.
20:35:58  <creationix>dominictarr does "end" == (true), "error" == (other-truthy), "data" == (falsy, data)
20:36:12  <tilgovi>having trouble with browserify's b.require() API. the result doesn't seem to create a require() function on the page
20:36:16  <creationix>yeah, that's nasty, unless you're cool with exceptions like in domains
20:36:23  <tilgovi>anyone familiar?
20:36:37  <thlorenz>tilgovi: do you have sample code somewhere?
20:36:40  <isaacs>creationix: well, it means that you have to wrap EVERY call to read() in a try/catch
20:36:55  <tilgovi>thlorenz: I would have to extract it a bit
20:37:01  <tilgovi>just wondering if I'm doing anything immediately wrong.
20:37:12  <thlorenz>tilgovi: just make a quick gist -- then we can help you
20:37:20  <Domenic_>isaacs: that seems equivalent to read(cb) in terms of how it forces you to handle errors
20:37:20  <tilgovi>I can try
20:37:26  <creationix>honestly, this encoding problem is one of the reasons I'm looking for something other than simple-streams
20:37:32  * aslantjoined
20:37:36  <creationix>if you have seperate ondata and onend handlers, it's very clear
20:37:36  <tilgovi>there's just a lot more going on
20:37:53  <isaacs>Domenic_: yeah
20:37:58  <creationix>ondata will be called zero or more times, and onend is the continuation
20:38:00  <isaacs>Domenic_: but, at least, there's no "error" sigil
20:38:02  * ferossjoined
20:38:05  <creationix>which may or may not have an error
20:39:28  <creationix>ok, new question, how important is it to be able to change the data handler on the fly?
20:39:47  <tilgovi>a thlorenz, while you're here
20:39:50  <creationix>suppose I want function a to handle data for a few chunks, but later I want to switch it?
20:40:15  <tilgovi>I had some problems with source-map-combine (I think it was combine, and not convert)
20:40:29  <tilgovi>yeah, combine. if the input has a source map already, you only take the first source
20:40:32  <tilgovi>would you like a PR to fix that?
20:40:38  <thlorenz>tilgovi: could you file an issue?
20:40:42  <tilgovi>sure
20:40:48  <tilgovi>at least then it's not lost
20:41:04  <thlorenz>tilgovi: I like PRs that fix things :) as long as they come with tests
20:41:19  <tilgovi>speaking of, if you're on browser-pack, I just submitted one such
20:48:07  <creationix>isaacs, I know, declarative, closure based streams!
20:48:20  <creationix>force everyone to think like me
20:48:25  <creationix>;)
20:48:33  <isaacs>creationix: declarative closure based streams is not a bad idea.
20:48:36  <isaacs>creationix: sketch it up
20:48:38  <creationix>ok
20:48:50  <isaacs>creationix: but without sigils, or events
20:49:05  <isaacs>creationix: the problem usually is that closures are often very hard to optimize
20:49:30  <isaacs>creationix: classy oop approaches are easier to get your head around, especially if your head is V8 or SpiderMonkey
20:49:54  <rowbit>substack, pkrumins: These encoders are STILL down: 50.57.226.209(free4)
20:50:51  <creationix>isaacs, right, I get a lot of push back about performance any time I mention that style
20:51:16  <creationix>and the annoying this is that V8 and others *could* optimize for it if they wanted to. But they don't because nobody writes that style. Nobody writes that style because they don't optimize for it.
20:51:28  <Raynos>creationix: whats the encoding problem?
20:51:33  <isaacs>creationix: well, that's not the only reason :)
20:51:54  <creationix>isaacs, and it's not the way programming is generally taught
20:51:56  <isaacs>creationix: but it's still useful to sketch, even if it's just an example, and we then refactor its Good Parts back to a classy api
20:52:01  <creationix>most people start with C++ and Java classes
20:52:22  <isaacs>creationix: i've been doing functionals and closures for a long time. part of the thing that sucks about it in production is that your state is too hidden
20:52:25  <isaacs>it's TOO encapsulated :)
20:52:34  <creationix>yeah, it's pretty private
20:52:37  <isaacs>and tooling hasn't caught up well
20:52:46  <creationix>both feature and problem
20:52:51  <isaacs>plus, it's way too easy to leak large amounts of memory
20:53:09  <isaacs>all FP languages have this problem, but most advocates are resistant to talking about it
20:53:26  <creationix>actually I tend to leak less because there tend to not be cycles
20:53:26  <creationix>break a reference one way and there aren't others to worry about
20:53:41  <creationix>also I don't tend to write huge programs
20:53:50  <isaacs>creationix: but it's hard to read a program and easily grok how much is being held by what
20:53:57  <creationix>right
20:54:14  <isaacs>when you see an object with a zillion members, you go "Oh... hm. That's probably not great."
20:54:14  <creationix>isaacs, you've seen my sink interface right?
20:54:34  <creationix>sink(readable, callback)
20:54:39  <isaacs>creationix: i thought you just had the normal kind, with the faucet and the little thingie to open the drain...?
20:55:31  <creationix>actually the faucet is not part of the sink
20:55:31  <creationix>that's more like a transform
20:55:31  <creationix>the sink only consumes/drains
20:57:22  <creationix>hmm, not sure my closure idea was a good one
20:57:32  <creationix>streams have too much surface area on both sides
20:57:52  <creationix>both producer and consumer need to initiate communication on their own at various times
21:01:18  * st_lukequit (Remote host closed the connection)
21:02:59  * jxsonjoined
21:05:01  * jxsonquit (Remote host closed the connection)
21:05:08  * jxsonjoined
21:05:29  * thlorenz_joined
21:07:19  <creationix>Domenic_, ok, so abstractly producer needs to send consumer (DATA, END, ERROR) and consumer needs to send producer (PAUSE, RESUME, ABORT, ERROR)
21:09:04  <creationix>I think END/ERROR can be combined into just END and ABORT/ERROR into just ABORT.
21:09:46  * thlorenz_quit (Ping timeout: 245 seconds)
21:11:24  <rowbit>substack, pkrumins: These encoders are STILL down: 173.203.67.76(free3)
21:15:12  * ferossquit (Quit: feross)
21:16:45  <rowbit>Hourly usage stats: [developer: 0, free: 18]
21:17:02  <Raynos>creationix: Agreed, { DATA, END } + { PAUSE, RESUME, ABORT }
21:26:20  * timoxleyjoined
21:31:12  * mikolalysenkoquit (Ping timeout: 246 seconds)
21:31:30  * timoxleyquit (Ping timeout: 289 seconds)
21:32:06  <creationix>Raynos, it's finally starting to become clear
21:32:06  <creationix>still not sure what's the best concrete syntax though
21:32:06  <creationix>event handlers are ugly
21:32:06  <creationix>but this is truly two-way communication
21:33:54  <rowbit>substack, pkrumins: Encoders down: 173.203.67.76 (free3)
21:34:35  * calvinfojoined
21:35:11  <Raynos>creationix: https://gist.github.com/Raynos/7272324
21:35:20  <Raynos>that's the simplest possible API i can think of to achieve it
21:39:06  <Raynos>creationix: I forgot about errors
21:42:31  <Raynos>creationix: so more like https://gist.github.com/Raynos/7272324
21:42:36  <Raynos>which just exploded in surface area
21:45:32  <defunctzombie>substack: does testling support server stuff yet?
21:46:34  * mikolalysenkojoined
21:46:39  * jcrugzzchanged nick to jcrugzz|afk
21:47:52  * ferossjoined
21:48:38  <creationix>Raynos, here is my take. One with no helpers and one with setup functions https://gist.github.com/creationix/7270104#minimalist
21:49:06  <creationix>hmm, I should adda pipe example
21:52:11  <creationix>wow, that was easy
21:52:15  <creationix>I sure love this symmetry
21:52:35  <creationix>Domenic_, isaacs check this out^
21:53:51  <creationix>Raynos, as much as I love the readable-only-using-sinks idea, it's been hard to use in practice
21:54:13  <creationix>and with this simple, symmetric interface for readable and writable, piping them together is super cheap.
21:54:24  <Domenic_>creationix: that is pretty interesting. those TODOs seem somewhat crucial, but, I guess they'd be parameters to the makeReadable/makeWritable?
21:54:47  <creationix>right, I left out a lot of implementation details
21:55:32  <creationix>based on my experience, it shouldn't be any worse than any of the other interfaces I've tried.
21:57:11  <creationix>and for substack's concern of being notified when the pipe is done, it can simply take a third param that taps into both readable.abort and writable.end and notifies when one of them happens.
21:57:14  <Domenic_>creationix: I don't quite get the correspondence between the first set of object literals and the things returned by your functions.
21:57:33  <creationix>Domenic_, so in the first set, I just left placeholders for the event handlers
21:57:50  <creationix>in the second I replaced them with a setup function that accepts the two functions
21:58:03  <creationix>I like the second better, it's cleaner
21:58:10  <creationix>and gives a place to hook init code
21:58:14  <Domenic_>the second and the first use completely different property names
21:58:34  <Raynos>creationix: I think ERROR & FINISH are important too
21:59:15  <creationix>Domenic_, readable in the first has {onwrite, onend, flow, abort} the second has {produce, flow, abort{
21:59:27  <creationix>onwrite,onend is replaced with produce(onwrite, onend)
21:59:41  <Domenic_>creationix: so the first is just confusing then.
22:00:01  <Domenic_>i think i see
22:00:11  <Raynos>creationix: do you have examples of where readable-only-using-sinks is hard in practice?
22:00:21  <Raynos>creationix: I've found it very clean for writing filters & transforms
22:00:27  <Domenic_>so produce is not actually a method you would call as a consumer
22:00:37  <Raynos>or is it a hard in practice because of closures and ffs we need more OOP for performance
22:00:53  <creationix>Raynos, don't I have that?
22:00:53  <creationix>Domenic_, perhaps in docs I should put the common properties first so it's more obvious
22:01:13  <creationix>Raynos, right, it's clean for most stuff
22:01:17  <creationix>Raynos, but nasty complicated for certain cases
22:01:22  <Domenic_>creationix: I think the promise constructor-like pattern I use in the whatwg/streams readme makes this much clearer
22:01:36  <Domenic_>i.e. new ReadableStream(function onRead(push, end, error) { ... })
22:01:41  <creationix>in js-git where I'm writing protocol commands to negotiate pack-file contents it's a mess
22:01:48  <Raynos>creationix: you dont explain how active is bad
22:02:39  <creationix>Domenic_, which syntax? I can adjust I think
22:02:43  <Domenic_>creationix: from what I am gathering produce is qualitatively different from flow and abort; you would do `new ReadableStream(function produce(onWrite, onEnd) { ... }) and the resulting object would have .flow and .abort
22:03:00  <Raynos>creationix: what makes it a mess ?
22:03:04  <creationix>Domenic_, yes!
22:03:24  <creationix>Domenic_, both readable and writable need to accept callbacks at setup and return handles
22:03:31  <creationix>constructor is probably a lot cleaner for this
22:03:33  <Domenic_>creationix: awesome, that sounds nice.
22:03:55  <creationix>Plus with constructors you could inherit a tiny pipe helper if you wanted
22:04:09  <Domenic_>it seems like the correct way to do "privileged access to internal operations" as opposed to Node's "derive a class and overwrite underscored-methods"
22:04:11  <creationix>though binding would be a problem
22:04:51  <creationix>Raynos, it's kinda hard to explain because it's been several weeks
22:05:30  <creationix>Raynos, but basically it's cases where I'm writing data to a filter that eventually goes to a TCP sink
22:05:31  <creationix>but I write the data based on program events, not based on some other input stream
22:05:34  <creationix>like state machine outputs in some protocol logic
22:06:06  * thlorenz_joined
22:06:16  <creationix>Domenic_, ok, I'll write a constructor version. That should be a lot cleaner...
22:10:26  * thlorenz_quit (Ping timeout: 245 seconds)
22:10:45  <creationix>Domenic_, what about instead of passing in (onWrite, onEnd) we pass in an object containing {write,end} so that "this" scope can be preserved without creating bound functions?
22:10:45  <creationix>the less functions we create the better
22:10:54  <creationix>also they could update their write function dynamically and we'd get the update
22:11:39  * thlorenzquit (Remote host closed the connection)
22:12:32  * AvianFluquit (Remote host closed the connection)
22:14:19  * Maciek416quit (Remote host closed the connection)
22:14:51  * Maciek416joined
22:15:36  <Domenic_>creationix: hmm probably good? not sure i completely understand but worth looking at.
22:16:03  <Domenic_>creationix: unfortunately i think i have to stop paying attention to IRC for a while, running out of steam for the day and lots of real-job work still to do :(
22:16:35  <creationix>Domenic_, ok, take care
22:16:45  <rowbit>Hourly usage stats: [developer: 9, free: 19]
22:17:01  <Domenic_>creationix: you too, very fruitful day I feel. really looking forward to being able to work on this stuff tomorrow for reals.
22:17:19  * Maciek416_joined
22:17:24  * tmcwquit
22:19:11  * Maciek416quit (Ping timeout: 240 seconds)
22:26:04  * Maciek416_changed nick to Maciek416
22:27:03  * timoxleyjoined
22:31:55  * timoxleyquit (Ping timeout: 272 seconds)
22:42:31  * thlorenzjoined
22:50:39  * thlorenzquit (Ping timeout: 246 seconds)
22:55:36  * thlorenzjoined
23:15:07  * DTrejoquit (Remote host closed the connection)
23:15:43  * DTrejojoined
23:16:45  <rowbit>Hourly usage stats: [developer: 1, free: 25]
23:19:53  * DTrejoquit (Ping timeout: 240 seconds)
23:20:09  * defunctzombiechanged nick to defunctzombie_zz
23:23:11  * AvianFlujoined
23:23:31  * AvianFlu_joined
23:24:09  * AvianFlu_quit (Remote host closed the connection)
23:27:33  * AvianFluquit (Ping timeout: 240 seconds)
23:27:39  * ralphtheninjaquit (Quit: leaving)
23:27:46  * timoxleyjoined
23:31:00  * ferossquit (Quit: feross)
23:32:22  * DTrejojoined
23:32:27  * timoxleyquit (Ping timeout: 272 seconds)
23:36:04  * mikolalysenkoquit (Ping timeout: 260 seconds)
23:37:25  * DTrejoquit (Ping timeout: 272 seconds)
23:39:16  * thlorenzquit (Remote host closed the connection)
23:41:10  * cianomaidinjoined
23:42:04  * yorickquit (Remote host closed the connection)
23:52:44  * ferossjoined
23:59:09  <Raynos>spion: see answers :D