On Sat, 17 Jul 2010 10:34:28 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
Robert Jacques wrote:
Before reading TDPL I'd had agreed with you 100%. Now, I find that TDPL
is either ambiguous or anticipatory in a small number of cases. For
example, Functions-as-Methods get more exposure than @property, but no
limitations are mentioned nor are there any generalized examples
presented. So is the feature limited to arrays (current DMD) or
available to all types (Slide-ware from the D conference)? Clear and
the removal of delete got a solid paragraph of explanation and
rational, but recent discussions have highlighted issues. And while I
believe these issues to be solvable, as the devil is always in the
details, this might not always be the case where TDPL anticipates DMD.
By contrast, @property literally gets 1 line of text, 2 off-hand code
uses and Methods-as-Properties is never mentioned. So was
Methods-as-Properties not mentioned because it was dropped from the
spec or because TDPL is downright laconic with regard to properties in
general?
It's quite reasonable to not want to give very much detail about
features that are not yet fully implemented - that was the only
motivation.
What Walter and I had in mind was to remove methods-as-properties in
favor of @property. He mentioned that that would break quite a bit of
code in Phobos so it needs to be introduced with care. The current plan
is to initially enable it as a compiler switch.
Functions-as-methods is, I think, a good feature. I've encountered one
issue with them: it's difficult to define a function if there's no
method with the same name. Consider we want to define foo(T) if T does
not have a method foo():
void foo(T) if (!is(T.init.foo())) { ... }
This works today. However, with the new rule things are dicey. The
foo(T) free function is introduced before evaluating the constraint. So
T.init.foo() does find it. What happens currently (if T is an array
type) is infinite recursion during compilation.
I think the problem is solvable - I just introduced hasMember(T, string)
in std.traits that looks up straight in T's symbol table. So the
rewritten condition would be:
void foo(T) if (!hasMember!(T, "foo") || !is(T.init.foo())) { ... }
Assuming short-circuit evaluation, it all works but it's rather subtle.
Since recently, however, Walter became very adverse to introducing
breaking changes of any kind. He understandably wants to promote
stability of the language. The only question is whether stability refers
to the compiler's status quo or TDPL.
Finally, I should mention that we decided relatively early within the
book that TDPL won't be a reference manual including every single detail
of the language; it would have inflated with a lot of boring details.
Not even K&R is a complete reference to C, even as it was back when the
book was written.
Andrei
Thank you for that excellence explanation/clarification.
I'm also hopeful for Functions-as-methods, although you may be borrowing
trouble with your example. It appears that templates are not included in
T.init's scope as the following compiles:
struct Bar {
void foo(T)() if (!is(bar.foo!int)) { writeln("recursive"); }
}
void foo( T)(T x) if (!is(T.init.foo())) { writeln("recursive"); }
void foo2(T)(T x) if (!is(T.init.foo())) { writeln("recursive"); }
void main(string[] args) {
Bar b;
b.foo!int;
int[] bar;
bar.foo;
bar.foo2;
return;
}
As for @properties and Methods-as-properties, I know I dropped out of the
properties debate when the removal of Methods-as-properties was taken out
of the proposal. The more I use @property and see it used, the more I feel
that it's solving its motivating problems by exclusion: i.e. it's fixing a
problematic corner case by virally applying itself to everything else. So
perhaps like throw and nothrow, noproperty would be a superior alternative
to property. But in either case, no/property is a preemptive /
retrospective patch to the problem of opCall hijacking. And although I
appreciate the value of having the tools to fix an opCall hijack once
detected, I'd much rather have a generic solution that detects them at
compile-time.