November 15, 2006
== Quote from Chris Nicholson-Sauls (ibisbasenji@gmail.com)'s article
> > 2. Garbage collection must be avoided:
> >
> >   const class Scoped(T): T, Local {
> >     this(T object) {
> >       _object = object;
> >     }
> >     this.T {
> >       return _object;
> >     }
> >     private T _object;
> >   }
> >   Scoped(T) scoped(T)(T object) {
> >     return new Scoped!(T)(object);
> >   }
> >   class Foo {
> >     void foo() { ... }
> >   }
> >   void test() {
> >     Foo foo = scoped(new Foo());
> >     foo.foo();
> >     // foo is deleted here :)
> >   }
> >   void test2() {
> >     scoped(new Foo()).foo();
> >     // Foo instance is deleted here too! :D
> >   }
> I'm not so sure I understand how this is "avoiding" GC... it seems to be
/enforcing/ it.
> But its still a fascinating design concept.

Sorry, I expressed my "avoiding GC" idea very unclearly. What I meant was avoiding long GC runs, which occour when the system runs out of memory and a whole bunch of objects is checked for garbage. There are no guarantees about how long such a GC run may take. That's why real-time programs must avoid situations when system must GC unused objects. And by "real-time programs" I don't mean just mission-critical software that lives depend on, but also games and multimedia applications.

> If I want value semantics, I'll generally use a struct.  Just can't think of
cases right
> off hand where I'd want this.

Perhaps when you would need a "struct" to override some method. I'd like to see that the only difference between structs and classes is that structs don't have VMT table (and thereforce can't override methods). So, structs are in a sense 'lightweight' classes.

> Also, it makes me think of C# style properties -- and while I would like to see
them in D,
> I don't need constant false hope.  ;)

I like D-style properties much better :)

> > Also, get rid of static opCall
> Just: no.  Leave it be.

Well, I meant replace it with constructor (for structs). Or it can stay, but no struct can define both constructor and opCall.
November 15, 2006
Boris Kolar wrote:
> == Quote from Chris Nicholson-Sauls (ibisbasenji@gmail.com)'s article
> 
>>Also, it makes me think of C# style properties -- and while I would like to see
> 
> them in D,
> 
>>I don't need constant false hope.  ;)
> 
> 
> I like D-style properties much better :)
> 

Myself I really dislike D-style properties (as opposed to C# style).

Reason #1: delegate ambiguity

class Foo
{
    void delegate() m_bar;
    void delegate() bar() { return m_bar; }

    void func()
    {
        writefln( "..." );
    }

    this()
    {
        m_bar = &func;
    }
}

void main()
{
    Foo foo = new Foo();
    foo.bar(); // call foo.bar, or return the delegate m_bar?
}

If you think of properties as member variables, then this does not behave as expected - foo.bar() returns the delegate, but does not call it.  Thinking of foo.bar as a method that returns a delegate does cause the behaviour make sense, but then it's just shorthand for calling a method, and nothing more.

Reason #2:

No op*Assign.  This is why we have to type
array.length = array.length + 1;
instead of
array.length++;

Reason #3:

It's one more possible way to write code that just doesn't make sense. I suppose this isn't too bad since programmers tend to shoot for clarity, but I've run into it.

writefln = sqrt = 4.0f; // what?!?

...

So I see the current property syntax as nothing more than a shorthand for function/method calling.  It does not provide a means to wrap code around the getting and setting of member variables or have member variables with inheritance properties, because properties are not member variables they are methods.  I am a fast typer - I don't mind the extra 2 parens to call a function.  However, being a fast typer does not solve the delegate ambiguity (a bit of thought can, but that's what properties are supposed to save IMO).

Also I used C# properties a lot and enjoyed them thoroughly.  No problems there.

Well that's my case.  Could you explain why you prefer D-style properties, please?  I'd like to know if there are any significant advantages to having it this way.
November 15, 2006
== Quote from Chad J (gamerChad@_spamIsBad_gmail.com)'s article
> Reason #1: delegate ambiguity
> class Foo
> {
>      void delegate() m_bar;
>      void delegate() bar() { return m_bar; }
>      void func()
>      {
>          writefln( "..." );
>      }
>      this()
>      {
>          m_bar = &func;
>      }
> }
> void main()
> {
>      Foo foo = new Foo();
>      foo.bar(); // call foo.bar, or return the delegate m_bar?
> }
> If you think of properties as member variables, then this does not
> behave as expected - foo.bar() returns the delegate, but does not call
> it.  Thinking of foo.bar as a method that returns a delegate does cause
> the behaviour make sense, but then it's just shorthand for calling a
> method, and nothing more.

You're right, but it seems to me that your example is more of a hypothetical problem than a practical one. Not sold on reason #1 ;)

> Reason #2:
> No op*Assign.  This is why we have to type
> array.length = array.length + 1;
> instead of
> array.length++;

That convinced me. I remember now that I have stumbled on this problem as well. Still, a smart compiler might allow array.length++.

> Reason #3:
> It's one more possible way to write code that just doesn't make sense.
> I suppose this isn't too bad since programmers tend to shoot for
> clarity, but I've run into it.
> writefln = sqrt = 4.0f; // what?!?

That's a good one :) Never thought of that. Although it's merely a bad style - I always assume there are already infinite number of ways to write program in a cryptic style.

> Well that's my case.  Could you explain why you prefer D-style properties, please?  I'd like to know if there are any significant advantages to having it this way.

Well, I could never decide if a something is just a parameterless function, a property, or a field. In D, it's all used the same way.

You can, for example, build an early prototype by using a field and then turn it into a property (that, for example, logs every call).

Also, I like the fact that writing the parameterless function is exactly as verbose (not less, as in C#) than writing a read-only property.

Also, Eiffel and Wikipedia make some convincing arguments: http://www.eiffel.com/general/monthly_column/2005/Sept_October.html http://en.wikipedia.org/wiki/Uniform_access_principle
November 15, 2006
Bill Baxter wrote:
> Tomas Lindquist Olsen wrote:
>>
>> The main problem I have with the D spec is that a lot of stuff is very spread out, and finding the place where the detail you're looking for is, is often pretty hard.
> 
> Agreed.  I recommend using the comment page [click the button on the upper right of the spec page] to add cross references to things, and other findings about things that aren't clearly documented.
> 
> For instance on the operator overload page it doesn't mention opApply, which I think is the natural place you'd go to look for it.  But I added a link to where it can be found (statements, under 'foreach') on the comment page.
> 
> In general I think people should make more use of those comment pages. It's a very nice thing that Walter has added those links to every page of the spec.
> 
> --bb
Thanx for pointing this out, I had missed that button. I will definitely start using it, and in cases where I find something added appropriate, I will put it in the wiki!

Thanx again for the heads up :)
November 15, 2006
Boris Kolar wrote:
> == Quote from Chad J (gamerChad@_spamIsBad_gmail.com)'s article
> 
>>Reason #1: delegate ambiguity ...
> 
> 
> You're right, but it seems to me that your example is more of a hypothetical
> problem than a practical one. Not sold on reason #1 ;)
> 

It's practical, I've been bitten by it.  Otherwise I probably would have never thought about it.

> 
>>Reason #2:
>>No op*Assign.  This is why we have to type
>>array.length = array.length + 1;
>>instead of
>>array.length++;
> 
> 
> That convinced me. I remember now that I have stumbled on this problem
> as well. Still, a smart compiler might allow array.length++.
> 

A smart compiler won't save this.  That's because it will make the language depend on Quality Of Implementation (QOI).  If one were to write code while using said smart compiler, then the code gets moved to a 'dumb' compiler, the code will break if array.length++; was ever used.  This trashes the ability to easily port code between compilers.

> 
>>Reason #3:
>>It's one more possible way to write code that just doesn't make sense.
>>I suppose this isn't too bad since programmers tend to shoot for
>>clarity, but I've run into it.
>>writefln = sqrt = 4.0f; // what?!?
> 
> 
> That's a good one :) Never thought of that. Although it's merely a bad
> style - I always assume there are already infinite number of ways to
> write program in a cryptic style.
> 
> 
>>Well that's my case.  Could you explain why you prefer D-style
>>properties, please?  I'd like to know if there are any significant
>>advantages to having it this way.
> 
> 
> Well, I could never decide if a something is just a parameterless
> function, a property, or a field. In D, it's all used the same way.
> 
> You can, for example, build an early prototype by using a field and
> then turn it into a property (that, for example, logs every call).
> 

You would be able to do that with C# syntax too.  You just wouldn't be able to call it like a function.

IMO, calling a field is nonsensicle.  It's right alongside assigning to a function/method.

> Also, I like the fact that writing the parameterless function is
> exactly as verbose (not less, as in C#) than writing a read-only
> property.
> 

Maybe C# properties aren't perfect :)  Perhaps we can work on this...

> Also, Eiffel and Wikipedia make some convincing arguments:
> http://www.eiffel.com/general/monthly_column/2005/Sept_October.html
> http://en.wikipedia.org/wiki/Uniform_access_principle

I think that D fails to acheive UAP with the current property syntax.

foo.bar++; // implies field.

This betrays whether bar is implemented through storage or computation - it is implied that bar is implemented through storage.
I'm going to venture an educated guess that Eiffel does not have such opOperateApply type operators.  Ditch the ++, --, +=, -=, *=, etc. and UAP is restored.

Also:

int a = foo.bar(); // implies method

Now we know that bar is implemented through computation.

One important feature of UAP seems to be that it allows you to change the implementation of any object member without breaking code that uses that member.  D fails here, due to the above.  Indeed, this is the part I forgot to mention in my earlier post.  It is a corollary to Reason#2, and IMO a much more important reason to ditch the current syntax than having to write opOperateAssign the longhand way.

C# style syntax does break UAP as well, but I argue that it does not do so in a very damaging way.  Suppose you want to change a member from being a field, to being a method.  Why?  The reason I see is to add extra functionality to the field, as in logging, inheritance, program state update, etc.  Another would be to use fields and methods interchangably.  The former I find valuable, and C# accomplishes it. The latter I find nonsensicle in many cases (writefln = 2;), and C# prohibits it.  Now, suppose you want to change a member from being a method to being a field.  Why?  I see two reasons.  One is to reduce the code size of the method from small to slightly smaller (it was small already since you can reduce almost all functionality by simply writing func() { return m_val; }).  The other is to use fields and methods interchangably.  I don't see much value in the former, and am still opposed to the latter, so the fact that C# doesn't really support this is fine by me.

Another good argument leveled against C# style properties: too much keyword usage.  This shouldn't be too difficult to fix.

prop int getter()
{
	return myval;
}

prop void setter( int toAssign )
{
	myval = toAssign;
}

Now it has been reduced to one extra keyword, 'prop'.  Also, most of the current behaviour of D's properties is maintained.  Indeed, these may not necessarily even be in classes or structs, but also modules and functions and other scopes, as they can be nowadays.  It also seems to give the compiler all of the information it needs to determine usage in an easy and straightforward fashion.

There was also a suggestion to allow methods without parens

int foo
{
	return 5;
}

void main()
{
	writefln( foo ); // prints 5
}

No new keyword, but it breaks for setters.
hmmmm, maybe something like this for the setters:

private int m_assignable;
void foo[ int toAssign ]
{
	m_assignable = toAssign;
}

Or other possibilities:

void foo.( int toAssign ) {...}
void foo!{ int toAssign } {...}
void foo.{ int toAssign } {...}
void foo.[ int toAssign ] {...}
and so on...

Or perhaps the paren-less suggestion above, with an implicit variable defined like in variadic functions.  Let's call it _arg.  (perhaps it could be prettier?)

void foo
{
	m_assignable = _arg;
}

Perhaps it should be mandated in the above case that the function does not have a return type, in order to help the compiler tell at first glance that it is indeed a setter.

I'm sure there are many other possibilities, more than one of which are viable.
4 5 6 7 8 9 10 11 12 13 14
Next ›   Last »