Andy Wardley wrote:

> Quoted from "Seven Deadly Sins of Introductory Programming Language 
> Design" [1] by Linda McIver and Damian Conway:
> 
>     over one thousand novice programming students ...:
> 
>      "the quick brown fox" + "jumps over the lazy dog"
> 
>    ... they believed that the + should concatenate the two strings.
> 
> Makes perfect sense to me.

Makes sense in a language where variables are typed, because the type of
operation can use the type of the variables.  Having types in neither
variables nor operators causes confusion.

> Can we overload + in Perl 6 to work as both numeric addition and
> string concatenation, depending on the type of the operand on the
> left?
>
> I realise the answer is "probably not", given the number/string
> ambiguity of Perl variables:
> 
>   my $a = 123;
>   my $b = 456;
>   $a + $b;     # 579 or 123456?

Indeed.  And even more so with:

  my $a = 123;
  my $b = '456';
  print $a + $b;

You suggest using the type of the left operand.  So now when wanting to
perform addition the order of the operands can matter:

  print $b + $a;

I realize that by definition the operand order is significant in
concatenation.  (Some argue that this alone is sufficient reason for not
overloading C<+> for concatenation in any language.)  But having the
order of operands determine which of addition or concatenation takes
place strikes me as very fragile.

There are other languages which have attempted having both variables and
operators without types:

  * Basic has traditionally had typed variables and C<+> for both
    addition and concatenation.  Microsoft 'Visual Basic' introduced
    'variant# variables (in, I think, version 3) of no particular type.
    To avoid the addition or concat problem they added the C<&> operator
    to always mean concatenation (deprecating C<+> for concatenation,
    but continuing to allow it where unambiguous for backwards
    compatibility).

  * I think JavaScript does what you're suggesting.  I don't really know
    JavaScript, but recently while trying to hack on code I didn't
    understand I could I could access a previous array element with:

      options[i - 1]

    but, because C<i> was a string, this didn't give the following
    element:

      options[i + 1]      // multiplies by 10, _then_ adds one!

    and ended up with:

      options[i - 0 + 1]  // eurgh!

    Please let's not go there with Perl.

  * PHP has separate concatenation and addition operators, but tries to
    get away with a single untyped equality operator.  I posted a
    message to this list a couple of weeks ago demonstrating some of the
    ways this fails.

While I think that McIvery and Conway are absolutely right for the
context in which they made the above observations, I don't think that
they necessarily apply to Perl:

  * Data read in to Perl tends to arrive as strings.  This applies
    whether reading from the keyboard, getting values from a form on a
    webpage, reading from a file, or retrieving records from a database.
    Therefore you are very likely to end up with numeric data just
    happening to be stored as a string initially.  My example above:

      my $b = '456';

    is obviously contrived, but numbers stored as strings are common.
    (See also previous PHP equality operator rant.)

    This potential confusion doesn't occur in C++, therefore using C<+>
    for concatenation is much more sensible.

  * The paper points out what C++ actually does when C<+> is used with a
    couple of strings (trying to add the addresses of the first
    character of each string) is completely useless, therefore the
    syntax may as well be redeployed in a fruitful way.  Perl already
    does something useful with this syntax.

    Some beginners may use C<+> hoping to get concatenation, but I think
    on discovering that C<+> has tried to add their strings
    mathematically they will be able to understand this behaviour much
    more so than the C++ behaviour.

  * The paper is discussing what makes a good language to use when
    trying to teach programming.  The points made are not what makes a
    language easy to learn per se, but what helps when trying to use a
    language as the tool for teaching programming to complete beginners,
    those who don't know anything at all about programming and are
    struggling to come to terms with its concepts.

    I don't think use in teaching programming is a primary aim of Perl
    6.  (Or, another way round, I think that making Perl 6 a great
    language for teaching programming would make it too restrictive for
    the rest of us.)

  * If somebody uses C<+> in an attempt to concatenate two strings,
    chances are that at least one of those strings isn't numeric.  In
    this case Perl uses a value of zero and displays a warning.  In
    other words, it's very often possible to identify an attempted abuse
    of C<+> because it's being used somewhere that it doesn't make
    sense.

    If C<+> did double duty for concatenation then it would always make
    some sort of sense.  People would still write programs that did the
    wrong thing, but there could no longer be a warning message pointing
    this out because Perl wouldn't be able to notice.

    Arguably the warning (or related diagnostic message) in this case
    could be improved, for example by explicitly stating that C<+> only
    does arithmetic and that if concatenation is desired then C<~> (or
    whatever it is) should be used instead.

Not being able to use C<+> for concatenation may trip up some people
learning Perl some of the time, but I reckon it's a fairly easy hurdle
to get over and that it isn't the main cause of trouble people have with
learning Perl.

> Another option: could we quote operators to indicate string context?
> 
>   $a "+" $b

Hmmm ...

  print $a "+" "+" "+" $b "+" "=" $a + $b;
  print $a "+" qq("+") "+" $b "+" "=" $a "+" $b;

  print "$a+$b=" "+" $a + $b;
  print qq($a"+"$b=) "+" $a "+" $b;

  print "$a+$b=$($a + $b)";
  print qq($a"+"$b=$($a "+" $b));

I don't think I'm so keen on that idea.

Smylers

Reply via email to