D - type conversions
- Pavel Minayev (34/34) Apr 05 2002 These are a bit weird in D: strings we're already discussing,
- Walter (7/13) Apr 05 2002 It will be implicitly converted if you have just one function. But when ...
- Pavel Minayev (18/23) Apr 05 2002 you
- Walter (7/17) Apr 05 2002 should
- Pavel Minayev (9/12) Apr 06 2002 match,
- OddesE (37/49) Apr 06 2002 Why isn't there a distinction between integral types
- Pavel Minayev (5/12) Apr 06 2002 ...
- OddesE (20/32) Apr 07 2002 But then you keep the problem that it
- Matthew Wilson (8/44) May 06 2002 I kind of like this idea, but isn't it very much like templates & traits...
- Walter (4/10) Apr 06 2002 For the abs() case, I'd just do abs(long) for integral types, and
- Pavel Minayev (9/11) Apr 06 2002 So:
- Walter (10/21) Apr 06 2002 I'm of the curmudgeonly opinion that function overloading should be used
- Stephen Fuld (8/17) Apr 06 2002 Worse than that, since you can compare characters for greater than, etc....
- Pavel Minayev (5/8) Apr 07 2002 it
These are a bit weird in D: strings we're already discussing, now I'd like to point on the others. This time, it's about int <-> float conversions. I came over this when I was writing the math module. Suppose the abs function: long abs(long n) { return n > 0 ? n : -n; } extended abs(extended n) { // uses inline assembler for FPU's FABS asm { ... } } One for integers, one for floats. Now I write: x = abs(123); And get a compiler error! The problem is, 123 is of type int, and can be converted to both long and extended. So, the call is ambiguous. This can be solved by writing 123L, thus explicitly stating that constant is long, but what about variables? int x; x = abs(cast(long) x); // looks weird, no? Moreover, the same applies to floats: x = abs(123.456); 123.456 is double, and can be converted to both long and extended - ambiguity again, and program fails to compile. You have to: x = abs(cast(extended) 123.456); Of course, one can overload the function for ints and doubles, but don't forget there are also byte, short, ubyte, ushort, uint, ulong and float... well, you get the idea. I guess nobody wants to write all these one-line wrappers just to let user pass argument of any type to your function - probably, the compiler should take care of it. Any ideas?
Apr 05 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8kumf$vgd$1 digitaldaemon.com...Of course, one can overload the function for ints and doubles, but don't forget there are also byte, short, ubyte, ushort, uint, ulong and float... well, you get the idea. I guess nobody wants to write all these one-line wrappers just to let user pass argument of any type to your function - probably, the compiler should take care of it.It will be implicitly converted if you have just one function. But when you have multiple functions, and the call doesn't match exactly one, it should return an error. Otherwise, we fall into the C++ quagmire with a long list of such complicated rules about which one is a "better" fit that it just isn't clear what is happening anymore.
Apr 05 2002
"Walter" <walter digitalmars.com> wrote in message news:a8lbqc$1d7s$2 digitaldaemon.com...It will be implicitly converted if you have just one function. But whenyouhave multiple functions, and the call doesn't match exactly one, it should return an error. Otherwise, we fall into the C++ quagmire with a long list of such complicated rules about which one is a "better" fit that it just isn't clear what is happening anymore.It doesn't seem that it would be better. Some set of rules is still needed, IMO. Something like this: - any int can be casted to any other int (bit is an int), difficulty 1 - any float can be casted to any other float, difficulty 1 - any int can be casted to any float, difficulty 2 - any float can be casted to any int, difficulty 2 Compiler tries to minimize conversion difficulty when resolving ambiguity. So, whenever you pass an int literal, it will _first_ look for functions taking long, short, byte etc. Only then it tries floats. This means you could supply just two versions of every function: long foo(long) { ... } extended foo(extended) { ... } Now, any int type will be converted to foo, since it's "easier" than converting to extended, and every float will be converted to extended, since it's easier than converting to long.
Apr 05 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8lrq4$25k7$2 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8lbqc$1d7s$2 digitaldaemon.com...shouldIt will be implicitly converted if you have just one function. But whenyouhave multiple functions, and the call doesn't match exactly one, itlistreturn an error. Otherwise, we fall into the C++ quagmire with a longI understand what you mean and the motivation behind it. They're good reasons. But I want to try the three level system of one match, exact match, or ambiguous.of such complicated rules about which one is a "better" fit that it just isn't clear what is happening anymore.It doesn't seem that it would be better. Some set of rules is still needed, IMO. Something like this:
Apr 05 2002
"Walter" <walter digitalmars.com> wrote in message news:a8m5hc$2icj$1 digitaldaemon.com...I understand what you mean and the motivation behind it. They're good reasons. But I want to try the three level system of one match, exactmatch,or ambiguous.Then, for your system, which is the correct way to define a function which has two distinct versions for floats and ints, and is able to take arguments of any appropriate type: float, double, extended for float version, and byte, ubyte, short, ushort, int, uint, long, ulong for int version? Do you suggest to write wrappers for every possible case?
Apr 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8mkdf$na9$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8m5hc$2icj$1 digitaldaemon.com...Why isn't there a distinction between integral types and floating point types that is stronger than just typea != typeb? byte, short, int, long etc are all integral types, float, double and extended are floating point types. How about this: integral abs(integral n) { return n > 0 ? n : -n; } floating abs(floating n) { // uses inline assembler for FPU's FABS asm { ... } } Where the compiler will interpret any argument that fits a category as an exact match. Implementation of the function will always take the largest size available on the platform for that type category, making all smaller sizes 'fit'. This might also work for char and wchar: character upcase (character c) { // ... } Where character is the category into which all char-types fall, 8, 16 or 32 bit's. Just an idea... :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mailI understand what you mean and the motivation behind it. They're good reasons. But I want to try the three level system of one match, exactmatch,or ambiguous.Then, for your system, which is the correct way to define a function which has two distinct versions for floats and ints, and is able to take arguments of any appropriate type: float, double, extended for float version, and byte, ubyte, short, ushort, int, uint, long, ulong for int version? Do you suggest to write wrappers for every possible case?
Apr 06 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8n4jq$19iu$1 digitaldaemon.com...How about this:...Where the compiler will interpret any argument that fits a category as an exact match. Implementation of the function will always take the largest size available on the platform for that type category, making all smaller sizes 'fit'.Isn't it simplier to just use "long" and "extended" (since they are always the largest, on any platform)?
Apr 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8n8c3$1db8$1 digitaldaemon.com..."OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8n4jq$19iu$1 digitaldaemon.com...But then you keep the problem that it isn't an exact match. With type categories the programmer could explicitly state that he allows all types in the category to be used and that he expects that behaviour. Any integer type would always be a valid 'exact match' with any integral argument. Only if there where a function that was an exact match based on type instead of type category, that function would be called instead. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mailHow about this:...Where the compiler will interpret any argument that fits a category as an exact match. Implementation of the function will always take the largest size available on the platform for that type category, making all smaller sizes 'fit'.Isn't it simplier to just use "long" and "extended" (since they are always the largest, on any platform)?
Apr 07 2002
I kind of like this idea, but isn't it very much like templates & traits. If Walter would be interested in incorporating a (designed from the ground up, hence) better template implementation than has C++ (resulting in all the arcane wangles we have to do to get traits to manipulate type categories, etc.), then I think the appeal of D would widen very quickly (not that it isn't appealing already ... ;) "OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8p5km$12d5$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:a8n8c3$1db8$1 digitaldaemon.com..."OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8n4jq$19iu$1 digitaldaemon.com...But then you keep the problem that it isn't an exact match. With type categories the programmer could explicitly state that he allows all types in the category to be used and that he expects that behaviour. Any integer type would always be a valid 'exact match' with any integral argument. Only if there where a function that was an exact match based on type instead of type category, that function would be called instead. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mailHow about this:...Where the compiler will interpret any argument that fits a category as an exact match. Implementation of the function will always take the largest size available on the platform for that type category, making all smaller sizes 'fit'.Isn't it simplier to just use "long" and "extended" (since they are always the largest, on any platform)?
May 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8mkdf$na9$1 digitaldaemon.com...Then, for your system, which is the correct way to define a function which has two distinct versions for floats and ints, and is able to take arguments of any appropriate type: float, double, extended for float version, and byte, ubyte, short, ushort, int, uint, long, ulong for int version? Do you suggest to write wrappers for every possible case?For the abs() case, I'd just do abs(long) for integral types, and fabs(extended) for floating point types.
Apr 06 2002
"Walter" <walter digitalmars.com> wrote in message news:a8naiu$1fr8$1 digitaldaemon.com...For the abs() case, I'd just do abs(long) for integral types, and fabs(extended) for floating point types.So: min and fmin max and fmax avg and favg ... Then what's the point of function overloading? Seems we're back to C times...
Apr 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8njrd$1qjh$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8naiu$1fr8$1 digitaldaemon.com...I'm of the curmudgeonly opinion that function overloading should be used sparingly and that if used, then the argument types should match exactly. I've spent too many hours trying to get the "best" match idea working right in C++. I've run into too much code that was hard to figure out which function was getting called due to subtleties of the "best" match algorithm. It's not worth it. With abs() and fabs(), you only have two functions to handle all the arithmetic types. It's not so bad <g>.For the abs() case, I'd just do abs(long) for integral types, and fabs(extended) for floating point types.So: min and fmin max and fmax avg and favg ... Then what's the point of function overloading? Seems we're back to C times...
Apr 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8njrd$1qjh$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8naiu$1fr8$1 digitaldaemon.com...Worse than that, since you can compare characters for greater than, etc. it seems reasonable to allow max and min on them as well. Now you have three types to declare for those. -- - Stephen Fuld e-mail address disguised to prevent spamFor the abs() case, I'd just do abs(long) for integral types, and fabs(extended) for floating point types.So: min and fmin max and fmax avg and favg ...
Apr 06 2002
"Stephen Fuld" <s.fuld.pleaseremove att.net> wrote in message news:a8pt6h$2g47$1 digitaldaemon.com...Worse than that, since you can compare characters for greater than, etc.itseems reasonable to allow max and min on them as well. Now you have three types to declare for those.If I recall it correctly, characters are castable to ints, so the integer version would be used by the compiler.
Apr 07 2002