New Issue: I/O: relationship between Encoder/Decoder and channel

18504, "jhh67", "I/O: relationship between Encoder/Decoder and channel", "2021-09-30T23:16:10Z"

Issue #18499 proposes new Encoder/Decoder functionality. This issue addresses the relationship between the encoders/decoders and channels (for brevity I will use the term "encoder" to mean "encoder/decoder"). As described in #18499 the encoder has an associated channel so that all operations on the encoder result in I/O to/from the channel. As an example:

record Employee {
	var name: string;
	var id: int;
}

proc Employee.encodeTo(encoder: borrowed Encoder) throws {
	encoder.encode(key="name", name);
	encoder.encode(key="id", id);
}

var encoder = new JSONEncoder(…);
var bob = new Employee("Bob", 1);
encoder.encode(bob);  // {"name": "Bob", "id": 1}

This example has the effect of writing {"name": "Bob", "id": 1} to the channel. The channel would be passed as one of the arguments to JSONEncoder(). The advantage of this approach is that it allows multiple encoders to be used on one channel. This would be useful if the file contains multiple formats, e.g. only some of the data are in JSON.

An alternative is to associate the encoder with the channel so that all I/O to/from the channel goes through the encoder. As an example

record Employee {
	var name: string;
	var id: int;
}

proc Employee.encodeTo(encoder: borrowed Encoder) throws {
	encoder.encode(key="name", name);
	encoder.encode(key="id", id);
}

var writer = openfile.writer(encoder = JSONEncoder);
var bob = new Employee("Bob", 1);
writer.write(bob); // {"name": "Bob", "id": 1}

The advantage of this approach is that it allows the same encoder instance to be used across multiple channels.

Open Questions

  • Should a channel have a default encoder,e.g. Should write(myCustomRecord) call ‘encodeTo’ with some kind of default encoder?
    • In other words, how does read / write on a channel interact with the Encoder / Decoder?
    • Probably need something like this for writeln(myrecord) to work
    • Probably only makes sense for the second option above in which channels have associated encoders
  • Could/should we deprecate writeThis/readThis/readWriteThis?
    • A type could specify which fields are to be encoded in encodeTo.
    • A type could use tertiary methods on a DefaultEncoder to customize output.