Thread overview
A nice D coding pattern
Nov 24, 2014
bearophile
Nov 25, 2014
matovitch
Nov 25, 2014
Ali Çehreli
Nov 25, 2014
MattCoder
Nov 25, 2014
bearophile
Nov 25, 2014
Meta
Nov 25, 2014
MattCoder
Nov 25, 2014
Tobias Pankrath
Nov 25, 2014
Ali Çehreli
November 24, 2014
In some D programs I'm using this coding pattern:


struct Foo {
    // Instance fields here.

    @disable this();

    this(in string[] data) pure @safe
    in {
        // Many pre-conditions here.
    } out(result) {
        // Some post-conditions here.
    } body {
        // ...
    }

    Nullable!(string[][]) doIt() pure {
        //...
    }

    // Various other methods here...
}

void main() {
    // Created at compile-time.
    enum something = "........".Foo;

    // Something much larger is done at run-time.
    immutable const result = something.doIt;
}


The structure is created at compile-time using data known at compile-time (here a string). This struct has a constructor that runs at compile-time that has many pre-conditions that avoid wrong input data at compile-time.
The largest part of the computation is done at run-time calling one or more struct methods.
And the @disable this() assures that a struct is correctly initialized by the constructor.
This pattern has significant advantages regarding code reliability.

You can see an example of this pattern that I've used here:
http://rosettacode.org/wiki/Solve_a_Hopido_puzzle#D

Bye,
bearophile
November 25, 2014
On Monday, 24 November 2014 at 22:50:33 UTC, bearophile wrote:
> In some D programs I'm using this coding pattern:
>
> You can see an example of this pattern that I've used here:
> http://rosettacode.org/wiki/Solve_a_Hopido_puzzle#D
>
> Bye,
> bearophile

Awesome gist and great pattern ! Sometimes your forum post doesn't get any answers but you can be sure I read and enjoy them all (and I'm sure I am not alone). Keep it up ! :)

November 25, 2014
On Monday, 24 November 2014 at 22:50:33 UTC, bearophile wrote:
> And the @disable this() assures that a struct is correctly initialized by the constructor.

In the statement: @disable this()

May I understand that you're "disabling" the "default"
constructor of the struct to use your own constructor?

Matheus.
November 25, 2014
MattCoder:

> May I understand that you're "disabling" the "default"
> constructor of the struct to use your own constructor?

Right. So the instance data of the struct is more likely correct when you call its methods.

Bye,
bearophile
November 25, 2014
That's a neat trick, although if preconditions were able to be run at compile time when possible you wouldn't have to resort to using enum to force CTFE (you've talked a bit about this before I remember). Thinking about something like a good ranged number implementation, we can now get almost all the way there. Manually having to specify enum is still an undesirable.
November 25, 2014
On Tuesday, 25 November 2014 at 13:56:23 UTC, bearophile wrote:
> Right. So the instance data of the struct is more likely correct when you call its methods.

Thanks. - Well I'd like to see more of these tips. My current code in D looks like C++ and of course I sure that I'm not extracting the power of D. In fact lately I was looking around the Phobos source to open my mind for new features.

Matheus.
November 25, 2014
> void main() {
>     // Created at compile-time.
>     enum something = "........".Foo;
>

I don't think we should encourage UFCS with typenames or uppercase names. If anything, it does not provide any benefit in this case and Foo(".....") is much more clearer without any syntactical overhead.
November 25, 2014
On 11/25/2014 01:51 AM, matovitch wrote:

> On Monday, 24 November 2014 at 22:50:33 UTC, bearophile wrote:

> Sometimes your forum post doesn't get
> any answers but you can be sure I read and enjoy them all (and I'm sure
> I am not alone). Keep it up ! :)

Same here! Thank you, bearophile! :)

An artist friend of mine is working on the book cover for "Programming in D". Initially, I thought of having a subtle reference to a bear. :) (We are not pursuing that idea though.)

Ali

November 25, 2014
On 11/25/2014 10:58 AM, Tobias Pankrath wrote:

>> void main() {
>>     // Created at compile-time.
>>     enum something = "........".Foo;
>>
>
> I don't think we should encourage UFCS with typenames or uppercase
> names. If anything, it does not provide any benefit in this case and
> Foo(".....") is much more clearer without any syntactical overhead.

Agreed.

A guideline that makes sense to me is "UFCS is for when the function can be thought of as a special operation on its first parameter."

After seeing bearophile's code, I thought that even the following was better than UFCS:

    "hello".to!Foo

It only then feels like a special operation on "hello". (I haven't tried the code but I think it works.)

However, I would still use the Foo("hello").

Ali