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