[Pharo-project] XTream was Re: Ocean (was Re: Less plugins, more Smalltalk code!)

mkobetic at gmail.com mkobetic at gmail.com
Fri Oct 8 19:12:16 EDT 2010


"Nicolas Cellier"<nicolas.cellier.aka.nice at gmail.com> wrote:
> More example than the site http://code.google.com/p/xtreams/ ? If so, I'm interested.

Not more, but different. For example I'm quite fond of the Morse code decoding example:

	('. ... ..- --.  -... .- .-. -.-. . .-.. --- -. .-  -- -- -..- ' reading
		transforming: [ :in :out || node beep |
			node := MorseTree.
			[	beep := in get.
				beep = Character space 
			] whileFalse: [
				node := beep = $.
					ifTrue: [ node at: 3 ]
					ifFalse: [ node at: 2 ] ].
			out put: node first ]
	) rest

Where MorseTree is (http://en.wikipedia.org/wiki/File:Morse_code_tree3.png) encoded as nested three element arrays: #($ ($T ($M ($O) ($G ($Q) ($Z))) ($N ($K ($Y) ($C)) ($D ($X) ($B)))) ($E ($A ($W ($J) ($P)) ($R () ($L))) ($I ($U () ($F)) ($S ($V) ($H)))))

Anyway, I'll send you the PDF directly.

> Yes, that makes sense, what I call the Xtreme approach... Less confusion.
> However it would be wonderfull to get feedback from average programmer
> about this on real application.

Not sure what you meant.

> Maybe this will be a matter of adding one missing convenient message or two...

Yes we can certainly add a package that implements most (maybe all) of the classic API as an extension. But I'd rather keep the Core clean and minimal. This way you have the choice of both.

> Of course the best option is to share. Though I don't think Xtream was
> developped with portability as main goal, it's not sure it has so many
> external dependencies.

Yes, we didn't spend much time thinking about portability so far. We rewrote the whole thing bottom up several times trying to get the design right, so we didn't want to be distracted by other concerns. That doesn't mean that we can't focus on that now assuming we're reasonably happy with current design. I don't think there are particular dependencies that are critical to make Xtreams work in general. As long as we can preserve the efficiency, we can certainly make necessary changes.

That said, I think we'll just have dialect specific versions of some of the packages. Hopefully Xtreams-Core can be fully portable. Xtreams-Terminals are likely going to be dialect specific. Xtreams-Transforms could probably be portable if we move the VW specific encoding stuff elsewhere. Maybe it can just go into Xtreams-Xtras. It was nice to have the encodings with the core transforms but until we have portable encoders we can just maintain those in dialect specific packages. Something like that.

> Is there a tool to identify the dependency on classes outside the package in VW ?

Yes there is a tab in the browser that autocomputes prerequisites and a menu option that gives you depenedents if you want the other direction.

> We know in advance a few concerning the system, File & Sockets, DLLCC, compression...

Yes, I would expect each dialect to have it's own implementation of most of the terminal streams. It might be possible to share some of those, e.g. collection or buffer streams, but given that different dialects have different ways to deal with them efficiently, we may want to have dialect specific implementations anyway. Ultimately, it's fine if different dialects support different set of terminals. There will probably be some that we want everywhere, but maybe it would be great to be able to stream over some Morphs in Squeak or something such. If that's useful, there's no reason not to do it because VW doesn't have Morphic. Anyway, the point is not all the code has to be portable, we can try to share as much as is feasible and have dialect specific implementation of the rest.

So at least initially, I'd focus on getting a portable Core and Transforms, with dialect specific Terminals, and we can think about stuff in Xtras later.

> Then, there is the question of using Exception handling or not. In
> Squeak, this isn't going to be a matter of compatibility (though the
> difference might be subtle), rather a matter of efficiency.
> However, Incomplete is a corner stone of Xtream implementation if I
> understand correctly...
> Squeak is not using EndOfStream
> http://bugs.squeak.org/view.php?id=6755 and some of the efficiency
> reasons are there
> http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-November/122434.html
> 
> On the other hand, the endOfStreamAction of Squeak_Xtream is pleasant
> at first, but hard to handle across wrappers. I don't yet have an
> answer whether it scales on a more complete xtream library or not
> (thinking of blocking streams...).

Yes, this one is tricky. Exceptions cost something in VW as well, so you need to be reasonably prudent with them. As Michael mentioned we've made some serious adjustments in Xtreams earlier this year to avoid triggering Incomplete internally if we could get by without it. See

http://www.cincomsmalltalk.com/userblogs/mls/blogView?entry=3445952077
http://www.cincomsmalltalk.com/userblogs/mls/blogView?entry=3448891140

But I think your original argument that in common case the exception should not be triggered frequently is valid. Certainly if you write a micro-benchmark which stacks the odds the other way it will show, but as they say  micro-benchmarks are not applications. At the same time consider the cost of not using an exception. Exception allows me to write my algorithm without worrying about the end of stream if I wrap the whole thing in a handler. And the handler is normally located in the right place to handle the end of stream. Without the exception you'll have to add end checks to every single read call of the algorithm. I'm not talking about runtime cost here, I'm talking code complexity. And I don't see how an "end of stream block" makes this much better. The exception allows me to get out of the main body of the algorithm at any of its points, and if the handler exits, the main block gets unwound cleanly. How do I do that with a block that I set on the stream instance? You'd have to carefully structure the code so that the algorithm body is in a method of its own and then there's a dedicated wrapper method around that so that the block can use a side-ways return to exit the method. That is some pretty hideous boiler-plate code, if you ask me.f

So, I'm not saying that exception costs are negligible, but there are often ways to minimize them in specific scenarios, often via well designed APIs and patterns (and proper internal implementation). As Michael's posts above show, we were able to match and beat the speed of regular streams in the example without sacrificing the API. At the same time Squeak is getting faster, so I'm not at all convinced that the slow-down factor always does and always will trump the other costs. In fact I feel that it's more often than not the other way around, that the slow down can be made sufficiently small so that it does pay off in terms of code complexity. Maybe some things will always want a stream that doesn't trigger exceptions, but that doesn't mean most things are better off that way. That's just my opinion.

Anyway, so far we've been doing quite well in terms of performance without sacrificing exceptions. I'd say let's see if we can keep that track record on Squeak as well. If we find out that it's just not good enough in general case, maybe we'll re-evaluate then. But at this point I'm not convinced that we need to drop the exception to keep Xtreams reasonably usable.

Martin




More information about the Pharo-dev mailing list