www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Overloading property vs. non-property

reply dsimcha <dsimcha yahoo.com> writes:
Once property syntax is fully enforced (not necessarily recommended) will it
be possible to overload properties against non-properties?  My use case is
that I'm thinking about API improvements for my dflplot lib and one thing that
I would really like is to give a fluent interface to everything to further cut
back on the amount of boilerplate needed to generate simple plots.  For example:

Histogram(someData, 10)
    .barColor(getColor(255, 0, 0))
    .histType(HistType.Probability)
    .toFigure.title("A Histogram")
    .xLabel("Stuff").showAsMain();

The problem is that I also want things like barColor and title to be settable
via normal property syntax, using the equals sign.  Right now, this "just
works" because D's current non-analness about enforcing  property-ness is
awesome 99% of the time even if it leads to a few weird corner cases.  Will
there be a way to express such an interface to be provided (calling a setter
as either a member function or a property at the user's choice) once  property
is fully implemented?
Jul 15 2010
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 15 Jul 2010 09:16:47 -0400, dsimcha <dsimcha yahoo.com> wrote:

 Once property syntax is fully enforced (not necessarily recommended)  
 will it
 be possible to overload properties against non-properties?  My use case  
 is
 that I'm thinking about API improvements for my dflplot lib and one  
 thing that
 I would really like is to give a fluent interface to everything to  
 further cut
 back on the amount of boilerplate needed to generate simple plots.  For  
 example:

 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to be  
 settable
 via normal property syntax, using the equals sign.  Right now, this "just
 works" because D's current non-analness about enforcing  property-ness is
 awesome 99% of the time even if it leads to a few weird corner cases.   
 Will
 there be a way to express such an interface to be provided (calling a  
 setter
 as either a member function or a property at the user's choice) once  
  property
 is fully implemented?
I would say no. A property is not meant to be a function or vice versa. Also, a property setter should either return void or the type it's setting. I would suggest the following model: property int x(int i); typeof(this) setX(int i); This looks good IMO when used: int m = c.x = 5; c.setX(5).setY(6); I used this in tango.sys.Process to set various parameters for process creation. -Steve
Jul 15 2010
prev sibling next sibling parent reply torhu <no spam.invalid> writes:
On 15.07.2010 15:16, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily recommended) will it
 be possible to overload properties against non-properties?  My use case is
 that I'm thinking about API improvements for my dflplot lib and one thing that
 I would really like is to give a fluent interface to everything to further cut
 back on the amount of boilerplate needed to generate simple plots.  For
example:

 Histogram(someData, 10)
      .barColor(getColor(255, 0, 0))
      .histType(HistType.Probability)
      .toFigure.title("A Histogram")
      .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to be settable
 via normal property syntax, using the equals sign.  Right now, this "just
 works" because D's current non-analness about enforcing  property-ness is
 awesome 99% of the time even if it leads to a few weird corner cases.  Will
 there be a way to express such an interface to be provided (calling a setter
 as either a member function or a property at the user's choice) once  property
 is fully implemented?
In case the answer is no, that example of yours is the perfect opportunity to dust off the almost-forgotten with statement :) with (Histogram(someData, 10)) { barColor = getColor(255, 0, 0); histType = HistType.Probability; toFigure.title = "A Histogram"; xLabel = "Stuff"; showAsMain(); } A bit more typing, but I'd say that it's easier to read.
Jul 15 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from torhu (no spam.invalid)'s article
 In case the answer is no, that example of yours is the perfect
 opportunity to dust off the almost-forgotten with statement :)
 with (Histogram(someData, 10)) {
       barColor = getColor(255, 0, 0);
       histType = HistType.Probability;
       toFigure.title = "A Histogram";
       xLabel = "Stuff";
       showAsMain();
 }
 A bit more typing, but I'd say that it's easier to read.
But toFigure returns a Figure, not this. The idea is that you'd set all the properties for the Plot, then put toFigure somewhere in your chain, then set all the properties for the Figure.
Jul 15 2010
parent reply torhu <no spam.invalid> writes:
On 15.07.2010 17:42, dsimcha wrote:
 == Quote from torhu (no spam.invalid)'s article
  In case the answer is no, that example of yours is the perfect
  opportunity to dust off the almost-forgotten with statement :)
  with (Histogram(someData, 10)) {
        barColor = getColor(255, 0, 0);
        histType = HistType.Probability;
        toFigure.title = "A Histogram";
        xLabel = "Stuff";
        showAsMain();
  }
  A bit more typing, but I'd say that it's easier to read.
But toFigure returns a Figure, not this. The idea is that you'd set all the properties for the Plot, then put toFigure somewhere in your chain, then set all the properties for the Figure.
Oops, guess I should have waited until after my nap with posting :) You could nest the with statements, but then it's getting more verbose. Might be better to add a convenience constructor or two to Figure that takes care of the most common cases, and having toFigure forward to that. with (Histogram(someData, 10)) { barColor = getColor(255, 0, 0); histType = HistType.Probability; toFigure("A Histogram", "Stuff").showAsMain(); } Other options include having a factory function that returns a probability histogram, or even make it a template parameter and a have a ProbabilityHistogram alias, etc. A few small changes could help a lot for the common use cases. It would never be as quite flexible as what you have now, but you might get close enough.
Jul 15 2010
parent reply =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= <just ask.me> writes:
Dnia 15-07-2010 o 22:55:04 torhu <no spam.invalid> napisa=B3(a):

 On 15.07.2010 17:42, dsimcha wrote:
 =3D=3D Quote from torhu (no spam.invalid)'s article
  In case the answer is no, that example of yours is the perfect
  opportunity to dust off the almost-forgotten with statement :)
  with (Histogram(someData, 10)) {
        barColor =3D getColor(255, 0, 0);
        histType =3D HistType.Probability;
        toFigure.title =3D "A Histogram";
        xLabel =3D "Stuff";
        showAsMain();
  }
  A bit more typing, but I'd say that it's easier to read.
But toFigure returns a Figure, not this. The idea is that you'd set =
=
 all the
 properties for the Plot, then put toFigure somewhere in your chain,  =
 then set all
 the properties for the Figure.
Oops, guess I should have waited until after my nap with posting :) You could nest the with statements, but then it's getting more verbose=
.
 Might be better to add a convenience constructor or two to Figure that=
=
 takes care of the most common cases, and having toFigure forward to th=
at.
 with (Histogram(someData, 10)) {
        barColor =3D getColor(255, 0, 0);
        histType =3D HistType.Probability;
        toFigure("A Histogram", "Stuff").showAsMain();
 }

 Other options include having a factory function that returns a  =
 probability histogram, or even make it a template parameter and a have=
a =
 ProbabilityHistogram alias, etc.  A few small changes could help a lot=
=
 for the common use cases.  It would never be as quite flexible as what=
=
 you have now, but you might get close enough.
Perhaps another with? with (Histogram(someData, 10)) { barColor =3D getColor(255, 0, 0); histType =3D HistType.Probability; with (toFigure) { title =3D "A Histogram"; xLabel =3D "Stuff"; showAsMain(); } } Tomek
Jul 23 2010
parent =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= <just ask.me> writes:
 Oops, guess I should have waited until after my nap with posting :)

 You could nest the with statements, but then it's getting more verbose.
Didn't see that. Now it's my turn for a nap :)
Jul 23 2010
prev sibling next sibling parent reply BCS <none anon.com> writes:
Hello dsimcha,

 Histogram(someData, 10)
 .barColor(getColor(255, 0, 0))
 .histType(HistType.Probability)
 .toFigure.title("A Histogram")
 .xLabel("Stuff").showAsMain();
With a little meta programming you might be able to make a type that generate a fluent interface for any type. Using opDispatch you pass the args into a contained type and return self. The only difference from the users standpoint is that you need one more function call in the chain. -- ... <IXOYE><
Jul 15 2010
parent torhu <no spam.invalid> writes:
On 16.07.2010 01:46, BCS wrote:
 Hello dsimcha,

  Histogram(someData, 10)
  .barColor(getColor(255, 0, 0))
  .histType(HistType.Probability)
  .toFigure.title("A Histogram")
  .xLabel("Stuff").showAsMain();
With a little meta programming you might be able to make a type that generate a fluent interface for any type. Using opDispatch you pass the args into a contained type and return self. The only difference from the users standpoint is that you need one more function call in the chain.
Great idea. I figured a fancy solution wouldn't be worth it, but if it could be fully generic... --- import std.stdio; class Foo { int a; string b; property int propA(int v) { return a = v; } property int propA() { return a; } property string propB(string v) { return b = v; } property string propB() { return b; } void foo() { writeln("foo"); } } struct PSet(T) { T _obj; typeof(this) opDispatch(string prop, T...)(T val) { mixin("_obj." ~ prop ~ "=val;"); return this; } } PSet!T pset(T)(T obj) { return PSet!T(obj); } void main() { Foo f = new Foo; // Not sure why putting those foo()'s in there just like that works. // compiler bug? pset(f).propA(1).foo().propB("something").foo(); assert(f.a == 1); assert(f.b == "something"); } ---
Jul 15 2010
prev sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily recommended) will it
 be possible to overload properties against non-properties?  My use case is
 that I'm thinking about API improvements for my dflplot lib and one thing that
 I would really like is to give a fluent interface to everything to further cut
 back on the amount of boilerplate needed to generate simple plots.  For
example:
 
 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();
 
 The problem is that I also want things like barColor and title to be settable
 via normal property syntax, using the equals sign.  Right now, this "just
 works" because D's current non-analness about enforcing  property-ness is
 awesome 99% of the time even if it leads to a few weird corner cases.  Will
 there be a way to express such an interface to be provided (calling a setter
 as either a member function or a property at the user's choice) once  property
 is fully implemented?
 
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
Jul 16 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily recommended) will it
 be possible to overload properties against non-properties?  My use case is
 that I'm thinking about API improvements for my dflplot lib and one thing that
 I would really like is to give a fluent interface to everything to further cut
 back on the amount of boilerplate needed to generate simple plots.  For
example:

 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to be settable
 via normal property syntax, using the equals sign.  Right now, this "just
 works" because D's current non-analness about enforcing  property-ness is
 awesome 99% of the time even if it leads to a few weird corner cases.  Will
 there be a way to express such an interface to be provided (calling a setter
 as either a member function or a property at the user's choice) once  property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
This is what I'd vote for, but it's not what TDPL says. Page 156: "In particular 'property' is recognized by the compiler and signals the fact that the function bearing such an attribute must be called without the trailing ()."
Jul 16 2010
next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 17 Jul 2010 00:58:58 -0400, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily recommended)  
will it
 be possible to overload properties against non-properties?  My use  
case is
 that I'm thinking about API improvements for my dflplot lib and one  
thing that
 I would really like is to give a fluent interface to everything to  
further cut
 back on the amount of boilerplate needed to generate simple plots.   
For example:
 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to be  
settable
 via normal property syntax, using the equals sign.  Right now, this  
"just
 works" because D's current non-analness about enforcing  
property-ness is
 awesome 99% of the time even if it leads to a few weird corner  
cases. Will
 there be a way to express such an interface to be provided (calling a  
setter
 as either a member function or a property at the user's choice) once  
property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
You're impression is correct with regard to D as it currently stands and the final property proposal compromise.
 This is what I'd vote for, but it's not what TDPL says.  Page 156:

 "In particular 'property' is recognized by the compiler and signals the  
 fact that
 the function bearing such an attribute must be called without the  
 trailing ()."
Technically, TDPL simply doesn't mention Methods-as-Properties as they are currently implemented in D.
Jul 16 2010
parent reply Don <nospam nospam.com> writes:
Robert Jacques wrote:
 On Sat, 17 Jul 2010 00:58:58 -0400, dsimcha <dsimcha yahoo.com> wrote:
 
 == Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily 
recommended) will it
 be possible to overload properties against non-properties?  My use 
case is
 that I'm thinking about API improvements for my dflplot lib and one 
thing that
 I would really like is to give a fluent interface to everything to 
further cut
 back on the amount of boilerplate needed to generate simple plots.  
For example:
 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to 
be settable
 via normal property syntax, using the equals sign.  Right now, this 
"just
 works" because D's current non-analness about enforcing 
property-ness is
 awesome 99% of the time even if it leads to a few weird corner 
cases. Will
 there be a way to express such an interface to be provided (calling 
a setter
 as either a member function or a property at the user's choice) 
once property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
You're impression is correct with regard to D as it currently stands and the final property proposal compromise.
 This is what I'd vote for, but it's not what TDPL says.  Page 156:

 "In particular 'property' is recognized by the compiler and signals 
 the fact that
 the function bearing such an attribute must be called without the 
 trailing ()."
Technically, TDPL simply doesn't mention Methods-as-Properties as they are currently implemented in D.
In the event of a difference between TDPL and DMD, TDPL always wins. The compiler will have to change.
Jul 16 2010
parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 17 Jul 2010 02:38:20 -0400, Don <nospam nospam.com> wrote:

 Robert Jacques wrote:
 On Sat, 17 Jul 2010 00:58:58 -0400, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily  
recommended) will it
 be possible to overload properties against non-properties?  My use  
case is
 that I'm thinking about API improvements for my dflplot lib and one  
thing that
 I would really like is to give a fluent interface to everything to  
further cut
 back on the amount of boilerplate needed to generate simple plots.   
For example:
 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to  
be settable
 via normal property syntax, using the equals sign.  Right now, this  
"just
 works" because D's current non-analness about enforcing  
property-ness is
 awesome 99% of the time even if it leads to a few weird corner  
cases. Will
 there be a way to express such an interface to be provided (calling  
a setter
 as either a member function or a property at the user's choice)  
once property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
You're impression is correct with regard to D as it currently stands and the final property proposal compromise.
 This is what I'd vote for, but it's not what TDPL says.  Page 156:

 "In particular 'property' is recognized by the compiler and signals  
 the fact that
 the function bearing such an attribute must be called without the  
 trailing ()."
Technically, TDPL simply doesn't mention Methods-as-Properties as they are currently implemented in D.
In the event of a difference between TDPL and DMD, TDPL always wins. The compiler will have to change.
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?
Jul 17 2010
next sibling parent reply Don <nospam nospam.com> writes:
Robert Jacques wrote:
 On Sat, 17 Jul 2010 02:38:20 -0400, Don <nospam nospam.com> wrote:
 
 Robert Jacques wrote:
 On Sat, 17 Jul 2010 00:58:58 -0400, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily 
recommended) will it
 be possible to overload properties against non-properties?  My 
use case is
 that I'm thinking about API improvements for my dflplot lib and 
one thing that
 I would really like is to give a fluent interface to everything 
to further cut
 back on the amount of boilerplate needed to generate simple 
plots. For example:
 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to 
be settable
 via normal property syntax, using the equals sign.  Right now, 
this "just
 works" because D's current non-analness about enforcing 
property-ness is
 awesome 99% of the time even if it leads to a few weird corner 
cases. Will
 there be a way to express such an interface to be provided 
(calling a setter
 as either a member function or a property at the user's choice) 
once property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
You're impression is correct with regard to D as it currently stands and the final property proposal compromise.
 This is what I'd vote for, but it's not what TDPL says.  Page 156:

 "In particular 'property' is recognized by the compiler and signals 
 the fact that
 the function bearing such an attribute must be called without the 
 trailing ()."
Technically, TDPL simply doesn't mention Methods-as-Properties as they are currently implemented in D.
In the event of a difference between TDPL and DMD, TDPL always wins. The compiler will have to change.
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?
Andrei tried to avoid mentioning language features which he hoped would change. That's why there's no mention of __traits, for example.
Jul 17 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Sat, 17 Jul 2010 10:19:51 +0200, Don wrote:
 
 Andrei tried to avoid mentioning language features which he hoped would
 change. That's why there's no mention of __traits, for example.
But there is: §7.3.2, p. 275. -Lars
Jul 17 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Lars T. Kyllingstad wrote:
 On Sat, 17 Jul 2010 10:19:51 +0200, Don wrote:
  
 Andrei tried to avoid mentioning language features which he hoped would
 change. That's why there's no mention of __traits, for example.
But there is: §7.3.2, p. 275. -Lars
The enum names example was too appealing. Don is right about the book's general approach. Andrei
Jul 17 2010
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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
Jul 17 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 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.
There are some holes/problems/warts in D2 in need to be filled still. I am using D2 despite those problems, but leaving them in is the wrong kind of "stability". Bye, bearophile
Jul 17 2010
prev sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 17 Jul 2010 10:34:28 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail 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.
Jul 17 2010
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 07/17/2010 01:14 PM, Robert Jacques wrote:
 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"); }
Well it's not that the symbol is not included, it's that the expression doesn't compile. You should write is(T.init.foo!Something()) to see foo inside T. Andrei
Jul 17 2010
prev sibling parent reply Jonathan M Davis <jmdavisprog gmail.com> writes:
On Saturday 17 July 2010 11:14:26 Robert Jacques wrote:
 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.
Whereas I would have argued that the whole point of properties was for them to be distinct from methods and have it be decided by the programmer whether something was a property or a method. As such, the fact that you methods became properties based on their signature was an implementation issue of how properties were implemented in D, and that such an implementation was bug prone. I suppose that it all depends on what you consider properties to really be and how you look at them. - Jonathan M Davis
Jul 17 2010
parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 17 Jul 2010 17:13:02 -0400, Jonathan M Davis  
<jmdavisprog gmail.com> wrote:
 On Saturday 17 July 2010 11:14:26 Robert Jacques wrote:
 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.
Whereas I would have argued that the whole point of properties was for them to be distinct from methods and
Sadly, on a technical level this isn't true. (As it would be really cool if the compiler could exceed the limits of a method by knowing it was a 'property')
 have it be decided by the programmer whether
 something was a property or a method.
On which we agree. We disagree on which programmer gets to make this decision: the library writer vs the library user.
 As such, the fact that you methods became
 properties based on their signature was an implementation issue of how
 properties were implemented in D,
And in Eiffel and Ruby.
 and that such an implementation was bug prone.
Actually, property isn't really any less prone to nasty bugs. i.e. the ones that compile fine, but run wrong (all of which are really rare corner cases). What property allows is the seamless upgrading of an opCall-able field to a property without fixing dozens of compile errors.
 I suppose that it all depends on what you consider properties to really  
 be and
 how you look at them.

 - Jonathan M Davis
Yes, although in retrospect, I think part of the problem was calling D's solution 'Methods-as-properties' in the first place; it's really more of an application of the Uniform Access Principle. (http://www.eiffel.com/general/column/2005/Sept_October.html) For those who don't want to read the article (or who like cute summaries): The Uniform Access Principle is to properties what ranges are to iterators. :)
Jul 19 2010
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Chad J (chadjoan __spam.is.bad__gmail.com)'s article
 On 07/15/2010 09:16 AM, dsimcha wrote:
 Once property syntax is fully enforced (not necessarily recommended) will it
 be possible to overload properties against non-properties?  My use case is
 that I'm thinking about API improvements for my dflplot lib and one thing that
 I would really like is to give a fluent interface to everything to further cut
 back on the amount of boilerplate needed to generate simple plots.  For
example:

 Histogram(someData, 10)
     .barColor(getColor(255, 0, 0))
     .histType(HistType.Probability)
     .toFigure.title("A Histogram")
     .xLabel("Stuff").showAsMain();

 The problem is that I also want things like barColor and title to be settable
 via normal property syntax, using the equals sign.  Right now, this "just
 works" because D's current non-analness about enforcing  property-ness is
 awesome 99% of the time even if it leads to a few weird corner cases.  Will
 there be a way to express such an interface to be provided (calling a setter
 as either a member function or a property at the user's choice) once  property
 is fully implemented?
Wasn't this going to be handled by normal non- property functions? I was under the impression that normal functions/methods with no arguments would still allow omission of parentheses and the assignments would still be rewritten to 1-arg calls. As long as the semantics of it are handled correctly then that syntax will be safe; it just has to do what the programmer /expects/. The property syntax can resolve some ambiguities, so they are quite useful if you want to say, return a zero-argument delegate from a property.
This is what I'd vote for, but it's not what TDPL says. Page 156: "In particular 'property' is recognized by the compiler and signals the fact that the function bearing such an attribute must be called without the trailing ()."
At the time of writing, there had recently been a large discussion of properties in this newsgroup. Some good arguments had been made, mainly the ambiguity of functions that return delegates. Plus generally the participants to that discussion had taken a very strong pro- property stance (I was one of the few who disagreed and hoped a simpler solution could be found). So the text is written under the assumption that ultimately "()" must be present unless property was used in the definition. (And if it was used, "()" would be disallowed, hence the "must" in the quote above.) At the same time, the feature was not yet present in the compiler, so I didn't want to describe it in more detail. Andrei
Jul 17 2010