Hacker News new | ask | show | jobs
by Ultimatt 253 days ago
I haven't touched Perl in about ten years but your example is kind of insane. This is the one place Python is more annoying than Perl???

    my $a = ["foo", 123, {"bar" => [[1,2,3], {"qux" => "quux"}]}];
    $a->[2]{"bar"}[1]{"spam"} = "eggs";
    use JSON;
    print(encode_json($a))
That's the same as your example (minus the tuple type), but where Perl shines over Python (a lot) is you could have done the following:

    use JSON;
    my $a = [];
    $a->[2]{"bar"}[1]{"spam"} = "eggs";
    print(encode_json($a))
which would yield the json: [null,null,{"bar":[null,{"spam":"eggs"}]}]

To do this in Python is truly grim:

    import json
    from collections import defaultdict

    # recursive defaultdict using lambda
    datastructure = lambda: defaultdict(datastructure)

    a = [None] * 3
    a[2] = datastructure()
    a[2]["bar"][1]["spam"] = "eggs"

    print(json.dumps(a))
and thats doing it the unpythonic way, if you were to do this like the typical Python dev would accept in an MR for a large corp you would have written:

    import json
    from collections import defaultdict

    def datastructure():
       return defaultdict(datastructure)

    a = []
    # expand list to at least length 3
    while len(a) < 3:
       a.append(None)
 
    a[2] = datastructure()
    a[2]["bar"][1]["spam"] = "eggs"

    print(json.dumps(a))
They would still hate you for defaultdict(datastructure) though. Because absolutely no one in Python realises its got that level of expressionism one of the few places it does.
1 comments

Why is there an arrow between $a and [2], but not between [2] and {“bar”}, in this?

  $a->[2]{"bar"}
The highest rated SO answer here explains a little, and it’s the kind of situational nitpickiness that let to me dropping Perl like a hot potato when something better matching my mental model came across my radar: https://stackoverflow.com/questions/1817394/whats-the-differ...
I suppose it's because very soon people got tired of writing

  $a->[2]->{"bar"}
which is equivalent and also works, but suffers from the explosion of punctuation that Perl often gets criticised for. There's an element of Do What I Mean where the first arrow says this is a reference and work the rest out for me.
In Perl -> is the dereference operator, similar to C.

So when you see

    $a->[2]{"bar"}
then $a is an array reference where each item is a hashmap. But with

    $a->[2]->{"bar"}
then $a is an array reference where each item is a reference to a hashmap.
$a->[2]->{"bar"} is the same as $a->[2]{"bar"} or as $a->[2]{bar}