December 06, 2010
On Mon, 06 Dec 2010 14:00:17 -0500, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> 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.

I think writeTo sounds good because it will be called like this:

object.writeTo(sink);

BTW, writeTo was spir's idea: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=122335

But again, the name isn't critical to me (well, it is important but writeTo is not the be-all end-all of good names :).

>
>> BTW, the proposal does properly mark writeTo as const.
>
> Good. It figures that you'd remember given your general take on const.

:)

-Steve
December 06, 2010
On Mon, 6 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?

As I understand the (non-)semantics of 'ref', there should be no error. This code should considered by the compiler as equivalent to:
	Object a;
	Object b;

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

December 06, 2010
On 2010-12-06 14:46:51 -0500, spir <denis.spir@gmail.com> said:

> On Mon, 6 Dec 2010 13:44:41 -0500
> Michel Fortin <michel.fortin@michelf.com> wrote:
> 
>> 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?
> 
> As I understand the (non-)semantics of 'ref', there should be no error. Thi
> s code should considered by the compiler as equivalent to:
> 	Object a;
> 	Object b;

And that's what my patch does. It only gets confusing when you add modifiers:

	alias const(Object)ref A;
	alias const(Object ref) B;
	alias const(Object) C;

	A ref a;
	B ref b;
	C ref c;

With my patch, variables 'a', 'b', and 'c' are all of the same type: "const(Object)ref", the later 'ref' changing the constness of the reference specified in the 'B' alias.

Note that while this behaviour is allowed with an alias, it is *not* allowed directly, so you can't write this for instance:

	const(Object ref) ref d;

That's an error.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 06, 2010
On Mon, 06 Dec 2010 15:01:25 -0500, Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2010-12-06 14:46:51 -0500, spir <denis.spir@gmail.com> said:
>
>> On Mon, 6 Dec 2010 13:44:41 -0500
>> Michel Fortin <michel.fortin@michelf.com> wrote:
>>
>>> 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?
>>  As I understand the (non-)semantics of 'ref', there should be no error. Thi
>> s code should considered by the compiler as equivalent to:
>> 	Object a;
>> 	Object b;
>
> And that's what my patch does. It only gets confusing when you add modifiers:
>
> 	alias const(Object)ref A;
> 	alias const(Object ref) B;
> 	alias const(Object) C;
>
> 	A ref a;
> 	B ref b;
> 	C ref c;
>
> With my patch, variables 'a', 'b', and 'c' are all of the same type: "const(Object)ref", the later 'ref' changing the constness of the reference specified in the 'B' alias.
>
> Note that while this behaviour is allowed with an alias, it is *not* allowed directly, so you can't write this for instance:
>
> 	const(Object ref) ref d;
>
> That's an error.

I don't know if that's good.  Redundancy is OK as long as it is consistent.  If Object ref is treated as Object everywhere it is used, that helps to be able to explain how it works.

Similarly Object ref ref should probably reduce to Object.

We really need to ensure that all types using this notation are reduced to their canonical types internally.  Otherwise, strange results would occur.

-Steve
December 06, 2010
On 2010-12-06 15:14:28 -0500, "Steven Schveighoffer" <schveiguy@yahoo.com> said:

> On Mon, 06 Dec 2010 15:01:25 -0500, Michel Fortin  <michel.fortin@michelf.com> wrote:
> 
>> On 2010-12-06 14:46:51 -0500, spir <denis.spir@gmail.com> said:
>> 
>>> On Mon, 6 Dec 2010 13:44:41 -0500
>>> Michel Fortin <michel.fortin@michelf.com> wrote:
>>> 
>>>> 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?
>>>  As I understand the (non-)semantics of 'ref', there should be no  error. Thi
>>> s code should considered by the compiler as equivalent to:
>>> 	Object a;
>>> 	Object b;
>> 
>> And that's what my patch does. It only gets confusing when you add  modifiers:
>> 
>> 	alias const(Object)ref A;
>> 	alias const(Object ref) B;
>> 	alias const(Object) C;
>> 
>> 	A ref a;
>> 	B ref b;
>> 	C ref c;
>> 
>> With my patch, variables 'a', 'b', and 'c' are all of the same type:  "const(Object)ref", the later 'ref' changing the constness of the  reference specified in the 'B' alias.
>> 
>> Note that while this behaviour is allowed with an alias, it is *not*  allowed directly, so you can't write this for instance:
>> 
>> 	const(Object ref) ref d;
>> 
>> That's an error.
> 
> I don't know if that's good.  Redundancy is OK as long as it is  consistent.  If Object ref is treated as Object everywhere it is used,  that helps to be able to explain how it works.
> 
> Similarly Object ref ref should probably reduce to Object.
> 
> We really need to ensure that all types using this notation are reduced to  their canonical types internally.  Otherwise, strange results would occur.

Don't worry. Internally, my patch makes sure types "Object ref" and "Object" have the exact same internal representation. The double-ref check is a check against the syntax tree, not against the actual type. That's why it's still possible to have two 'ref' if one is in the alias definition and the other is part of the variable declaration.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 07, 2010
On 07/12/10 05:51, Steven Schveighoffer wrote:
> 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
Vote++

-- 
Graham St Jack

December 07, 2010
On Mon, 6 Dec 2010 15:01:25 -0500
Michel Fortin <michel.fortin@michelf.com> wrote:

> On 2010-12-06 14:46:51 -0500, spir <denis.spir@gmail.com> said:
> 
> > On Mon, 6 Dec 2010 13:44:41 -0500
> > Michel Fortin <michel.fortin@michelf.com> wrote:
> > 
> >> 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?
> > 
> > As I understand the (non-)semantics of 'ref', there should be no error. Thi
> > s code should considered by the compiler as equivalent to:
> > 	Object a;
> > 	Object b;
> 
> And that's what my patch does. It only gets confusing when you add modifiers:
> 
> 	alias const(Object)ref A;
> 	alias const(Object ref) B;
> 	alias const(Object) C;
> 
> 	A ref a;
> 	B ref b;
> 	C ref c;
> 
> With my patch, variables 'a', 'b', and 'c' are all of the same type: "const(Object)ref", the later 'ref' changing the constness of the reference specified in the 'B' alias.

Well, as your patch introduces the possibility to "const-en" the target of ref's, it _should_ have some meaning. Else, it leaves the language unconsistent, no? B & C are clearly synonym (constant references to objects), but A should not (references to constant objects). I see nothing wrong in having a type defined as one for <references to constant objects>, and in having this different from <constant references to objects>. Do I miss some point?

> [...]


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

December 07, 2010
Michel Fortin <michel.fortin@michelf.com> wrote:

> And that's what my patch does. It only gets confusing when you add modifiers:
>
> 	alias const(Object)ref A;
> 	alias const(Object ref) B;
> 	alias const(Object) C;
>
> 	A ref a;
> 	B ref b;
> 	C ref c;
>
> With my patch, variables 'a', 'b', and 'c' are all of the same type: "const(Object)ref", the later 'ref' changing the constness of the reference specified in the 'B' alias.

const(Object ref) is implicitly castable to const(Object) ref, no?

So to me, it seems all of these should be const(Object) ref.
Seeing Foo ref name, I read this as 'non-const reference to some
class'. IOW, if you want a rebindable reference to a class T, the type
of T should not affect what hoops you must jump through to get there.

-- 
Simen
December 07, 2010
On 2010-12-07 02:32:11 -0500, spir <denis.spir@gmail.com> said:

> On Mon, 6 Dec 2010 15:01:25 -0500
> Michel Fortin <michel.fortin@michelf.com> wrote:
> 
>> And that's what my patch does. It only gets confusing when you add modifi
> ers:
>> 
>> 	alias const(Object)ref A;
>> 	alias const(Object ref) B;
>> 	alias const(Object) C;
>> 
>> 	A ref a;
>> 	B ref b;
>> 	C ref c;
>> 
>> With my patch, variables 'a', 'b', and 'c' are all of the same type:
>> "const(Object)ref", the later 'ref' changing the constness of the
>> reference specified in the 'B' alias.
> 
> Well, as your patch introduces the possibility to "const-en" the target of
> ref's, it _should_ have some meaning. Else, it leaves the language unconsis
> tent, no? B & C are clearly synonym (constant references to objects), but A
>  should not (references to constant objects). I see nothing wrong in having
>  a type defined as one for <references to constant objects>, and in having
> this different from <constant references to objects>. Do I miss some poin

The point is that the 'ref' in in the 'b' and 'c' variable declaration has the effect of changing the ref from B and C from const to mutable, even for B where the ref was explicitly specified to be const. I was wondering if some people would find that surprising, but if I understand you well that's what you expect when seeing this, right?


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 07, 2010
On 2010-12-07 05:23:34 -0500, "Simen kjaeraas" <simen.kjaras@gmail.com> said:

> Michel Fortin <michel.fortin@michelf.com> wrote:
> 
>> And that's what my patch does. It only gets confusing when you add  modifiers:
>> 
>> 	alias const(Object)ref A;
>> 	alias const(Object ref) B;
>> 	alias const(Object) C;
>> 
>> 	A ref a;
>> 	B ref b;
>> 	C ref c;
>> 
>> With my patch, variables 'a', 'b', and 'c' are all of the same type:  "const(Object)ref", the later 'ref' changing the constness of the  reference specified in the 'B' alias.
> 
> const(Object ref) is implicitly castable to const(Object) ref, no?

Yes.


> So to me, it seems all of these should be const(Object) ref.
> Seeing Foo ref name, I read this as 'non-const reference to some
> class'. IOW, if you want a rebindable reference to a class T, the type
> of T should not affect what hoops you must jump through to get there.

Great. That's how it works. I'm glad to see it suits you.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/