Walter Bright:

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

I agree that the number of votes alone means very little. But perhaps those persons have reasons. (If votes from people are not important, then better to remove this feature from Bugzilla.)


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

The lambda syntax for function/class methods is not needed, but it's handy and it's sufficiently natural, expecially for many little methods. It's not an important feature, and there are D features that I need far more than this (like syntax to unpack tuples), but some people like it. Apparently C#6 designers agree with that, search for "Expression-bodied members" here:

http://www.dotnetcurry.com/showarticle.aspx?ID=1042

The C#6 syntax is the same as the proposed one for D:

class Rectangle(int width, int height)
{
    public int Area => width * height;
}


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

This is the theory :-) Sometimes I have seen this not to be true.


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

The point of having an @outer() is to enforce what module-level names a function is using and how it is using them (in/out/inout), so it's useful for _impure_ functions. If your functions can be annotated with "pure" you don't need @outer much.


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

In D we have modules, so variables are module-level, or they are imported from other modules (unfortunately names in a module are public on default when you import the module. I'd like the opposite, to be private to the module, and importable only if they are tagged with "public"). The problem with module-level variables is that sometimes I am using by mistake a global variable when I am instead trying to use a local one. Or on the opposite I am using a local variable by mistake when I'd like to use a module-level one. An attribute like "pure" disallows the access to global mutables, so it solves only half of the problem. Generally knowing exactly what module-level variables (and how) a function is using is very handy to understand the purpose and working of the function itself. So I see @outer() as a tool for code understanding, even legacy code because I can add @outer() to old code written by other persons.


- @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.

Templates are a blunt tool to solve the problems faced by @outer(). @outer() allows you to specify for each variable if it's going to just be read, written, or read-written. And @outer() is not named @globals() because it works for inner functions too, it allows to control and specify the access of names from the outer scopes, so an inner impure nonstatic function can use @outer() to specify what names it can use from the scope of the outer function:

void foo() {
  int x;
  @outer(in x) void bar() {
    writeln(x);
  }
  bar();
}


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

I think I've never done this. To be tried.

Bye,
bearophile

Reply via email to