views:

361

answers:

5

I am just learning Perl's comparison operators. I tried the below code :-

$foo=291;
$bar=30;

if ($foo < $bar) { 
        print "$foo is less than $bar (first)\n"; 
}

if ($foo lt $bar) { 
        print "$foo is less than $bar (second)\n"; 
}

The output is 291 is less than 30 (second). Does this mean the lt operator always converts the variables to string and then compare? What is the rationale for Perl making lt operator behave differently from the < operator?

Thanks,

+7  A: 

Your guess is right. The alphabetic operators like lt compare the variables as strings whereas the symbolic ones like < compare them as numbers. You can read the perlop man page for more details.

The rationale is that scalars in Perl are not typed, so without you telling it Perl would not know how to compare two variables. If it did guess then it would sometimes getting it wrong, which would lead to having to do things like ' ' + $a < ' ' + $b to force string comparsion which is probably worse than lt.

That said this is a horrible gotcha which probably catches out everyone new to Perl and still catches me out when coming back to Perl after some time using a less post-modern language.

Dave Webb
If 'lt' is only an alphabetic operator why does it not complain when given non-alphabets. Does this mean in perl there is no type-safety? I read a lot of interviews of Bjarne Stroustrup(as per my teacher's recommendation) who says any language that has no type-safety is not good though i do not understand a lot of his language :-(.
Perl is not type safe at all. It always assumes that you know what you're doing which, as we all know, is very dangerous. For example, imagine the array @list = ('a','b','c','d'). Let's say you try to find the length of the array using length(@list). The problem being that length is for calculating the length of a string. Instead of throwing an error, Perl will silently convert the array to a number, reflecting the length of the array - 4 - it will then silently convert this number to a string - "4" - and then return the length of the string - 1.
Dave Webb
String would be a better term than alphabetic. Imagine sorting a list of book titles. The sort function would use lt. If you ran it over my books, among the first few would be 1632 (by Eric Flint) and 1984 (George Orwell). You wouldn't want it to error.
David Dorward
I see, thanks for the explanation. Since Perl seems to convert everything to string, it must be good at anything that deals with string manipulation...
No, Perl is not type-safe. If you use something as a string, Perl treats it as a string. If you use it as a number, Perl treats it like a number. Whether this is a good thing or a bad thing depends heavily on what you're doing. At heart, Perl is a language for processing text and this feature is hugely useful in that context. For example, if you read the string "123" from a file you don't have to parse it before using it as a number like you would in C or Java.
Michael Carman
And to those of us who have been bitten by too much operator overloading in C++, being able to say what you mean, i.e. if you want numeric comparison `<` or string comparison `lt` is priceless.
Sinan Ünür
Perl is type safe only regarding scalars/arrays/hashes. To get more type safety, use modules from CPAN (like Moose).
Alexandr Ciornii
+5  A: 

Since Perl is loosely typed, and values can silently convert between strings and integers at any moment, Perl needs two different types of comparison operators to distinguish between integer comparison (<) and string comparison (lt). If you only had one operator, how would you tell the difference?

Greg Hewgill
A: 

Does this mean the 'lt' operator always converts the variables to string and then compare?

Yes, see perlop

What is the rationale for Perl making 'lt' operator behave differently from '<' operator?

Because having a numeric comparison operator and a string comparison operator makes a lot more sense then having a mumble mumble operator and another, identical mumble mumble operator.

David Dorward
+2  A: 

Rationale? It's a string operator. From "perldoc perlop":

Binary "lt" returns true if the left argument is stringwise less than the right argument.

If that's not what you want, don't use it.

Marius Kjeldahl
Yes, but the real question is why does Perl have string and number operators when many other languages don't.
Chas. Owens
And some do. Common Lisp, for example, has a large number of equality operators, including numbers, characters, and strings. Perl is not C, C#, C++, Basic, nor Java.
David Thornley
+2  A: 

lt compares values lexically (i.e. in ASCII/UNICODE or locale order) and < compares values numerically. Perl has both operators for the same reason "10" + 5 is 15 rather than a type error: it is weakly typed. You must always tell the computer something unambiguous. Languages that are strongly typed tend to use casting to resolve ambiguity, whereas, weakly typed languages tend to use lots of operators. The Python (a strongly typed language) equivalent to "10" + 5 is float("10") + 5.

Chas. Owens
O.K. thanks for the enlightenment