[Semi OT] Language for Game Development talk

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Sat Sep 27 16:55:20 PDT 2014


On 9/27/2014 4:20 PM, bearophile wrote:
> Walter Bright:
>
>>> It could be nice to have a syntax like lambdas for small struct/class methods:
>>> https://issues.dlang.org/show_bug.cgi?id=7176
>>>
>>> struct Foo {
>>>     int bar(int x) pure { return x * x; }
>>> }
>>>
>>> Becomes something like::
>>>
>>> struct Foo {
>>>     int bar = (int x) pure => x * x;
>>> }
>>
>> I see no gain from that syntax.
>
> Issue 7176 has currently seven votes, so someone seems to like it.

A feature without a solid rationale is no good in spite of how many votes it has.


> Now some D code is written in a functional style, this means many function
> bodies are very small, and sometimes they contain just a UFCS chain.
> Usually editors (and Phobos style guides) format that bar function like:
>
> int bar(int x) pure
> {
>      return x * x;
> }
>
> So now you have 4 lines instead of 1 line of the lambda-like syntax. Generally
> the presence of a  "return" is regarded as a "code smell" in functional-style code.

D has a nice inline lamda syntax, which was needed. It is not needed for 
separate functions.


>> I suggest using 'pure' and passing the globals you actually need as ref
>> parameters.
>
> This is what I usually do in D, but it has some small disadvantages:
> - It increases the number of function arguments (they are 8 bytes each),
> increasing the size of the function, adding some stack management instructions.
> This slows the function a little, if the function is performance-critical.

If the function is small enough that parameter setup time is significant, it is 
likely to be inlined anyway which will erase the penalty.

Such arguments can also be passed as template alias parameters, which are zero cost.

> - Sometimes you can't use "pure", for various reasons, like Phobos functions not
> yet pure, I/O action in your function, or other causes.

Then you really aren't encapsulating the globals the function uses, anyway, and 
the feature is useless.


> - If your pure function foo receives two global argument as out and ref, the
> function bar that calls it needs to access to global variables or it too needs
> those two ref/out arguments. The current design of @outer() is not transitive,
> so only foo needs to state what global variables are in/out/inout.

Being global variables, they are accessible from everywhere :-) which is why 
they're an encapsulation problem in the first place.


> - @outer is more DRY, because you don't need to specify the type of the global
> variable received by ref, you just need to know its name.

That's why gawd invented templates.


> - With @outer you can tighten some old code, without changing the signature of a
> function. If you have an old D module (or a C function converted to C) you often
> can't (or you don't want) to change the function signature to add the global
> arguments passed by ref. With @outer() the function signature doesn't change, so
> you can improve your legacy code. It allows a simpler refactoring of code.

You can always wrap it with a template and pass the global by alias.


> More notes:
> - SPARK language has added a feature similar to @outer, but more verbose. See
> comment 5 in issue 5007.
> - @outer() is optional and it's fiddly because not it's not meant for small D
> script-like programs, it's meant as a help for medium-integrity D programs
> (where you may think about using Ada language instead).

Better encapsulation is intended for larger programs - I agree it is useless for 
small ones.



More information about the Digitalmars-d mailing list