| Thread overview | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 20, 2012 String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Hello,
since people discussed a lot about user-defined attributes recently, I've been thinking about a way to implement it with a string mixins. The problem with them is their syntax - it's far from what we want to use in everyday job. I understand, they should be easily distinguished at use site, but perhaps this may be accomplished in other ways as well. My idea is to translate this kind of statements:
# identifier statement
into this:
mixin( identifier( q{ statement } ) );
where an identifier is a, possibly templated, function that accepts one string argument and returns a string. Here are some possible use cases:
#serialize int a; // marked to be serializable
#serialize!not int b; // -.- non-serializable
#readonly float c; // generate trivial private setter and public getter
#handles!Events.Foo void handler(); // event handler
#attribute!"Foo" void foo(); // function with additional compile-time info
Most of these examples require some D parser, but, since it is planned to add parser-generation into Phobos, this shouldn't be a problem.
What do you think, does it have some value for the language, and, if yes, is it possible to implement?
| ||||
March 20, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | On 20.03.2012 22:25, Mantis wrote: > Hello, > > since people discussed a lot about user-defined attributes recently, > I've been thinking about a way to implement it with a string mixins. The > problem with them is their syntax - it's far from what we want to use in > everyday job. Use template mixins? At least in struct/class area that catches the most attention it should work perfectly. I understand, they should be easily distinguished at use > site, but perhaps this may be accomplished in other ways as well. My > idea is to translate this kind of statements: > > # identifier statement > > into this: > > mixin( identifier( q{ statement } ) ); > > where an identifier is a, possibly templated, function that accepts one > string argument and returns a string. Here are some possible use cases: > > #serialize int a; // marked to be serializable > #serialize!not int b; // -.- non-serializable > > #readonly float c; // generate trivial private setter and public getter Why not just leave it alone, and (if need comes) turn it into property on demand. > > #handles!Events.Foo void handler(); // event handler > > #attribute!"Foo" void foo(); // function with additional compile-time info It's just voodoo - no guaranties that #attribute can do that given the above rewrite. > > Most of these examples require some D parser, but, since it is planned > to add parser-generation into Phobos, this shouldn't be a problem. > What do you think, does it have some value for the language, and, if > yes, is it possible to implement? Looks like throwing nukes to pin down a pesky cockroach. The sugar is more or less nice, but encourages ineffective compile-time wise idiom. -- Dmitry Olshansky | |||
March 20, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | On 2012-03-20 19:25, Mantis wrote: > Hello, > > since people discussed a lot about user-defined attributes recently, > I've been thinking about a way to implement it with a string mixins. The > problem with them is their syntax - it's far from what we want to use in > everyday job. I understand, they should be easily distinguished at use > site, but perhaps this may be accomplished in other ways as well. My > idea is to translate this kind of statements: > > # identifier statement > > into this: > > mixin( identifier( q{ statement } ) ); I don't like it. I want real user defined attributes. -- /Jacob Carlborg | |||
March 20, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Tuesday, 20 March 2012 at 21:28:25 UTC, Jacob Carlborg wrote: > On 2012-03-20 19:25, Mantis wrote: >> Hello, >> >> since people discussed a lot about user-defined attributes recently, >> I've been thinking about a way to implement it with a string mixins. The >> problem with them is their syntax - it's far from what we want to use in >> everyday job. I understand, they should be easily distinguished at use >> site, but perhaps this may be accomplished in other ways as well. My >> idea is to translate this kind of statements: >> >> # identifier statement >> >> into this: >> >> mixin( identifier( q{ statement } ) ); > > > I don't like it. I want real user defined attributes. I think the idea has merit, string mixins together with CTFE parsing is the holy grail... because of the current syntax it's not really feasible to use on a per-member basis... but it is possible to use on a struct/class basis... mixin(attr(q{struct Foo { @NonSerialized int x; @NonSerialized int y; int z; }})); Please disregard my broken parser(it's just a proof of concept) However, consider what we could do with the latest CTFE parser advances, coupled with a tighter compiler/library callback interface. ==================================================================== import std.stdio; import std.array; import std.string; import std.algorithm; string attr(string complex_decl) { string org_struct; string ser_struct; auto lines = splitLines(complex_decl); { auto decl = split(stripLeft(lines[0])); if(decl[0]=="struct") { org_struct = decl[0] ~ " " ~ decl[1]; ser_struct = decl[0] ~ " " ~ decl[1] ~ "_Serializable"; } else return complex_decl; } foreach(line; lines[1..$]) { auto attr = findSplitAfter(stripLeft(line), "@NonSerialized "); if(attr[0]=="@NonSerialized ") org_struct ~= attr[1]; else { org_struct ~= attr[1]; ser_struct ~= attr[1]; } } return ser_struct ~ "\n" ~ org_struct; } mixin(attr(q{struct Foo { @NonSerialized int x; @NonSerialized int y; int z; }})); void main() { auto m = [ __traits(allMembers, Foo) ]; writeln("Normal members of Foo:", m); auto n = [ __traits(allMembers, Foo_Serializable) ]; writeln("Serializable members of Foo:", n); } | |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky Attachments:
| > Use template mixins? At least in struct/class area that catches the most attention it should work perfectly.
I believe template mixins are equally ugly. Don't you have to explicitly specify that you are invoking a mixin? Or am I missing something here.
Regards
- Puneet
| |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | On 03/20/2012 11:25 AM, Mantis wrote: > Hello, > > since people discussed a lot about user-defined attributes recently, > I've been thinking about a way to implement it with a string mixins. The > problem with them is their syntax - it's far from what we want to use in > everyday job. I understand, they should be easily distinguished at use > site, but perhaps this may be accomplished in other ways as well. My > idea is to translate this kind of statements: > > # identifier statement > > into this: > > mixin( identifier( q{ statement } ) ); No no no no, oh the humanity no! String mixins should be a method of LAST resort. Please don't add sugar to make them look nicer. If anything add vinegar and make them look as ugly as they really are. > > where an identifier is a, possibly templated, function that accepts one > string argument and returns a string. Here are some possible use cases: > > #serialize int a; // marked to be serializable > #serialize!not int b; // -.- non-serializable > > #readonly float c; // generate trivial private setter and public getter > > #handles!Events.Foo void handler(); // event handler > > #attribute!"Foo" void foo(); // function with additional compile-time info > > Most of these examples require some D parser, but, since it is planned > to add parser-generation into Phobos, this shouldn't be a problem. > What do you think, does it have some value for the language, and, if > yes, is it possible to implement? | |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | Mantis <mail.mantis.88@gmail.com> wrote: > Hello, > > since people discussed a lot about user-defined attributes recently, I've been thinking about a way to implement it with a string mixins. The problem with them is their syntax - it's far from what we want to use in everyday job. I understand, they should be easily distinguished at use site, but perhaps this may be accomplished in other ways as well. My idea is to translate this kind of statements: > > # identifier statement > You mean 'declaration'. > into this: > > mixin( identifier( q{ statement } ) ); > > where an identifier is a, possibly templated, function that accepts one string argument and returns a string. Here are some possible use cases: > > #serialize int a; // marked to be serializable #serialize!not int b; // -.- non-serializable > > #readonly float c; // generate trivial private setter and public getter > > #handles!Events.Foo void handler(); // event handler > > #attribute!"Foo" void foo(); // function with additional compile-time info > > Most of these examples require some D parser, but, since it is planned to > add parser-generation into Phobos, this shouldn't be a problem. > What do you think, does it have some value for the language, and, if yes, > is it possible to implement? The syntax may conflict with '#line'. What to do where there are multiple attributes? E.g. #license!"BSD" @safe #memoize pure nothrow auto invertMatrix(T)(T[] elements) if (isArithmetic!T) { ... } What to do with .di files? // in .di #handler void onLoad(); // in .d #handler void onLoad() { .... } Besides, what's wrong with using '@'? @serialize int a; | |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to kennytm | 21.03.2012 13:35, kennytm пишет: > Mantis<mail.mantis.88@gmail.com> wrote: >> [...] >> # identifier statement >> > You mean 'declaration'. Not necessarily, this could be used anywhere a mixin can be. >> [...] > The syntax may conflict with '#line'. I didn't know. The choice for the symbol is not that important however. > What to do where there are multiple attributes? E.g. > > #license!"BSD" @safe #memoize pure nothrow auto invertMatrix(T)(T[] > elements) if (isArithmetic!T) { ... } Evaluation order stays the same as in this example, the improvement is purely syntactical: // import std.stdio, std.array; string m1( string s ) { return replace( s, "foo", "bar" ); } string m2( string s ) { return replace( s, "bar", "baz" ); } mixin( m1( q{ mixin( m2( q{ void foo( int i ) { writeln( i ); }}));})); void main() { baz( 42 ); } // > What to do with .di files? > > // in .di > #handler void onLoad(); > // in .d > #handler void onLoad() { .... } Since the function receives a string, it can deal with declarations differently from definitions, it's only a matter of parser. > Besides, what's wrong with using '@'? > > @serialize int a; Builtin annotations' names are not reserved keywords, so this would be possible and ambiguous: string safe( string s ); @safe void foo(); // what @safe stands for? | |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | and what about attribute parameters like @serialize(version=2)
Am 21.03.2012 13:35, schrieb Mantis:
> 21.03.2012 13:35, kennytm пОÑеÑ:
>> Mantis<mail.mantis.88@gmail.com> wrote:
>>> [...]
>>> # identifier statement
>>>
>> You mean 'declaration'.
>
> Not necessarily, this could be used anywhere a mixin can be.
>>> [...]
>> The syntax may conflict with '#line'.
>
> I didn't know. The choice for the symbol is not that important however.
>
>> What to do where there are multiple attributes? E.g.
>>
>> #license!"BSD" @safe #memoize pure nothrow auto invertMatrix(T)(T[]
>> elements) if (isArithmetic!T) { ... }
>
> Evaluation order stays the same as in this example, the improvement is
> purely syntactical:
> //
> import std.stdio, std.array;
>
> string m1( string s ) { return replace( s, "foo", "bar" ); }
> string m2( string s ) { return replace( s, "bar", "baz" ); }
>
> mixin( m1( q{ mixin( m2( q{ void foo( int i ) {
> writeln( i );
> }}));}));
>
> void main() {
> baz( 42 );
> }
> //
>> What to do with .di files?
>>
>> // in .di
>> #handler void onLoad();
>> // in .d
>> #handler void onLoad() { .... }
>
> Since the function receives a string, it can deal with declarations
> differently from definitions, it's only a matter of parser.
>> Besides, what's wrong with using '@'?
>>
>> @serialize int a;
> Builtin annotations' names are not reserved keywords, so this would be
> possible and ambiguous:
>
> string safe( string s );
> @safe void foo(); // what @safe stands for?
| |||
March 21, 2012 Re: String mixin syntax sugar | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mantis | On Wednesday, 21 March 2012 at 12:37:50 UTC, Mantis wrote:
> Builtin annotations' names are not reserved keywords, so this would be possible and ambiguous:
>
> string safe( string s );
> @safe void foo(); // what @safe stands for?
What about "@" for built-in annotations and "@!" for user-defined?
@!license("BSD") @safe @!memoize pure nothrow auto
invertMatrix(T)(T[] elements) if (isArithmetic!T) { ... }
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply