www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Implicit conversions and defining a function on all types

reply Sam McCall <tunah.d tunah.net> writes:
If I wanted to define a function on all types, would the following be 
enough overloads? IE, can all variables be implicitly cast to one of the 
following with no loss of information?
intmax_t
uintmax_t
ireal
real
Object
char
dchar
wchar

I've just realised that doesn't include functions or delegates, is there 
a way to accept _any_ function/delegate, regardless of parameters?

I would love to use a template for this, but I need operator overloading 
and we don't have automtic instantiation.

Sam
Jun 29 2004
next sibling parent reply Andy Friesen <andy ikagames.com> writes:
Sam McCall wrote:

 If I wanted to define a function on all types, would the following be 
 enough overloads? IE, can all variables be implicitly cast to one of the 
 following with no loss of information?
 intmax_t
 uintmax_t
 ireal
 real
 Object
 char
 dchar
 wchar
 
 I've just realised that doesn't include functions or delegates, is there 
 a way to accept _any_ function/delegate, regardless of parameters?
 
 I would love to use a template for this, but I need operator overloading 
 and we don't have automtic instantiation.

It won't cover structs or associative arrays either. :( One thing you could do is make the function variadic, and assert that the length of _arguments is exactly equal to 1. This is suboptimal in that the argument count can't be checked until runtime, though. -- andy
Jun 29 2004
parent reply Sam McCall <tunah.d tunah.net> writes:
Andy Friesen wrote:

 Sam McCall wrote:
 
 If I wanted to define a function on all types, would the following be 
 enough overloads? IE, can all variables be implicitly cast to one of 
 the following with no loss of information?
 intmax_t
 uintmax_t
 ireal
 real
 Object
 char
 dchar
 wchar

 I've just realised that doesn't include functions or delegates, is 
 there a way to accept _any_ function/delegate, regardless of parameters?

 I would love to use a template for this, but I need operator 
 overloading and we don't have automtic instantiation.

It won't cover structs or associative arrays either. :(

Or, in fact, normal arrays, which wouldn't be possible: have to do Object[] and Object[][] and Object[][][]... why can't arrays be objects?
 One thing you could do is make the function variadic, and assert that 
 the length of _arguments is exactly equal to 1.  This is suboptimal in 
 that the argument count can't be checked until runtime, though.

I suddenly see the point of those requests for a variant type: it'd be nice to take _any_ parameter, but just the one, in some cases. Using variadic functions seems like a workaround, but provides pretty exactly the functionality required. Sam
Jun 29 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Wed, 30 Jun 2004 15:13:01 +1200, Sam McCall <tunah.d tunah.net> wrote:

 Andy Friesen wrote:

 Sam McCall wrote:

 If I wanted to define a function on all types, would the following be 
 enough overloads? IE, can all variables be implicitly cast to one of 
 the following with no loss of information?
 intmax_t
 uintmax_t
 ireal
 real
 Object
 char
 dchar
 wchar

 I've just realised that doesn't include functions or delegates, is 
 there a way to accept _any_ function/delegate, regardless of 
 parameters?

 I would love to use a template for this, but I need operator 
 overloading and we don't have automtic instantiation.

It won't cover structs or associative arrays either. :(

Or, in fact, normal arrays, which wouldn't be possible: have to do Object[] and Object[][] and Object[][][]... why can't arrays be objects?
 One thing you could do is make the function variadic, and assert that 
 the length of _arguments is exactly equal to 1.  This is suboptimal in 
 that the argument count can't be checked until runtime, though.

I suddenly see the point of those requests for a variant type: it'd be nice to take _any_ parameter, but just the one, in some cases. Using variadic functions seems like a workaround, but provides pretty exactly the functionality required. Sam

It'd be nice to be able to check variadic function arguments at compile time. Did either of you see/read my post containing an idea for this, I believe it could be extended to check the arguments length also. Here it is again... ---------- Is there a way to avoid runtime type checking? For example say I have a variadic function that will only accept certain types eg. int, and uint currently I have to go something like.. void fn(...) { if (_arguments[i] != typeid(int) && _arguments[i] != typeid(uint)) { //error } //etc } which tests at runtime and throws an error. Instead it'd be nice if I could go void fn(...) { _argtypes[] = [int,uint]; //etc } or void fn(...) argtypes(int,uint) { } body { //etc } and at compile time it could check the types being passed to this fn and generate an error. ---------- Not sure how to extend it to handle your new requirement. It also looks a little like runtime DBC which is probably a bad thing as people might assume it was runtime checking. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 29 2004
prev sibling parent Sam McCall <tunah.d tunah.net> writes:
Sorry for the spam today, I was bored ;-)

Hmm, to do with implicit conversions:

 The type of a string is determined by the semantic phase of
 compilation. The type is one of: char[], wchar[], dchar[], and is
 determined by implicit conversion rules. If there are two equally
 applicable implicit conversions, the result is an error.

This makes sense to me. It is irritating when you try to pass a literal string and have to cast it, I'd prefer that it chooses, say, the widest available type (or the narrowest, doesn't matter, just something arbitrary and consistent).
 Character literals are single characters and resolve to one of type
 char, wchar, or dchar. If the literal is a \u escape sequence, it
 resolves to type wchar. If the literal is a \U escape sequence, it
 resolves to type dchar. Otherwise, it resolves to the type with the
 smallest size it will fit into.

This does not. If I have a function foo with overloads foo(long) foo(dchar) and someone calls foo('X'), then the dchar version should be called. At the moment, what happens is: 1) Compiler sees 'X' an unescaped character literal, and puts it in a char. 2) Compiler looks for foo(char), and doesn't find it. 3) Compiler promotes the value to an int. 4) Compiler looks for a foo(T) such that an int can be implicitly cast to T. 5) It finds both foo(long) and foo(dchar), and gives an ambiguity error. So if I want to be able to pass any character literal in and handle it as a single unicode character, I have to overload foo(char) and foo(wchar) to call foo(dchar). Can anyone think of a good reason why it shouldn't accept (say) the widest available type (narrowest isn't so good here as then results would be affected by the value of the character), otherwise falling back to the current behaviour? Sam
Jun 30 2004