LPMuds.net
February 09, 2010, 02:37:55 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: This is the forum page. For the main LPMuds page, visit http://lpmuds.net
 
   Home   SITE FAQ INTERMUD DOWNLOADS LINKS Help Search Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: Why does casting a string convert the L-value?  (Read 1065 times)
Sluggy
Acquaintance
*
Offline Offline

Posts: 43


View Profile
« 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  Grin
Logged
chaos
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« 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
BFF
***
Offline Offline

Posts: 245


View Profile
« 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 (: Smiley code.
Logged
Sluggy
Acquaintance
*
Offline Offline

Posts: 43


View Profile
« 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
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« 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
Acquaintance
*
Offline Offline

Posts: 43


View Profile
« 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.Grin

 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
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« 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
BFF
***
Offline Offline

Posts: 205



View Profile
« 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
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« 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

Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!