Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Sorry for the dot-confusion, i replaced it with "->".

As I said, it may be documented and known in the perl community, in my option it's still horrible. But yes, that's just my opinion of course.

> Perl is not the only language to support this kind of feature; it is present in Ruby with the "splat" operator (*array).

Unfortunately I also don't know ruby, but as far as i understand from what you're saying is that in ruby you need to explicitly tell ruby to "splat" the list in.

I really have problems coming up with usecases for this kind of behaviour, but yes, sure under some curcumstances it might be nice. But i'd argue it's the minority and so having to explicitly "whitelist" it would make sense. To avoid exactly this problem, of accidentaly calling a function that might return a list. The problem that I also see is that at some point you could refactor a function that previously couldn't return a list.

Except maybe that's actually a thing in perl, to use this behaviour as a feature, I don't know.



Except maybe that's actually a thing in perl, to use this behaviour as a feature, I don't know.

Yes, that's common. List processing via variadic arity functions is an explicit feature of Perl.


Not explicit enough. Perl is the only language I've ever seen where

  sub f { return 1, 2 }
  my %x = (a => f(), b => f());
produces a three-element hash that has '2' as a key and 'b' as a value with no warnings. "Even offsets are keys" is far more error-prone than an actual syntax for hash literals, and splicing a list (not a hash!) into a hash doesn't need syntax this terse because it's hardly ever what I wanted. I think even PHP is more sane here.


I think even PHP is more sane here.

I'm not sure how an appeal to PHP as lowest-common-denominator of language sanity argues against understanding the return values of functions you call.


> understanding the return values of functions you call

Sure you should. But confusion between keys and values isn't useful, so there's no reason for a subexpression to be able to do that, and in PHP it can't.


If you are interested (feel free to ignore if not)... Here are some examples for understanding list context and some of the things it can do for you. One funny way to think about it is that in Perl, you store array, array ref, hash, and hash ref structures, and you do not store lists. Lists are a way to express in code, distinct from the actual storage.

    my $arr1 = [1, (), 2, (3, 4, (5, 6)), 7];   # $arr1 is [1, 2, 3, 4, 5, 6, 7]
    my $arr2 = [1, [], 2, [3, 4, [5, 6]], 7];   # $arr2 is [1, [], 2, [3, 4, [5, 6]], 7]

Perl's fat arrow => is the same thing as a comma, except that the thing on the left of it may be a bare word under "use strict". In other words, it has little special meaning and helps you to construct a list of things.

    my $arr3 = [1 => 2 => 3, 4 => 5];  # $arr3 is [1, 2, 3, 4, 5]

For readability, when we construct hashmaps, we use the fat arrow so that you can more easily distinguish key from value.

    my $hash1 = {x => 1, y => 2};  # $hash1->{x} is 1

But you don't have to use the fat arrow:

    my $hash2 = {'x', 1, 'y', 2};  # same as $hash1

An array used in an expression like this is considered to be in list context:

    my @pairs = ('x', 1, 'y', 2);
    my $hash3 = {@pairs};  # same as hash1

Since we can boil about anything down to expression in list context, we have a lot of concise flexibility on constructing arrays and hashes and a variety of ways to express the same concept. Here is a fun use case: Build a hashmap where the keys are the numbers from 1 to 100, and the values are all the string "foo". Other languages perform an elegant dance with infinite cycles and zippers. In Perl, knowing the list context magic, this is a possible solution that shows that "map" may not return the same number of elements as the input list/array:

    my %answer = map { $_ => "foo" } (1..100);

Let's join together two arrays with the letter 'x' between them:

    my @result = (@array1, 'x', @array2);

Take an array reference, and return a reference to its elements cycled once (this specific problem is awkward in Perl and easier in other languages with nice array operators):

    my $doubled = [@$ref, @$ref];

Construct a hashmap where some of the keys are completely optional. This is also an alternative expression for the "many optional parameters to object creation" problem, which most languages let you resolve by allowing you to instantiate the object with defaults and then alter the defaults with accessors in "if" clauses afterwards. In this example, if $self->y is false, then there will not be a "y" key.

    my %params = (
        x => $self->x,
        $self->y ? (y => $self->y) : (),
        z => $self->z,
    );
    MyClass->new(%params);  # this actually converts the hashmap into list context!

Tip of the iceberg. Note that I am not defending, just demonstrating. I am on the fence on if I prefer the Ruby explicit style over Perl's style. For one, in Ruby, the fat arrow actually means that you are now constructing a hashmap. In Perl, since it is just a comma, I can exploit it to mean new things, depending on my context.

    use Moose;
    has age => (isa => 'Int', required => 1);

    use Test::More;
    subtest 'Math is still valid' => sub {
        is(1, 1 => "1 is still equal to itself");
        is(2, 2 => "2 is still equal to itself");
    };




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: