Jump to page: 1 25  
Page
Thread overview
I want to add a Phobos module with template mixins for common idioms.
May 06, 2013
Idan Arye
May 06, 2013
Diggory
May 06, 2013
Idan Arye
May 06, 2013
Idan Arye
May 06, 2013
Idan Arye
May 07, 2013
Jacob Carlborg
May 06, 2013
Robert Rouse
May 06, 2013
Idan Arye
May 07, 2013
Dicebot
May 07, 2013
Idan Arye
May 07, 2013
Dicebot
May 07, 2013
Idan Arye
May 08, 2013
Idan Arye
May 10, 2013
Idan Arye
May 11, 2013
Diggory
May 13, 2013
Tove
May 18, 2013
Idan Arye
May 19, 2013
Diggory
May 19, 2013
Idan Arye
May 19, 2013
Diggory
May 19, 2013
Idan Arye
May 19, 2013
Idan Arye
May 20, 2013
Diggory
May 20, 2013
Idan Arye
May 20, 2013
Diggory
May 20, 2013
Idan Arye
May 20, 2013
Dmitry Olshansky
May 20, 2013
Idan Arye
May 20, 2013
Dmitry Olshansky
May 20, 2013
Idan Arye
May 20, 2013
Diggory
May 21, 2013
Idan Arye
May 21, 2013
Dmitry Olshansky
May 21, 2013
Idan Arye
May 21, 2013
Idan Arye
May 21, 2013
Idan Arye
May 22, 2013
Idan Arye
May 24, 2013
Dmitry Olshansky
May 24, 2013
Jonathan M Davis
May 24, 2013
Dmitry Olshansky
May 24, 2013
Jonathan M Davis
May 24, 2013
Idan Arye
May 24, 2013
Idan Arye
May 20, 2013
Jesse Phillips
May 20, 2013
Jesse Phillips
May 20, 2013
Idan Arye
May 06, 2013
Template mixins can be used to implement some common programming idioms(and design patterns). I have already implemented two of them for my own project - and I want to make them into a Phobos module - maybe `std.mixins`. The wiki at http://wiki.dlang.org/Review/Process says that before I start a new module contribution, I should post here to see if the community actually wants it, so this is what I'm doing.

The first one is the property idiom - a pair of getter and setter methods used to mutate a private member field. I have created four variants:
`propertyGetterOnly` - creates only the field and the getter.
`property` - creates the field, a getter and a setter.
`propertyAsserted` - creates the field, a getter and a setter that verifies it's input using an assert.
`propertyVerified` - creates the field, a getter and a setter that verifies it's input using an `if` statement and throws `PropertyException` if you try setting it to a bad value.

For example:

    class Foo
    {
        //Add an `int` property with value of 44, that can not exceed 60.
        mixin propertyVerified!(int, "x", `a <= 60`, 44);
    }

    Foo foo = new Foo();
    writeln(foo.x); //Prints 44
    foo.x = 55;
    writeln(foo.x); //Prints 55
    foo.x = 66; //throws PropertyException


The second idiom is the singleton pattern. I implemented it using the check-lock-check version, but I want to change the implementation to Dave's and Alexander Terekhov's low lock version(http://forum.dlang.org/thread/pelhvaxwjzhehdjtpsav@forum.dlang.org). At any rate, it'll be used like this

    class Foo
    {
        mixin lowLockSingleton!false;

        private this(/*args*/)
        {
            ...
        }

        void init(/*args*/)
        {
            singleton_initInstance(new Foo(/*args*/));
        }
    }

The `false` sent to `lowLockSingleton` means you don't want to automatically initialize your singleton when someone request an instance before it was initialized - this is useful if you want to send initialization arguments. You could set it to `true`(which will be the default) and get a regular singleton, but I want to elaborate on this version. `lowLockSingleton` creates a private static method named `singleton_initInstance` which accepts a lazy argument for constructing the global instance. You need to implement your own initialization method, which should call `singleton_initInstance` to set the global instance based on initialization arguments. The `lowLockSingleton` implementation will make sure that only one call to `singleton_initInstance` will invoke the lazy argument and set the global instance to it's result.

I also want to implement a thread local singleton. That's it for now, but I think that's enough to justify a new module and once this module is up and running I'm sure other people will have other common and why-the-heck-is-this-not-common idioms to add.



The rationale behind having those template mixin is laziness. I'm a lazy programmer, and I know I'm not the only one.

I *know* I should use properties, and I know why, but it's so much easier to just use public fields. If I'll need getter&setter properties I can always change it later for just the fields where I need it, and if someone else needs them than it's their problem, not mine.

I *know* I should make my singletons thread-safe, and I know how, but the unsafe version is easier and between us, what are the chances for a race condition? *wink wink*

Having this `std.mixins` will make the right way also be the easy way. Writing `mixin property!(int, "x");` is not that bad, and since I can easily throw in a value check - I might just as well do it! And while the unsafe singleton is easier to implement than the safe version - not to mention the low lock version(they are not really *that* hard, but still harder than the unsafe version) - using `mixin lowLockSingleton;` is so much easier.



So, I would like to hear opinions. I already have a crude implementation of those two idioms, but I need to polish it some more before it's Phobos-worthy.

I also have a question about the contribution process. I know that when you contribute a small enhancement you need to open an enhancement issue on Bugzilla, but the modules in the review queue don't seem to have one. Are enhancement issues not required for a module contribution? Is this forum thread used instead of the Bugzilla issue to discuss the contribution?
Also, the wiki says that big features should start on their own feature branch(http://wiki.dlang.org/Development_and_Release_Process#Official_branches), but the modules on the review queue that have a GitHub pull request are pull-requested directly to master. Does that mean that what the wiki says is obsolete, or that the fork that these modules were developed on is in fact the feature branch?


Thanks for suffering through my long post!
May 06, 2013
It's a nice idea but personally I don't like the syntax much, for example it's completely non-obvious what "true" does when passed to the singleton mixin, or that the parameters to the property mixin are "type, name, condition, initial value".

I suppose you could do something like this:
mixin property!`int x = 1`;

The other problem is that I don't think it's beneficial to invite the use of mixins for such simple substitutions. I'd rather see the majority of code be standard D syntax, and the use of mixins be the exception rather than the rule. It's similar to how excessive use of macros in C++ is generally considered bad practice.
May 06, 2013
On 5/6/13 3:14 PM, Idan Arye wrote:
> Template mixins can be used to implement some common programming
> idioms(and design patterns). I have already implemented two of them for
> my own project - and I want to make them into a Phobos module - maybe
> `std.mixins`.

Nice idea, but at the first level of detail (without looking into it) the title should not be dictated by implementation artifacts, i.e. we don't have modules such as "std.templates" or "std.structs" etc. Conversely, if you implement a pattern via other means than a mixin, you're in trouble :o).

Andrei
May 06, 2013
On Monday, 6 May 2013 at 19:57:27 UTC, Andrei Alexandrescu wrote:
> On 5/6/13 3:14 PM, Idan Arye wrote:
>> Template mixins can be used to implement some common programming
>> idioms(and design patterns). I have already implemented two of them for
>> my own project - and I want to make them into a Phobos module - maybe
>> `std.mixins`.
>
> Nice idea, but at the first level of detail (without looking into it) the title should not be dictated by implementation artifacts, i.e. we don't have modules such as "std.templates" or "std.structs" etc. Conversely, if you implement a pattern via other means than a mixin, you're in trouble :o).
>
> Andrei

Since they are idioms, why not std.idioms or std.idiomatic?
May 06, 2013
On 5/6/13 4:03 PM, Robert Rouse wrote:
> On Monday, 6 May 2013 at 19:57:27 UTC, Andrei Alexandrescu wrote:
>> On 5/6/13 3:14 PM, Idan Arye wrote:
>>> Template mixins can be used to implement some common programming
>>> idioms(and design patterns). I have already implemented two of them for
>>> my own project - and I want to make them into a Phobos module - maybe
>>> `std.mixins`.
>>
>> Nice idea, but at the first level of detail (without looking into it)
>> the title should not be dictated by implementation artifacts, i.e. we
>> don't have modules such as "std.templates" or "std.structs" etc.
>> Conversely, if you implement a pattern via other means than a mixin,
>> you're in trouble :o).
>>
>> Andrei
>
> Since they are idioms, why not std.idioms or std.idiomatic?

std.patterns is the sweet spot.

Andrei
May 06, 2013
On Monday, 6 May 2013 at 20:10:59 UTC, Andrei Alexandrescu wrote:
> On 5/6/13 4:03 PM, Robert Rouse wrote:
>> On Monday, 6 May 2013 at 19:57:27 UTC, Andrei Alexandrescu wrote:
>>> On 5/6/13 3:14 PM, Idan Arye wrote:
>>>> Template mixins can be used to implement some common programming
>>>> idioms(and design patterns). I have already implemented two of them for
>>>> my own project - and I want to make them into a Phobos module - maybe
>>>> `std.mixins`.
>>>
>>> Nice idea, but at the first level of detail (without looking into it)
>>> the title should not be dictated by implementation artifacts, i.e. we
>>> don't have modules such as "std.templates" or "std.structs" etc.
>>> Conversely, if you implement a pattern via other means than a mixin,
>>> you're in trouble :o).
>>>
>>> Andrei
>>
>> Since they are idioms, why not std.idioms or std.idiomatic?
>
> std.patterns is the sweet spot.
>
> Andrei

I like `std.idioms`. `std.patterns` can be ambiguous, since it can also refer to regex patterns or to functional pattern matching - and not just to design patterns.
May 06, 2013
On Monday, 6 May 2013 at 19:47:33 UTC, Diggory wrote:
> It's a nice idea but personally I don't like the syntax much, for example it's completely non-obvious what "true" does when passed to the singleton mixin, or that the parameters to the property mixin are "type, name, condition, initial value".
>
> I suppose you could do something like this:
> mixin property!`int x = 1`;
>
> The other problem is that I don't think it's beneficial to invite the use of mixins for such simple substitutions. I'd rather see the majority of code be standard D syntax, and the use of mixins be the exception rather than the rule. It's similar to how excessive use of macros in C++ is generally considered bad practice.

If D supported Java's annotation metaprogramming I could have implemented a syntax like:

    @Property(`a < 50`) int a = 1;

since it doesn't, I have to use mixin templates...

(Declaimer: I do not want to imply here that Java is a good language. Java is a terrible language. Annotation metaprogramming is it's only redeeming feature, and even that feature is far too complex for common use...)


Anyways, I'll have to add a new trait template to extract the name from the declaration(Compile time regex are too slow), but I think I can pull off the style you suggest. However, we still need an extra template argument for the verifier, something like this:

    mixin propertyVerified!(`int x = 1`, `a < 50`);

Is this readable enough?
May 06, 2013
On Monday, 6 May 2013 at 21:18:56 UTC, Idan Arye wrote:
> Anyways, I'll have to add a new trait template to extract the name from the declaration(Compile time regex are too slow)

You know what? I take that back. I can probably pull this off with an anonymous struct to get better compilation speed *and* more readable code.
May 06, 2013
On Mon, 06 May 2013 17:13:00 -0400, Idan Arye <GenericNPC@gmail.com> wrote:

> On Monday, 6 May 2013 at 19:47:33 UTC, Diggory wrote:
>> It's a nice idea but personally I don't like the syntax much, for example it's completely non-obvious what "true" does when passed to the singleton mixin, or that the parameters to the property mixin are "type, name, condition, initial value".
>>
>> I suppose you could do something like this:
>> mixin property!`int x = 1`;
>>
>> The other problem is that I don't think it's beneficial to invite the use of mixins for such simple substitutions. I'd rather see the majority of code be standard D syntax, and the use of mixins be the exception rather than the rule. It's similar to how excessive use of macros in C++ is generally considered bad practice.
>
> If D supported Java's annotation metaprogramming I could have implemented a syntax like:
>
>      @Property(`a < 50`) int a = 1;
>
> since it doesn't, I have to use mixin templates...

D supports @Property syntax (though I would suggest a different identifier) via User-defined-attributes.  However, you will still need the mixin, I don't think it can add code.

This brings up a good idiom though.  Since mixin is the only thing that can inject code, but its usage is ugly, @uda's can be useful for specifying nice parameters to the mixin, and you could have one mixin per class instead of per property.  I think Manu uses this to great effect (was in his first talk).

-Steve
May 06, 2013
On Monday, 6 May 2013 at 21:58:08 UTC, Steven Schveighoffer wrote:
> On Mon, 06 May 2013 17:13:00 -0400, Idan Arye <GenericNPC@gmail.com> wrote:
>
>> On Monday, 6 May 2013 at 19:47:33 UTC, Diggory wrote:
>>> It's a nice idea but personally I don't like the syntax much, for example it's completely non-obvious what "true" does when passed to the singleton mixin, or that the parameters to the property mixin are "type, name, condition, initial value".
>>>
>>> I suppose you could do something like this:
>>> mixin property!`int x = 1`;
>>>
>>> The other problem is that I don't think it's beneficial to invite the use of mixins for such simple substitutions. I'd rather see the majority of code be standard D syntax, and the use of mixins be the exception rather than the rule. It's similar to how excessive use of macros in C++ is generally considered bad practice.
>>
>> If D supported Java's annotation metaprogramming I could have implemented a syntax like:
>>
>>     @Property(`a < 50`) int a = 1;
>>
>> since it doesn't, I have to use mixin templates...
>
> D supports @Property syntax (though I would suggest a different identifier) via User-defined-attributes.  However, you will still need the mixin, I don't think it can add code.
>
> This brings up a good idiom though.  Since mixin is the only thing that can inject code, but its usage is ugly, @uda's can be useful for specifying nice parameters to the mixin, and you could have one mixin per class instead of per property.  I think Manu uses this to great effect (was in his first talk).
>
> -Steve

I don't like this idea of marking the class with a `mixin` statement, and having all the parameters fed to it somewhere else. It doesn't feel clean to me...

And feeling aside, there was one thing I neglected - in Java the convention is to use `getX` and `setX` as `x`'s accessors, but in D the convention is to use `@property` accessors. Now, if we wrote:

    class Foo
    {
        private @Property int x;
        mixin makeProperties;
    }

then `makeProperties` would have made:

    @property int x(){...}
    @property int x(int value){...}

And we wouldn't be able to use them because they are overshadowed by the original x! That means we would have to rename `x` to `m_x` and either supply the desired property name as a UDA attribute or analyze the variable's name to remove the prefix notation.

Not as elegant as we wanted.


However, your idea of having a single mixin handle all the class\struct's properties gave me another idea - to use a single mixin, but instead of having it analyze the owner class to find the fields we want to make properties, we simply give them to it with a token string:

    class Foo
    {
        mixin properties!q{
            @asserting(`a < 50`)     int x = 1;
            @verifying(`a !is null`) string y = "hello";
            @privateSetter           double z = 44.4;
        };
    }

This can be easily implemented by making a private `struct` and `mixin`ing all those declarations as it's arguments, which gives me a data structure schema to query with `std.traits`, and also allows me to define the UDA's so that they can only be used inside the `mixin properties` "block". Also, it encourages programmers to put all their member fields in the same section of the class\struct.

One problem I see here, BTW, is DDoc - I have no idea how to document properties created like this...
« First   ‹ Prev
1 2 3 4 5