Re: Frustrations with const

2012-03-09 Thread Timon Gehr

On 03/08/2012 09:06 PM, H. S. Teoh wrote:

On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:

On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh
hst...@quickfur.ath.cx  wrote:


On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:

[...]

inout(Slot)* findSlot(Key key) inout { ... }


Ahhh. Thanks!

But that still doesn't solve the problem:

inout(Slot)* findSlot(Key key) inout {
auto slot = slots[hash(key)];


What is type slot, and how is it constructed?  This snippit isn't
enough to provide help.

[...]

Slot is a struct, and slots is Slots*[].  But anyway, I found the
problem.  I needed to explicitly declare slot as:

inout(Slot)* slot = ...

because for whatever reason, auto turns it into inout(Slot*) which
cannot be modified.


Probably it does not. What is the type of the slots hashtable?




I think inout is one of those things that really needs more thorough
treatment for newbies, because coming from a C/C++ background I had no
idea what was wrong. Now that I get it, it makes so much more sense.


T



This is a general issue with how auto infers types. It would often be 
useful to get the head-mutable type out of the type deduction instead of 
the actual type.


Re: Frustrations with const

2012-03-09 Thread H. S. Teoh
On Fri, Mar 09, 2012 at 11:24:46AM +0100, Timon Gehr wrote:
 On 03/08/2012 09:06 PM, H. S. Teoh wrote:
 On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
[...]
 What is type slot, and how is it constructed?  This snippit isn't
 enough to provide help.
 [...]
 
 Slot is a struct, and slots is Slots*[].  But anyway, I found the
 problem.  I needed to explicitly declare slot as:
 
  inout(Slot)* slot = ...
 
 because for whatever reason, auto turns it into inout(Slot*) which
 cannot be modified.
 
 Probably it does not. What is the type of the slots hashtable?

Here are the relevant declarations:

struct Slot
{
Slot   *next;
hash_t  hash;
Key key;
Value   value;

this(hash_t h, Key k, Value v)
{
hash = h;
key = k;
value = v;
}
}

struct Impl
{
Slot*[]  slots;
size_t   nodes;

// Prevent extra allocations for very small AA's.
Slot*[4] binit;
}


[...]
 I think inout is one of those things that really needs more thorough
 treatment for newbies, because coming from a C/C++ background I had
 no idea what was wrong. Now that I get it, it makes so much more
 sense.
[...]
 This is a general issue with how auto infers types. It would often be
 useful to get the head-mutable type out of the type deduction instead
 of the actual type.

Yeah, that would be very useful.


T

-- 
Tech-savvy: euphemism for nerdy.


Re: Frustrations with const

2012-03-09 Thread Adam D. Ruppe

On Friday, 9 March 2012 at 15:30:50 UTC, H. S. Teoh wrote:

Yeah, that would be very useful.


I think it was actually decided to do that... they
made the change for templates already.


PS: you might want to take a look at your mutt settings.
Your replies seem to have a truncated References header
which messes up threading in many clients.


[OT] mutt settings (Was: Re: Frustrations with const)

2012-03-09 Thread H. S. Teoh
On Fri, Mar 09, 2012 at 04:39:13PM +0100, Adam D. Ruppe wrote:
[...]
 PS: you might want to take a look at your mutt settings.  Your replies
 seem to have a truncated References header which messes up threading
 in many clients.

Oh really? I don't think I changed any settings related to that. AFAICT
it does generate the right references header. How do I fix it?

P.S. I do have mutt set on mailing list mode when replying to this list,
though, and I usually reply using 'L'. Does that make a difference?


T

-- 
Computerese Irregular Verb Conjugation: I have preferences.  You have
biases.  He/She has prejudices. -- Gene Wirchenko


Frustrations with const

2012-03-08 Thread H. S. Teoh
I'm writing an AA implementation, and ran into this problem with the way
const behaves in D. Basically, I have an auxiliary function that
searches the internal hash table for a given key, and returns the slot
containing the matching entry, if found.

The problem is, how to write this function so that it can be called from
*both* a const public method and a non-const public method? Since the
method itself doesn't actually modify anything, it *should* in theory be
possible to mark it as const:

const Slot *findSlot(Key key) { ... }

However, because the const applies to 'this', the compiler insists that
referencing anything via 'this', including reading a pointer to a slot,
must also be const, so it refuses to let the return type be Slot*; it
has to be const(Slot)*.

But this is silly, because now the caller isn't allowed to modify the
Slot either, so now I need to bloat the code with two identical copies
of findSlot, one with const, and one without (since if it wasn't marked
const, then a const method couldn't call it).

Is there any way to work around this?

Or more importantly, why does the compiler force all internal members of
this to be const inside a const method, when what it really should be
enforcing is that nothing is being *modified*? What's wrong with
extracting non-const members from the object in a const method, if you
never actually do anything to it?


T

-- 
Never wrestle a pig. You both get covered in mud, and the pig likes it.


Re: Frustrations with const

2012-03-08 Thread Timon Gehr

On 03/08/2012 08:09 PM, H. S. Teoh wrote:

I'm writing an AA implementation, and ran into this problem with the way
const behaves in D. Basically, I have an auxiliary function that
searches the internal hash table for a given key, and returns the slot
containing the matching entry, if found.

The problem is, how to write this function so that it can be called from
*both* a const public method and a non-const public method? Since the
method itself doesn't actually modify anything, it *should* in theory be
possible to mark it as const:

const Slot *findSlot(Key key) { ... }

However, because the const applies to 'this', the compiler insists that
referencing anything via 'this', including reading a pointer to a slot,
must also be const, so it refuses to let the return type be Slot*; it
has to be const(Slot)*.

But this is silly, because now the caller isn't allowed to modify the
Slot either, so now I need to bloat the code with two identical copies
of findSlot, one with const, and one without (since if it wasn't marked
const, then a const method couldn't call it).

Is there any way to work around this?

Or more importantly, why does the compiler force all internal members of
this to be const inside a const method, when what it really should be
enforcing is that nothing is being *modified*? What's wrong with
extracting non-const members from the object in a const method, if you
never actually do anything to it?


T



inout(Slot)* findSlot(Key key) inout { ... }


Re: Frustrations with const

2012-03-08 Thread H. S. Teoh
On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
 On 03/08/2012 08:09 PM, H. S. Teoh wrote:
[...]
 The problem is, how to write this function so that it can be called from
 *both* a const public method and a non-const public method? Since the
 method itself doesn't actually modify anything, it *should* in theory be
 possible to mark it as const:
 
  const Slot *findSlot(Key key) { ... }
 
 However, because the const applies to 'this', the compiler insists that
 referencing anything via 'this', including reading a pointer to a slot,
 must also be const, so it refuses to let the return type be Slot*; it
 has to be const(Slot)*.
 
 But this is silly, because now the caller isn't allowed to modify the
 Slot either, so now I need to bloat the code with two identical copies
 of findSlot, one with const, and one without (since if it wasn't marked
 const, then a const method couldn't call it).
[...]
 inout(Slot)* findSlot(Key key) inout { ... }

Ahhh. Thanks!

But that still doesn't solve the problem:

inout(Slot)* findSlot(Key key) inout {
auto slot = slots[hash(key)];
while (slot) {
if (slot.hash == hash(key)  slot.key == key)
return slot;

// Error: cannot modify inout(Slot)*
---slot = slot.next;
}
return null;
}



T

-- 
Help a man when he is in trouble and he will remember you when he is in trouble 
again.


Re: Frustrations with const

2012-03-08 Thread Steven Schveighoffer
On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh hst...@quickfur.ath.cx  
wrote:



On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:

On 03/08/2012 08:09 PM, H. S. Teoh wrote:

[...]
The problem is, how to write this function so that it can be called  
from

*both* a const public method and a non-const public method? Since the
method itself doesn't actually modify anything, it *should* in theory  
be

possible to mark it as const:

const Slot *findSlot(Key key) { ... }

However, because the const applies to 'this', the compiler insists that
referencing anything via 'this', including reading a pointer to a slot,
must also be const, so it refuses to let the return type be Slot*; it
has to be const(Slot)*.

But this is silly, because now the caller isn't allowed to modify the
Slot either, so now I need to bloat the code with two identical copies
of findSlot, one with const, and one without (since if it wasn't marked
const, then a const method couldn't call it).

[...]

inout(Slot)* findSlot(Key key) inout { ... }


Ahhh. Thanks!

But that still doesn't solve the problem:

inout(Slot)* findSlot(Key key) inout {
auto slot = slots[hash(key)];


What is type slot, and how is it constructed?  This snippit isn't enough  
to provide help.



while (slot) {
if (slot.hash == hash(key)  slot.key == key)
return slot;

// Error: cannot modify inout(Slot)*


An exact message is preferrable.


--- slot = slot.next;
}
return null;
}


-Steve


Re: Frustrations with const

2012-03-08 Thread H. S. Teoh
On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:
 On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh
 hst...@quickfur.ath.cx wrote:
 
 On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:
[...]
 inout(Slot)* findSlot(Key key) inout { ... }
 
 Ahhh. Thanks!
 
 But that still doesn't solve the problem:
 
  inout(Slot)* findSlot(Key key) inout {
  auto slot = slots[hash(key)];
 
 What is type slot, and how is it constructed?  This snippit isn't
 enough to provide help.
[...]

Slot is a struct, and slots is Slots*[].  But anyway, I found the
problem.  I needed to explicitly declare slot as:

inout(Slot)* slot = ...

because for whatever reason, auto turns it into inout(Slot*) which
cannot be modified.

I think inout is one of those things that really needs more thorough
treatment for newbies, because coming from a C/C++ background I had no
idea what was wrong. Now that I get it, it makes so much more sense.


T

-- 
Life would be easier if I had the source code. -- YHL


Re: Frustrations with const

2012-03-08 Thread Timon Gehr

On 03/08/2012 08:49 PM, H. S. Teoh wrote:

On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:

On 03/08/2012 08:09 PM, H. S. Teoh wrote:

[...]

The problem is, how to write this function so that it can be called from
*both* a const public method and a non-const public method? Since the
method itself doesn't actually modify anything, it *should* in theory be
possible to mark it as const:

const Slot *findSlot(Key key) { ... }

However, because the const applies to 'this', the compiler insists that
referencing anything via 'this', including reading a pointer to a slot,
must also be const, so it refuses to let the return type be Slot*; it
has to be const(Slot)*.

But this is silly, because now the caller isn't allowed to modify the
Slot either, so now I need to bloat the code with two identical copies
of findSlot, one with const, and one without (since if it wasn't marked
const, then a const method couldn't call it).

[...]

inout(Slot)* findSlot(Key key) inout { ... }


Ahhh. Thanks!

But that still doesn't solve the problem:

inout(Slot)* findSlot(Key key) inout {
auto slot = slots[hash(key)];


inout(Slot)* slot = slots[hash(key)];


while (slot) {
if (slot.hash == hash(key)  slot.key == key)
return slot;

// Error: cannot modify inout(Slot)*
--- slot = slot.next;
}
return null;
}



T



Re: Frustrations with const

2012-03-08 Thread Steven Schveighoffer
On Thu, 08 Mar 2012 15:06:19 -0500, H. S. Teoh hst...@quickfur.ath.cx  
wrote:



On Thu, Mar 08, 2012 at 02:50:50PM -0500, Steven Schveighoffer wrote:

On Thu, 08 Mar 2012 14:49:12 -0500, H. S. Teoh
hst...@quickfur.ath.cx wrote:

On Thu, Mar 08, 2012 at 08:22:05PM +0100, Timon Gehr wrote:

[...]

inout(Slot)* findSlot(Key key) inout { ... }

Ahhh. Thanks!

But that still doesn't solve the problem:

inout(Slot)* findSlot(Key key) inout {
auto slot = slots[hash(key)];

What is type slot, and how is it constructed?  This snippit isn't
enough to provide help.

[...]

Slot is a struct, and slots is Slots*[].  But anyway, I found the
problem.  I needed to explicitly declare slot as:

inout(Slot)* slot = ...

because for whatever reason, auto turns it into inout(Slot*) which
cannot be modified.


I was wondering, because your error message identified it as inout(Slot)*,  
which should be modifiable...



I think inout is one of those things that really needs more thorough
treatment for newbies, because coming from a C/C++ background I had no
idea what was wrong. Now that I get it, it makes so much more sense.


It's kind of a new concept to D even (since 2.056).  It's not completely  
fleshed out yet, Timon, Kenji, and Stuart have some great ideas on making  
it better.


This article might help: http://drdobbs.com/blogs/cpp/231902461

I plan to write a const/inout article at some point.

-Steve