|
Sluggy
|
 |
« on: August 09, 2008, 04:56:41 PM » |
|
This isn't a problem so much as a hiccup that caught me off guard. But why is it that when I cast a string as an int and try to then assign that value to an int it causes the int to become a string? It just seems to me that if you are building a semi-weakly typed language you would simply use the cast to convert the value to the type on the lhs. My first guess is that it was simply easier 
|
|
|
|
|
Logged
|
|
|
|
|
chaos
|
 |
« Reply #1 on: August 09, 2008, 08:30:42 PM » |
|
Well, the funny thing about LPC is that (in one of the many conflicting ways these terms are used) it has weak static typing and strong dynamic typing... which sort of naturally leads to the fact that the dynamic typing generally knows nothing about the static typing. Which is why the behavior you're expecting there, promotion of a strongly-dynamically-typed RHS to the type of a weakly statically typed LHS, is kinda far afield from how LPC does business.
I normally would not expect what you're describing with the str/int/str thing to happen, though. I rarely, if ever, use casting syntax because last I knew it was effectively just an alias for to_int() / to_string() / etc, but maybe your driver does something else, something less useful. In any event, my recommendation is that you change your int foo = (int) bar to int foo = to_int(bar).
|
|
|
|
|
Logged
|
|
|
|
|
wodan
|
 |
« Reply #2 on: August 09, 2008, 08:59:37 PM » |
|
in (FluffOS/MudOS) LPC you use casts to tell the driver what something is (as it can be anything due to the lack of strict types) so int i; float f; i = f; //this will make the compiler insert a conversion from float to int i = (int) f; //this will copy the float into the int as you told the compiler it already was a float, your int var is a float now. usually you'll not want to cast, i find it's only useful when using the class type in (:  code.
|
|
|
|
|
Logged
|
|
|
|
|
Sluggy
|
 |
« Reply #3 on: August 12, 2008, 04:35:16 AM » |
|
wodan, that is exactly the problem. The code
int i; string s; i = (int)s;
in fact completely changed the type of i to a string. At first I was tearing my hair out trying to understand why until I threw in some stringp() / intp() tests to find out what was actually going on. It wasn't difficult to solve I was just more curious as to why that was happening. But chaos seems to have given a fair answer.
|
|
|
|
|
Logged
|
|
|
|
|
chaos
|
 |
« Reply #4 on: August 12, 2008, 05:19:10 AM » |
|
What wodan's saying is relevant. He's saying that if you weren't doing that cast to int, s would be promoted to an integer. (My driver wouldn't do that, it would throw a bad assignment error, but perhaps yours and his would.) Under these semantics, apparently with your (int) cast you're telling it that s already contains an integer and so no promotion needs to be done. (Again, my driver differs, and the (int) cast would tell it to do the type promotion.)
The thing is, the static int and string types on i and s are barely even advisory. It's not so much that i "became a string"; it's that the value of s simply got put into it, and that value happens to be a string. Any variable in LPC is basically just a slot that can hold any type of data, with the data itself having type information attached to it, exactly like a scalar in Perl or a variable in PHP. LPC just fools you because, unlike those languages, it lets you make claims about what type the variable is supposed to be. But the compiler takes that as more of a vague guideline than a rule. At runtime, everything operates pretty much as if you have declared everything 'mixed'.
|
|
|
|
|
Logged
|
|
|
|
|
Sluggy
|
 |
« Reply #5 on: August 12, 2008, 05:51:12 AM » |
|
No. The compiler simply throws an error if I don't cast. Telling me that I can't assign a string to an int. You'll have to bear with me on this as I've spent much more time working with statically typed and compiled languages. Just to make sure I wasn't missing anything I tried the reverse and got a string to transform into an int. I'm glad I learned this now rather than down the road though.  It still somehow seems counter-intuitive to me that the LHS would change. I mean, you say that the datatyping is more advisory than fact, which makes sense to me in other languages where types are not used that often. But when a type of 'mixed' is introduced it becomes a little less reasonable without explicit casts. I suppose one could argue that the driver was designed to handle both cases of conversion. One with a function and the other with an explicit cast.
|
|
|
|
|
Logged
|
|
|
|
|
chaos
|
 |
« Reply #6 on: September 05, 2008, 07:40:34 PM » |
|
If it errors when you don't cast, then the correct thing to do is (still) to use to_int().
About the counterintuitiveness of the LHS 'changing', what I've been trying to tell you is that the only way in which it is changing is that it's being assigned the value you tell it.
|
|
|
|
|
Logged
|
|
|
|
|
quixadhal
|
 |
« Reply #7 on: September 05, 2008, 11:41:03 PM » |
|
Wow, that is counter-intuitive for us stone-age C folk. I had to read that a few times to figure it out.
int i; float f;
i = (int) f;
In C, you'd be asking the compiler to convert the RHS to an int before handing it to the LHS. In some cases, that will change the value (here, it truncates). In others, usually when pointers are involved, it only tells the compiler to change the type info. Your mob_data * is now a char_data *, but that doesn't mean it points to the same size structure.
In LPC, if I've got this right, it's an even further extension of the second case. You're telling the compiler to change the type, but instead of pushing the value into i as an integer, it's actually moving pointers so that variable i now points to a copy of the WHOLE STRUCTURE that f pointed to. Since a variable in LPC (if I remember correctly!!!) is a struct containing the type and the data, by saying you don't need to change types, you get a full copy and thus inherit both the type AND the value.
My question is... what happens if you do
i = (float) f;
Error? Same thing? I'm actually going to guess you'll get an integer, because the float cast will be applied to the already float f (doing nothing), and then i will to a type conversion on the float expression, since the LHS and RHS types don't match at that point.
|
|
|
|
|
Logged
|
|
|
|
|
chaos
|
 |
« Reply #8 on: September 06, 2008, 12:53:45 AM » |
|
That's how it is, yeah, give or take a little.
For your last example, apparently in wodan's driver you would get an integer, and in my driver and Sluggy's you would get a compilation error on incompatible types (in Sluggy's directly because you told it that the RHS was a float, in mine because it's translated to a call to to_float(), whose output type is float).
|
|
|
|
|
Logged
|
|
|
|
|