std.serialization: pre-voting review / discussion

Tyler Jameson Little beatgammit at gmail.com
Mon Aug 19 20:42:46 PDT 2013


On Monday, 19 August 2013 at 18:06:00 UTC, Johannes Pfau wrote:
> Am Mon, 19 Aug 2013 16:21:44 +0200
> schrieb "Tyler Jameson Little" <beatgammit at gmail.com>:
>
>> On Monday, 19 August 2013 at 13:31:27 UTC, Jacob Carlborg 
>> wrote:
>> > On 2013-08-19 15:03, Dicebot wrote:
>> >
>> >> Great! Are there any difficulties with the input?
>> >
>> > It just that I don't clearly know how the code will need to 
>> > look like, and I'm not particular familiar with implementing 
>> > range based code.
>> 
>> Maybe we need some kind of doc explaining the idiomatic usage 
>> of ranges?
>> 
>> Personally, I'd like to do something like this:
>> 
>>      auto archive = new XmlArchive!(char); // create an XML 
>> archive
>>      auto serializer = new Serializer(archive); // create the 
>> serializer
>>      serializer.serialize(foo);
>> 
>>      pipe(archive.out, someFile);
>
> Your "pipe" function is the same as 
> std.algorithm.copy(InputRange,
> OutputRange) or std.range.put(OutputRange, InputRange);

Right, for some reason I couldn't find it... Moot point though.

> An important question regarding ranges for std.serialization is 
> whether
> we want it to work as an InputRange or if it should _take_ an
> OutputRange. So the question is
>
> -----------------
> auto archive = new Archive();
> Serializer(archive).serialize(object);
> //Archive takes OutputRange, writes to it
> archive.writeTo(OutputRange);
>
> vs
>
> auto archive = new Archive()
> Serializer(archive).serialize(object);
> //Archive implements InputRange for ubyte[]
> foreach(ubyte[] data; archive) {}
> -----------------
>
> I'd use the first approach as it should be simpler to 
> implement. The
> second approach would be useful if the ubyte[] elements were 
> processed
> via other ranges (map, take, ...). But as binary data is usually
> not processed in this way but just stored to disk or sent over 
> network
> (basically streaming operations) the first approach should be 
> fine.

+1 for the first way.

> The first approach has the additional benefit that we can 
> easily do
> streaming like this:
> ----------------
> auto archive = new Archive(OutputRange);
> //Immediately write the data to the output range
> Serializer(archive).serialize([1,2,3]);
> ----------------

This can make a nice one-liner for the general case:

Serializer(new Archive(OutputRange)).serialize(...);

> Another point is that "serialize" in the above example could be
> renamed to "put". This way Serializer would itself be an 
> OutputRange
> which allows stuff like 
> [1,2,3,4,5].stride(2).take(2).copy(archive);
>
> Then serialize could also accept InputRanges to allow this:
> archive.serialize([1,2,3,4,5].stride(2).take(2));
> However, this use case is already covered by using copy so it 
> would just
> be for convenience.

This is nice, but I think I like serialize() better. I also don't 
think serializing a range is it's primary purpose, so it doesn't 
make a lot of sense to optimize for the uncommon case.


More information about the Digitalmars-d mailing list