digitalmars.D - const(Object)ref is here!
- Michel Fortin <michel.fortin michelf.com> Dec 05 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Dec 05 2010
- Graham St Jack <Graham.StJack internode.on.net> Dec 05 2010
- Michel Fortin <michel.fortin michelf.com> Dec 06 2010
- Michel Fortin <michel.fortin michelf.com> Dec 06 2010
- Michel Fortin <michel.fortin michelf.com> Dec 06 2010
- Michel Fortin <michel.fortin michelf.com> Dec 06 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Jason House <jason.james.house gmail.com> Dec 07 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Dec 07 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Dec 07 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Michel Fortin <michel.fortin michelf.com> Dec 07 2010
- Jason House <jason.james.house gmail.com> Dec 08 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- spir <denis.spir gmail.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- spir <denis.spir gmail.com> Dec 06 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Dec 07 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 07 2010
- so <so so.do> Dec 05 2010
- Jonathan M Davis <jmdavisProg gmx.com> Dec 06 2010
- Jason House <jason.james.house gmail.com> Dec 06 2010
- Jason House <jason.james.house gmail.com> Dec 06 2010
- spir <denis.spir gmail.com> Dec 06 2010
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Dec 21 2010
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Dec 21 2010
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Jan 27 2011
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Jan 27 2011
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Jan 28 2011
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Jan 28 2011
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Feb 01 2011
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Jan 27 2011
- "Simen kjaeraas" <simen.kjaras gmail.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- so <so so.do> Dec 06 2010
- Jonathan M Davis <jmdavisProg gmx.com> Dec 06 2010
- Graham St Jack <Graham.StJack internode.on.net> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- Jonathan M Davis <jmdavisProg gmx.com> Dec 06 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 06 2010
- Walter Bright <newshound2 digitalmars.com> Dec 08 2010
- Michel Fortin <michel.fortin michelf.com> Dec 08 2010
- Walter Bright <newshound2 digitalmars.com> Dec 08 2010
- Michel Fortin <michel.fortin michelf.com> Dec 08 2010
- Walter Bright <newshound2 digitalmars.com> Dec 08 2010
- Michel Fortin <michel.fortin michelf.com> Dec 08 2010
- Jason House <jason.james.house gmail.com> Dec 08 2010
- Walter Bright <newshound2 digitalmars.com> Dec 08 2010
- Don <nospam nospam.com> Dec 10 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 08 2010
- Fawzi Mohamed <fawzi gmx.ch> Dec 10 2010
- Michal Minich <michal.minich gmail.com> Dec 10 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 10 2010
- Fawzi Mohamed <fawzi gmx.ch> Dec 10 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 21 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Dec 21 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Dec 21 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Dec 21 2010
After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325> Let's hope Walter likes my patch. In the tail-const thread, I proposed the challenge of making this code work when an array of const object is passed as an argument: T[] giveMeASortedArray(alias Predicate, T)(T[] t) { // creating new array of the same length but with assignable elements auto copy = new Unqual!(typeof(t[0]))[t.length]; foreach (index, value; t) copy[index] = value; // sorting the copy sort!(Predicate)(copy); return copy; } Well, with the patch I made it now works!... irrespective of the type attribute (const,immutable,shared,inout). The only modification required to Phobos is to make to!string() compile when passed a const(Object) because somehow 'sort' requires that. Here is how the function is invoked: void main() { int*[] a = giveMeASortedArray!("a < b")(new int*[12]); Object[] b = giveMeASortedArray!("a < b")(new Object[12]); const(int*)[] c = giveMeASortedArray!("a < b")(new const(int*)[12]); const(Object)[] d = giveMeASortedArray!("cast(void*)a < cast(void*)b")(new const(Object)[12]); } See the strange predicate for the const(Object) version? That's because opCmp() in Object doesn't work with const. Two minor modifications are required in Phobos to make the above compile. First, to!string(const(Object)) needs an implementation because somehow 'sort' requires it. Also template std.traits.isMutable needed an adjustment so that swap()'s template constrains are satisfied. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 05 2010
That was fast. 0o :) On 12/6/10, Michel Fortin <michel.fortin michelf.com> wrote:After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325> Let's hope Walter likes my patch. In the tail-const thread, I proposed the challenge of making this code work when an array of const object is passed as an argument: T[] giveMeASortedArray(alias Predicate, T)(T[] t) { // creating new array of the same length but with assignable elements auto copy = new Unqual!(typeof(t[0]))[t.length]; foreach (index, value; t) copy[index] = value; // sorting the copy sort!(Predicate)(copy); return copy; } Well, with the patch I made it now works!... irrespective of the type attribute (const,immutable,shared,inout). The only modification required to Phobos is to make to!string() compile when passed a const(Object) because somehow 'sort' requires that. Here is how the function is invoked: void main() { int*[] a = giveMeASortedArray!("a < b")(new int*[12]); Object[] b = giveMeASortedArray!("a < b")(new Object[12]); const(int*)[] c = giveMeASortedArray!("a < b")(new const(int*)[12]); const(Object)[] d = giveMeASortedArray!("cast(void*)a < cast(void*)b")(new const(Object)[12]); } See the strange predicate for the const(Object) version? That's because opCmp() in Object doesn't work with const. Two minor modifications are required in Phobos to make the above compile. First, to!string(const(Object)) needs an implementation because somehow 'sort' requires it. Also template std.traits.isMutable needed an adjustment so that swap()'s template constrains are satisfied. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 05 2010
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) Are there any other show-stopping syntax issues that are holding up widespread adoption/rollout of const-correctness? What do Walter and Andrei think? Does anyone know what the plan is for rolling const-correctness thoughout druntime and phobos (and shared/immutable in std.concurrency)? Having to do casting all the time is a real drag. I for one would be happy to help if help is needed. On 06/12/10 11:21, Michel Fortin wrote:After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325> Let's hope Walter likes my patch. In the tail-const thread, I proposed the challenge of making this code work when an array of const object is passed as an argument: T[] giveMeASortedArray(alias Predicate, T)(T[] t) { // creating new array of the same length but with assignable elements auto copy = new Unqual!(typeof(t[0]))[t.length]; foreach (index, value; t) copy[index] = value; // sorting the copy sort!(Predicate)(copy); return copy; } Well, with the patch I made it now works!... irrespective of the type attribute (const,immutable,shared,inout). The only modification required to Phobos is to make to!string() compile when passed a const(Object) because somehow 'sort' requires that. Here is how the function is invoked: void main() { int*[] a = giveMeASortedArray!("a < b")(new int*[12]); Object[] b = giveMeASortedArray!("a < b")(new Object[12]); const(int*)[] c = giveMeASortedArray!("a < b")(new const(int*)[12]); const(Object)[] d = giveMeASortedArray!("cast(void*)a < cast(void*)b")(new const(Object)[12]); } See the strange predicate for the const(Object) version? That's because opCmp() in Object doesn't work with const. Two minor modifications are required in Phobos to make the above compile. First, to!string(const(Object)) needs an implementation because somehow 'sort' requires it. Also template std.traits.isMutable needed an adjustment so that swap()'s template constrains are satisfied.
-- Graham St Jack
Dec 05 2010
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/
Dec 06 2010
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/
Dec 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/
Dec 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?
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/
Dec 06 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
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/
Dec 07 2010
Michel Fortin Wrote: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?
I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations. I think the array case would be missed. I'm not sure what people would think of the template case, especially when it pops up in code such as foo!(typeof(x)). If ref isn't a storage class, then generic programmers will need an equivalent to unqual that only strips the outer-most ref. As a storage class typeof would not return the ref. How do templates work with your patch?
Dec 07 2010
On 2010-12-07 09:05:20 -0500, Jason House <jason.james.house gmail.com> said:Michel Fortin Wrote: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?
I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations. I think the array case would be missed. I'm not sure what people would think of the template case, especially when it pops up in code such as foo!(typeof(x)). If ref isn't a storage class, then generic programmers will need an equivalent to unqual that only strips the outer-most ref. As a storage class typeof would not return the ref. How do templates work with your patch?
From my tests, templates work as they should. For instance, I can easily call std.algorithm.sort on an array of const(Object)ref. Which brings the question: how do you do that if 'ref' is a storage class? :-) The way I implemented the feature in the compiler is that I added the notion of head-modifiers for types. For most types, head-modifiers are just a pointer to the regular modifiers, so they're always identical. But for a class type, encountering a 'ref' suffix changes the head-modifiers to match those applied to the suffix. Then when declaring a variable, when the compiler deduces the storage class for that variable from its type, I changed it so it checks the head-modifiers of the type instead of its regular modifiers. A few other tweaks like that were required to make it work with foreach and array ops, but the end result is a very small change to the compiler that fits reasonably well within the type system. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 07 2010
On 12/7/10 7:05 AM, Michel Fortin wrote:On 2010-12-07 09:05:20 -0500, Jason House <jason.james.house gmail.com> said:Michel Fortin Wrote: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?
I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations. I think the array case would be missed. I'm not sure what people would think of the template case, especially when it pops up in code such as foo!(typeof(x)). If ref isn't a storage class, then generic programmers will need an equivalent to unqual that only strips the outer-most ref. As a storage class typeof would not return the ref. How do templates work with your patch?
From my tests, templates work as they should. For instance, I can easily call std.algorithm.sort on an array of const(Object)ref.
Does it work on a general random-access range? Generally, does the feature have a solution for all issues discussed? Andrei
Dec 07 2010
On 2010-12-07 11:15:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 12/7/10 7:05 AM, Michel Fortin wrote:From my tests, templates work as they should. For instance, I can easily call std.algorithm.sort on an array of const(Object)ref.
Does it work on a general random-access range?
It should. Let's try: auto array = new const(Object)ref[12]; auto range = retro(array); sort!("cast(void*)a < cast(void*)b")(range); Compiles and runs with no error. Also, if I put actual objects in the array, I can see they're properly sorted.Generally, does the feature have a solution for all issues discussed?
It fixes all issues about mutable references to const classes that I can think of. But it's hard to see if I missed something without a proper checklist. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 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/
Dec 07 2010
On 12/6/10 9:56 AM, Michel Fortin wrote: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.
I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch. Also providing precompiled binaries would help people who don't care to build their own compiler. Andrei
Dec 07 2010
On 2010-12-07 11:09:50 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 12/6/10 9:56 AM, Michel Fortin wrote: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.
I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch.
The patch itself is documented in the bug tracker where it resides. It lacks some details about the internal implementation, but beside that I'm not sure how more elaborate the documentation should be. D's documentation doesn't tell about every corner case of the language either. <http://d.puremagic.com/issues/show_bug.cgi?id=5325>Also providing precompiled binaries would help people who don't care to build their own compiler.
I can easily provide one for Mac OS X. Can someone else build it for Linux and Windows? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 07 2010
On 2010-12-07 12:54:49 -0500, Michel Fortin <michel.fortin michelf.com> said:On 2010-12-07 11:09:50 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 12/6/10 9:56 AM, Michel Fortin wrote: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.
I think actually offering a patch is a great initiative! I think the syntax is not all that intuitive, but it's great to experiment with. Michel, I suggest you put together some documentation (instead of implicitly referring to an earlier newsgroup discussion) so the community knows what to expect from the patch.
The patch itself is documented in the bug tracker where it resides. It lacks some details about the internal implementation, but beside that I'm not sure how more elaborate the documentation should be. D's documentation doesn't tell about every corner case of the language either. <http://d.puremagic.com/issues/show_bug.cgi?id=5325>Also providing precompiled binaries would help people who don't care to build their own compiler.
I can easily provide one for Mac OS X. Can someone else build it for Linux and Windows?
Here is a Mac OS X build. It's based on SVN revision 780 (two days old). It's a debug build so it might run a little slower than release versions of the compiler. <http://michelf.com/docs/d/dmd-rev780-objconst.zip> You should be able to use it with druntime either from DMD 2.050 or the latest SVN (nothing needs to be patched in druntime). Phobos unittests will pass (except for Rebindable tests, Rebindable itself works fine but some assertions the unittests aren't expecting the new type). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 07 2010
Andrei Alexandrescu Wrote:What do Walter and Andrei think?
That I'd like to know.
I think actually offering a patch is a great initiative!
Yeah, it's great initiative. Working prototypes really make it easy to fully evaluate an option and require almost no effort to formally adopt.I think the syntax is not all that intuitive, but it's great to experiment with.
Really? Back when this stuff was actively being bikeshedded, it was my favorite syntax for this feature. Since then, a somewhat conflicting feature was added: auto ref. I saw some posts recently about tail being someone else's favorite, but I personally like the ref syntax better. Basically, reference types have an implicit ref which you can manually specify to disambiguate your intention with const stuff.
Dec 08 2010
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.
Dec 06 2010
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
Dec 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=20 <andrej.mitrovich gmail.com> said: =20Actually I really like the optional usage of ref here because it might help to disambiguate between a class and a struct object: =20 E.g.: =20 class Foo { } =20 struct Bar { } =20 void main() { Foo ref foo; // I can be sure Foo is a class Bar bar; } =20 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=20 of this usage. :-) =20 Since we're speaking of the optional use of 'ref', here's a little quiz: =20 alias Object A; alias Object ref B; =20 A ref a; B ref b; =20 What happens here? Should there be an error somewhere? Where? Also,=20 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; Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 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?
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
Dec 06 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: =20On Mon, 6 Dec 2010 13:44:41 -0500 Michel Fortin <michel.fortin michelf.com> wrote: =20Since we're speaking of the optional use of 'ref', here's a little qui=
=20 alias Object A; alias Object ref B; =20 A ref a; B ref b; =20 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.=
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 modifi=
=20 alias const(Object)ref A; alias const(Object ref) B; alias const(Object) C; =20 A ref a; B ref b; C ref c; =20 With my patch, variables 'a', 'b', and 'c' are all of the same type:=20 "const(Object)ref", the later 'ref' changing the constness of the=20 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 point?[...]
Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 06 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
Dec 07 2010
On Tue, 07 Dec 2010 09:05:20 -0500, Jason House <jason.james.house gmail.com> wrote:Michel Fortin Wrote: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?
I've been wondering if it makes more sense for 'ref' to be a storage class rather than some kind of type constructor. Doing that would make the typedef's with ref be illegal. It'd also make foo!(const(T) ref) be illegal as well as (const(T) ref)[]. As a storage class, it can only be added to variable declarations.
IIUC, I think ref in this case is a type modifier. There are other examples of keywords that are both storage classes and type modifiers (const, shared). -Steve
Dec 07 2010
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? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 05 2010
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
Dec 06 2010
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).
Dec 06 2010
Jason House 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).
I should have added: if anyone tests making derived object's methods const-correct and it fails to compile, then it should be filed into bugzilla.
Dec 06 2010
On Mon, 6 Dec 2010 00:31:41 -0800 Jonathan M Davis <jmdavisProg gmx.com> wrote:toString() (or writeFrom() or whatever=20 it's going to become)
guess it was writeTo() ;-) but "writeFrom" is nice as well, we should find = some useful use for it Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Dec 06 2010
On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time) -- Bruno Medeiros - Software Engineer
Dec 21 2010
On 12/21/10 12:19 PM, Steven Schveighoffer wrote:On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Conversion to text should be called toText. That makes the essence of the function visible (it emits characters) without tying the representation of the text. Andrei
Dec 21 2010
On 21/12/2010 19:17, Andrei Alexandrescu wrote:On 12/21/10 12:19 PM, Steven Schveighoffer wrote:On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Conversion to text should be called toText. That makes the essence of the function visible (it emits characters) without tying the representation of the text. Andrei
I don't understand this point. The representation of the text is tied, it's going to be char[] ( aka UTF-8). Unless you were planning to have overloads of toText, but that sounds like an awful idea. -- Bruno Medeiros - Software Engineer
Jan 27 2011
On 1/27/11 9:33 AM, Bruno Medeiros wrote:On 21/12/2010 19:17, Andrei Alexandrescu wrote:On 12/21/10 12:19 PM, Steven Schveighoffer wrote:On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Conversion to text should be called toText. That makes the essence of the function visible (it emits characters) without tying the representation of the text. Andrei
I don't understand this point. The representation of the text is tied, it's going to be char[] ( aka UTF-8). Unless you were planning to have overloads of toText, but that sounds like an awful idea.
Could be wchar or dchar. Andrei
Jan 27 2011
On 27/01/2011 18:12, Andrei Alexandrescu wrote:On 1/27/11 9:33 AM, Bruno Medeiros wrote:On 21/12/2010 19:17, Andrei Alexandrescu wrote:On 12/21/10 12:19 PM, Steven Schveighoffer wrote:On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Conversion to text should be called toText. That makes the essence of the function visible (it emits characters) without tying the representation of the text. Andrei
I don't understand this point. The representation of the text is tied, it's going to be char[] ( aka UTF-8). Unless you were planning to have overloads of toText, but that sounds like an awful idea.
Could be wchar or dchar. Andrei
You mean to say that there would be three possible signatures for toText (for char[], wchar[], dchar[]), that the class coder can choose? But of course, the coder would only need to define one, right? (otherwise that would be the awful idea) -- Bruno Medeiros - Software Engineer
Jan 28 2011
On 1/28/11 5:37 AM, Bruno Medeiros wrote:You mean to say that there would be three possible signatures for toText (for char[], wchar[], dchar[]), that the class coder can choose? But of course, the coder would only need to define one, right? (otherwise that would be the awful idea)
Probably standardizing on one width is a good idea. Andrei
Jan 28 2011
On 28/01/2011 15:19, Andrei Alexandrescu wrote:On 1/28/11 5:37 AM, Bruno Medeiros wrote:You mean to say that there would be three possible signatures for toText (for char[], wchar[], dchar[]), that the class coder can choose? But of course, the coder would only need to define one, right? (otherwise that would be the awful idea)
Probably standardizing on one width is a good idea. Andrei
Indeed. -- Bruno Medeiros - Software Engineer
Feb 01 2011
On 21/12/2010 18:19, Steven Schveighoffer wrote:On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis wrote:On Monday, December 06, 2010 05:41:42 Steven Schveighoffer wrote: 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Sorry for the long delay in replying.. I don't have any specific favorite name. Could be writeString, asString, stringWrite, ouputString, even toString (despite a different signature from other languages), etc. Or a similar name with Text instead of String, as Andrei suggested (although I'm not 100% sure about that last one). It's just that I would prefer the String connotation to be implied in the function name, not just implied in the parameter (makes the code clearer, in a somewhat subjective opinion). And also to not take up the "writeTo" overload in all Objects ever, as some might want to use that overload name for their own stuff. -- Bruno Medeiros - Software Engineer
Jan 27 2011
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
This reminded me of INTERCAL's WRITE IN and READ OUT. -- Simen
Dec 06 2010
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. BTW, the proposal does properly mark writeTo as const. -Steve
Dec 06 2010
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
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
Dec 06 2010
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/
Dec 06 2010
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
Dec 06 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
-- Graham St Jack
Dec 06 2010
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
Dec 06 2010
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
Dec 06 2010
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
Dec 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
Dec 06 2010
Michel Fortin wrote:After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
I think it's great that you're trying this out. I failed at getting tail const to work. I don't think it can work, but I might be wrong.
Dec 08 2010
On 2010-12-08 03:43:45 -0500, Walter Bright <newshound2 digitalmars.com> said:Michel Fortin wrote:After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
I think it's great that you're trying this out. I failed at getting tail const to work. I don't think it can work, but I might be wrong.
Is there something I can do to convince you this patch works? Because it does. There is still some rough edges for which I wasn't sure what was the best solution -- head-modifiers not reflected in TypeInfo or with is(T == const) -- but they're relatively minor and easy to fix once we know what we want. By the way, I pushed this into a separate branch in my dmd-objc git repository (this branch does not include the Objective-C-related changes). So you can get the source with the patch pre-applied this way: git clone http://git.michelf.com/dmd-objc/ cd dmd-objc git checkout objconst -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 08 2010
Michel Fortin wrote:On 2010-12-08 03:43:45 -0500, Walter Bright <newshound2 digitalmars.com> said:Michel Fortin wrote:After a recent discussion on this list about tail-const class references, it became rather clear that someone interested would have to implement the thing if we were to have it. So I did it. See enhancement request 5325 for an explanation and a patch. <http://d.puremagic.com/issues/show_bug.cgi?id=5325>
I think it's great that you're trying this out. I failed at getting tail const to work. I don't think it can work, but I might be wrong.
Is there something I can do to convince you this patch works? Because it does. There is still some rough edges for which I wasn't sure what was the best solution -- head-modifiers not reflected in TypeInfo or with is(T == const) -- but they're relatively minor and easy to fix once we know what we want.
I haven't been able to look at it yet. But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test: 1. auto variable declarations 2. typeof 3. mangleof 4. template type deduction 5. interaction with inout 6. arrays of, pointers to, functions returning 7. tail const functions 8. tail immutable 9. tail shared const 10. tail inout
Dec 08 2010
On 2010-12-08 14:17:10 -0500, Walter Bright <newshound2 digitalmars.com> said:I haven't been able to look at it yet. But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test: 1. auto variable declarations 2. typeof 3. mangleof 4. template type deduction 5. interaction with inout 6. arrays of, pointers to, functions returning 7. tail const functions 8. tail immutable 9. tail shared const 10. tail inout
I've already tested most of this, but I'll make sure my unit tests cover it all. That said, what's a "tail const function"? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 08 2010
Michel Fortin wrote:That said, what's a "tail const function"?
applying tail const to a function type
Dec 08 2010
On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2 digitalmars.com> said:Michel Fortin wrote:That said, what's a "tail const function"?
applying tail const to a function type
You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works. Would you like some documentation on the changes I've made? This might be useful when reviewing it. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 08 2010
Michel Fortin Wrote:On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2 digitalmars.com> said:Michel Fortin wrote:That said, what's a "tail const function"?
applying tail const to a function type
You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works.
He might mean functions and delegates... A rebindable function pointer, etc... He might also mean a member function that is "const ref". If I understand your design, I don't those are allowed.
Dec 08 2010
Michel Fortin wrote:On 2010-12-08 17:26:02 -0500, Walter Bright <newshound2 digitalmars.com> said:Michel Fortin wrote:That said, what's a "tail const function"?
applying tail const to a function type
You mean as the return type? I'll add a unit test for that. But on the whole, I'd be very surprised to find problems in the list of things you mentioned given how the patch works. Would you like some documentation on the changes I've made? This might be useful when reviewing it.
A test suite for it would be better.
Dec 08 2010
Fawzi Mohamed wrote:If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code. Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects). In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer.
Any mutable object returned from a strongly pure function, is guaranteed to be unique.
Dec 10 2010
On Wed, 08 Dec 2010 15:21:38 -0500, Michel Fortin <michel.fortin michelf.com> wrote:On 2010-12-08 14:17:10 -0500, Walter Bright <newshound2 digitalmars.com> said:I haven't been able to look at it yet. But the const system in dmd is rather complex, and I'm not at all comfortable with saying it works without quite a lot of testing. Some things to test: 1. auto variable declarations 2. typeof 3. mangleof 4. template type deduction 5. interaction with inout 6. arrays of, pointers to, functions returning 7. tail const functions 8. tail immutable 9. tail shared const 10. tail inout
I've already tested most of this, but I'll make sure my unit tests cover it all. That said, what's a "tail const function"?
it's not necessary to have a tail-const function for a class. The only advantage of having a tail-const function would be if you wanted to change the 'this' pointer, which you shouldn't do anyways. tail-const for a struct would then require tail-const functions (and would require being able to mark member functions to pass 'this' by value), but I don't think your patch addresses those. Also note that inout doesn't really work at all, so I wouldn't bother testing anything with inout. -Steve
Dec 08 2010
It is nice that Michel Fortin made the effort to propose a patch trying to address the ability to rebind const objects. Looking at the "uglification" of my code to support const, I saw that many cases I actually had a unique type, or partially unique type. There are several examples of similar attempts, like linear types, or various uniqueness types systems (more or less related to the Clean example). It is known that some uniqueness settings are equivalent to shared, so maybe using uniqueness with const might be meaningful. This is a difficult topic, as pushing those concepts into the type system is always tricky, and the consequences of various choices are often non obvious, anyway here is what I thought. If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code. Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects). In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer. I did also think about having a front_unique attribute that can be applied to any local variable or argument that would make it tail const in the sense discussed previously, and still implicitly castable to full const. In that case the situation is more complex (one should ensure that local references cannot spill out, otherwise a full const is needed, and for immutable, making it immutable is "irreversible". The front_unique property can almost always be checked by the compiler, but activating it implicitly would have effects that would probably deemed surprising by the programmer (front_unique immutable objects would be rebindable). Thus I am not sold on front_unique, but I still find it interesting, due to its relationship with tail const. Fawzi
Dec 10 2010
V Fri, 10 Dec 2010 11:53:04 +0100, Don wrote:Any mutable object returned from a strongly pure function, is guaranteed to be unique.
the function should be probably be safe too, to guarentee to not cast const away.
Dec 10 2010
On Fri, 10 Dec 2010 07:40:49 -0500, Fawzi Mohamed <fawzi gmx.ch> wrote:On 10-dic-10, at 11:53, Don wrote:Fawzi Mohamed wrote:If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code. Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects). In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer.
Any mutable object returned from a strongly pure function, is guaranteed to be unique.
indeed good catch, I was saying that in some occasions the compiler can verify uniqueness, that is indeed an important case. But I don't understand if you want to imply that uniqueness should not be explicit, but just guaranteed to be detected and used in some occasions, as in the case you gave. Because any object builder (as for example an array concatenate object) cannot be pure, but can still return an unique object.
I'm not sure I understand your example, but why not? Pure functions have gotten a lot better in the last release (with the possibility of weakly-pure functions). I agree with Don, let's make strongly-pure functions implicitly castable and see how far we can get. If we can do uniqueness without having to mess with the type system, then it will be much easier to deal with. -Steve
Dec 10 2010
On 10-dic-10, at 11:53, Don wrote:Fawzi Mohamed wrote:If one could declare return or out types as unique (note that unique is *not* part of the type, it is like the storage attributes), these methods could be implicitly castable to const or immutable, allowing nicer code. Constructors *might* return unique objects (an object is unique only if all its references are to unique or immutable objects). In several cases uniqueness could be checked by the compiler. I think that such a change would improve part of my code, removing the need for several spurious casts, while at the same time making the code safer.
Any mutable object returned from a strongly pure function, is guaranteed to be unique.
indeed good catch, I was saying that in some occasions the compiler can verify uniqueness, that is indeed an important case. But I don't understand if you want to imply that uniqueness should not be explicit, but just guaranteed to be detected and used in some occasions, as in the case you gave. Because any object builder (as for example an array concatenate object) cannot be pure, but can still return an unique object. about front_const , there I thought harder about having an implicit only use of it, but also there I think that it is not such a good idea
Dec 10 2010
On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros <brunodomedeiros+spam com.gmail> wrote:On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have "string"/"String" somewhere in the name. (I mentioned this on the other original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you, and I think others feel the same way. writeTo seems perfectly fine to me, and the 'string' part is implied by the char[] parameter for the delegate. Changing the name to contain 'string' is fine as long as: 1) it's not toString. This is already established as "returning a string" in both prior D and other languages. I think this would be too confusing. 2) it's short. I don't want writeAsStringTo or something similar. What did you have in mind? -Steve
Dec 21 2010
Hmm.. if we get uniform function call syntax for all types, perhaps
this code might even work some day:
import std.stdio;
import std.conv;
string toString(A)(A a)
{
return to!string(a);
}
class A
{
string name;
this(string name)
{
this.name = name;
}
string writeTo()
{
return name;
}
}
void main()
{
auto foo = new A("I'm foo! ");
writeln(foo.toString); // using uniform function call syntax
}
Right now this code will compile but it will use Object's toString
instead of the one we defined above.
On 12/21/10, Steven Schveighoffer <schveiguy yahoo.com> wrote:
On Tue, 21 Dec 2010 13:10:12 -0500, Bruno Medeiros
<brunodomedeiros+spam com.gmail> wrote:
On 06/12/2010 19:00, Jonathan M Davis 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 don't think it's entirely fine. It should at least have
"string"/"String" somewhere in the name. (I mentioned this on the other
original thread, although late in time)
First, I'll say that it's not as important to me as it seems to be to you,
and I think others feel the same way. writeTo seems perfectly fine to me,
and the 'string' part is implied by the char[] parameter for the delegate.
Changing the name to contain 'string' is fine as long as:
1) it's not toString. This is already established as "returning a string"
in both prior D and other languages. I think this would be too confusing.
2) it's short. I don't want writeAsStringTo or something similar.
What did you have in mind?
-Steve
Dec 21 2010
On Tue, 21 Dec 2010 19:46:11 +0100, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Hmm.. if we get uniform function call syntax for all types, perhaps this code might even work some day: import std.stdio; import std.conv; string toString(A)(A a) { return to!string(a); } class A { string name; this(string name) { this.name = name; } string writeTo() { return name; } } void main() { auto foo = new A("I'm foo! "); writeln(foo.toString); // using uniform function call syntax } Right now this code will compile but it will use Object's toString instead of the one we defined above.
It would still use Object's toString, as member functions would be tested for first. -- Simen
Dec 21 2010
On 12/21/10, Simen kjaeraas <simen.kjaras gmail.com> wrote:It would still use Object's toString, as member functions would be tested for first. -- Simen
I'm talking about the case where Object's toString function doesn't exist (in some future release of D), but is replaced with writeTo or some alternate name. In that case your old code could still compile by adding this toString template.
Dec 21 2010









Andrej Mitrovic <andrej.mitrovich gmail.com> 