| Thread overview | |||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 04, 2008 unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
I was wrong. Stephen was right. (This is great, actually. I love being wrong because every time I'm wrong, I learn something new. Plus, I love the debate). Still, I must bow my head to the superior argument.
I'm pretty good at explaining stuff, once I understand it, so I'm going to try to do that, right now.
The thing is, I didn't actually truly understand why I (and Walter) was wrong until I made that post about "transitive" being the wrong word, and "recursive" being the right word, to describe what the const() operation does. I guess it's all about how you think about stuff. Words are so important.
So let's reinvent "logical const" from scratch, in a way that will work for D, if it were to be implemented. For the record, this is Stephen's idea, not mine - I'm just rewording it - although I do make /one/ new observation.
What we do is this: we classify every field of a class/struct/union as being either "paintable" or "unpaintable". (Fields which would be called "mutable" in C++ are called "unpaintable" here).
When the type-constructor const(...) is applied to a type, all
paintable fields are recursively painted const. (Unpaintable fields
are left alone). That's it!
Similarly, when invariant(...) is applied to a type, all paintable
fields are recursively painted invariant. (And again, unpaintable
fields are left alone).
For functional programming to work, you need one additional restriction: pure functions are only allowed to access fields which are either paintable or invariant. (In the current regime, all fields are paintable).
Because you still have recursion, this buys you enough guarantees to make D's const system work, to allow functional programming, etc..
One thing Steven /didn't/ think of (or at least, didn't tell us about) is that it is perfectly possible for a field to be simultaneously both paintable and invariant. (That's one reason why "mutable" is really not a good word for "unpaintable"). For example:
class C
{
T a;
unpaintable T b;
invariant(T) c;
unpaintable invariant(T) d;
}
If we paint this class const, with the const(...) type constructor, we
get a const(C) - the fields of which will look like this:
// pseudocode
class const(C)
{
const(T) a;
unpaintable T b;
const(T) c;
unpaintable invariant(T) d;
}
As you can see, the members a and c have been painted const, but the members b and d have been left alone. They are untouched. They are /unpainted/. That's what unpaintable means.
Now let's see what a pure function might be allowed to do in such a class:
class C
{
T a;
unpaintable T b;
invariant(T) c;
unpaintable invariant(T) d;
pure void f() invariant
{
auto w = a; /* OK: "this" is invariant */
auto x = b; /* ERROR: b is unpaintable and not invariant */
auto y = c; /* OK: "this" is invariant */
auto z = d; /* OK: d is invariant */
}
}
Words matter. What we call things matters. When we use the word "mutable", it becomes counterintuitive that a field could be both mutable and invariant at the same time. But when we use the word "unpaintable", the mental dichotomy disappears: of /course/ you can have an invariant field cannot be painted const.
Walter said that having mutable fields breaks the whole const system. He may have been right - but having /unpaintable/ fields is just fine and dandy. Everything works. const(...) and invariant(...) will paint only the paintable fields with constancy, but those fields the paint recursively.
It just works.
| ||||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | "Janice Caron" wrote >I was wrong. Stephen was right. (This is great, actually. I love being > wrong because every time I'm wrong, I learn something new. Plus, I love the debate). Still, I must bow my head to the superior argument. > > I'm pretty good at explaining stuff, once I understand it, so I'm going to try to do that, right now. I'm not very good at it apparently :) Glad to see I finally did though... > What we do is this: we classify every field of a class/struct/union as being either "paintable" or "unpaintable". (Fields which would be called "mutable" in C++ are called "unpaintable" here). > > When the type-constructor const(...) is applied to a type, all > paintable fields are recursively painted const. (Unpaintable fields > are left alone). That's it! I like the idea, but not the keyword. It is exactly what I was thinking. I don't like the keyword because it looks to me like pain-table and un-pain-table :) > One thing Steven /didn't/ think of (or at least, didn't tell us about) is that it is perfectly possible for a field to be simultaneously both paintable and invariant. From my original post: "mutable is used as the keyword in C++ to describe this type. However, I do not like this word..." "...We need a word that says "this isn't affected by const or invariant, but it could already be const or invariant". Something that is short and not heavily used in code. Mabye even some form of punctuation." So you must have missed it. It was at the bottom, I guess that should have been more prominent. -Steve | |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | Janice Caron Wrote:
> I was wrong. Stephen was right. (This is great, actually. I love being wrong because every time I'm wrong, I learn something new. Plus, I love the debate). Still, I must bow my head to the superior argument.
I too like debate, but I almost felt like the thread Stephen started was extremely cyclical... To the point that I was barely reading anything you and Stephen said.
Sort of a rhetorical question, but is there a method of debate that could have lead to a faster resolution? A lot of posts looked to be knee-jerk reactions, trying to defend a position rather than understanding what the other person was trying to say.
| |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jason House | On 04/04/2008, Jason House <jason.james.house@gmail.com> wrote:
> Sort of a rhetorical question, but is there a method of debate that could have lead to a faster resolution? A lot of posts looked to be knee-jerk reactions, trying to defend a position rather than understanding what the other person was trying to say.
That's a misleading impression. We /didn't/ understand what each other was saying, but that's not because of entrenchment. In fact, I think it had a lot more to do with using different words for the same thing, and the same words for different things, and ... you know ... basically just not speaking the same language. But eventually, there's that "ping" moment when you "get it".
You said the question was rhetorical, so I guess you know the answer's probably no. Nothing substitutes for debate, except debate. You have to argue, or you don't learn. You'll never find out you're wrong if you don't try to defend your case.
| |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | On Fri, 04 Apr 2008 14:11:53 +0200, Janice Caron <caron800@googlemail.com> wrote:
> class C
> {
> T a;
> unpaintable T b;
> invariant(T) c;
> unpaintable invariant(T) d;
> }
>
> If we paint this class const, with the const(...) type constructor, we
> get a const(C) - the fields of which will look like this:
>
> // pseudocode
> class const(C)
> {
> const(T) a;
> unpaintable T b;
> const(T) c;
> unpaintable invariant(T) d;
> }
What reason would exist for having an unpaintable invariant field? As far as I've understood, invariant is implicitly castable to const, and casting away const/invariant is a Bad Thing, so whether it is const or invariant does little difference, except for functions that demand invariant arguments. In the latter case, the field is in a way 'less constant' when cast to const than for a normal instance, if I have understood things correctly (invariant values will not change, const values might change underneath you).
| |||
April 04, 2008 Re: unpaintable (the solution to logical const) [~ot] | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote: > > I like the idea, but not the keyword. > every once in a while (about as often as I poke my head into one of these threads) I have the crazy idea that maybe we should just invent new words for the different flavors of const. words that have no connotations that people have to get around. My proposal for the five (?) different consts are: a9ae7ba0-456b-4c61-82f0-93e19802f99f ff535086-ec2c-44bb-90ea-20eb8a46efc3 f025566c-8dff-4f41-b891-f37d19b470bb a8d70a83-022e-43d9-b3a5-c799b86e34eb a491956a-023e-4a60-8eeb-7cb37ef80b13 I'm not sure how well those will parse with the "-"'s <G> | |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On 04/04/2008, Simen Kjaeraas <simen.kjaras@gmail.com> wrote: > What reason would exist for having an unpaintable invariant field? As far > as I've understood, invariant is implicitly castable to const So is mutable. I don't know what the uses would be. C++ doesn't have it. No language that I'm aware of has it. This is new. Like mixins - when they were first introduced, Walter said words to the effect of "I've no idea what these things will be used for, but they might be useful, so let's wait and see". No one is suggesting there is a specific need to create permanently invariant fields, but people /are/ suggesting we need logical const, and this is a solution (...and so far as we are aware, the /only/ solution...) that works. That it gives us unpaintable invariant fields as a side-effect is an interesting bonus. > and casting > away const/invariant is a Bad Thing, Right - which is why this scheme specifically avoids any need to do that. Everything is tightly constrained. > so whether it is const or invariant > does little difference, except for functions that demand invariant > arguments. And there may well be those - especially when it comes to pure functions. | |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | "Simen Kjaeraas" wrote
> On Fri, 04 Apr 2008 14:11:53 +0200, Janice Caron
> wrote:
>
>> class C
>> {
>> T a;
>> unpaintable T b;
>> invariant(T) c;
>> unpaintable invariant(T) d;
>> }
>>
>> If we paint this class const, with the const(...) type constructor, we
>> get a const(C) - the fields of which will look like this:
>>
>> // pseudocode
>> class const(C)
>> {
>> const(T) a;
>> unpaintable T b;
>> const(T) c;
>> unpaintable invariant(T) d;
>> }
>
> What reason would exist for having an unpaintable invariant field? As far as I've understood, invariant is implicitly castable to const, and casting away const/invariant is a Bad Thing, so whether it is const or invariant does little difference, except for functions that demand invariant arguments. In the latter case, the field is in a way 'less constant' when cast to const than for a normal instance, if I have understood things correctly (invariant values will not change, const values might change underneath you).
I agree that there seems no reason to have an unpaintable invariant type. However, currently the compiler outputs this:
class C
{
invariant(int)* i;
}
void f(const(C) c)
{
pragma(msg, typeof(c.i).stringof);
}
outputs:
const(int)*
Which seems to me like a mistake, but there is no harm done because you can't change i through a const reference. Having logical const would prevent the painting of i, and then it would remain as invariant(int)*.
Having it be invariant always could potentially have some benefits, such as being able to call invariant versions of functions.
-Steve
| |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Janice Caron | On Fri, 04 Apr 2008 20:09:43 +0200, Janice Caron <caron800@googlemail.com> wrote: > On 04/04/2008, Simen Kjaeraas <simen.kjaras@gmail.com> wrote: >> What reason would exist for having an unpaintable invariant field? As far >> as I've understood, invariant is implicitly castable to const > > So is mutable. > > I don't know what the uses would be. C++ doesn't have it. No language > that I'm aware of has it. This is new. Like mixins - when they were > first introduced, Walter said words to the effect of "I've no idea > what these things will be used for, but they might be useful, so let's > wait and see". > > No one is suggesting there is a specific need to create permanently > invariant fields, but people /are/ suggesting we need logical const, > and this is a solution (...and so far as we are aware, the /only/ > solution...) that works. That it gives us unpaintable invariant fields > as a side-effect is an interesting bonus. > >> and casting >> away const/invariant is a Bad Thing, > > Right - which is why this scheme specifically avoids any need to do > that. Everything is tightly constrained. I agree on all points. At first I felt this whole idea was foolish, but as I read more and started groking it, I see it has its uses, and the solution seems elegant. >> so whether it is const or invariant >> does little difference, except for functions that demand invariant >> arguments. > > And there may well be those - especially when it comes to pure functions. It would appear I messed up some text in my post. I was thinking of /paintable/ invariant fields. Unpaintable ones are ok. Paintable invariants I'm not so sure of. Take the following example: class foo { invariant int bar; } int somePureFunction(invariant(foo) f) { return f.bar; } void main() { foo f = new foo(); auto a = somePureFunction(f); const foo g = new foo(); auto b = somePureFunction(g); // error here, due to g.bar being const, not invariant } Now to find a better name than paintable, and convincing Walter... -- Simen | |||
April 04, 2008 Re: unpaintable (the solution to logical const) | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On 04/04/2008, Simen Kjaeraas <simen.kjaras@gmail.com> wrote:
> Now to find a better name than paintable, and convincing Walter...
Actually, all fields are paintable by default. It's the /un/paintable ones that need a keyword. In C++, that keyword is "mutable", but that's inappropriate for D.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply