January 02, 2008
On Wed, 02 Jan 2008 17:53:28 -0000, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> If you do:
>
> setValueTo5(T)(T x)
> {
>    x.value = 5;
> }
>
> If T is a class, then it affects data outside the function.  If T is a
> struct, it does not.  We have to know if T is a class or not.
>
Unless the struct contains a pointer or class reference :)

You seem to be talking about purity rather than constness here.
January 02, 2008
"Bruce Adams" wrote
>On Wed, 02 Jan 2008 17:53:28 -0000, Steven Schveighoffer wrote:

>> If you do:
>>
>> setValueTo5(T)(T x)
>> {
>>    x.value = 5;
>> }
>>
>> If T is a class, then it affects data outside the function.  If T is a struct, it does not.  We have to know if T is a class or not.
>>
> Unless the struct contains a pointer or class reference :)
>
> You seem to be talking about purity rather than constness here.

This example has nothing to do with const :)  What I'm talking about is the argument against my idea.  The argument is that it is impossible to implement a tail-const reference to a class because anything you do results in you having to know whether a generic type is a class or not.

For example, if const(*C)* is a tail-const reference to a class C, then the generic code:

f(T)(const(*T)* x) {....}

Will only compile for T's that are reference types (i.e. classes or pointers).  The argument is that this is not desired, because no matter what we do, we should be able to substitute any type in there and have it work.

My counter-argument is that there are already inconsistencies between classes and structs and primitives, in that classes are references and you have to treat them as such.  Since we may already need to check if a type in a template is a reference or non-reference type, the original argument that my const ideas cannot be implemented is contradictory.  You can't say the new behavior violates some rule when the current behavior already violates that rule.  My point is, the rule is incorrect, not the behavior.

-Steve


January 03, 2008
Janice Caron wrote:
> But whatever the syntax, I must conclude that it can't be done,
> without violating one or more of the principles of D, and that's what
> Walter (and I) are trying to explain here.

You pick over cases where this is clearly the case; those where it is not clear, you just say this and no more. You could at least provide a link to the relevant discussions in webnews. Otherwise, I have no reason to believe you and every reason to doubt.

>> If references are to be consistent, the
>> meaning of an int reference is that it acts like an int until you assign to
>> another int reference.  If you assign it to another int reference, then type
>> now references the same thing as the new int reference.  If you assign it to
>> another int, that is a compiler error (can't assign a non reference value to
>> a reference just like you can't assign a non pointer value to a pointer).
> 
> D doesn't have a reference-to-int type, only reference-to-class-data.

We do, actually: int*.

> This appears to be a new feature request.

Yup. Because it looks kludgy to use const(T)*, and it looks kludgy to use const(T), and so I'm betting const will be used as often in D as in C++.

>> One further thing.  If you could at least pledge to have a way to specify a
>> tail-const class reference before 2.0 is officially released, I would be
>> willing to accept that for now.
> 
> Walter cannot do that without sacrificing generic programming.

Well, the thing is, we already have a technique to get tailconst anything, and that's using a pointer. As far as I can tell, people just want a prettier syntax for using mutable pointers to const data, and an equivalent to const(Object)* that involves one pointer dereference instead of two to access the object. Pretty syntax isn't a minor thing, either.

Also, there's the problem, with pointers:
const(T)*[] array = init_array();
array.sort; // sorts according to pointer values -- eep!

This can mess with generic programming, too:
struct S { int i; }
void reset_first_element(T)(array[] array) {
   static if (is (T == class)) {
      array[0] = new T();
   } else {
      array[0] = T.init;
   }
}
const(S)*[] array = init_array();
reset_first_element(array);

(channeling Gunther Hermann)
I wanted *array[0] == S.init.
It gave me segmentation fault.


Then the 'right' way would be something like:
void reset_first_element(T)(array[] array) {
   static if (is (T == class)) {
      array[0] = new T();
   } else static if (is (T == const(U)*, U)) {
      static if (is (T == class)) {
         *array[0] = new U();
      } else {
         *array[0] = U.init;
      }
   } else {
      array[0] = T.init;
   }
}

And that doesn't distinguish between situations where I want a reference and I want an actual pointer.

Basically, references solve a bunch of problems with const and with generic programming. The previous example becomes:

void reset_first_element(T)(array[] array) {
   static if (is (T == class)) {
      array[0] = new T();
   } else static if (is (T == U&, U)) {
      array[0] = U.init;
   } else {
      array[0] = T.init;
   }
}

Or maybe, depending on what T&.init is, you could eliminate the second element.

C# did something clever: for any value type T, new T() returns T.init. This makes sense; for value type T, T.init is usually sensible, or at least a lot more useful than null. So you'd get:
void reset_first_element(T)(array[] array) {
   static if (is (T == U&, U)) {
      array[0] = new U();
   } else {
      array[0] = new T();
   }
}

Or even:
void reset_first_element(T)(array[] array) {
   array[0] = new T();
}

Whether it's desirable for D is another matter.
January 03, 2008
Walter Bright wrote:
> Sean Kelly wrote:
>> I don't suppose the use of 'enum' in this context has had any impact on named enumerations?  ie. We still cannot have a named enum which contains strings, correct?
> 
> You can do named enums with strings now.

Really?  Well that eliminates a lot of my issues with consistency.


Sean
January 03, 2008
Walter Bright wrote:
> Lars Ivar Igesund wrote:
> 
>> Most C++-users I know refuse to even acknowledge that C++ is bad.
> 
> Interestingly, many C++ users I know will not publicly acknowledge the flaws in C++. Off the record, though, they say very different things. People do not want to damage their careers built up around C++. There are some pretty high level C++ experts who have been privately very helpful to me in explaining how to do things right.

I've noticed this as well, though I can't say I understand it.  It's certainly possible to have issues with something and still consider it the best around.  In fact, having (sufficiently informed) issues with something is a mark of experience in my opinion.  I'd much rather hire someone who knows a tool well enough to understand its limitations than who has never said anything negative about it.  I'd wonder if they were trying to sell me snake oil.


Sean
January 05, 2008
Bill Baxter wrote:
> Walter Bright wrote:
>> Bill Baxter wrote:
>>> Maybe someone else has better insight into the minds of these "keyword accountants" but from where I sit it just doesn't make a lot of sense to obsess over +/- a few dozen keywords in a C-like language.
>>
>> By itself, it is not an issue. But it can be an indicator of sloppy design.
> 
> Agreed.  And judging a language merely by keyword count is a certain indicator of sloppy analysis :-)
> 
> --bb

Well said!

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
1 2 3 4 5 6 7
Next ›   Last »