Hacker News new | past | comments | ask | show | jobs | submit login

Perl's syntax is really confusing.

Especially for example how variables have symbols for different types ($ for scalars, % for hashes, @ for arrays). And if you want to for example pass an array to a function you have to send it manually referenced with like method(\@myArray) which then inside the method is contained in a $scalar.

Compared to Python for example where you'd literally just pass the array to the method like method(array).




For many years Perl subroutines didn't even have method signatures so you had to unroll @ on the first line of every sub. I think even today it may still be considered experimental. Jeez!


The reason for the @_ is that it is a simple way to get both pass by value and pass by reference semantics.

The values in @_ are aliased to the values in the subroutine call.

Most of the time, you want pass by value semantics, so you unpack the array and copy the values into function variables. If you want to modify an argument, it's typically passed in as a reference, and you can mess with it that way.

However, there are times when it would be horribly inefficient to make those copies, or when you need to do some magic (generally best avoided in 99.999% of your code), that this makes possible.

Also, since Perl functions are always variadic, it means that it's easy to work with a variable list of arguments in a function. For example, if you are expecting a list of key value pairs for your function, you can simply write:

  my %args = @_
Making signatures default will be a big improvement, but the power of the simple abstraction @_ provides should not be underestimated. It's actually an elegant solution to a complex problem.


Yeah it's pretty archaic. Shortest hand way of doing it is like this:

  sub method {
    my ($self, $a, $b, $c) = @_;
  }
$self being a reference to the current module (ala Javascript's 'this')


$self is only for OOP so not needed in a regular subroutine.


> Compared to Python for example where you'd literally just pass the array to the method like method(array).

How does one tell Python to pass the contents of said array as distinct parameters to the function, instead of as a lone array parameter?

In Perl, that's the difference between foo(@bar) and foo(\@bar) or foo(1, 2, 3) vs foo([1, 2, 3]).


> How does one tell Python to pass the contents of said array as distinct parameters to the function, instead of as a lone array parameter?

With an asterisk: method(*array)


Right, which I sorta kinda get why coming from C - a *something is the thing pointed to by that something.

How is that more understandable than @ vs \@ without knowing the language? My guess is it isn't.


Python is "relatively" consistent about * and being used to expand or contract arrays and dicts, respectively.

   a, *, b = [1,2,3,4]
   def foo(*args):
   bar(*[1,2,3])
all do "what you'd expect" from the single concept that "* is sort of pattern-matchy for an array".

But the more important bit is just that you don't have to prefix variables with @ and $. Python is optimized for writing code that acts on variables, while perl is optimized for code that acts on strings. While strings are certainly a common data type, most code isn't modifying strings directly. So optimizing for that case doesn't make a lot of sense.


As someone who learned python first - the idea that `myfn(@xs)` would call `myfn(1,2,3)` is... unnerving. Implicitly splicing in arguments makes me wonder what other kind of syntactic oddities are going over my head in my code.


a = [1]

def f(b):

   print(b)
f(a)

f(*a)




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

Search: