www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: A Perspective on D from game industry

reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Jun 16, 2014 at 08:08:50PM -0700, Walter Bright via Digitalmars-d wrote:
 On 6/16/2014 5:44 AM, "Ola Fosheim Grøstad"
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
As far as I can tell string mixins have the same bad properties that
macros have.

Assuming you are talking about C macros: Having implemented the C preprocessor (multiple times), make's macro system, designed and implemented ABEL's macro system, Ddoc's macro system, and string mixins, I can unequivocably object to that opinion! The C macro system is awesome in its awfulness. Let me count the ways: 1. Probably < 10 people in the world actually understand it all the way down. It is absurdly complex for what little it does. Paul Mensonidas is usually acknowledged as the "world's leading expert on the C preprocessor." Why would a freakin' macro processor even have an ecological niche for a world leading expert on it? The mind boggles.

So that you can write IOCCC entries that abuse the dark corners of cpp, of course. ;-) [...]
 5. There is no scoping of names of any sort - no hygiene whatsoever.
 Any #include file can trash any subsequent, unrelated, #include file
 in any way.

Do string mixins have scoping of names? I do agree, though, that D's string mixins eliminated a whole class of cpp abuses by requiring that the input string be a set of complete statements or declarations -- things like: mixin("writeln("); mixin(");"); are rejected by the compiler, whereas in C: #define MIXIN_1 writeln( #define MIXIN_2 ); MIXIN_1 MIXIN_2 are happily accepted, leading to IOCCC tricks like: #define block(x) { x } #define split_block(y) } y { void func() block( printf("a"); split_block(void main()) printf("b"); ) // The above nastiness translates to: void func() { printf("a"); } void main() { printf("b"); } (To my shame, I must admit that I actually did this in an IOCCC entry -- in fact, in an even worse form than shown above. :P) None of this insanity is permitted by D's string mixins, which is a big plus, in my book.
 6. Any syntax highlighter cannot work entirely correctly without
 having a full preprocessor.

And how would you syntax-highlight a string mixin that's assembled from arbitrary string fragments?
 7. Because of the preprocessor, valid C code need not look remotely
 like C code according to the C grammar.

Ah yes, this brings back sweet memories of this amusing little IOCCC entry: http://www.ioccc.org/2005/chia/chia.c :-)
 8. There are no looping macros, no CAR/CDR capabilities (Ddoc has the
 latter).

On Mon, Jun 16, 2014 at 08:10:40PM -0700, Walter Bright via Digitalmars-d wrote:
 On 6/16/2014 8:18 AM, "Ola Fosheim Grøstad"
 <ola.fosheim.grostad+dlang gmail.com>" wrote:
Sure,  just like m4 and cpp can be extremely powerful. Too powerful…

One of the sins of cpp is it is not powerful enough, forcing a lot of awkward usages.

I thought cpp's non-Turing-completeness was actually intentional? As if cpp nastiness isn't already bad enough, as you pointed out above... I dread to imagine a cpp that is "powerful enough"(!). In any case, string mixins are better than cpp in several ways, but they still do suffer from some of cpp's problems. T -- Stop staring at me like that! It's offens... no, you'll hurt your eyes!
Jun 16 2014
next sibling parent Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 6/17/2014 12:32 AM, H. S. Teoh via Digitalmars-d wrote:
 I do agree, though, that D's string mixins eliminated a whole class of
 cpp abuses by requiring that the input string be a set of complete
 statements or declarations -- things like:

 	mixin("writeln(");
 	mixin(");");

 are rejected by the compiler, whereas in C:

 	#define MIXIN_1 writeln(
 	#define MIXIN_2 );

 	MIXIN_1 MIXIN_2

 are happily accepted

OTOH, this does make it harder for D to emulate the nifty "stackless fibers" trick used by C's sweet ProtoThreads library (The one thing I'm envious of C over): http://dunkels.com/adam/pt/
Jun 16 2014
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 6/16/2014 9:32 PM, H. S. Teoh via Digitalmars-d wrote:
 Do string mixins have scoping of names?

Yes, of course, since they are D code.
 And how would you syntax-highlight a string mixin that's assembled from
 arbitrary string fragments?

You wouldn't need to, since the text editor sees only normal D code.
Jun 17 2014
next sibling parent reply dennis luehring <dl.soluz gmx.net> writes:
Am 17.06.2014 11:30, schrieb Walter Bright:
 And how would you syntax-highlight a string mixin that's assembled from
 arbitrary string fragments?

You wouldn't need to, since the text editor sees only normal D code.

the text editor sees just D-code-Strings - so no syntax-highlight except that for Strings
Jun 17 2014
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/17/2014 3:25 AM, dennis luehring wrote:
 the text editor sees just D-code-Strings - so no syntax-highlight except that
 for Strings

The syntax highlighter could highlight q{ ... } strings differently, if it chose to, with little difficulty.
Jun 17 2014
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/17/2014 04:00 PM, John Colvin wrote:
 I though the primary use of static foreach was to force the
 compiler to attempt compile-time iteration even for
 non-TemplateArgList arguments like arrays known at compile-time

 e.g.

 static foreach(el; [1,2,3,4])
 {
       pragma(msg, el);
 }

 or

 static foreach(el; 5 .. 8)
 {
       pragma(msg, el);
 }

No, that's a distinct use and IMO shouldn't be called static foreach (it would be inconsistent with static if in how scopes are handled.) In any case, it is a quite boring use case as well, one can write a template that converts a range into such a list and then plain foreach will work.
Jun 17 2014
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 06/17/2014 03:36 PM, John Colvin wrote:

also, foreach that works outside of function scope would be awesome: mixin template A(TL ...) { foreach(i, T; TL) { mixin("T v" ~ i.to!string); } }

Also, identifier mixins might then somewhat clean up a lot of code. The cases where a declaration name needs to be generated and this forces the whole declaration to be written in awkward string interpolation style are just too common, even more so if static foreach is supported (if there is any named declaration inside the static foreach body at all and the loop loops more than once, mixins will be required to prevent name clashes.) Eg: mixin template A(T...){ static foreach(i,S;T){ S mixin(`v`~i.to!string); auto mixin(`fun`~i.to!string)(S s){ // lots of code potentially using `i' without first // converting it to a string only for it to be parsed back. // ... return s.mixin(`member`~i); // I've wanted this too } } } Also, there may be cases where one really wants to have local declarations (eg. enums) inside the static foreach loop. (I really need to get around to polishing/make formal that static foreach DIP!)
Jun 17 2014
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/17/2014 6:12 AM, Artur Skawina via Digitalmars-d wrote:
 rtur (who implemented both features last weekend; it started out as a
 fun "let's-see-how-D-would-look-if-it-had-this"-project, but after making
 them work and then converting a few small programs,

Taking action rather than debating - I love it!
 immediately realized that he now does not want to live w/o this functionality)

I don't think I can take that kind of pressure!
Jun 17 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 10:25:39 UTC, dennis luehring wrote:
 Am 17.06.2014 11:30, schrieb Walter Bright:
 And how would you syntax-highlight a string mixin that's 
 assembled from
 arbitrary string fragments?

You wouldn't need to, since the text editor sees only normal D code.

the text editor sees just D-code-Strings - so no syntax-highlight except that for Strings

All editors with D support highlight token strings as if it was code.
Jun 17 2014
prev sibling next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Tuesday, 17 June 2014 at 10:25:39 UTC, dennis luehring wrote:
 Am 17.06.2014 11:30, schrieb Walter Bright:
 And how would you syntax-highlight a string mixin that's 
 assembled from
 arbitrary string fragments?

You wouldn't need to, since the text editor sees only normal D code.

the text editor sees just D-code-Strings - so no syntax-highlight except that for Strings

The q{ } syntax is meant to work around this. mixin(q{ void foo() { return 8; } }); Should be highlighted.
Jun 17 2014
prev sibling next sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 06/17/14 11:30, Walter Bright via Digitalmars-d wrote:
 On 6/16/2014 9:32 PM, H. S. Teoh via Digitalmars-d wrote:
 
 And how would you syntax-highlight a string mixin that's assembled from
 arbitrary string fragments?

You wouldn't need to, since the text editor sees only normal D code.

That's just because D lacks string interpolation and static-foreach. These two things take meta programming to a whole new level. The difference is similar to the C++- vs D-templates case. Superficially "it's just a neater syntax", but in practice it allows perfectly readable code to be written for cases where traditional (both template- and ctfe- based) meta programs become an almost unmaintainable mess. And the fact that those meta-programs can then be properly syntax- highlighted in an editor is a nice extra. artur (who implemented both features last weekend; it started out as a fun "let's-see-how-D-would-look-if-it-had-this"-project, but after making them work and then converting a few small programs, almost immediately realized that he now does not want to live w/o this functionality)
Jun 17 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 13:13:00 UTC, Artur Skawina via 
Digitalmars-d wrote:
 artur (who implemented both features last weekend; it started 
 out as a
 fun "let's-see-how-D-would-look-if-it-had-this"-project, but 
 after making
 them work and then converting a few small programs, almost 
 immediately
 realized that he now does not want to live w/o this 
 functionality)

I'd be very interested in seeing PR for the static foreach at the very least ;)
Jun 17 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 17 June 2014 at 13:24:11 UTC, Dicebot wrote:
 On Tuesday, 17 June 2014 at 13:13:00 UTC, Artur Skawina via 
 Digitalmars-d wrote:
 artur (who implemented both features last weekend; it started 
 out as a
 fun "let's-see-how-D-would-look-if-it-had-this"-project, but 
 after making
 them work and then converting a few small programs, almost 
 immediately
 realized that he now does not want to live w/o this 
 functionality)

I'd be very interested in seeing PR for the static foreach at the very least ;)

also, foreach that works outside of function scope would be awesome: mixin template A(TL ...) { foreach(i, T; TL) { mixin("T v" ~ i.to!string); } }
Jun 17 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 13:36:48 UTC, John Colvin wrote:
 also, foreach that works outside of function scope would be 
 awesome:

 mixin template A(TL ...)
 {
 	foreach(i, T; TL)
 	{
 		mixin("T v" ~ i.to!string);
 	}
 }

It is not "also", it is primary use case of static foreach
Jun 17 2014
prev sibling next sibling parent "Kiith-Sa" <kiithsacmp gmail.com> writes:
On Tuesday, 17 June 2014 at 13:36:48 UTC, John Colvin wrote:
 On Tuesday, 17 June 2014 at 13:24:11 UTC, Dicebot wrote:
 On Tuesday, 17 June 2014 at 13:13:00 UTC, Artur Skawina via 
 Digitalmars-d wrote:
 artur (who implemented both features last weekend; it started 
 out as a
 fun "let's-see-how-D-would-look-if-it-had-this"-project, but 
 after making
 them work and then converting a few small programs, almost 
 immediately
 realized that he now does not want to live w/o this 
 functionality)

I'd be very interested in seeing PR for the static foreach at the very least ;)

also, foreach that works outside of function scope would be awesome: mixin template A(TL ...) { foreach(i, T; TL) { mixin("T v" ~ i.to!string); } }

This would drastically improve readability of some of my code.
Jun 17 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 17 June 2014 at 13:52:48 UTC, Dicebot wrote:
 On Tuesday, 17 June 2014 at 13:36:48 UTC, John Colvin wrote:
 also, foreach that works outside of function scope would be 
 awesome:

 mixin template A(TL ...)
 {
 	foreach(i, T; TL)
 	{
 		mixin("T v" ~ i.to!string);
 	}
 }

It is not "also", it is primary use case of static foreach

I though the primary use of static foreach was to force the compiler to attempt compile-time iteration even for non-TemplateArgList arguments like arrays known at compile-time e.g. static foreach(el; [1,2,3,4]) { pragma(msg, el); } or static foreach(el; 5 .. 8) { pragma(msg, el); } The mixin template example I gave is already a "static" foreach, just not explicitly so.
Jun 17 2014
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Tuesday, 17 June 2014 at 14:00:44 UTC, John Colvin wrote:
 I though the primary use of static foreach was to force the
 compiler to attempt compile-time iteration even for
 non-TemplateArgList arguments like arrays known at compile-time

If static foreach acts as code generator there is no practical difference. Also I don't believe compile-time iteration use case is even remotely as common as declaration injection.
Jun 17 2014
prev sibling parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 06/17/14 22:15, Walter Bright via Digitalmars-d wrote:
 On 6/17/2014 6:12 AM, Artur Skawina via Digitalmars-d wrote:
 immediately realized that he now does not want to live w/o this functionality)

I don't think I can take that kind of pressure!

I was responding to "text editor sees only normal D code" -- my point was just that it doesn't have to be like that. But it's something that can be hard to realize or even imagine, until one sees the whole picture, with several language features playing well together. Just like otherwise very experienced C++ programmers often completely fail to appreciate certain D features, which only really start to make sense in context and combination. The difference that these two features made certainly surprised me; suddenly I didn't had to write unreadable lambdas and mixins, the code shrunk by a factor of ~three and became beautiful, even properly syntax highlighted after a few tweaks to the editor settings. It became very obvious that this is not just something-that-would-be- -neat-to-have-but-D-has-so-many-other-more-important-problems, but that it is a must-have. And it's really trivial do add - I did it /within/ the language, took ~100LOC; a proper built-in implementation wouldn't be significantly harder. But I'll shut up now, as apparently meta programming is considered harmful in certain industries, at least from what I read here. :) Wouldn't want to scare anybody away. I'll post in a new thread instead, in a few days, once I find the time to construct a proper example and write at least a few sentences explaining the syntax. artur
Jun 18 2014