View mode: basic / threaded / horizontal-split · Log in · Help
December 06, 2010
Re: const(Object)ref is here!
On Mon, 06 Dec 2010 08:47:33 -0500, Jason House  
<jason.james.house@gmail.com> wrote:

> Jonathan M Davis Wrote:
>
>> On Sunday 05 December 2010 23:59:58 so wrote:
>> > On Mon, 06 Dec 2010 02:51:32 +0200, Michel Fortin
>> >
>> > <michel.fortin@michelf.com> wrote:
>> > > <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
>> >
>> > Great!
>> >
>> > > See the strange predicate for the const(Object) version? That's  
>> because
>> > > opCmp() in Object doesn't work with const.
>> >
>> > For the same reason opEquals acting funny with const?
>>
>> Neither are marked as const on Object itself, and that needs to happen  
>> for
>> Object to be const correct. toHash() and toString() (or writeFrom() or  
>> whatever
>> it's going to become) have the same problem. None of them are const in  
>> Object.
>>
>> - Jonathan M Davis
>
> If object did that, things deriving from Object could not be lazy or  
> memoize. It occurs to me that things deriving from object should be able  
> to use const-correct functions and still compile. I don't have a D  
> compiler handy or I'd see how well dmd handles that. I'd expect changing  
> an input argument from T to const(T) should work since it's expanding  
> the range of valid inputs. Similarly, the method itself should be able  
> to become const since that too is expanding the valid input (to the  
> implicit first argument).

It doesn't work.  obj == obj calls .opEquals(obj, obj), whose signature is:

bool opEquals(Object obj1, Object obj2)

So even if you mark a derived instance's opEquals as const, the derived  
class is stripped back down to Object before any calls are made.

Memoization and lazy calculations are not as important as being able to  
compare const or immutable objects.

-Steve
December 06, 2010
Re: const(Object)ref is here!
> It doesn't work.  obj == obj calls .opEquals(obj, obj), whose signature  
> is:
>
> bool opEquals(Object obj1, Object obj2)
>
> So even if you mark a derived instance's opEquals as const, the derived  
> class is stripped back down to Object before any calls are made.
>
> Memoization and lazy calculations are not as important as being able to  
> compare const or immutable objects.
>
> -Steve

This one is a very serious issue.
Should changing their signatures to:
bool op###(auto ref const Object) const // breaking change but just  
signature

and addressing "auto ref" enough to fix it?

A few reports and Andrei's comment indicates that there is some  
misunderstanding(?) on semantics/implementation.
http://d.puremagic.com/issues/show_bug.cgi?id=4215#c4
http://d.puremagic.com/issues/show_bug.cgi?id=4668
http://d.puremagic.com/issues/show_bug.cgi?id=4258

With a glance to source code, looks like all that is required is just a  
few lines of change.

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 06, 2010
Re: const(Object)ref is here!
On Mon, 06 Dec 2010 10:11:30 -0500, so <so@so.do> wrote:

>> It doesn't work.  obj == obj calls .opEquals(obj, obj), whose signature  
>> is:
>>
>> bool opEquals(Object obj1, Object obj2)
>>
>> So even if you mark a derived instance's opEquals as const, the derived  
>> class is stripped back down to Object before any calls are made.
>>
>> Memoization and lazy calculations are not as important as being able to  
>> compare const or immutable objects.
>>
>> -Steve
>
> This one is a very serious issue.
> Should changing their signatures to:
> bool op###(auto ref const Object) const // breaking change but just  
> signature
>
> and addressing "auto ref" enough to fix it?

auto ref doesn't matter, these are classes, they are always ref ;)

All that is needed is to make opEquals const (and its arguments const) as  
you say.

> With a glance to source code, looks like all that is required is just a  
> few lines of change.

It should be relatively painless.  Just change the signatures of the base  
functions, and fix any compile errors.

-Steve
December 06, 2010
Re: const(Object)ref is here!
On 2010-12-06 00:16:27 -0500, Graham St Jack 
<Graham.StJack@internode.on.net> said:

> First, I have to say that it is wonderful that someone is taking a 
> serious look at this area again, and even better, you have come up with 
> a compiler patch to make it happen!
> 
> Some questions (assuming your patch or something like it gets into dmd):
> 
> Does this mean that I would be able to write this:
> immutable(Foo)ref foo; // create a reference
> foo = new immutable(Foo)(); // re-bind it (not sure about "new" syntax 
> for immutables)

That's the whole point yes. This syntax works with my patch. :-)


> Are there any other show-stopping syntax issues that are holding up 
> widespread adoption/rollout of const-correctness?

Surly there are others issues to solve. But this one is the one I kept 
falling into when trying to use immutable objects in my code some time 
ago.


> What do Walter and Andrei think?

That I'd like to know.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
December 06, 2010
Re: const(Object)ref is here!
Actually I really like the optional usage of ref here because it might
help to disambiguate between a class and a struct object:

E.g.:

class Foo
{
}

struct Bar
{
}

void main()
{
   Foo ref foo;  // I can be sure Foo is a class
   Bar bar;
}

Sometimes it happens that I forget to 'new' a class object, and to the
naked eye the code doesn't appear wrong, but using the optional ref
keyword helps in tracking this kind of bug down. I guess the compiler
should throw an error in cases where Foo is a struct.
December 06, 2010
Re: const(Object)ref is here!
On 2010-12-06 13:35:27 -0500, Andrej Mitrovic 
<andrej.mitrovich@gmail.com> said:

> Actually I really like the optional usage of ref here because it might
> help to disambiguate between a class and a struct object:
> 
> E.g.:
> 
> class Foo
> {
> }
> 
> struct Bar
> {
> }
> 
> void main()
> {
>     Foo ref foo;  // I can be sure Foo is a class
>     Bar bar;
> }
> 
> Sometimes it happens that I forget to 'new' a class object, and to the
> naked eye the code doesn't appear wrong, but using the optional ref
> keyword helps in tracking this kind of bug down. I guess the compiler
> should throw an error in cases where Foo is a struct.

It does (throw an error in cases where Foo is a struct). I never though 
of this usage. :-)

Since we're speaking of the optional use of 'ref', here's a little quiz:

	alias Object A;
	alias Object ref B;

	A ref a;
	B ref b;

What happens here? Should there be an error somewhere? Where? Also, 
what happens if we apply different modifiers at different places?


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
December 06, 2010
Re: const(Object)ref is here!
On Mon, 06 Dec 2010 13:44:41 -0500, Michel Fortin  
<michel.fortin@michelf.com> wrote:

> On 2010-12-06 13:35:27 -0500, Andrej Mitrovic  
> <andrej.mitrovich@gmail.com> said:
>
>> Actually I really like the optional usage of ref here because it might
>> help to disambiguate between a class and a struct object:
>>  E.g.:
>>  class Foo
>> {
>> }
>>  struct Bar
>> {
>> }
>>  void main()
>> {
>>     Foo ref foo;  // I can be sure Foo is a class
>>     Bar bar;
>> }
>>  Sometimes it happens that I forget to 'new' a class object, and to the
>> naked eye the code doesn't appear wrong, but using the optional ref
>> keyword helps in tracking this kind of bug down. I guess the compiler
>> should throw an error in cases where Foo is a struct.
>
> It does (throw an error in cases where Foo is a struct). I never though  
> of this usage. :-)
>
> Since we're speaking of the optional use of 'ref', here's a little quiz:
>
> 	alias Object A;
> 	alias Object ref B;
>
> 	A ref a;
> 	B ref b;
>
> What happens here? Should there be an error somewhere? Where? Also, what  
> happens if we apply different modifiers at different places?

alias Object ref B should be the same as alias Object B, since Object ref  
is the same type as Object.

So there should be no error.

Now, what happens for this:

alias const(Object) ref A;

A ref a;

My gut says this should be the same error as trying to ref a struct.  But  
I can see it also being allowed.

-Steve
December 06, 2010
Re: const(Object)ref is here!
On Monday, December 06, 2010 05:41:42 Steven Schveighoffer wrote:
> On Mon, 06 Dec 2010 04:44:07 -0500, spir <denis.spir@gmail.com> wrote:
> > On Mon, 6 Dec 2010 00:31:41 -0800
> > 
> > Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> >> toString() (or writeFrom() or whatever
> >> it's going to become)
> > 
> > guess it was writeTo() ;-) but "writeFrom" is nice as well, we should
> > find some useful use for it
> 
> It was proposed as writeTo, but I'm not opposed to a different name.

I have no problem with writeTo(). I just couldn't remember what it was and 
didn't want to take the time to look it up, and the name isn't as obvious as 
toString(), since it's not a standard name which exists in other languages, and 
it isn't actually returning anything. Whether it's to or from would depend on 
how you look at it - to the given delegate or from the object. But writeTo() is 
fine. Once it's used, it'll be remembered.

> BTW, the proposal does properly mark writeTo as const.

Good. It figures that you'd remember given your general take on const.

- Jonathan M Davis
December 06, 2010
Re: const(Object)ref is here!
On Monday, December 06, 2010 07:37:27 Steven Schveighoffer wrote:
> On Mon, 06 Dec 2010 10:11:30 -0500, so <so@so.do> wrote:
> >> It doesn't work.  obj == obj calls .opEquals(obj, obj), whose signature
> >> is:
> >> 
> >> bool opEquals(Object obj1, Object obj2)
> >> 
> >> So even if you mark a derived instance's opEquals as const, the derived
> >> class is stripped back down to Object before any calls are made.
> >> 
> >> Memoization and lazy calculations are not as important as being able to
> >> compare const or immutable objects.
> >> 
> >> -Steve
> > 
> > This one is a very serious issue.
> > Should changing their signatures to:
> > bool op###(auto ref const Object) const // breaking change but just
> > signature
> > 
> > and addressing "auto ref" enough to fix it?
> 
> auto ref doesn't matter, these are classes, they are always ref ;)
> 
> All that is needed is to make opEquals const (and its arguments const) as
> you say.
> 
> > With a glance to source code, looks like all that is required is just a
> > few lines of change.
> 
> It should be relatively painless.  Just change the signatures of the base
> functions, and fix any compile errors.

And watch all the code break... I'll definitely welcome the change (it's probably 
the first bug that I voted on in bugzilla), but there will be tons of code broken 
by it, since you just _know_ that a lot of user code doesn't bother to make 
toString() and its friends const. It's still a change that needs to be made 
though. Being unable to properly compare const and immutable objects is 
crippling. Of course, it would be more of an issue if it were easier to actually 
create immutable objects which are classes rather than strcuts, but that's a 
separate issue.

- Jonathan M Davis
December 06, 2010
Re: const(Object)ref is here!
On Mon, 06 Dec 2010 14:04:43 -0500, Jonathan M Davis <jmdavisProg@gmx.com>  
wrote:

> On Monday, December 06, 2010 07:37:27 Steven Schveighoffer wrote:

>> It should be relatively painless.  Just change the signatures of the  
>> base
>> functions, and fix any compile errors.
>
> And watch all the code break... I'll definitely welcome the change (it's  
> probably
> the first bug that I voted on in bugzilla), but there will be tons of  
> code broken
> by it, since you just _know_ that a lot of user code doesn't bother to  
> make
> toString() and its friends const. It's still a change that needs to be  
> made
> though. Being unable to properly compare const and immutable objects is
> crippling. Of course, it would be more of an issue if it were easier to  
> actually
> create immutable objects which are classes rather than strcuts, but  
> that's a
> separate issue.

Yes, one of the issues is that const has a viral effect.  If you ignore  
const, none of your functions are const.  So if you use functions inside  
opEquals, those have to be marked as const, and so on.

But there are very few circumstances where opEquals needs to be marked as  
mutable.  If that is the case, there is something broken with your code  
(and you should fix it) or there's something wrong with code you use (and  
you'll have to insert casts to deal with it for now).  In a very small  
number of circumstances, non-const opEquals can be beneficial (such as  
caching data that is expensive to calculate).  We need to find another way  
to deal with that (I suggest having logical const, but that's not a  
popular idea with Walter :).  But it shouldn't detract from the  
requirements.  You can always circumvent if you need special cases.  I'd  
rather start from a solid const-supporting position and add holes where  
they make sense then start from a base that is full of holes and try to  
patch them slowly.

In many cases affixing const to your code is not just a simple 'slap a  
const on here'.  It can involve careful thought and possibly redesign.

But without these changes, const is very useless, the standard library  
needs to eat its own dogfood if we want to peddle it to others.

-Steve
1 2 3 4 5 6
Top | Discussion index | About this forum | D home