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

Sigils in Perl were awful. They didn't behave concretely. Sometimes it was sort of a type annotation sometimes they were a weird incantation.

Things like implicit scalar conversion

  @foods = qw(burgers fries shakes);
  $length = @foods;
  print $length, "\n";
Yeah it's easy to understand once you know what is happening but it's obscure. There are no easy clues to let you know what is happening.

Then there are situations where you have a scalar but it's a ref

  %author = (
  'name'              => "Harsha",
  'designation'      => "Manager"
  );
  
  $hash_ref = \%author;
So it's not a type its more of a language implementation detail that doesn't add value to the programmer.

Where as with the Hindley–Milner type system the types exist and add value without requiring all of the extra code. You can infer the type most of the time and you get a nice strong type check at compile time.

Sigils seem like a step in the opposite direction to strong inferred types. You have to add a little bit of boiler plate but it's not that strict so it's meaning can still be confusing.



Perl is the most confusing language I’ve ever used professionally, largely because of how it uses sigils sometimes as operators. The other source of confusion are the million and a half implicit variables that are context-specific. It’s the only language where even after ten years I still regularly have to google to do simple things like iterate over a hash. And half the time it doesn’t work because the hash is actually a ref so now you need an arcane syntax or it doesn’t work. In Perl all of the implementation details of the language become footguns for you to shoot yourself with.


> And half the time it doesn’t work because the hash is actually a ref

Perl still supports both „copy by value“ and „copy by reference“. For example:

  my @copy = @original;
  my %hash_copy = %orig_hash;
  my @processed = foo_func(@copy);
  my $ref = \@copy;
  bar_func($ref); # modifies @copy in place
That’s why it uses these sigils to distinguish between references being scalar values (“$”) and actual lists/dictionaries (“@“ and “%”). Since Perl is also dynamically typed if it weren’t for the sigils, it would be quite confusing when reading “array[i] =“ somewhere not knowing whether it modifies an array created remotely or locally. Sigils communicate that because it reads “$array[$i] =“ for a local array or “$$array[$i]” for a remote one.

In other languages like JavaScript or Python everything is basically a reference and, hence, you don’t quite need sigils there. However, on the flip side, you need to be more careful and constantly remind yourself of the fact you are dealing with references and not to accidentally modify the objects you get passed into your function.


not knowing whether it modifies an array created remotely or locally

Yes, good language design allows the programmer to ignore details such as how an object was created or where it is stored.

Having to remember something like that violates so many design principles. Why would a programmer using the array need to know how it was created? It just adds unnecessary complexity to the code, making the programmer's job harder than it needs to be. It's accidental complexity ossified in the programming language.


> Having to remember something like that violates so many design principles.

While I am inclined to agree, this is the case for many languages. Python and JS for example IRC. When you receive a dictionary or an object as a function argument you have no write protection if you poke around inside of it. Perl makes it at least a bit more obvious.

In C++ you have constant reference signatures if you happen to use them but the syntax is also not exactly pretty.

In C you only may pass pointers to an array which is even done implicitly. No write protection either.


I hate to question someone's credentials, but

    for my $key (keys %hash) { ... }
or if it's a reference

    for my $key (keys %{$ref_to_hash}) { ... }
That is fairly simple, and not a good example of something that is difficult in Perl. If you cannot keep that straight, I suspect the extent to which you really use Perl is limited.


Perl is hardly alone in the million and a half implicit variables. Python is a far worse offender on this point and probably equally so in the context specific meaning of a statement (is this a generator or a list). My guess is this gripe is a familiarity thing. Iterating a hash in perl isn't that complicated, neither is iterating a hashref but you do need to be aware of which it is - which you should be anyway so you know whether you're modifying it locally or for the caller.

That said, I'm also in the camp of "I don't care much for sigils."


  @foods = qw(burgers fries shakes);
  $length = @foods;
Not to mention that this refactoring introduces a bug:

  $length = qw(burgers fries shakes);
Because lists and arrays convert to scalars differently. A list is more of a syntactic construct and an array is a data structure. Confused the heck out of me my first few weeks of Perl.


> So it's not a type its more of a language implementation detail

Well, it’s used to distinguish between values that were passed into a function via „copy by value“ or „copy by reference“. Insofar sigils have nothing to do with types but rather with function passing semantics. Yes, with a good type system you can also communicate whether an array is passed by “copy by reference” in the type signature of a function. Then you wouldn’t need sigils. But it’s a secondary feature of static types.

However, you could also abolish “copy by value” altogether (as JS and Python do) and then wouldn’t need neither sigils nor types.

> Where as with the Hindley–Milner type system the types exist

Perl is a dynamically typed language. If it were using static types, it wouldn’t quite need sigils, yes, but then it also wouldn’t have been the Perl programming language…

Sigils do not really have anything to do with static types and shouldn’t be discussed in this context. Then they are also not as confusing.

BTW: This whole discussion of static vs. dynamic typing has become a bit tiresome over the years. It will never be settled. In the 90s everybody tended to hate static typing and for good reasons so: It makes generic programming quite a bit more complicated than necessary. This was when all these dynamically typed scripting languages were invented to enable programmers write abstract code more easily by lifting the burden of constantly inventing composite types. „If it walks like a duck …“

Of course, everything is a trade off and with that approach you are prone to get more run time errors and, hence, people started test-driven development. Then developers started to hate writing tests (also for good reasons) and re-discovered static typing. Now people seem to be happy hacking ad-hoc types together — until they have to refactor other people’s programs and find it rather tricky because of the contagiousness of type signatures. When they spent enough weeks to rewrite type signatures in half of the program base they will long for the good ol’ scripting languages of the 90s again. And the cycle begins again.


The problem here isn't that Perl is a dynamically typed languages but because it uses pass-by-value semantics to an almost absurd degree. This is why it needs explicit references in the first place where as most other languages these either use references for non-primitive types (Ruby, Python, anything on the JVM, &c.) implicitly or treat values and references uniformly (Go, for instance).


I was attempting to contrast the usefulness of sigils vs static typing. While they're different things the do serve similar purposes. They restrict a thing so one can reason about it. At a meta level they do similar things.

The reason I don't like Perl's sigils is that my head is not good at inferring meaning from something like a $ or % or \%. I prefer they way it's done in other languages where you have to call a copy or deep copy function. Not everyone would agree with that preference.

I think dynamic languages have their place. I'm personally more comfortable with the training wheels on in a statically typed language. But there are times where using a statically typed language is going to arrive at an overengineered solution. There are developers that can do amazing things in dynamic languages because they're good at catching their own errors and can leverage the flexibility of dynamic typing to their benefit.


> It makes generic programming quite a bit more complicated than necessary. This was when all these dynamically typed scripting languages were invented to enable programmers write abstract code more easily by lifting the burden of constantly inventing composite types. „If it walks like a duck …“

Don't confuse duck typing with dynamic typing.




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

Search: