View mode: basic / threaded / horizontal-split · Log in · Help
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On Monday, May 14, 2012 21:18:42 deadalnix wrote:
> This whole thing is overinflated. This isn't a problem. I'm pretty sure
> that most code that will broke was actually already a bad idea in the
> first place.

I'm fine with it, but there are people who complain quite bitterly about it 
(generally game programmers, I think - people with pretty insane restrictions
on their programs due to very strict performance requirements).

- Jonathan M Davis
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On Mon, May 14, 2012 at 11:55:15PM +0400, Dmitry Olshansky wrote:
> On 14.05.2012 23:26, Steven Schveighoffer wrote:
[...]
> >Oh, and also, we should fix that problem (that writef allocates).
> >However, I think we need DIP9 in order to do that.
> >http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
> >
> 
> DIP9 for the win!
> I tried to revive at least *some* interest in it for a long time.
[...]

+1.

I like this proposal. I have never liked the idea of toString() ever
since Java introduced it.  Besides memory usage issues, toString() also
binds you to the string type for no good reason: what if you wanted to
store the result into a database file? Why waste resources on an
intermediate representation if it can be written straight to its final
destination?

I'd even argue that DIP9 is an excellent example of:

http://en.wikipedia.org/wiki/Dependency_inversion_principle

We don't know what representation the caller ultimately wants (string in
memory, file on disk, network socket, etc.), so why impose an
essentially arbitrary concrete representation type? Let the delegate
decide what to do with the data.


T

-- 
Just because you survived after you did it, doesn't mean it wasn't stupid!
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On Monday, 14 May 2012 at 19:24:15 UTC, Steven Schveighoffer 
wrote:
> I have never seen this suggested before.  I would guess that it 
> might be considered a bug, since you are accessing the outer 
> instance via a pointer contained in the inner instance.
>
> But I like the approach (even if it is a bug)!

 I was thinking something along these lines last night, although 
I couldn't put it quite together, it did end up using alias this.


 I forget but someone commented on possibly using a flag that 
would let you write to a variable for the first time, and break 
if you tried to read from it. A thought that went through my head 
would indeed need a little thought, but I couldn't see an easy 
way to do it outside of a new keyword. What if .init (or null) 
was your flag effectively? Let's assume allowinit (or something 
better) to be the keyword. Then...

struct S {
  allowinit uint hash;

  uint toHash() const {
    if (hash == uint.init) { //read always allowed safely within 
struct
        hash = 1;
    }

    return hash;
  }

  void throwtest() {
    hash = 2; //might not throw
  }
}

func(){
 const S s, z;

// writeln(s.hash);   //throw!

 //throwtest();       //would not throw here
 writeln(z.toHash()); //fine
 writeln(z.toHash()); //yep still fine
 writeln(z.hash);   //allowed? technically yes...

 throwtest();       //throw!
}

 Course these types may cause more problems if outside code had 
to do extra checks, so making allowinit forced to be private 
would remove that issue leaving it only to within the struct, 
making it good for caching results as you could only set it once.

 But that only works with const data, immutable being locked in 
memory it wouldn't do the job. So the only way to get around that 
is to allow a constructor that sets it during construction.

//as above
struct S {
  this(uint h) {
    hash = h;
  }
}

func(){
  immutable S i; //compile error! Immutable cannot have allowinit 
with default constructor!
  immutable S i2 = S(10); //fine
  immutable S i2 = S(uint.init); //error! allowinit cannot be 
assigned to .init value for immutable!
}
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On 05/14/2012 09:18 PM, deadalnix wrote:
> Le 14/05/2012 04:47, Jonathan M Davis a écrit :
>> They can be in almost all cases. The problem is the folks who want to
>> have
>> caching and/or lazy initiailization in their classes/structs. You
>> can't cache
>> the result of any of those functions (toHash being the main target for
>> it) if
>> they're const and pure except in overloads which _aren't_ const,
>> making those
>> functions more expensive in comparison to what they could be if they
>> weren't
>> required to be const. And lazy initialization becomes almost impossible,
>> because if the member variables needed in those functions haven't been
>> initialized yet when they're called, then you _can't_ initialize them. If
>> getting the value that it _would_ be without actually initializing the
>> member
>> variable works, then you can do that if it hasn't been initialized,
>> but if you
>> can't do that (e.g. the variable _must_ be set only once), then you're
>> screwed. And regardless of whether you can make it work with const, it
>> _will_
>> be less efficient.
>>
>
> Lazy initialization is more a problem than a solution when it comes to
> multithreading.

How to solve the problem of representation of infinite data structures 
otherwise?

> And I'm afraid it is the future.
>

Sharing mutable data frivolously is likely not the future. I guess that 
usually every thread will have its own cache.

> BTW, nothing prevent to define toString an non const and another as
> const. The const one cannot cache the result, but certainly can read it.
> And every method that is aware of the non const version will use it.
>
> This whole thing is overinflated. This isn't a problem. I'm pretty sure
> that most code that will broke was actually already a bad idea in the
> first place.

That is a rather optimistic assumption. And even if it is true for 
'most' code, that is not enough imho.
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On 5/14/2012 10:08 AM, Tove wrote:
> but c++ has the 'mutable' keyword as an easy escape route...

The existence of that capability means that 'const' in C++ cannot be 
meaningfully reasoned about.
May 14, 2012
Re: Getting the const-correctness of Object sorted once and for all
On Monday, 14 May 2012 at 12:22:30 UTC, Steven Schveighoffer
wrote:
> On Mon, 14 May 2012 02:35:16 -0400, Jakob Ovrum 
> <jakobovrum@gmail.com> wrote:
>>
>> How about logically constant opEquals, toString etc? 
>> Currently, this is perfectly possible by just *not using 
>> const*. Logical constancy goes beyond memoization.
>
> This means you cannot compare two const objects.

Yes, but using const for these objects makes no sense because
they all require temporary mutation (the Lua stack) to do
anything meaningful. This includes opEquals and toString. Thus
the option should be there not to use const.

> The issue is, non-const opEquals makes sense on some objects, 
> and const opEquals makes sense on others.  However, you must 
> make them all come together in Object.opEquals.
>
> I think we already have the hooks to properly compare objects 
> without requiring Object.opEquals.
>
> Right now, when two objects are compared, the compiler calls 
> object.opEquals (that's little o for object, meaning the module 
> function *not* the class method).
>
> So why can't object.opEquals be a template that decides whether 
> to use Object.opEquals (which IMO *must be* const) or a derived 
> version?  I don't think it's that much of a stretch (not sure 
> if we need a compiler fix for this).
>
> -Steve

Right, I think this is the way to go. We have to accommodate both
kind of object.
May 15, 2012
Re: Getting the const-correctness of Object sorted once and for all
On Monday, 14 May 2012 at 18:52:06 UTC, deadalnix wrote:
> The only reason I'd see a toSting function as non pure or non 
> const is memoize. It can be tackled with lib support in phobos.
>
> What are other uses cases ?

Did you miss my post?

http://forum.dlang.org/post/azevkvzkhhfnpmtzgnvp@forum.dlang.org
May 15, 2012
Re: Getting the const-correctness of Object sorted once and for all
On 5/14/2012 12:47 AM, Chris Cain wrote:
> And all this together culminates into a much greater ability to _reason about
> code_.

Exactly. And ditto for the rest of your post - it's spot on.

Being able to reason about code is *intensely* important. All those decorations 
- const, pure, nothrow, out - serve to help that out.
May 15, 2012
Re: Getting the const-correctness of Object sorted once and for all
On 5/14/2012 1:03 AM, Mehrdad wrote:
> On Monday, 14 May 2012 at 06:27:15 UTC, Walter Bright wrote:
>> #3 Improves self-documentation of code - it's more understandable and less
>> susceptible to breakage during maintenance.
>
> #3 is also valid for C++, so I wasn't exactly considering that.

No, it isn't.

1. C++ legally allows changing const values.

2. const only applies to the top level (i.e. head const). So if you have 
anything more than a simple value type, it literally means *nothing*.

>
>> #4 Improves encapsulation
>
> o.O How does it improve encapsulation?

By guaranteeing that the method call is a reader, not a mutator.


D is a very deliberate step away from correctness by convention and towards 
correctness with mechanical verification.
May 15, 2012
Re: Getting the const-correctness of Object sorted once and for all
Walter Bright:

> Being able to reason about code is *intensely* important. All 
> those decorations - const, pure, nothrow, out - serve to help 
> that out.

Bertrand Meyer (Eiffel author) is now working a lot on this, as
you see from many of the last posts on his blog
(http://bertrandmeyer.com/ ). The "Modern Eiffel" language is
being designed right to allow more reasoning about code. This
seems a small trend in new languages, but I can't predict how
much important it will become in ten years.

Bye,
bearophile
4 5 6 7 8 9 10
Top | Discussion index | About this forum | D home