float init 0 request
Jonathan M Davis
newsgroup.d at jmdavisprog.com
Thu Aug 20 02:40:50 UTC 2026
On Wednesday, August 19, 2026 1:57:57 PM Mountain Daylight Time Walter Bright via Digitalmars-d wrote:
> Casting is a hammer that overrides the type system. Hence one can plausibly
> argue that every cast is a bug in the program, or at least shows the programmer
> didn't do a good job selecting types properly. In my own code, I try to select
> types to minimize a need for casting.
>
> Implicit conversions, however, are a "soft" conversion rather than a hammer. C
> is a bit too loose with that, as such can do hidden truncations. D's design is
> better because of Value Range Propagation.
>
> Before C, I programmed in Wirth's Pascal. It all looked good in the manual, but
> in practice it was a horrible language. There were no implicit conversions,
> everything had to be constantly cast back and forth. So the hammer is
> everywhere. I disliked it strongly, and I think that was a big mistake in
> Pascal's design.
>
> I've also always disliked C's "char" type because it is how one gets a byte
> integer, having nothing to do with characters. D fixes that.
>
> But integral promotions are still retained, because doing integer operations on
> char's is not that unusual (such as upper/lower case conversions).
>
> All in all, D's semantic selections for integral types are better than anyone
> else's for type safety and convenience.
D has definitely done a better job with type conversions than any other
language that I've used, but I also think that it would be better by being
stricter with some of its conversions (particularly to integer types). IMHO,
there are still too many corner cases where implicit conversions cause
subtle issues. So, I do think that we're better off than the competition,
but we could do better than we're currently doing.
As for explicit casts being an issue, I think that part of the problem is
that we only have the one cast operator which tries to do everything,
including the really blunt casts that aren't safe. Having std.conv.to helps,
because it has a more restricted set of conversions, but it's also overly
generalized for many situations where there would ideally be fewer
conversions available so that it's much less likely that refactoring would
break the code in subtle ways.
For instance, the fact that the same cast operator which is used to do a
narrowing conversion is also used to do bit casting is a bit of a footgun.
It's certainly manageable, but I feel that there are a number of situations
where a cast is currently required or would ideally be required where you
don't want to have to worry about accidentally reinterpreting the bits of
what you're casting. Being able to do something like convert from a floating
point type to an integer type with a conversion that's only allowed to work
between floating point and integer types rather than trying to convert _any_
type to an integer type would be less error-prone, particularly when
refactoring code.
I'm not sure that I have a great solution to the problem, but I do think
that there's a middle ground between allowing implicit conversions and using
the cast operator. In some cases, it would probably be a good idea to
provide functions to do specific types of conversions in a checked manner
(e.g. only allowing a specific subset of conversions based on a template
constraint), but I've also sometimes thought that it would be nice to have
an explicit implicit cast (for lack of a better term) where there's only a
specific set of conversions that are allowed (similar to what you get with
an implicit conversion now), but it's explicit. Perhaps explicit
construction would be one way to do that, or some other operator could be
introduced.
So, for instance, let's say you could do something like `int('A')` but
`int i = 'A';` would be illegal, and a function that accepted int wouldn't
accept char. That way, you wouldn't need to use `cast(int) foo` and risk
accidentally doing a bit cast on some other type when the code was
refactored, and the type of foo changed from something with a sensible
conversion to int to something that did a bit cast in order to be converted
to int.
I'm not currently proposing that we make any such changes in D (and even if
we wanted to, we'd have to be very careful about it because of all of the
existing code which allows a variety of implicit conversions that we would
ideally restrict), but there's no question that if I were to create my own
language, I'd reduce the number of implicit conversions in comparison to
what D has, and I'd provide ways to convert types which did not involve a
cast operator which could do any sort of unsafe cast. IMHO, D's cast
operator just does way too much and makes it far too easy to do one type of
cast when you intended to do a different one - and/or to have the type of
cast changee in unintended ways when code is refactored.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list