Re^2: (Completely OT) - Hero(i)n programming language on Slashdot
by jdporter (Paladin) on Dec 14, 2004 at 17:26 UTC
|
| [reply] |
|
Here's some more typing goodness from MJD.
-- All code is 100% tested and functional unless otherwise noted.
| [reply] |
strong typing
by sleepingsquirrel (Chaplain) on Dec 14, 2004 at 16:58 UTC
|
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.
| [reply] [d/l] |
|
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] [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] [d/l] |
|
|
|
|
|
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] [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] [d/l] [select] |
|
|
| [reply] |
|
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] |
|
|
|
|
|
|
$ 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] [d/l] |