August 28, 2011
On 28-08-2011 01:05, bearophile wrote:
> Mehrdad:
>
>> "With transitivity, there is no way to have a const pointer to mutable int."
>>
>> But... so what? Maybe it should actually explain the benefit, since I
>> can't figure it out on my own.
>
> D wants both mutable data and (strongly) pure functions. How do you bridge such two worlds? If you have mutable data and you want to pass it to a pure function, you need a way to say this data structure will not change, nor any data it refers to. I think the D transitive const is the simpler way to do this.
>
>
>> C++'s non-transitivity seems to be quite type-safe, even if unintuitive
>> to the beginner (which I don't think it is). I *never* ran into issues
>> with it.
>
> The C++ compiler doesn't offer means to enforce pure functions.
>
> In my opinion it's possible to add a C++-style const to D too, but this further increases the complexity of D, it cannot be used for purity, and it can't be used for compiler optimizations, you are allowed to safely cast it away when you want, it's just a convention, as in C++. But maybe it's useful anyway because most times you try to mutate the first level of a data structure, and such shallow const is enough to catch such unintentional mutation bug.
>
> Bye,
> bearophile

const_cast is the root of all evil. I really don't want to see it in D.

- Alex
August 28, 2011
On 8/28/11 8:54 PM, Alex Rønne Petersen wrote:
> const_cast is the root of all evil. I really don't want to see it in D.
>
> - Alex

It is already in D, and in an, in my personal opinion, much worse way: You can just cast away const/immutable with cast().

What do you propose for the situations where you need to cast away const? (Yes you'll find yourself in one of them from time to time in the real world, e.g. when dealing with legacy/C code…)

I know that this is not the general consensus, but I very much like the C++ casting operators, because you can quickly get a rough idea what is going on when you see a cast in the code, whereas for D, cast() be anything between a perfectly harmless downcast (if checking for null, obviously), changing the storage class (const/immutable/shared), or causing the bytes stored to be interpreted in a completely different way!

David
August 28, 2011
On 8/28/2011 12:44 PM, David Nadlinger wrote:
> It is already in D, and in an, in my personal opinion, much worse way: You can
> just cast away const/immutable with cast().

True, but such is explicitly undefined behavior, and is not allowed in safe mode.


> What do you propose for the situations where you need to cast away const? (Yes
> you'll find yourself in one of them from time to time in the real world, e.g.
> when dealing with legacy/C code…)

That's why D does allow this, in a user visible manner, rather than forcing one to do it in a backdoor manner (like using inline asm).


> I know that this is not the general consensus, but I very much like the C++
> casting operators, because you can quickly get a rough idea what is going on
> when you see a cast in the code, whereas for D, cast() be anything between a
> perfectly harmless downcast (if checking for null, obviously), changing the
> storage class (const/immutable/shared), or causing the bytes stored to be
> interpreted in a completely different way!

To cast away const, use:

   cast()expr

i.e. there is a special syntax for it.
August 28, 2011
On 8/27/2011 8:59 AM, dsimcha wrote:
> When I add the directive:
>
> pragma(lib, "foo");
>
> to a file called "bar.d" and then do:
>
> dmd -c bar.d
>
> does the object file bar.o or bar.obj contain a directive that reflects the
> pragma, or does pragma(lib) only work when compiling and linking in one step,
> e.g. dmd bar.d?


On Windows, it embeds a reference to the library in the .obj file. The .o format does not support this, so on those platforms it adds "foo.a" to the link command.
August 28, 2011
On 08/28/2011 02:44 PM, David Nadlinger wrote:
> On 8/28/11 8:54 PM, Alex Rønne Petersen wrote:
>> const_cast is the root of all evil. I really don't want to see it in D.
>>
>> - Alex
>
> It is already in D, and in an, in my personal opinion, much worse way:
> You can just cast away const/immutable with cast().
>
> What do you propose for the situations where you need to cast away
> const? (Yes you'll find yourself in one of them from time to time in the
> real world, e.g. when dealing with legacy/C code…)
>
> I know that this is not the general consensus, but I very much like the
> C++ casting operators, because you can quickly get a rough idea what is
> going on when you see a cast in the code, whereas for D, cast() be
> anything between a perfectly harmless downcast (if checking for null,
> obviously), changing the storage class (const/immutable/shared), or
> causing the bytes stored to be interpreted in a completely different way!
>
> David

It is quite easy to define C++-like cast operators as D functions. If there's enough demand for that, we may include such in the standard library.

Andrei
August 28, 2011
On 8/28/2011 4:52 PM, Andrei Alexandrescu wrote:
> It is quite easy to define C++-like cast operators as D functions. If
> there's enough demand for that, we may include such in the standard
> library.
>
> Andrei

I think we should define at least the following and probably put them in std.conv, since these would add real value over the cast operator, the first in terms of straightforwardness and readability and the second in terms of error checking:

reinterpretCast:  Reinterprets the bit pattern at a given address as some other type.  This should be broadened from C++ to allow reinterpretCasting from any type to any type.  For example:

// Fancy way of making a floating point number negative.
float f = 5;
auto i = reinterpretCast!int(f);

// Flip the sign bit.
i &= ~(1 << 31);
f = reinterpretCast!float(i);

dynamicCast:  Cast a class to another.  This should throw something derived from Error (not Exception) on failure instead of just returning null.  If you want null, just use the cast operator.  Maybe we should change its name, though.  How about checkedCast or downCast?
August 28, 2011
Andrei Alexandrescu:

> It is quite easy to define C++-like cast operators as D functions. If there's enough demand for that, we may include such in the standard library.

I'd like this one in Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=5559

Having it in Phobos is hopefully better than creating your own one from scratch when the need arises.

Bye,
bearophile
August 28, 2011
Am 28.08.2011 23:13, schrieb dsimcha:
> On 8/28/2011 4:52 PM, Andrei Alexandrescu wrote:
>> It is quite easy to define C++-like cast operators as D functions. If
>> there's enough demand for that, we may include such in the standard
>> library.
>>
>> Andrei
>
> I think we should define at least the following and probably put them in
> std.conv, since these would add real value over the cast operator, the
> first in terms of straightforwardness and readability and the second in
> terms of error checking:
>
> reinterpretCast: Reinterprets the bit pattern at a given address as some
> other type. This should be broadened from C++ to allow
> reinterpretCasting from any type to any type. For example:
>
> // Fancy way of making a floating point number negative.
> float f = 5;
> auto i = reinterpretCast!int(f);
>
> // Flip the sign bit.
> i &= ~(1 << 31);
> f = reinterpretCast!float(i);
>
> dynamicCast: Cast a class to another. This should throw something
> derived from Error (not Exception) on failure instead of just returning
> null. If you want null, just use the cast operator. Maybe we should
> change its name, though. How about checkedCast or downCast?

I think, to!someClass(x) works like you want dynamic cast to work.
August 28, 2011
On 8/28/11 10:17 PM, Walter Bright wrote:
> On 8/28/2011 12:44 PM, David Nadlinger wrote:
>> I know that this is not the general consensus, but I very much like
>> the C++
>> casting operators, because you can quickly get a rough idea what is
>> going on
>> when you see a cast in the code, whereas for D, cast() be anything
>> between a
>> perfectly harmless downcast (if checking for null, obviously),
>> changing the
>> storage class (const/immutable/shared), or causing the bytes stored to be
>> interpreted in a completely different way!
>
> To cast away const, use:
>
> cast()expr
>
> i.e. there is a special syntax for it.

I know about the »it's not a bug, it's a feature« cast() syntax officially added some three (?) months ago, but it should be noted that it also removes shared from the type (incidentally, const_cast removes volatile as well).

Personally, I think that being explicit about the type of operation one intends to perform is a good thing, especially if you are about to subvert the type system. Still, I feel using my own custom set of casting templates would be too confusing for other people reading my code – would anybody else be interested in adding »restricted« casting templates to Phobos?

David
August 28, 2011
On 8/28/2011 5:18 PM, Mafi wrote:
>> dynamicCast: Cast a class to another. This should throw something
>> derived from Error (not Exception) on failure instead of just returning
>> null. If you want null, just use the cast operator. Maybe we should
>> change its name, though. How about checkedCast or downCast?
>
> I think, to!someClass(x) works like you want dynamic cast to work.

(Slaps self in forehead.)  You're right, I forgot about that.  Never mind.