Calling delegate properties without parens

2012-04-14 Thread Piotr Szturmaj

I have following code:

import std.array, std.range, std.stdio;

struct CommonInputRange(E)
{
@property bool delegate() empty;
@property E delegate() front;
void delegate() popFront;
}

void main(string[] args)
{
alias CommonInputRange!dchar DCRange;
static assert(isInputRange!DCRange);
DCRange dc;
auto dcr = "abcdefg";
auto t = dcr.takeExactly(3);
dc.empty = &t.empty;
dc.front = &t.front;
dc.popFront = &t.popFront;

for ( ; !dc.empty(); dc.popFront())
writeln(dc.front());
}

As you can see in the for loop, range primitives must be called using 
parens (), otherwise they don't work.


Do you know if there are plans to implement @property for delegates and 
function pointers?


Re: Calling delegate properties without parens

2012-04-14 Thread Artur Skawina
On 04/14/12 20:47, Piotr Szturmaj wrote:
> I have following code:
> 
> import std.array, std.range, std.stdio;
> 
> struct CommonInputRange(E)
> {
> @property bool delegate() empty;
> @property E delegate() front;
> void delegate() popFront;
> }
> 
> void main(string[] args)
> {
> alias CommonInputRange!dchar DCRange;
> static assert(isInputRange!DCRange);
> DCRange dc;
> auto dcr = "abcdefg";
> auto t = dcr.takeExactly(3);
> dc.empty = &t.empty;
> dc.front = &t.front;
> dc.popFront = &t.popFront;
> 
> for ( ; !dc.empty(); dc.popFront())
> writeln(dc.front());
> }
> 
> As you can see in the for loop, range primitives must be called using parens 
> (), otherwise they don't work.
> 
> Do you know if there are plans to implement @property for delegates and 
> function pointers?

@property is for functions masquerading as data, i'm not sure extending it
to pointers and delegates would be a good idea. What you are asking for is
basically syntax sugar for:

   struct CommonInputRange(E)
   {
   bool delegate() _empty;
   @property auto empty() { return _empty(); };
   @property auto empty(typeof(_empty) dg) { _empty = dg; };
   E delegate() _front;
   @property auto front() { return _front(); };
   @property auto front(typeof(_front) dg) { _front = dg; };
   void delegate() popFront;
   }

// [1]

artur

[1] which could also /almost/ be expressed as:

   struct PropDeleg(T) {
  T dg;
  @property auto get() { return dg(); };
  alias get this;
  void opAssign(T d) { dg = d; };
   }

   struct CommonInputRange(E)
   {
  PropDeleg!(bool delegate()) empty;
  PropDeleg!(E delegate()) front;
  void delegate() popFront;
   }

except this one would need an (implicit) conversion to get the same
behavior. IOW it should work everywhere, as long as the result is
assigned to a different type; ie you'd need 
"{ dchar c = dc.front; writeln(c); }" in the above example, because
otherwise the writeln template will accept the struct, but never
really use it, so the dchar conversion does not happen.


Re: Calling delegate properties without parens

2012-04-14 Thread Piotr Szturmaj

Artur Skawina wrote:

@property is for functions masquerading as data, i'm not sure extending it
to pointers and delegates would be a good idea. What you are asking for is
basically syntax sugar for:

struct CommonInputRange(E)
{
bool delegate() _empty;
@property auto empty() { return _empty(); };
@property auto empty(typeof(_empty) dg) { _empty = dg; };
E delegate() _front;
@property auto front() { return _front(); };
@property auto front(typeof(_front) dg) { _front = dg; };
void delegate() popFront;
}

>

Yes, I was thinking about this, but it adds unnecessary overhead. I want 
to call delegates directly.


I think the whole idea is harmless because semantically, from the user 
perspective, delegates and function pointers works just like normal 
functions. So, why not?


Re: Calling delegate properties without parens

2012-04-14 Thread Jonathan M Davis
On Saturday, April 14, 2012 20:47:20 Piotr Szturmaj wrote:
> I have following code:
> 
> import std.array, std.range, std.stdio;
> 
> struct CommonInputRange(E)
> {
>  @property bool delegate() empty;
>  @property E delegate() front;
>  void delegate() popFront;
> }
> 
> void main(string[] args)
> {
>  alias CommonInputRange!dchar DCRange;
>  static assert(isInputRange!DCRange);
>  DCRange dc;
>  auto dcr = "abcdefg";
>  auto t = dcr.takeExactly(3);
>  dc.empty = &t.empty;
>  dc.front = &t.front;
>  dc.popFront = &t.popFront;
> 
>  for ( ; !dc.empty(); dc.popFront())
>  writeln(dc.front());
> }
> 
> As you can see in the for loop, range primitives must be called using
> parens (), otherwise they don't work.
> 
> Do you know if there are plans to implement @property for delegates and
> function pointers?

front returns an element in the range. In your case, it's returning a 
delegate, because you have a range of delegates. If front returned a class or 
struct with a member function called foo, which you wanted to call, then you'd 
be doing something like

for(; !dc.empty; dc.popFront())
writeln(dc.front.foo());

But in your case, it's a delegate, so operating on that delegate means calling 
it, which means using the parens. dc.front just gives you the delegate, and it 
would be horrible if it did anything else. If front also called the delegate, 
the doing something like

auto arr = arr(dc);

would call each and every one of the delegates in the range, because it uses 
front to access the element _without calling it_. If there were some way to 
indicate that a delegate was called with property syntax, then you could no 
longer distinguish between simply returning the delegate and returning and 
call it.

Not to mention, properties are supposed to be an abstraction that mimicks 
member variables. That makes no sense whatsoever with a delegate. And in this 
case, the member variable which _is_ being mimicked (front) happens to be a 
delegate. So, it makes perfect sense that you'd have to use parens on it to 
actually call it.

- Jonathan M Davis


Re: Calling delegate properties without parens

2012-04-15 Thread Artur Skawina
On 04/15/12 03:01, Piotr Szturmaj wrote:
> Artur Skawina wrote:
>> @property is for functions masquerading as data, i'm not sure extending it
>> to pointers and delegates would be a good idea. What you are asking for is
>> basically syntax sugar for:
>>
>> struct CommonInputRange(E)
>> {
>> bool delegate() _empty;
>> @property auto empty() { return _empty(); };
>> @property auto empty(typeof(_empty) dg) { _empty = dg; };
>> E delegate() _front;
>> @property auto front() { return _front(); };
>> @property auto front(typeof(_front) dg) { _front = dg; };
>> void delegate() popFront;
>> }
>>
> 
> Yes, I was thinking about this, but it adds unnecessary overhead. I want to 
> call delegates directly.

The compiler has to implement it internally exactly like that anyway. D's design
relies on such code being efficient - there is no preprocessor, no inline 
attribute and no macros. The trivial functions have to be inlined, if that
doesn't happen it's a compiler bug. Once inlined, there's no overhead.

> I think the whole idea is harmless because semantically, from the user 
> perspective, delegates and function pointers works just like normal 
> functions. So, why not?

I can see it being confusing and don't see much benefit - that's all. The 
current
syntax is just a little more verbose, and mixins could be used if this scheme 
had
to be used on a larger scale.

artur


Re: Calling delegate properties without parens

2012-04-15 Thread Piotr Szturmaj

Artur Skawina wrote:

On 04/15/12 03:01, Piotr Szturmaj wrote:

Artur Skawina wrote:

@property is for functions masquerading as data, i'm not sure extending it
to pointers and delegates would be a good idea. What you are asking for is
basically syntax sugar for:

 struct CommonInputRange(E)
 {
 bool delegate() _empty;
 @property auto empty() { return _empty(); };
 @property auto empty(typeof(_empty) dg) { _empty = dg; };
 E delegate() _front;
 @property auto front() { return _front(); };
 @property auto front(typeof(_front) dg) { _front = dg; };
 void delegate() popFront;
 }



Yes, I was thinking about this, but it adds unnecessary overhead. I want to 
call delegates directly.


The compiler has to implement it internally exactly like that anyway. D's design
relies on such code being efficient - there is no preprocessor, no inline
attribute and no macros. The trivial functions have to be inlined, if that
doesn't happen it's a compiler bug. Once inlined, there's no overhead.


I wondered if properties can be inlined that way. But you have conviced 
me that indeed, inlining should help here. So, I'll use proxy 
properties. Thanks for your advice.


Re: Calling delegate properties without parens

2012-04-15 Thread Piotr Szturmaj

Jonathan M Davis wrote:

On Saturday, April 14, 2012 20:47:20 Piotr Szturmaj wrote:


struct CommonInputRange(E)
{
  @property bool delegate() empty;
  @property E delegate() front;
  void delegate() popFront;
}


front returns an element in the range. In your case, it's returning a
delegate, because you have a range of delegates.


Gah. That explains everything... Thanks!