New syntax for string mixins

Jacob Carlborg doob at me.com
Thu Dec 16 10:06:53 PST 2010


On 2010-12-15 00:19, Graham St Jack wrote:
>
>> I don't know, do you have an example ?
>>
>>> For example taking a classname and a bunch of field types and names, and
>>> turning it into a class definition complete with constructor from field
>>> values, constructor from an input stream, a method to write to an output
>>> stream, and const getters. Or maybe std.typecons.AutoImplement.
>>
>> Could you post an example of how that mixin would be used and the code
>> it would generate then I can see if I can translate it to my syntax.
>> AutoImplement seems to just contain template mixins which is something
>> else.
>>
>
> I have attached my concurrency framework, which relies heavily on
> mixins, plus its unit test to show how it is used. I haven't included
> the various dependencies because I assume you just want the example
> code. Let me know if you want something buildable, or perhaps something
> more cut-down.
>
> What the code-generating template does is to create from something like
> this (you can have any number of Messages in a Protocol):
>
>
> alias Protocol!("Requests", Message!("job", string, "name")).code jobCode;
> mixin(jobCode);
>
>
> this code:
>
>
> class Requests {
> struct jobMsg {
> string name;
> this(string name) {
> this.name = name;
> }
> void read(InStream stream) {
> name = stream.get!string;
> }
> void write(OutStream stream) {
> stream(name);
> }
> }
> struct Message {
> uint kind;
> union {
> jobMsg job;
> }
> this(ref jobMsg msg) {
> kind = 0;
> job = msg;
> }
> this(InStream stream) {
> kind = stream.get!uint;
> switch(kind) {
> case 0: job.read(stream); break;
> default: assert(0, "Cannot read unsupported message kind");
> }
> }
> void write(OutStream stream) {
> stream(kind);
> switch(kind) {
> case 0: job.write(stream); break;
> default: assert(0, "Cannot write unsupported message kind");
> }
> }
> }
> private alias Channel!(Message) _Chan;
> private alias shared _Chan Chan;
>
> private Chan channel;
> this() { channel = new Chan(); }
> ChannelSelectable newSelectable() { return channel.newSelectable(); }
> void finalize() { channel.finalize; }
>
> interface IHandler {
> void job(string name);
> }
> void job(string name) {
> channel.add(Message(jobMsg(name)));
> }
> void receive(IHandler handler) {
> auto message = channel.remove;
> switch (message.kind) {
> case 0: handler.job(message.job.name); break;
> default: assert(0, "Cannot dispatch unsupported message kind");
> }
> }
> }
>
>
>
> I use this for inter-thread communications, and I use the discriminated
> union to pass messages between processes. The manual mixin after the
> alias is a debugging aid - the compiler errors when doing mixins aren't
> helpful at all. I case you are wondering why I did all this, it was
> partly a learning experience, but mostly an attempt to do something
> properly thread-safe (!hasAliasing), using shared, const and immutable
> properly.

I've attached a part of how concurrency.d could look like translated to 
my suggested syntax. It probably contains a lot of errors because did a 
quick translation and I had some trouble understanding the mixins.

-- 
/Jacob Carlborg
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: concurrency.d
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20101216/553272e0/attachment.ksh>


More information about the Digitalmars-d mailing list