in reply to Re: (Completely OT) - Hero(i)n programming language on Slashdot in thread (Completely OT) - Hero(i)n programming language on Slashdot
Strong typing loses most of its meaning when most everything is automatically coerced into a new type...
#!/usr/bin/perl -w
use strict; #try to catch as many type errors as possible
#setup a few initial things
$\="\n";
my $a=4; my $ref_a=\$a;
my @b=("b",5); my $ref_b=\@b;
my %c=("c",6); my $ref_c=\%c;
print $a+@b; #coerce array into number
print $a+$ref_b; #coerce reference into number
my $d=eval %c; #coerce hash into string
print "d=$d"; #amusing result
my @e=%c;print "@e"; #hashes and arrays are different types. Oh wait
+...
print "c=$_" for %c;
my @t=12; #coerce number into array
print @t;
print 0+@t;
print "\\4 = ".(\4->{"what???"}); #???
sub test{ return ("a",123) }; #sub returns a list
my $scalar_list=test(); #coerce into scalar
my @array_list=test(); #coerce into array
my %hash_list=test(); #coerce into hash
print "\$scalar_list=$scalar_list\n\@array_list=@array_list";
no warnings;
my %i=$ref_a;
print %i; #apparently hashes can be scalar refs...
no strict;
$$ref_a->[88]=7;
print $$ref_a->[88]
-- All code is 100% tested and functional unless otherwise noted.
Re: strong typing
by hardburn (Abbot) on Dec 14, 2004 at 17:53 UTC
|
print $a+@b; #coerce array into number
This is exactly the same as array.length() in Java. It's not a type conversion.
print $a+$ref_b; #coerce reference into number
Those are both scalars. Not a type conversion.
my $d=eval %c; #coerce hash into string
This one is tricky. What the eval actually gets is certain internal information concerning the hash, which happens to be output as a valid perl expression (a division operation). You've lost all real information about the hash, and therefore is not a type conversion.
my @e=%c;print "@e"; #hashes and arrays are different types. Oh wait
My own view on this is that hashes and arrays are both subtypes of lists. So it's not so much a conversion between different types than between different subtypes. There are those that disagree, though.
my @t=12; #coerce number into array
This simply makes a scalar containing 12 that is placed as the first element of the list, and the list is then assigned to an array. The scalar is still there, so it's not a type conversion.
I think I've established a pattern here. None of these are really type conversions.
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
print $a+$ref_b; #coerce reference into number
Those are both scalars. Not a type conversion.
Humm, no! To make any arithmetic operation we need to convert the string (that are just a sequence of bytes), into numbers, where we use 4 bytes (32 bits processor) to make the calculation. (this is standart calculation ok!)
The wonderful job that Perl does for us, with speed, is to convert automatically all the boolean, integer, floating and string types with a single type, SCALAR.
Graciliano M. P.
"Creativity is the expression of liberty".
| [reply] [Watch: Dir/Any] [d/l] |
|
I said they're both scalars. Perl's type system has no concept of "integer", "boolean", etc.--it only knows about scalars, arrays, etc. Since the orginal code presented only deals with scalars, there is only one type involved: scalars.
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
| [reply] [Watch: Dir/Any] |
|
|
|
|
Re: strong typing
by herveus (Prior) on Dec 14, 2004 at 18:37 UTC
|
Howdy!
There's a whole bunch of misdirection in them thar comments...
use strict; #try to catch as many type errors as possibleWrong... The strict pragma is meant to "restrict unsafe constructs",
according to its POD. This is not the same thing as "catching type errors". See below for applications... print $a+@b; #coerce array into number
Misleading... This isn't "type coercion". This is "evaluation in
a scalar context".print $a+$ref_b; #coerce reference into number
A reference is a species of scalar that numifies to the memory address
of its referent. No coercion here. It's still a scalar.my $d=eval %c; #coerce hash into string
print "d=$d"; #amusing result
Misleading again. This is "evaluation of a hash in a scalar context".
I'm not sure what is actually amusing about the result. It's all there in
the documentation.my @e=%c;print "@e"; #hashes and arrays are different types. Oh wait
+...
print "c=$_" for %c;
They are both collections, so one could group them as the same meta-type, but they have different characteristics that warrant treating them as different types. The assignment is simply "evaluation of a hash in a list context".
'for %c' produces the same situation. As usage goes, it's value is limited.my @t=12; #coerce number into array
print @t;
print 0+@t;
The assignment sets up a list context, in which there is only one item,
the "12". I don't see "type coercion" here either. The two 'print' statements
are unremarkable demonstrations of evaluating an array in list and scalar
contexts.print "\\4 = ".(\4->{"what???"}); #???
The output of this line lies. \4 produces a different value than does
\4->{"what???"}. In the debugger, 'p \4' prints a ref to a scalar; 'x \4' shows
that '4' is the referent. The numeric part of the ref is different from that
printed by this line, which is, in fact, a scalar reference to an undefined
value. What was this supposed to demonstrate?
Further fun with perl -MO=Deparse finds that this print is parsed as print '\\4 = ' . \$4{'what???'};
How interesting...sub test{ return ("a",123) }; #sub returns a list
my $scalar_list=test(); #coerce into scalar
my @array_list=test(); #coerce into array
my %hash_list=test(); #coerce into hash
print "\$scalar_list=$scalar_list\n\@array_list=@array_list";
$scalar_list demonstrates the comma operator in action. What are you
trying to demonstrate here? What did you intend to demonstrate with %hash_list?
Where does "coercion" come into play here?no warnings;
my %i=$ref_a;
print %i; #apparently hashes can be scalar refs...
Oh? How do you demonstrate that? I note that you "cleverly" turn warnings
off so the casual observer won't see "Odd number of elements in hash assignment"
pop up from the assignment, nor "Use of uninitialized value in print" from the
print. What do you think is actually stored in %i? Iterate over the keys and
dereference them, if you dare. Hint: it won't work. Spectacularly.
Further investigation with Deparse show that this is parsed as my (%i) = $ref_a;
creating the list context from which it expects to get an even number
of items. The same condition applies above at 'my @t=12;'no strict;
$$ref_a->[88]=7;
print $$ref_a->[88]
Why turn strict off here? Which facet of strictures were you hoping to
sneak by here? Pray explain.
Deparse reports a triple dollar sign, not a double.
So, to get to the bottom: bad troll; no biscuit.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Misleading... This isn't "type coercion". This is "evaluation in a scalar context"
I'd be interested to know the difference. Here are some quotes and references I've been able to round up...
- Coercion is the implicit, automatic conversion of the type of an expression to the type required by its context. Most programming languages that have type checking also have some coercions, such as integer to real in mixed expressions. (Dereferencing is a coercion associated with pointers $\S $16.) Coercions can be dangerous because they are not explicit, but depend on declarations that may be some way away in the program text, and it is easy for the user to make mistakes.
- The ($$) is the prototype. It's a shorthand to identify the types of the arguments that will be passed to your subroutine. In this case, Perl is told to expect two scalars. You can prototype your subroutines without defining them:
sub add_two ($$); # add_two will be defined later
If you then try to call your subroutine without two arguments that can be evaluated as scalars, Perl will complain. (However, almost everything can be coerced to a scalar. Scalar prototypes accept @arrays and %hashes without warning!)
- Normally, when an array is an operand of a unary or binary operator, it is evaluated in the scalar context imposed by the operator and yields a single result. For example, if we execute:
$account_balance = @credits + @debits;
$biblical_metaphor = @sheep - @goats;
then $account_balance gets the total number of credits plus the number of debits, and $biblical_metaphor gets the numerical difference between the number of @sheep and @goats.
That's fine, but this scalar coercion also happens when the operation is in a list context:
@account_balances = @credits + @debits;
@biblical_metaphors = @sheep - @goats;
- Tutorial on Collections and References in Perl
$length2 = scalar(@intArray); # type coercion, reports size of the arr
+ay
$hashTable{"third"} = @intArray; # coercion to a scalar type means the
+ value is not the array but its length
- When overloaded operators are applied to mixed expressions such as plus to an integer and a rational number there are two possible choices. Either the evaluation of the expression fails or one or more of the subexpressions are coerced into a corresponding object of another type
- Coercion allows the user to omit semantically necessary type conversions. The required type conversions must be determined by the system, inserted in the program, and used by the compiler to generate required type conversion code. Coercions are essentially a form of abbreviation which may reduce program size and improve program readability, but may also cause subtle and sometimes dangerous system errors.
- Implicit. In this case, no actual notation is required to specify the conversion: conversions are automatically supplied by the language processor. This type of conversion is often called coercion. ...When a type mismatch occurs between the actual type Ta of expression occuring in a context which expects a type Te, a type checker would normally report an error. However, if the language defines a coercion in this case, then that coercion is applied instead of reporting the error.
- JScript can perform operations on values of different types without the compiler raising an exception. Instead, the JScript compiler automatically changes (coerces) one of the data types to that of the other before performing the operation. Other languages have much stricter rules governing coercion.
- Internally, adding a float and an integer is not possible, so the compiler should convert one type to the other type “as necessary”. This is called type coercion and can be the source of some subtle bugs (coercing floats to integers, for example). Type coercion is controversial topic in language design, since it is an easy abstraction, but weakens the type system.
- Truth in Perl is always evaluated in a scalar context. (Other than that, no type coercion is done.)
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Howdy!
If you "coerce" a value, you still have the same value, expressed in
different units, if you will. For example, 1 (integer) can be coerced
into 1.0 (float) without loss of information. However, when you write
$a + @b, the operation being performed is not, in my mind, type coercion.
There is an implicit operation being performed on @b, but you cannot
say the @b is the same thing as the number of elements it contains.
The two values are incommensurable.
I am reminded of an advertisement that has been on the air lately that
speaks of "miles", "nautical miles" ("a wetter version of miles"), and
"square miles" ("a squarier version of miles"), as if they expressed the
same thing (before segueing to the point of the advertisement). It's
inane to assert that you can somehow compare length with area, just as
it does not make sense to think that @z in "$x = $y + @z" can mean "the
collection of elements in the array z". Now, the hypothetically legal
"@x = $y + @z" could cause @x to contain the elements of @z each with $y
added to them, but that's a whole different kettle of fish.
Many of the alleged "type coercions" sleepingsquirrel presents are of
this sort, where a variable or expression is being evaluated in an unusual
context, causing implicit operations to be performed that extract attributes
of the variable rather than its value. Perl does this a lot more than most
languages.
Now, the lengthy dissertation I reply to dodges the fact that many of the
examples adduced are obfuscated by the misleading comments appended thereto.
Warnings are suppressed at key moments; strictures are misrepresented.
It still comes across as trollish...
| [reply] [Watch: Dir/Any] |
"strong typing" is a meaningless phrase
by chromatic (Archbishop) on Dec 14, 2004 at 17:54 UTC
|
Consider the difference between value typing and container typing. Then consider that you've told perl not to check for type violations. Why would you expect it to complain about type system violations?
| [reply] [Watch: Dir/Any] |
|
Then consider that you've told perl not to check for type violations.
Hmm. Honest question: how do you tell perl to turn on type checking?
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [Watch: Dir/Any] |
|
What do you consider "type-checking"? That's also an honest question - it means different things to different people.
Being right, does not endow the right to be rude; politeness costs nothing. Being unknowing, is not the same as being stupid. Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence. Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.
| [reply] [Watch: Dir/Any] |
|
|
|
|
|
|
|
types.pm is an effort in that direction.
| [reply] [Watch: Dir/Any] |
Re: strong typing
by hardburn (Abbot) on Dec 14, 2004 at 19:10 UTC
|
One other thing: note that even the most strongly typed langauge will let you define a function that takes one type and returns another:
$ ocaml
Objective Caml version 3.08.1
# let rec sum = function
[] -> 0
| i :: l -> i + sum l;;
val sum : int list -> int = <fun>
# let list = 1 :: 2 :: 3 :: [];;
val list : int list = [1; 2; 3]
# sum list;;
- : int = 6
(If you're not familer with OCaml, the above makes a function that takes a list of integers and sums them, returning a single integer. In OCaml, "int list" and "int" are totally seperate types.)
Indeed, a language that didn't allow you to do this would be very limited. All Many of the examples you presented essentially do this, although the actual function call is hidden away by Perl.
"There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.
| [reply] [Watch: Dir/Any] [d/l] |
|
|