Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

strong typing

by sleepingsquirrel (Hermit)
on Dec 14, 2004 at 16:58 UTC ( #414770=note: print w/replies, xml ) Need Help??


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.

Replies are listed 'Best First'.
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.

      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".

        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.

Re: strong typing
by herveus (Parson) 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.

    yours,
    Michael
      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.
        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...

        yours,
        Michael
"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?

      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.
        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.

        types.pm is an effort in that direction.
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.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://414770]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2021-01-18 07:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?