February 23, 2005
xs0 wrote:
> Two questions:
> 
> 1) why inout not just out?

I know I had a reason... but I forget it now.

> 2) why not have void return type, and in case of failure you can just throw an exception yourself? presumably this would be a rare occasion, and you can avoid a bunch of checks this way..

That's possible too.  I just assumed the D runtime might have some use for a success/failure flag, for throwing a default exception or something.  I admit I haven't looked at how the D compiler/runtime handle casting right now.

> 
> Otherwise, not a bad idea at all, if you ask me. The only issue I can see is that the result is not returned (as in "return something;"), so it can't be used in expressions as easily (i.e. you need those temporary variables, which probably complicates implementation significantly).

Yes that's most of my own personal issue with it, but it does give us multiple overloads for casting, and without having to add overload-on-return-type to the language spec.  Although that could still possibly have its uses, but I'm not even diving into that can of worms.  Also I would assume an opCast with a stable return type in its signature would be easier for the compiler anyhow.  Keyword is of course 'assume'.

-- Chris S
February 23, 2005
In article <lx6y84tsdjq9.6hf2uroobfec$.dlg@40tude.net>, Derek Parnell says...
>
>On Wed, 23 Feb 2005 02:09:08 +0100, xs0 wrote:
>
>>> I still think the signature for opCast should change to something like:
>>>   bit opCast(inout T result);
>>> 
>>> Return 'true' on success, 'false' on failure (could not cast for some reason).  Then we could have as many opCasts as we need.
>> 
>> Two questions:
>> 
>> 1) why inout not just out?
>> 2) why not have void return type, and in case of failure you can just
>> throw an exception yourself? presumably this would be a rare occasion,
>> and you can avoid a bunch of checks this way..
>> 
>> Otherwise, not a bad idea at all, if you ask me. The only issue I can see is that the result is not returned (as in "return something;"), so it can't be used in expressions as easily (i.e. you need those temporary variables, which probably complicates implementation significantly).
>
>Agree, this is not a bad compromise.
>
>  void opCast(out T result);
>
>Eg.
>
>  class Foo{
>    int val;
>
>   void opCast(out uint result)
>   {
>     if (val < 0)
>       throw new Exception(
>              std.string.format("Foo: Cannot convert %d to a uint", val));
>     result = cast(uint)val * 100;
>   }
>  }
>  . . .
>  Foo A = new Foo;
>  uint y = A;
>
>  . . .
>
>Hmmm... this I could really use right now!
>-- 


Isn't there another way (or alternate design) to resolve the issue you have, Derek? I ask for several broad reasons; each of which is not intended to reflect in any manner upon your particular coding style/approach:

1) casting should be limited to special cases only. It should absolutely not be used as a panacea for design issues. I'm amazed how much writing is being done about it! Much like goto, I suppose. <sigh>

2) the compiler should catch as many errors as possible at compile time. Using opCast() to throw *runtime* exceptions is, in my opinion, akin to casting one's code unto the winds.

3) in exceptional circumstances, isn't it better to leverage an explicitly
provided method? Within the class/struct? Arguing opCast() vs method() is
talking syntactics rather than semantics ~ yet I find it hard to imagine the
(deliberately?) ugly cast(X) being preferable over a clean method invocation. Oh
well.

4) the apparently popular use of casts to make the method-selection algorithm 'work', simply shows a serious flaw in the design of the latter. I've raged about that aspect in the past, and it's a shame the energy of this thread isn't served in that direction instead.


Spent quite a bit of time messing with opCast last year. Came to the (potentially flawed) conclusion that it's a bit of an outcast ~ so to speak.  D would likely be better off without it. IMO.

- Kris


February 23, 2005
>>>  No, your example didn't show one, you described one being added later.  All  I want is an example that compiles. Which should be possible.
>>
>> Bah, my example was obviously both parts of it.
> 
> Obviously? I think not.

It starts with "For example, consider:". It ends with "returning the unrounded square root" (plus the parenthesised comment). The next sentence is "The problem is that ...". I feel that it is very obvious that the example was both parts, but you seem to not agree. So be it.


> As I said, I want to fiddle with it.

Go ahead then. Fill what's missing, and fiddle with it. Why would anyone (including me) have to help you fiddle with something? You can hire me, of course, and I'll make you a really nice example to fiddle with. I'll even include several extra functions.


>> I'm assuming you don't have access to the compiler from that universe? :)
> 
> Now you're being silly.

Yup, but so are you. I stated (in the next sentence; see above) that the example is an example of a problem with return type overloads.


>> The compiler doesn't error because it cannot pick the overload
> 
> Well, it could pick one at random.
> 
>> , it errors, because Walter said it should, and for good reasons.  There's a large difference there.
> 
> I don't think so, given that the compiler will never and should never pick  one at random.

I agree completely :) Now reread what I said..


>> As for the purpose, if you say the purpose of casting can be overload  selection, then you'll also have to admit that there are also a large  number of other possible purposes to casting.
> 
> Name one.

Here's three:

to round a number (cast(int)3.4)
to just keep the lowest eight bits (cast(ubyte)12354)
to decrease storage requirements (cast(float)3.4)


>> But then, you can't argue that it is the best syntax for doing so,  because all those other purposes are just as valid, and casting is not  somehow the natural choice.
> 
> I believe it is. Georg would agree (it seems).

Georg also said "Of course, changing the semantics of cast may, for all I know, raise other issues." But you conveniently ignored that.. Brad didn't agree, but you also conveniently ignored that..


> I give up, you're either ignoring my point, or you simply disagree, either  way this is pointless.

Well, you're certainly ignoring a number of my points, so I agree that this is pointless.


> As above.
yup


>> That's just ridiculous. "Cast by definition" has a well-defined purpose  and it is not selecting overloads.
> 
> As above.

Now, this one still deserves a special attention, so I'll ask explicitly: do you or do you not agree that cast's only _defined_ purpose/functionality in this (or any other) language is that of type conversion?


> I simply asked you to provide one that compiled, and told you why I wanted  it.

Well, like I said, you can hire me and then I can code whatever you want (as long as I'm able to, of course).


> Your code was not representing something that couldn't or shouldn't  compile, as I've said it showed the code 'before' adding the fictional  feature.

No, it wasn't "before" the fictional feature, it was "after" the fictional feature (I assume you mean overloaded return types). Only the first part was before the second part.


>> Well, I'd say that if someone understands cast as mainly being the thing  to select overloads, he's a newbie (no offense meant to newbies; I was  once a newbie too and also believed many wrong things).
> 
> I never said "mainly".

No, you didn't use that word. But your argument is that cast is so often used to select overloads, that casting and overload selection are practically the same thing.


>>> Further it requires no additional syntax and is easily parsable.
>>
>> Why would no additional syntax for new functionality be a plus?
> 
> It depends on each situation, but generally speaking no new syntax means  less to learn, less to parse etc.

No, it means more to learn and harder to parse. You could also have all looping statements like this:

loop {} (...); // do while statement
loop (...) {} // while statement
loop (...;...) {} // foreach statement
loop (...;...;...) {} // for statement

Are you claiming that is easier to learn?


>> And why would it be more easily parsable than any other syntax?
> 
> Because it's already being parsed.

Not in this way.


>> If anything, it's harder - you need to figure out whether there is a  function call involved, and if so, if it has overloaded return types and  choose some completely different functionality based on the answers to  those questions.
> 
> That isn't parsing, it's process the results of parsing.

Parse: To analyze a sentence or language statement. Parsing breaks down words into functional units that can be converted into machine language. For example, to parse the expression sum salary for title = "MANAGER" the word SUM must be identified as the primary command, FOR as a conditional search, TITLE as a field name and MANAGER as the data to be searched.

So, obviously you need to know what that cast() does?


>>>  It's not converting per-se, more extending and setting bits to 0.
>>
>> Whatever.
> 
> I see you're no longer interested, so I'll stop now.

Well, considering how you failed to reply to the last part of my post, I'll assume you had no counter argument and that you agree..


xs0
February 23, 2005
>> 2) why not have void return type, and in case of failure you can just throw an exception yourself? presumably this would be a rare occasion, and you can avoid a bunch of checks this way..
> 
> That's possible too.  I just assumed the D runtime might have some use for a success/failure flag, for throwing a default exception or something.  I admit I haven't looked at how the D compiler/runtime handle casting right now.

afaik, non-class types either always can or always can't be cast, so that is checked at compile time. casting between classes returns a null if the cast is not possible (that's why there's no instanceof operator, like in Java, you can just do if (cast(SomeClass)obj) {}


> Yes that's most of my own personal issue with it, but it does give us multiple overloads for casting, and without having to add overload-on-return-type to the language spec.

I was actually referring to compiling such code; you can't just replace

cast(SomeType)obj

with

SomeType tmp; obj.opCast(tmp)

because it could be in the middle of an expression. Although, now that I think about it, there is no need for that tmp variable, the compiler can use the result directly, unlike the coder..


>  Also I would assume an opCast with a stable return type in its signature would be easier for the compiler anyhow.  Keyword is of course 'assume'.

Well, I assume that too, and I agree that overloaded return types are a bad thing (except possibly for opCast(), because its not a "normal" function and because imho it has legitimate uses)


xs0
February 23, 2005
On Wed, 23 Feb 2005 03:27:44 +0100, xs0 <xs0@xs0.com> wrote:
>> As I said, I want to fiddle with it.
>
> Go ahead then. Fill what's missing

I tried, I got to a point where, without knowing what you were trying to show, I couldn't decide what to use, which is why I asked you to do it.

> , and fiddle with it. Why would anyone (including me) have to help you fiddle with something?

You don't 'have' to help. I figured you'd want to, to clarify your example for me. It appears I was wrong.

>>> The compiler doesn't error because it cannot pick the overload
>>  Well, it could pick one at random.
>>
>>> , it errors, because Walter said it should, and for good reasons.  There's a large difference there.
>>  I don't think so, given that the compiler will never and should never pick  one at random.
>
> I agree completely :) Now reread what I said..

Done. I still don't agree that "there is a large difference there".

>>> As for the purpose, if you say the purpose of casting can be overload  selection, then you'll also have to admit that there are also a large  number of other possible purposes to casting.
>>  Name one.
>
> Here's three:
>
> to round a number (cast(int)3.4)
> to just keep the lowest eight bits (cast(ubyte)12354)
> to decrease storage requirements (cast(float)3.4)

Excellent. Thanks. I hadn't thought of any of them. So you agree that there is a purpose to casting, other than to simply change the format of the data?

>>> But then, you can't argue that it is the best syntax for doing so,  because all those other purposes are just as valid, and casting is not  somehow the natural choice.
>>  I believe it is. Georg would agree (it seems).
>
> Georg also said "Of course, changing the semantics of cast may, for all I know, raise other issues." But you conveniently ignored that..

I'm trying to think of any and waiting for someone else to think of some.

> Brad didn't agree, but you also conveniently ignored that..

I am conversing with brad as we speak. How am I ignoring him?

>> I give up, you're either ignoring my point, or you simply disagree, either  way this is pointless.
>
> Well, you're certainly ignoring a number of my points, so I agree that this is pointless.

I am disagreeing with several of your points.

>> As above.
> yup
>
>
>>> That's just ridiculous. "Cast by definition" has a well-defined purpose  and it is not selecting overloads.
>>  As above.
>
> Now, this one still deserves a special attention, so I'll ask explicitly: do you or do you not agree that cast's only _defined_ purpose/functionality in this (or any other) language is that of type conversion?

Only purpose, disagree. It has several purposes, you've supplied some above.
It's functionality, or effect.. agree. It does type conversion.

>> I simply asked you to provide one that compiled, and told you why I wanted  it.
>
> Well, like I said, you can hire me and then I can code whatever you want (as long as I'm able to, of course).

So, you have no desire to provide an example to back up your statement, fine.

>> Your code was not representing something that couldn't or shouldn't  compile, as I've said it showed the code 'before' adding the fictional  feature.
>
> No, it wasn't "before" the fictional feature, it was "after" the fictional feature (I assume you mean overloaded return types). Only the first part was before the second part.

Just so we're talking about the same example, it went:

int mysqrt(double a) {
   return floor(sqrt(a));
}

double eval_some_cost(...)
{
    double cost=sqrt(..);

    if (something)
        cost*=1.3;

    return cost;
}

where is the overloaded return type?
where is the cast(type) or other syntax of this feature?

What I am asking for is the above example to compile, either working, or showing the collision error similar to passing parameters.

You also talk about adding another function, I'd like to see that function also, and explore how it can best be:

1. detected
2. solved.

>>> Well, I'd say that if someone understands cast as mainly being the thing  to select overloads, he's a newbie (no offense meant to newbies; I was  once a newbie too and also believed many wrong things).
>>  I never said "mainly".
>
> No, you didn't use that word. But your argument is that cast is so often used to select overloads, that casting and overload selection are practically the same thing.

No, that was not my argument. I never said "often".

>>>> Further it requires no additional syntax and is easily parsable.
>>>
>>> Why would no additional syntax for new functionality be a plus?
>>  It depends on each situation, but generally speaking no new syntax means  less to learn, less to parse etc.
>
> No, it means more to learn and harder to parse.

Assuming you learn that to resolve an overload collision for parameters requires a cast, it's natural to apply the same learning to overload collision for return type.

The parsing is identical, as the syntax is identical.

The additional effort/code is in the name resoultion system.

> You could also have all looping statements like this:
>
> loop {} (...); // do while statement
> loop (...) {} // while statement
> loop (...;...) {} // foreach statement
> loop (...;...;...) {} // for statement
>
> Are you claiming that is easier to learn?

No.

>>> And why would it be more easily parsable than any other syntax?
>>  Because it's already being parsed.
>
> Not in this way.

I think we have a different definition of "parse".
To me, parse means take the text and break it into tokens.

>>> If anything, it's harder - you need to figure out whether there is a  function call involved, and if so, if it has overloaded return types and  choose some completely different functionality based on the answers to  those questions.
>>  That isn't parsing, it's process the results of parsing.
>
> Parse: To analyze a sentence or language statement. Parsing breaks down words into functional units that can be converted into machine language. For example, to parse the expression sum salary for title = "MANAGER" the word SUM must be identified as the primary command, FOR as a conditional search, TITLE as a field name and MANAGER as the data to be searched.

Yep, that's my definition

> So, obviously you need to know what that cast() does?

No, you just need to identify it as a cast. Parsing "breaks down
words into functional units", the phase that does the "converted into machine language" comes after the parsing.

>>>>  It's not converting per-se, more extending and setting bits to 0.
>>>
>>> Whatever.
>>  I see you're no longer interested, so I'll stop now.
>
> Well, considering how you failed to reply to the last part of my post, I'll assume you had no counter argument and that you agree..

You could, that would be illogical.

Regan
February 23, 2005
Hi :)


> 1) casting should be limited to special cases only. It should absolutely not be
> used as a panacea for design issues. I'm amazed how much writing is being done
> about it! Much like goto, I suppose. <sigh>

I tend to agree, but there is this issue with interfaces that I have that casting solves really neatly. Consider SomeInterface with 25 methods (like Java's List). If you want to implement it, you need to write and maintain all those 25 methods. OTOH, you can just be castable to it and need to write only one, using some generic implementation to handle everything, you just provide the data (of course, the functionality most probably isn't the same (like modifying the list in List's case), but I find it that in most cases it is not a big issue). Now, without overloadable casts, you can only handle one interface in this manner, which isn't that many...


> 2) the compiler should catch as many errors as possible at compile time. Using
> opCast() to throw *runtime* exceptions is, in my opinion, akin to casting one's
> code unto the winds.

Yup, I agree.. Returning null should be the norm, as it is with non-user-defined casts..


> 3) in exceptional circumstances, isn't it better to leverage an explicitly
> provided method? Within the class/struct? Arguing opCast() vs method() is
> talking syntactics rather than semantics ~ yet I find it hard to imagine the
> (deliberately?) ugly cast(X) being preferable over a clean method invocation. Oh
> well.

Well, consider the above case. Let's say you also have a method that takes SomeInterface, and you call it 150 times in your project. Isn't casting it in one place better than calling func(obj.asSomeInterface()) 150 times? And maybe you later decide to change the method to use AnotherInterface. If you used casts, you only have two places to change (the method and the opCast()), if you use .asSomeInterface(), there's 150 places to change...


> 4) the apparently popular use of casts to make the method-selection algorithm
> 'work', simply shows a serious flaw in the design of the latter. I've raged
> about that aspect in the past, and it's a shame the energy of this thread isn't
> served in that direction instead.

I'd rather say that it's bad design to overload methods with parameters that are implicitly castable between each other.. IMO, of course :)


xs0
February 23, 2005
On Wed, 23 Feb 2005 04:16:56 +0100, xs0 <xs0@xs0.com> wrote:
>> 1) casting should be limited to special cases only. It should absolutely not be
>> used as a panacea for design issues. I'm amazed how much writing is being done
>> about it! Much like goto, I suppose. <sigh>
>
> I tend to agree, but there is this issue with interfaces that I have that casting solves really neatly. Consider SomeInterface with 25 methods (like Java's List). If you want to implement it, you need to write and maintain all those 25 methods. OTOH, you can just be castable to it and need to write only one, using some generic implementation to handle everything, you just provide the data (of course, the functionality most probably isn't the same (like modifying the list in List's case), but I find it that in most cases it is not a big issue). Now, without overloadable casts, you can only handle one interface in this manner, which isn't that many...

Good point.

>> 2) the compiler should catch as many errors as possible at compile time. Using
>> opCast() to throw *runtime* exceptions is, in my opinion, akin to casting one's
>> code unto the winds.
>
> Yup, I agree.. Returning null should be the norm, as it is with non-user-defined casts..

I agree. I think consistency is a good thing here.

>> 3) in exceptional circumstances, isn't it better to leverage an explicitly
>> provided method? Within the class/struct? Arguing opCast() vs method() is
>> talking syntactics rather than semantics ~ yet I find it hard to imagine the
>> (deliberately?) ugly cast(X) being preferable over a clean method invocation. Oh
>> well.
>
> Well, consider the above case. Let's say you also have a method that takes SomeInterface, and you call it 150 times in your project. Isn't casting it in one place better than calling func(obj.asSomeInterface()) 150 times? And maybe you later decide to change the method to use AnotherInterface. If you used casts, you only have two places to change (the method and the opCast()), if you use .asSomeInterface(), there's 150 places to change...

Good point.

>> 4) the apparently popular use of casts to make the method-selection algorithm
>> 'work', simply shows a serious flaw in the design of the latter. I've raged
>> about that aspect in the past, and it's a shame the energy of this thread isn't
>> served in that direction instead.
>
> I'd rather say that it's bad design to overload methods with parameters that are implicitly castable between each other.. IMO, of course :)

I tend to agree here also, however is it at all possible that the methods could provide more efficient, or a more exact 'something' for specific types than a cast and 1 method could?

Regan
February 23, 2005
On Wed, 23 Feb 2005 02:25:40 +0000 (UTC), Kris wrote:

> In article <lx6y84tsdjq9.6hf2uroobfec$.dlg@40tude.net>, Derek Parnell says...
[snip]

>>Agreed, this is not a bad compromise.
>>
>>  void opCast(out T result);
>>
[snip]

>>Hmmm... this I could really use right now!

> 
> Isn't there another way (or alternate design) to resolve the issue you have, Derek? I ask for several broad reasons; each of which is not intended to reflect in any manner upon your particular coding style/approach:

Thanks Kris. Your questions and observations below a very good and valid ones.

> 1) casting should be limited to special cases only. It should absolutely not be used as a panacea for design issues. I'm amazed how much writing is being done about it! Much like goto, I suppose. <sigh>

LOL. Yes it has become a little too emotional. I agree with your sentiments above. And we are talking about *explicit* casting, right?

Currently, an explicit cast does one of two things, depending on what is getting cast to what...

1) To tell the compiler that some data, even though it has a data type of
'x', is to be treated as if it has a data type of 'y', and that no actual
data is modified by this.
2) To tell the compiler that data of type 'x' is to be modified (converted)
to a new storage format of data type 'y'.

Now (1) is definitely a low-use, special circumstance, situation. It may even cause runtime errors, but that's okay because the coder has accepted responsibility of that due to the explicit cast.

But (2) is a common activity of programs. To convert data from one format to another is done all the time.

Because it is commonly required, it would be _nice_ to have some syntax sugar to help us (lazy?) coders. And maybe, an improved opCast is a way to achieve that sugary rush.

> 2) the compiler should catch as many errors as possible at compile time. Using opCast() to throw *runtime* exceptions is, in my opinion, akin to casting one's code unto the winds.

Yes, in principle I agree. But consider the conversion process. Often conversions can only fail at run time. If we use an improved opCast in order to invoke a customized conversion function, then one would expect that runtime errors may occur.

For example, if we have two classes, Foo and Bar, then

  aFoo = aBar;

would trip up with the "cannot implicitly cast" error. But

  aFoo = cast(Foo)aBar;

would first try to see if Bar has an opCast(Foo) defined, and if so invoke it, otherwise issue an error like it does today.

If we knew that a runtime error is sometime possible we could write ...

  try { aFoo = cast(Foo) aBar;} catch ( ... whatever ... ) ...;

> 3) in exceptional circumstances, isn't it better to leverage an explicitly
> provided method? Within the class/struct? Arguing opCast() vs method() is
> talking syntactics rather than semantics ~ yet I find it hard to imagine the
> (deliberately?) ugly cast(X) being preferable over a clean method invocation. Oh
> well.

Yes, it is just syntax.

   aFoo = cast(Foo)aBar;

verses

   aFoo = aBar.toFoo();
or
   aBar.toFoo( aFoo );


I suspect the 'cast' syntax is more amenable to templates though.

   template(T) {
      T a = new T;
      a = cast(T)parm;
   }
(yeah, the above syntax is wrong but you get the idea )

> 4) the apparently popular use of casts to make the method-selection algorithm 'work', simply shows a serious flaw in the design of the latter. I've raged about that aspect in the past, and it's a shame the energy of this thread isn't served in that direction instead.

True, one could do ...

  class Bar{
       void Convert(out Foo x) { .... };
       void Convert(out uint x) { ... };
       void Convert(out real x) { ... };
       void Convert(out char[] x) { ... };
   }

   Foo aFoo;
   real r;

   aBar.Convert( aFoo );
   aBar.Convert( r );

Which is identical to the opCast() idea being discussed here, except that
it is non-standard (everyone comes up with a new name for 'Convert').

This sort of method-selection is not, per se, indicative of a serious flaw in the design. The difference that has been suggested is ...

  class Bar{
       void opCast(out Foo x) { .... };
       void opCast(out uint x) { ... };
       void opCast(out real x) { ... };
       void opCast(out char[] x) { ... };
   }

   Foo aFoo;
   real r;

   aFoo = cast(Foo)aBar;
   r  = cast(real)aBar;

> Spent quite a bit of time messing with opCast last year. Came to the (potentially flawed) conclusion that it's a bit of an outcast ~ so to speak.  D would likely be better off without it. IMO.

I totally agree with you regards the current implementation of opCast. It is basically worthless.

-- 
Derek
Melbourne, Australia
23/02/2005 1:44:38 PM
February 23, 2005
In article <cvgsj4$2dja$1@digitaldaemon.com>, xs0 says...
>
>Hi :)
>
>
>> 1) casting should be limited to special cases only. It should absolutely not be used as a panacea for design issues. I'm amazed how much writing is being done about it! Much like goto, I suppose. <sigh>
>
>I tend to agree, but there is this issue with interfaces that I have that casting solves really neatly. Consider SomeInterface with 25 methods (like Java's List). If you want to implement it, you need to write and maintain all those 25 methods. OTOH, you can just be castable to it and need to write only one, using some generic implementation to handle everything, you just provide the data (of course, the functionality most probably isn't the same (like modifying the list in List's case), but I find it that in most cases it is not a big issue). Now, without overloadable casts, you can only handle one interface in this manner, which isn't that many...

Ouch!  :-)


>> 2) the compiler should catch as many errors as possible at compile time. Using opCast() to throw *runtime* exceptions is, in my opinion, akin to casting one's code unto the winds.
>
>Yup, I agree.. Returning null should be the norm, as it is with non-user-defined casts..

opCast() is, by definition, a runtime call. Getting the compiler to invoke it at compile-time would certainly be interesting.


>> 3) in exceptional circumstances, isn't it better to leverage an explicitly
>> provided method? Within the class/struct? Arguing opCast() vs method() is
>> talking syntactics rather than semantics ~ yet I find it hard to imagine the
>> (deliberately?) ugly cast(X) being preferable over a clean method invocation. Oh
>> well.
>
>Well, consider the above case. Let's say you also have a method that takes SomeInterface, and you call it 150 times in your project. Isn't casting it in one place better than calling func(obj.asSomeInterface()) 150 times? And maybe you later decide to change the method to use AnotherInterface. If you used casts, you only have two places to change (the method and the opCast()), if you use .asSomeInterface(), there's 150 places to change...

Aye

>> 4) the apparently popular use of casts to make the method-selection algorithm 'work', simply shows a serious flaw in the design of the latter. I've raged about that aspect in the past, and it's a shame the energy of this thread isn't served in that direction instead.
>
>I'd rather say that it's bad design to overload methods with parameters that are implicitly castable between each other.. IMO, of course :)

There's the rub ~ a Haitian Divorce waiting to happen.



February 23, 2005
The depth of this thread is becoming rediculous. Maybe we should take this to e-mail?

> I tried, I got to a point where, without knowing what you were trying to  show, I couldn't decide what to use, which is why I asked you to do it.

int a() { return 1; }
double a() { return 1.5; } // this is the second part
double b() { double tmp=a(); return a*2; }

happy? :)


> Done. I still don't agree that "there is a large difference there".

There is. You said the compiler errors because it cannot pick an overload. I said that the compiler errors because it doesn't want to pick an overload.


>>>> As for the purpose, if you say the purpose of casting can be overload   selection, then you'll also have to admit that there are also a large   number of other possible purposes to casting.
>>>
>>>  Name one.
>>
>> Here's three:
>>
>> to round a number (cast(int)3.4)
>> to just keep the lowest eight bits (cast(ubyte)12354)
>> to decrease storage requirements (cast(float)3.4)
> 
> 
> Excellent. Thanks. I hadn't thought of any of them. So you agree that  there is a purpose to casting, other than to simply change the format of  the data?

No, I don't agree those are purposes, those are side-effects. I said YOU'll have to agree that there are many purposes with reference to the next statement:


>>>> But then, you can't argue that it is the best syntax for doing so,   because all those other purposes are just as valid, and casting is  not  somehow the natural choice.


> I'm trying to think of any and waiting for someone else to think of some.

Of course, whatever I write is not an issue, because you said so.


>> Brad didn't agree, but you also conveniently ignored that..
> 
> I am conversing with brad as we speak. How am I ignoring him?

Well, in your summary of the current score, you only mentioned Georg but not Brad. And I never said you ignored Brad.


> Only purpose, disagree. It has several purposes, you've supplied some  above. It's functionality, or effect.. agree. It does type conversion.

You skipped DEFINED purpose, even though I emphasized it.


> Just so we're talking about the same example, it went:
> [snip]
> 
> where is the overloaded return type?
> where is the cast(type) or other syntax of this feature?

The overloaded return type is in the statement following this code. And it was in reply to what Derek wrote:

> The main [issue] seems to be, what would happen if someone coded a function
> call but did not assign the return to anything? How would the compiler know
> which signature to use if it had to use return-type as a determinate? 

So I don't see what it has to do with cast or other syntax of this feature.


> No, that was not my argument. I never said "often".

Yeah, really funny. So, what exactly is your argument that makes cast() the best possible syntax for selecting an overloaded return type?


>> No, it means more to learn and harder to parse.
> 
> Assuming you learn that to resolve an overload collision for parameters  requires a cast, it's natural to apply the same learning to overload  collision for return type.

Resolving an overload collision doesn't require a cast, it's just one way of doing it. Casting the result when there isn't an overload is natural, because casting works the same everywhere. What isn't natural is using cast syntax for something completely different.


>> You could also have all looping statements like this:
>>
>> loop {} (...); // do while statement
>> loop (...) {} // while statement
>> loop (...;...) {} // foreach statement
>> loop (...;...;...) {} // for statement
>>
>> Are you claiming that is easier to learn?
> 
> No.

So having the same keyword for looping constructs is not easier to learn, but having the same keyword for both casting types and selection of return-overloaded functions is easier to learn?


> I think we have a different definition of "parse".
> To me, parse means take the text and break it into tokens.

Nope, that's lexing (or lexical analysis, if you want to look it up).


>> Parse: To analyze a sentence or language statement. Parsing breaks down  words into functional units that can be converted into machine language.  For example, to parse the expression sum salary for title = "MANAGER"  the word SUM must be identified as the primary command, FOR as a  conditional search, TITLE as a field name and MANAGER as the data to be  searched.
> 
> Yep, that's my definition

No, it isn't. It says "Parsing breaks down words into functional units", what you're saying is "Parsing breaks input into words". Also notice how SUM is already identified as a command at this stage, even before machine language is produced.


>>>> Whatever.
>>>
>>>  I see you're no longer interested, so I'll stop now.
>>
>> Well, considering how you failed to reply to the last part of my post,  I'll assume you had no counter argument and that you agree..
> 
> You could, that would be illogical.

It's also illogical to claim I was no longer interested (considering the amount of text after "Whatever"), but you still did..


xs0