www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opImplicitCast/opImplicitCastFrom

reply Hxal <Hxal freenode.irc> writes:
So it seems they were supposed to get implemented but it never happened.
Were there difficulties in implementing them properly?

Implementing range checked numeric types would be my example of implicit casts'
usefulness,
but I'm sure a lot of people desire them.

An invocation to:
void foo (intrange!(1,10) x);
currently needs to include a painful cast or constructor call.
Oct 27 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Hxal:
 Implementing range checked numeric types would be my example of implicit
casts' usefulness, but I'm sure a lot of people desire them.<

ObjectPascal programmers use them all the time, they seem to help avoiding some bugs in the program and to better state the meaning of certain variables. In a modern language it's probably good for ALL integral numeric types to be range checked (when unspecified their range is the whole range their number of bits can represent). D being a system language, has to allow such checks to be disabled into a module or into the whole program (so some syntax to single-module-disabling may be useful. ObjectPascals uses compiling setting to enable/disable it globally for the whole program, and {$R-} to disable rangle checking locally and {$R+} to enable it locally, locally overriding the compilation setting of the project). I think that such checks are quite important to avoid bugs. But putting things into the language isn't enough: you have to put them into the head of D programmers and into the D culture. For example in Pascal is very common to use user-defined types to create a stricter (and safer?) type checking; D offers the typedef that allows to do the same (you just have to write 'typedef' for each line of code instead of using a typedef section like typedef: ...). But in my D programs for a long time I haven't used such typedef, and only in the last months I have started to use it more. Sometimes it's a matter of power or syntax (example: D contract programming isn't much powerful, so people may have less incentive to use it. Another example is that if a syntax is too much long, it becomes not convenient to be used, even if its semantic is good, for example certain operations done in functional languages, compared to the same operations done in D) but in the case of typedef I think it's mostly just a matter of being used to use it. Bye, bearophile
Oct 27 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
bearophile wrote:
 Hxal:
 Implementing range checked numeric types would be my example of implicit
casts' usefulness, but I'm sure a lot of people desire them.<

ObjectPascal programmers use them all the time, they seem to help avoiding some bugs in the program and to better state the meaning of certain variables. In a modern language it's probably good for ALL integral numeric types to be range checked (when unspecified their range is the whole range their number of bits can represent).

The Bounded!() (originally Positive!()) template suggested by Andrei earlier? When a programmer cares for integer overflow one can use Bounded!(T.min, T.max).
 D being a system language, has to allow such checks to be disabled into a
module or into the whole program (so some syntax to single-module-disabling may
be useful. ObjectPascals uses compiling setting to enable/disable it globally
for the whole program, and {$R-} to disable rangle checking locally and {$R+}
to enable it locally, locally overriding the compilation setting of the
project).
 
 I think that such checks are quite important to avoid bugs. But putting things
into the language isn't enough: you have to put them into the head of D
programmers and into the D culture. For example in Pascal is very common to use
user-defined types to create a stricter (and safer?) type checking; D offers
the typedef that allows to do the same (you just have to write 'typedef' for
each line of code instead of using a typedef section like typedef: ...). But in
my D programs for a long time I haven't used such typedef, and only in the last
months I have started to use it more. Sometimes it's a matter of power or
syntax (example: D contract programming isn't much powerful, so people may have
less incentive to use it. Another example is that if a syntax is too much long,
it becomes not convenient to be used, even if its semantic is good, for example
certain operations done in functional languages, compared to the same
operations done in D) but in the case of typedef I think it

 
 Bye,
 bearophile

Oct 27 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:
 The Bounded!() (originally Positive!()) template suggested by Andrei 
 earlier?

No, I mean something built-in, and generally invisible. See ObjectPascals.
 When a programmer cares for integer overflow one can use Bounded!(T.min,
T.max).

Nope. It has to be the other way round: when a programmer doesn't care of avoiding some integer-related bugs he/she/shi can add a "-release" to the compilation arguments. Forcing the programmer to use an ugly and long syntax everywhere in the program isn't a way to avoid that class of bugs in most D programs. Bye, bearophile
Oct 27 2008
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
bearophile wrote:
 KennyTM~:
 The Bounded!() (originally Positive!()) template suggested by Andrei 
 earlier?

No, I mean something built-in, and generally invisible. See ObjectPascals.

I haven't touched Pascal after Turbo Pascal 7 for DOS, so I thought you're talking about the subrange types in Pascal. I mean something like this: var x: 1..10; y: 'A'..'Z'; Do you mean automatic integer overflow checking (i.e. bounds checking)?
 
 When a programmer cares for integer overflow one can use Bounded!(T.min,
T.max).

Nope. It has to be the other way round: when a programmer doesn't care of avoiding some integer-related bugs he/she/shi can add a "-release" to the compilation arguments. Forcing the programmer to use an ugly and long syntax everywhere in the program isn't a way to avoid that class of bugs in most D programs.

I see. This is much more elegant.
 Bye,
 bearophile

Oct 27 2008
parent bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:

 so I thought you're talking about the subrange types in Pascal. I mean
something like this:
    var
      x: 1..10;
      y: 'A'..'Z';

Yes, something like that. Plus a syntax like this in D2: short z; becomes just a short way to write this: ushort z: 0 .. 65535; That is, all integral/char variables become checked range types :-)
 Do you mean automatic integer overflow checking (i.e. bounds checking)?

Yes (But note that here Delphi5 cheats a little). ----------------- Simen Kjaeraas:
So make all the normal built-in types (uint, int, float, etc) throw exceptions,
and give access to lower-level types marked as unsafe. Basically, rename uint
to 'uint_unsafe', and provide 'uint' as a typedef of Bounded!(uint_unsafe.min,
uint_unsafe.max). I feel uint_unsafe is too long a name, but I'm sure something
could be worked out (_uint?).<

I don't like that. I think a better solution is to make all char/integral types become range checked by default when not in -release mode, plus add some syntax to disable the range check in a part of the code (or in a module), a bit like the "unsafe" statement of C#, and the {$R-} / {$R+} syntax of Delphi. What syntax use for D to disable the integral range checks locally? Some possible syntaxes (that can be used for other kind of safeties too, like for the SafeD ideas): unsafe (IntegerOverflow) { ...code... } unsafe (IntegerOverflow): ...code... unsafe (IntegerOverflow) expression; safe (IntegerOverflow) { ...code... } safe (IntegerOverflow): ...code... safe (IntegerOverflow) expression; Bye, bearophile
Oct 27 2008
prev sibling parent reply Hxal <Hxal freenode.irc> writes:
Simen Kjaeraas Wrote:
 So make all the normal built-in types (uint, int, float, etc) throw  
 exceptions, and give access to lower-level types marked as unsafe.
 Basically, rename uint to 'uint_unsafe', and provide 'uint' as a typedef  
 of Bounded!(uint_unsafe.min, uint_unsafe.max).
 I feel uint_unsafe is too long a name, but I'm sure something could be  
 worked out (_uint?).

Both overflow-checked and wrap-around integers are useful, the latter kind should not be viewed as inherently unsafe, but rather as a different set of desired semantics. Ada calls these range types and modular types. Efficient overflow checking would require the use of hardware exceptions, which are currently not convertible to exceptions due to lack of compiler support for non-call exceptions (on Linux at least). But anyway, the point was to include the implicit cast mechanism to allow the user to implement such interesting things. No point putting ranged types into the language if it can be made perfectly doable at library level. If you put them in the standard lib, people who care about security will surely use them. (At least if you don't call the type Bounded :P)
Oct 27 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Hxal:

No point putting ranged types into the language if it can be made perfectly
doable at library level. If you put them in the standard lib, people who care
about security will surely use them. (At least if you don't call the type
Bounded :P)<

Unfortunately I think such library solution is nearly useless. Programmers are lazy, and lot of them even actively resist changes and ideas that may improve their programs. So I fear that you will see very few programs pasted in this newsgroup that show the usage of that syntax of yours everywhere in the program. And if you suggest the poster to do that change you will receive bites, like when I suggest people to improve the syntax and idioms of some programs shown here. Even if you put a built-in syntax for ranged types, it's probably quite useless still. If you look at the C language sometimes programmers insert bugs in the code because they forget to initialize vars. D turns the situation over, adding a syntax to not initialize variables, avoiding most of those bugs. The situation with range checkes is similar (not equal, because while the compiler can infer to remove some range checks, some of them have to be left for runtime, this changes the code performance a little, so the situation is more similar to the current bound checks done on of arrays, disabled by -release). Bye, bearophile
Oct 27 2008
parent reply Hxal <Hxal freenode.irc> writes:
bearophile Wrote:
 Unfortunately I think such library solution is nearly useless. Programmers are
lazy, and lot of them even actively resist changes and ideas that may improve
their programs.

Well then, that's their problem, isn't it? I mean, there's no point making their programs better against their will. :P As long as range checked types were part of the standard library and there weren't dozens different implementations from different libraries, then a people would probably use them.
Oct 27 2008
next sibling parent Hxal <Hxal freenode.irc> writes:
Hxal Wrote:
 As long as range checked types were part of the standard library and there
weren't dozens different
 implementations from different libraries, then a people would probably use
them.

Bah, the apparent grammar mistake is an effect of my touchpad posting before I finished editing :P
Oct 27 2008
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Hxal:
 Well then, that's their problem, isn't it?

I can't agree. While it's generally impossible to engineer/design a really "fool proof" system, a well designed system (I am talking about machines too, car/plane pilot levers and commands too) must take into account the basics of what we today know about the human nature too, and avoid human errors when possible and/or not too much costly. You can read books written by Donald Norman (www.jnd.org ) about this topic. What today often we call "human errors" (of some user) are instead errors of the human designers (that haven't done well what I have just said), and not of the humans that use a system. On the other hand those human designers where often working in situations where their bosses didn't want a better design, etc. So basic social psychology studies have seen the cause of the mistake is often politics inside a hyerarchical group of working people... But I don't want to slip into this can of worms now. Bye, bearophile
Oct 27 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 27 Oct 2008 15:25:32 +0100, bearophile <bearophileHUGS lycos.com>  
wrote:

 KennyTM~:
 The Bounded!() (originally Positive!()) template suggested by Andrei
 earlier?

No, I mean something built-in, and generally invisible. See ObjectPascals.
 When a programmer cares for integer overflow one can use  
 Bounded!(T.min, T.max).

Nope. It has to be the other way round: when a programmer doesn't care of avoiding some integer-related bugs he/she/shi can add a "-release" to the compilation arguments. Forcing the programmer to use an ugly and long syntax everywhere in the program isn't a way to avoid that class of bugs in most D programs. Bye, bearophile

So make all the normal built-in types (uint, int, float, etc) throw exceptions, and give access to lower-level types marked as unsafe. Basically, rename uint to 'uint_unsafe', and provide 'uint' as a typedef of Bounded!(uint_unsafe.min, uint_unsafe.max). I feel uint_unsafe is too long a name, but I'm sure something could be worked out (_uint?). I do believe this would eliminate some bugs, and having programmed quite a lot in ObjectPascal, I agree its nice to have. -- Simen
Oct 27 2008
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 27 Oct 2008 17:40:44 +0100, Hxal <Hxal freenode.irc> wrote:

 bearophile Wrote:
 Unfortunately I think such library solution is nearly useless.  
 Programmers are lazy, and lot of them even actively resist changes and  
 ideas that may improve their programs.

Well then, that's their problem, isn't it? I mean, there's no point making their programs better against their will. :P

As was mentioned here, the 'int foo = void;' syntax is an example of the above, and, I feel, works great. It forces programmers to be explicit about their intentions, without adding too much overhead syntax. The same could be said of using int_unsafe instead of int. -- Simen
Oct 27 2008
prev sibling next sibling parent reply Don <nospam nospam.com.au> writes:
bearophile wrote:
 In a modern language it's probably good for ALL integral numeric types to be
range checked 

I've noticed you've argued for range checking on integral types many times. Have you found overflow to be a common bug? IE, is your comment mainly based on experience, or mainly on theory? I ask this because I've very rarely encountered that type of bug. (It could be that it occurs frequently in some problem domains; maybe we could work out what they are).
Oct 28 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:
 I've noticed you've argued for range checking on integral types many 
 times.

You are right, I am sorry for spamming this newsgroup (and to bore people). I have seen that lot of people don't follow this newsgroup closely, so saying the same thing every once in a while makes more people read it. But for people like you that probably reads every post, it becomes boring...
 Have you found overflow to be a common bug?

Not too much common, but I have had 2 bugs derived by mixing signed and unsigned types (once by array.length). I have have had one or two bugs derived by applying a map() on an array of bytes, and returning a byte that contains a bogus value. I have stopped using unsigned values every time I don't strictly need them, because instead of being safer, that is using them to represent nonnegative numbers, they are actually much less safe. So I think integral values are a source of troubles. This document from experience says that integral overflow bugs are a significant percentage of the total: http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf Bye, bearophile
Oct 28 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Tue, Oct 28, 2008 at 7:21 AM, bearophile <bearophileHUGS lycos.com> wrote:
 This document from experience says that integral overflow bugs are a
significant percentage of the total:
 http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

No, it says array-out-of-bounds errors, dereferencing null pointers, accessing uninitialized variables _and_ integer overflows together represent 50% of the bugs. I don't know about you but I run into those first three cases (well.. two, since there aren't uninitialized variables in D) waaaaay more than I do integer overflows.

I think the frequency of a bug should be multiplied with the trouble it takes to fix it. Frequency alone isn't terribly relevant. Andrei
Oct 28 2008
next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Andrei Alexandrescu wrote:
 Jarrett Billingsley wrote:
 On Tue, Oct 28, 2008 at 7:21 AM, bearophile <bearophileHUGS lycos.com> 
 wrote:
 This document from experience says that integral overflow bugs are a 
 significant percentage of the total:
 http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

No, it says array-out-of-bounds errors, dereferencing null pointers, accessing uninitialized variables _and_ integer overflows together represent 50% of the bugs. I don't know about you but I run into those first three cases (well.. two, since there aren't uninitialized variables in D) waaaaay more than I do integer overflows.

I think the frequency of a bug should be multiplied with the trouble it takes to fix it. Frequency alone isn't terribly relevant. Andrei

And the time it takes to find the source of the bug. It doesn't matter if it's a one-character fix if you have to go through 10 KLOC to find where the problem is. For dereferencing null, you can look at the call stack and add contracts to find where null's being passed in. For integer overflows, it's a bit more difficult.
Nov 01 2008
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Christopher Wright wrote:
 Andrei Alexandrescu wrote:
 Jarrett Billingsley wrote:
 On Tue, Oct 28, 2008 at 7:21 AM, bearophile 
 <bearophileHUGS lycos.com> wrote:
 This document from experience says that integral overflow bugs are a 
 significant percentage of the total:
 http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf 

No, it says array-out-of-bounds errors, dereferencing null pointers, accessing uninitialized variables _and_ integer overflows together represent 50% of the bugs. I don't know about you but I run into those first three cases (well.. two, since there aren't uninitialized variables in D) waaaaay more than I do integer overflows.

I think the frequency of a bug should be multiplied with the trouble it takes to fix it. Frequency alone isn't terribly relevant. Andrei

And the time it takes to find the source of the bug. It doesn't matter if it's a one-character fix if you have to go through 10 KLOC to find where the problem is. For dereferencing null, you can look at the call stack and add contracts to find where null's being passed in. For integer overflows, it's a bit more difficult.

Finding the source of the bug is part of the "trouble it takes to fix it". -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Nov 04 2008
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Andrei Alexandrescu wrote:
 Jarrett Billingsley wrote:
 On Tue, Oct 28, 2008 at 7:21 AM, bearophile <bearophileHUGS lycos.com> 
 wrote:
 This document from experience says that integral overflow bugs are a 
 significant percentage of the total:
 http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

No, it says array-out-of-bounds errors, dereferencing null pointers, accessing uninitialized variables _and_ integer overflows together represent 50% of the bugs. I don't know about you but I run into those first three cases (well.. two, since there aren't uninitialized variables in D) waaaaay more than I do integer overflows.

I think the frequency of a bug should be multiplied with the trouble it takes to fix it. Frequency alone isn't terribly relevant. Andrei

Indeed! -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Nov 04 2008
prev sibling parent Jason House <jason.james.house gmail.com> writes:
Don Wrote:

 bearophile wrote:
 In a modern language it's probably good for ALL integral numeric types to be
range checked 

I've noticed you've argued for range checking on integral types many times. Have you found overflow to be a common bug? IE, is your comment mainly based on experience, or mainly on theory?

I hit an overflow bug in my D code 2 weeks ago. An intermediate value overflowed.
 
 I ask this because I've very rarely encountered that type of bug.
 (It could be that it occurs frequently in some problem domains; maybe we 
 could work out what they are).

Oct 28 2008
prev sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Tue, Oct 28, 2008 at 7:21 AM, bearophile <bearophileHUGS lycos.com> wrote:
 This document from experience says that integral overflow bugs are a
significant percentage of the total:
 http://www.st.cs.uni-sb.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf

No, it says array-out-of-bounds errors, dereferencing null pointers, accessing uninitialized variables _and_ integer overflows together represent 50% of the bugs. I don't know about you but I run into those first three cases (well.. two, since there aren't uninitialized variables in D) waaaaay more than I do integer overflows.
Oct 28 2008