May 18, 2008
Nick Sabalausky wrote:
> I was just looking through the documentation on some of the Phobos stuff that's new in D2, and at pipe! and compose! in particular. This is kind of nice (from docs):
> 
> int[] a = pipe!(readText, split, map!(to!(int)))("file.txt");
> 
> Not to nag about extension methods (well, ok, yes: to nag ;) ), but with extension methods (regardless if they're explicit or implicit), that could be cleaned up to:
> 
> int[] a = "file.txt".readText().split().map!(to!(int)))();

Or: auto a = "file.txt".readText.split.map!(to!(int)));

Now, since "file.txt" is an array, readText returns an array, and split returns an array, you can currently do this. Were any of those a class, struct, or scalar, you'd be SOL until uniform call syntax is implemented.

I wonder if uniform call syntax could be used the opposite way:
class A
{
	void foo(){}
}
foo(new A);
May 18, 2008
Nick Sabalausky Wrote:

> "Nick Sabalausky" <a@a.a> wrote in message news:g08fha$2e5$1@digitalmars.com...
> >I thought I had seen discussion on something like this back when the "Functions as Array Properties" feature was introduced, but I just did a search and didn't see much of anything. So sorry if this has been discussed to death before.
> >
> > I propose adding to D a feature that C# calls extension methods. These are similar to D's "Functions as Array Properties", but provide more control and flexibility.
> >
> > For any function that's not a member of a class (and maybe also static member functions of classes), if you add the modifier "extend" or "this" to first argument of the function declaration like this:
> >
> > // Normal Function
> > void Foo(MyClass arg) {/*...*/}
> >
> > // Extension Method (I'm proposing either of these, but not both):
> > void Foo(this MyClass arg) {/*...*/} // C#-style
> > void Foo(extend MyClass arg) {/*...*/} // Might be more readable
> >
> > (Although, there wouldn't actually be overloading based soley on whether or not it's declared as an extension method. (Or would there? Probably not.))
> >
> > Then that allows you to call Foo like this:
> >
> > auto obj = new MyClass();
> >
> > // Always allowed
> > Foo(obj);
> >
> > // Allowed if and only if Foo has been declared
> > // using the above extension method syntax.
> > // But regardless, Foo never has access to private members
> > // of MyClass, since it still isn't a true member.
> > obj.Foo();
> >
> > This should also be allowed for primitives:
> >
> > void Foo(extend int arg);
> > int myInt = 7;
> > myInt.Foo();
> > 5.Foo(); // Might interfere with parsing of floating-point literals,
> > though.
> >
> > This has two advantages over the current "Functions as Array Properties" feature:
> >
> > 1. It supports more than just arrays (obviously).
> > 2. The special syntax is only available if the function's author intends
> > it as a non-member "extension" to the given type.
> >
> > Possible modifications to this proposal:
> >
> > - If advantage #2 is deemed to be an unwarranted concern, I'd be happy to at least have the current "Functions as Array Properties" feature extended to all types, not just arrays.
> >
> > - Maybe declaring a function as an extension method would *require* it to be called using extension method syntax. Although under this arrangement, if you wanted a function to be callable via either syntax (but would this ability really be desirable?), that would require a function overload or a messy kludge like using "maybe_extend" instead of "extend".
> >
> 
> I was just looking through the documentation on some of the Phobos stuff that's new in D2, and at pipe! and compose! in particular. This is kind of nice (from docs):
> 
> int[] a = pipe!(readText, split, map!(to!(int)))("file.txt");
> 
> Not to nag about extension methods (well, ok, yes: to nag ;) ), but with extension methods (regardless if they're explicit or implicit), that could be cleaned up to:
> 
> int[] a = "file.txt".readText().split().map!(to!(int)))();
> 
> Granted, this doesn't actually create a new composite function. But for cases like this one where a reusable composite function isn't needed, it increases readablity quite a bit.
> 
> It would also allow extra paramaters to be specified without having to turn them into template parameters:
> 
> int[] a = "file.csv".readText().split(",").map!(to!(int)))();

This is big problem with functional style in D! D does not have currying. Unfortunate you can not write split(",") and obtain a new function. Maybe language in future can accept split(_, ",") meaning function that takes one argument and passes to split in first position and "," in second position. Dee Girl
May 18, 2008
"Dee Girl" <deegirl@noreply.com> wrote in message news:g0pfva$1cqb$1@digitalmars.com...
> Nick Sabalausky Wrote:
>> It would also allow extra paramaters to be specified without having to
>> turn
>> them into template parameters:
>>
>> int[] a = "file.csv".readText().split(",").map!(to!(int)))();
>
> This is big problem with functional style in D!

Yea, I kinda thought that would cause a problem with functional style. But like I said, if you need a functional style, you can still just use pipe! or compose!.

> D does not have currying. Unfortunate you can not write split(",") and obtain a new function. Maybe language in future can accept split(_, ",") meaning function that takes one argument and passes to split in first position and "," in second position. Dee Girl

Couldn't you do something like that with templates? It wouldn't be as pretty as built-in currying support though.


May 18, 2008
"Chris Wright" <dhasenan@gmail.com> wrote in message news:g0pcpm$14f2$1@digitalmars.com...
> Nick Sabalausky wrote:
>> I was just looking through the documentation on some of the Phobos stuff that's new in D2, and at pipe! and compose! in particular. This is kind of nice (from docs):
>>
>> int[] a = pipe!(readText, split, map!(to!(int)))("file.txt");
>>
>> Not to nag about extension methods (well, ok, yes: to nag ;) ), but with extension methods (regardless if they're explicit or implicit), that could be cleaned up to:
>>
>> int[] a = "file.txt".readText().split().map!(to!(int)))();
>
> Or: auto a = "file.txt".readText.split.map!(to!(int)));
>
> Now, since "file.txt" is an array, readText returns an array, and split returns an array, you can currently do this. Were any of those a class, struct, or scalar, you'd be SOL until uniform call syntax is implemented.
>

Heh, true, I wasn't thinking about that example using all arrays. Bad example :)

Does eliminating the no-argument parentheses like that currently work, or are you proposing that?

> I wonder if uniform call syntax could be used the opposite way:
> class A
> {
> void foo(){}
> }
> foo(new A);

That's been my assumption. After all, isn't that what happens behind-the-scenes anyway (ie, "this" being passed as a hidden first parameter)? (I know it is in C++)

But, I wonder if disallowing that might eliminate some of the concerns I had about "uniform call syntax"/"implicit extension methods". I'll have to think about that.


May 19, 2008
Nick Sabalausky wrote:
> "Chris Wright" <dhasenan@gmail.com> wrote in message news:g0pcpm$14f2$1@digitalmars.com...
>> Or: auto a = "file.txt".readText.split.map!(to!(int)));
>>
>> Now, since "file.txt" is an array, readText returns an array, and split returns an array, you can currently do this. Were any of those a class, struct, or scalar, you'd be SOL until uniform call syntax is implemented.
>>
> 
> Heh, true, I wasn't thinking about that example using all arrays. Bad example :)
> 
> Does eliminating the no-argument parentheses like that currently work, or are you proposing that?

It works currently. In dunit assertions, for instance, you can do:
expect(foo).not.sameAs(bar);
// equivalent to expect(foo).not().sameAs(bar);

>> I wonder if uniform call syntax could be used the opposite way:
>> class A
>> {
>> void foo(){}
>> }
>> foo(new A);
> 
> That's been my assumption. After all, isn't that what happens behind-the-scenes anyway (ie, "this" being passed as a hidden first parameter)? (I know it is in C++)
> 
> But, I wonder if disallowing that might eliminate some of the concerns I had about "uniform call syntax"/"implicit extension methods". I'll have to think about that.

I'm not sure how you would explicitly use the class method rather than the free function if it were allowed. I just thought it was amusing.
May 19, 2008
Chris Wright wrote:
> Nick Sabalausky wrote:
>> "Chris Wright" <dhasenan@gmail.com> wrote in message news:g0pcpm$14f2$1@digitalmars.com...
>>> Or: auto a = "file.txt".readText.split.map!(to!(int)));
>>>
>>> Now, since "file.txt" is an array, readText returns an array, and split returns an array, you can currently do this. Were any of those a class, struct, or scalar, you'd be SOL until uniform call syntax is implemented.
>>>
>>
>> Heh, true, I wasn't thinking about that example using all arrays. Bad example :)
>>
>> Does eliminating the no-argument parentheses like that currently work, or are you proposing that?
> 
> It works currently. In dunit assertions, for instance, you can do:
> expect(foo).not.sameAs(bar);
> // equivalent to expect(foo).not().sameAs(bar);
> 

Oops, that works because expect is a UDT. It doesn't work with array stuff. My mistake.
June 10, 2008
Nick Sabalausky wrote:
> I thought I had seen discussion on something like this back when the "Functions as Array Properties" feature was introduced, but I just did a search and didn't see much of anything. So sorry if this has been discussed to death before.
> 
> I propose adding to D a feature that C# calls extension methods. These are similar to D's "Functions as Array Properties", but provide more control and flexibility.
> 
> For any function that's not a member of a class (and maybe also static member functions of classes), if you add the modifier "extend" or "this" to first argument of the function declaration like this:
> 
> // Normal Function
> void Foo(MyClass arg) {/*...*/}
> 
> // Extension Method (I'm proposing either of these, but not both):
> void Foo(this MyClass arg) {/*...*/} // C#-style
> void Foo(extend MyClass arg) {/*...*/} // Might be more readable
> 
> (Although, there wouldn't actually be overloading based soley on whether or not it's declared as an extension method. (Or would there? Probably not.))
> 
> Then that allows you to call Foo like this:
> 
> auto obj = new MyClass();
> 
> // Always allowed
> Foo(obj);
> 
> // Allowed if and only if Foo has been declared
> // using the above extension method syntax.
> // But regardless, Foo never has access to private members
> // of MyClass, since it still isn't a true member.
> obj.Foo();
> 
> This should also be allowed for primitives:
> 
> void Foo(extend int arg);
> int myInt = 7;
> myInt.Foo();
> 5.Foo(); // Might interfere with parsing of floating-point literals, though.
> 
> This has two advantages over the current "Functions as Array Properties" feature:
> 
> 1. It supports more than just arrays (obviously).
> 2. The special syntax is only available if the function's author intends it as a non-member "extension" to the given type.
> 
> Possible modifications to this proposal:
> 

Overall it seems like an interesting idea. Note: I would prefer the syntax:
  void Foo(MyClass this, int a, ...) {...

Some other details might need to be worked out, but overall it looks sound.

> - If advantage #2 is deemed to be an unwarranted concern, I'd be happy to at least have the current "Functions as Array Properties" feature extended to all types, not just arrays.
> 

For the sake of consistency, I think it would be best if rule #2 remains.

> - Maybe declaring a function as an extension method would *require* it to be called using extension method syntax. Although under this arrangement, if you wanted a function to be callable via either syntax (but would this ability really be desirable?), that would require a function overload or a messy kludge like using "maybe_extend" instead of "extend".
> 
> 

I would prefer not. In fact, I think it would be useful that even class methods would be callable with an explicit 'this' parameter, like this:

  class Foo {
    void func(int a);
  }

  auto foo = new Foo();
  Foo.func(foo, 2); // same as foo.func(2);

The benefit of this, is to be able to use Foo.func as a function pointer, and thus we would have a feature similar to C++'s member functions, as well as the ability to call a specific override in a method override lineage.


-- 
Bruno Medeiros - Software Developer, MSc. in CS/E graduate
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
1 2
Next ›   Last »