The Tail Operator '#' enables clean typechecked builders with minimal language changes.

Eugene Wissner belka at caraus.de
Fri Jan 25 08:14:06 UTC 2019


On Friday, 25 January 2019 at 07:24:10 UTC, FeepingCreature wrote:
> A problem that's come up before is how to specify builders in a 
> typechecked manner. In my language syntax experiment, Neat, I'd 
> copied Haskell's '$' operator, which means "capture everything 
> to the right of here in one set of parens", in order to avoid 
> writing parentheses expressions:
>
>     foo(2 + 2);
>     // becomes
>     foo $ 2 + 2;
>
> But what if we wanted the *opposite*? What if we wanted to 
> capture everything to the *left* of an operator in one set of 
> parens? Enter the tail operator:
>
>     (2 + 2).foo;
>     // becomes
>     2 + 2 #.foo;
>
> Why is this useful?
>
> Well, we've had the debate before about struct initializers. 
> The irksome thing is that the language is *almost* there! We 
> can already write function calls as assignments:
>
>     foo(5);
>     // becomes
>     foo = 5;
>
> The main problem is that there's no way in the language to 
> chain assignments together in that syntax. If we could, we 
> could generate very clean looking builder expressions. But
>
>     (((Foo.build
>       .a = 3)
>       .b = 4)
>       .c = 5)
>       .value;
>
> Just doesn't look good and isn't as easy to modify as it should 
> be either.
>
> But with the tail operator, this becomes:
>
>     Foo.build
>       #.a = 3
>       #.b = 4
>       #.c = 5
>       #.value;
>
> Which is pure, typechecked, easy to extend and still readable.
>
> What do you think?

$ is a simple function in Haskell that is defined in a library, 
the same as '+', '-' are just functions and not special operators 
as in D. In D you have to define each operator in the language 
itself and the compiler should understand them. Defining a 
language construct for each use case doesn't seems pretty to me, 
it makes the grammar overcomplicated.


More information about the Digitalmars-d mailing list