Thread overview
Implicit conversions and defining a function on all types
Jun 30, 2004
Sam McCall
Jun 30, 2004
Andy Friesen
Jun 30, 2004
Sam McCall
Jun 30, 2004
Regan Heath
Jun 30, 2004
Sam McCall
June 30, 2004
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
June 30, 2004
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
June 30, 2004
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. :(
True.
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.
Thanks a lot, I'll do that :)
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
June 30, 2004
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. :(
> True.
> 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.
> Thanks a lot, I'll do that :)
> 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/
June 30, 2004
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