<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 2, 2015 at 8:06 AM, Chris Cunnington <span dir="ltr">&lt;<a href="mailto:brasspen@gmail.com" target="_blank">brasspen@gmail.com</a>&gt;</span> wrote:<br><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div></div><div>I do not have a mental model for what Xtreams is doing yet. How do other people conceptualize using Xtreams in contrast to the existing Streams implementation? </div></div></blockquote><div><br></div><div>I think the elegance of Xtreams boils down to one thing: composition is better than inheritance. </div><div><br></div><div>If you look at the Squeak stream hierarchy, it&#39;s a nightmare. Among the highlights:</div><div><br></div></div></div><div class="gmail_extra"><div class="gmail_quote"><ul><li>There&#39;s a whole subhierarchy dedicated to compression. It successfully shares code for different types of compression but since DeflateStream inherits from PositionalStream, it can only write compressed data into memory. If you want to write compressed data to a file, you&#39;ll have to write to a compression stream, get its contents and write that to a file stream.</li><li>On the flip side, there&#39;s CrLfFileStream, which converts line endings when reading and writing to a file. Except wait, it&#39;s obsolete now and <font face="times new roman, serif">CrLfFileStream new</font><font face="arial, helvetica, sans-serif"> actually returns an instance of MultiByteFileStream. This class has an annoying name, because it&#39;s camel-cased on syllable boundaries as well as word boundaries. Ugh. Worse, it combines line-end conversion with encoding conversion, but only when it text mode. Well, most of the time, when in text mode. You gotta be careful about those few methods that manipulate the file position in terms of bytes, because that can leave it in the middle of a multibyte character and then nothing works right. And if you want to do any of this conversion on data in memory, you&#39;re outta luck because </font><span style="font-family:arial,helvetica,sans-serif">MultiByteFileStream only works on data in files.</span></li><li><font face="arial, helvetica, sans-serif">Luckily MultiByteBinaryOrTextStream is here to save the day. (Again with the capitals on syllable breaks.) It *does* work on data in memory. It has a whole separate implementation of the encoding and line-ending conversion code, plus no-nops implementations of the file-related stuff in </font><span style="font-family:arial,helvetica,sans-serif">MultiByteFileStream so the two are polymorphic. So convenient.</span></li><li><font face="arial, helvetica, sans-serif">There&#39;s also ReadWriteStream, which subclasses WriteStream, and re-implements all of ReadStream&#39;s functionality.</font></li><li><font face="arial, helvetica, sans-serif">There&#39;s also SocketStream, for convenience in doing network IO. Oh wait, it&#39;s not part of the Stream hierarchy at all. Never mind.</font></li></ul><div><font face="arial, helvetica, sans-serif">There&#39;s more (lots more), but let&#39;s not get sidetracked. The point is that there is just no way to have a sane inheritance hierarchy for a whole bunch of orthogonal concerns:</font></div><div><ul><li><font face="arial, helvetica, sans-serif">the underlying data storage - memory, file, socket or something more exotic</font></li><li><span style="font-family:arial,helvetica,sans-serif">data transformation - encoding, compression, buffering, chunking etc</span></li><li><font face="arial, helvetica, sans-serif">reading vs writing</font></li></ul><font face="arial, helvetica, sans-serif">Where Squeak streams try to do everything in one object, and combine different options via inheritance, Xtreams splits a stream into a pipeline of objects that each provide a separate bit of functionality. It&#39;s so much more flexible.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">In the specific case of Altitude, Xtreams provide two main advantages:</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">First, the framework can build a custom pipeline of streams based on message headers. To handle a request, we just examine the headers, build the appropriate sequence of transformation streams and hand that off to the application for reading. When the response is ready, we again look at the headers, build a stream that performs all the transformations that the app has indicated it wants, and let the app write into it. We can use any of the features of HTTP, while still providing a simple and consistent interface to the app.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Second, it really helps with perceived performance. Browsers have incredibly optimized strategies for processing data as it arrives from the network. They&#39;re really good at rendering a page incrementally, adding content and refining the appearance as more data arrives. Xtreams allows Altitude to take advantage of that by doing the same thing on the server side. As the app is rendering content, we push it through the transformation streams in small chunks, and get it on the network as quickly as possible. (ALStreamingExample is a good demo of this.)</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Of course, there&#39;s a lot of other little details to like about Xtreams, I think composition is what really makes it shine.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Colin</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div></div></div></div>