4 ms·
Yeah, the sigils indicate a sort of namespace (@ for array, $ for scalar, & for function), but that breaks down because when dereferencing an array, the @ becom
by steve-howard 15y ago
Yeah, the sigils indicate a sort of namespace (@ for array, $ for scalar, & for function), but that breaks down because when dereferencing an array, the @ becomes $. I have a fair amount of experience with Perl and I still had to read your explanation to remember how that could be valid.
In the company I worked for that used Perl extensively, there were coding standards. In fact, you don't even need that, you just need to remind everyone that cleverness is not a goal in writing maintainable software, even if cleverness is what Perl's best at.
- skimbrel 15y agoThey weren't originally intended to provide namespacing, as far as I know. They were there to make the compiler's life easier. The reason that an array subscript is "$foo[0]" is because the $ sigil means "HEY COMPILER, the expression here is going to evaluate to some scalar". @foo is the entire list and the compiler treats it as a list type; $foo[0] is an element of the list and needs storage/behavior of a scalar. Same thing for hashes: %bar is the whole hash; $bar{quux} is an element and must be treated by the compiler as a scalar. The programmer must remember that square braces mean array subscript and curly braces mean hash lookup. So basically, this is a compiler optimization implemented by having the programmer provide hints to the compiler. It's overhead that probably isn't needed in the modern age, but we're effectively stuck with it. It wouldn't be so bad if they hadn't made the second (and IMO worse) decision: You can reuse symbols across contexts. The way this works is that the compiler maintains a symbol table where each symbol has a slot available for each of the types (scalar $, array @, hash %, subroutine &). This was originally the way to emulate pass-by-reference: you'd write a subroutine that assigned its arguments into typeglobs (* foo — think of it as a wildcard for all things named foo that behaves as a magic scalar with the contents of foo's symbol table entry) and then pulled them back out as the types it wanted: local(*foo) = @_; foreach $bar (@foo) { do_something($bar); } This amounts to telling the compiler "I want to alias the name foo in all contexts to my argument, and then go look at what's stored in the array at that name" and is a poor man's pass-by-reference. Perl 5 has a real reference system that completely obviates the need for this, except for the case of monkey-patching a subroutine, where you still say: local *Package::quux = sub { ... }" What's left is an unfortunate case where things like the GP mentioned ($bar = $foo[$foo]) are possible, and people who think they're being clever will do these things. Like the parent said, this is not a good thing to do.
- steve-howard 15y agoI appreciate the depth of your response; the original reasoning makes sense, and as Python 3 tells us, it is very hard to get people to use your new version if you break enough old code.
- danudey 15y agoThis seems unfair to Python 3. The Python community, including the developers of Python 3, have not been encouraging people to migrate to Python 3. In fact, it was never in their roadmap for people to migrate immediately. The common wisdom has always been 'When starting a new project from scratch, if all the libraries you need are ported, and you won't need backwards compatibility down the road, then use Python 3. Otherwise, use Python 2.x'. It's quite difficult to get people to use your new version when you actively tell them that it's probably not a good idea right now.
- Jeema3000 15y ago"So basically, this is a compiler optimization implemented by having the programmer provide hints to the compiler." I'm not entirely sure that's correct. I think Larry Wall (being a linguist originally) designed it that way because he thought that using context-sensitive sigils was more like regular speech where leading words indicate the number, i.e. 'a cup' vs. 'some cups'...
- epochwolf 15y ago> Larry Wall (being a linguist originally) Having taken a class on linguistics, I have to say basing a computer language on it is a horrible idea. Human languages are far more complex and verbose than is required for talking to computers. Consider that it takes years to master a spoken language. A computer language should be much easier to pick up once you already know how to use an existing language. Computer languages should attempt to reduce complexity and verbosity where possible. Example: I picked up lua in a week. (javascript and ruby experience helped a lot) I'm not an expert by any means but I'm capable of writing usable applications. I doubt a person could pick up a new human language in a week.
- kgtm 15y agoPerl is really powerful, and with power comes responsibility. Reference handling is an area that needs great care, as you can easily make subtle mistakes. Coding standards are important in a code base, often there are many ways to accomplish the same thing. Usually some forms are cleaner than others and can be enforced. An example regarding dereferencing: use v5.10; use strict; use warnings; my $ref = ['one', 2, 3]; say $ref; foreach (@{$ref}) { say; } # These are the same. The first form is much cleaner. # It also makes more sense semanticaly say @{$ref}->[0]; say @{$ref}[0]; say $ref->[0];
- qntm 15y agoYou're proving your own point about the subtlety of reference handling and the important of coding standards in Perl. Was that intentional? say @{$ref}->[0]; This raises a deprecation warning for me. say @{$ref}[0]; This is technically correct, as the leading sigil "@" indicates you are returning an array, but since you're only returning one element in that array, this should probably be "${$ref}[0]" which returns a scalar only. say $ref->[0]; This the only form which I would consider correct or "clean". This example proves nothing about Perl's power, though. The fact that difficult and fiddly reference handling shenanigans are necessary to handle something as trivial as nested arrays and hashes shows quite the opposite.
- kgtm 15y agoAbsolutely! Running the code under Strawberry (5.12.3) produces no warnings and "works" as one would expect. Can it be any easier to shoot yourself in the foot? Regardless, Perl has a special place in my heart.
- chromatic 15y ago... since you're only returning one element in that array, this should probably be "${$ref}[0]" which returns a scalar only. It's perfectly fine to use the array sigil, in which case it's a one-element list instead of a scalar. That's useful sometimes.
- danssig 15y ago
- mikecaron 15y agoSome years ago, Damien Conway spoke about changing sigils going away in Perl 6... whenever that comes out... perhaps 2030.
- cygx 15y agoPerl6 already is out - there's a Tetris-implementation using GTK for Niecza, a Perl6 implementation on Mono/.NET. The implementations are not feature-complete, but if that's your sole criterion, then neither C nor C++ are out yet. The most feature-complete implementation - Rakudo on Parrot - is not production-ready, though, and currently somewhat stalled due to low bus factor: The object-system refactor (which made things like natively-typed attributes possible) introduced a lot of regressions, and the regex engine in particular is not yet fixed as the lead-developer was hit by real-life issues.
- chromatic 15y agoThe implementations are not feature-complete, but if that's your sole criterion, then neither C nor C++ are out yet. That's a little disingenuous. I'm a Perl fan and I'd like to use Perl 6 practically, but the fact that someone wrote a Tetris clone in one of multiple incomplete implementations of Perl 6 doesn't mean that Perl 6 is actually useful for much.
- cygx 15y agoThat's a little disingenuous. Not really. It just shows that feature-completeness may be a good metric when comparing implementations of the same language, but not so much when comparing them to implementations of a different language. the fact that someone wrote a Tetris clone in one of multiple incomplete implementations of Perl 6 doesn't mean that Perl 6 is actually useful for much The fact that there's a Tetris-clone in Perl6 indeed doesn't mean much. However, the fact that it uses GTK is an example of CLR interop, which opens up a whole new level of practical applicability.