Perl is very well thought out, in a way that I don't think gets enough credit. For example, the three loop controls (next, last, redo) are four letters long, which makes remembering them easier. In a world where I sometimes have to jump between languages I haven't used in a while, and I'm always forgetting what arbitrary word choice this particular language used for a feature, it's nice to come back to Perl and have a language where the grammar is a little bit less arbitrary.
unless/until can be way more readable in some conditions than if/while.
Postfix conditionals and loops make flatter code, especially in scripts. Love writing "do function() if $condition".
Want to pass me a hashtable of lambdas that return arrays of alternating functions and regexps?
Go ahead. Show me how to invoke it. I'm waitng.
Python (which has all of the type safety and expressivity of perl) allows such abominations to hide behind clean looking syntax.
Sigils also improve readability. Bad Perl looks like serial port noise. Bad Python looks like good python.
(In Python's defense, it has a nice ffi.)
Never used Perl, so I can't really make an honest comparison. I do use Python at work, though, and I can assure you that is FAR from being true.
In fact, I think this is so untrue that I urge you to check out essentially any code written in academia (especially projects involving numeric computation and data science). If you come back and make that same statement with a straight face, I'll eat my hat.
In Python, that heuristic wouldn't work nearly as well.
...and people endlessly complain about it to this day.
many languages will allow you to succinctly express the concept of "the type of this element is a or b"
e.g. typescript:
https://www.typescriptlang.org/docs/handbook/2/everyday-type...
Rust:
https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html
F# :
https://docs.microsoft.com/en-us/dotnet/fsharp/language-refe...
IDK, allowing that kind of type to be declared seems like a good thing to me? Those links have good examples of where it's useful. You'd need a good reason to use actually "function or regexp" in actual code though.
Alternating functions and regexps looks like this:
[\&some_function, qr/some_regex/, \&another_function, qr/another_regex/]
This is distinct from the idea of sum types.So the design as stated is very contrived, to the point where it doesn't make sense, but existing constructs can be used to make sense of it with a change one way or the other.
I think that it does not make it less readable.
In some programming languages they will be used to avoid clashes with reserved words, which I think is a good idea.
Some programming languages (such as BASIC) have suffix sigils to indicate data type; some (such as OAA) have both prefix and suffix sigils.
Some programming language may allow multiple sigils together in some cases (e.g. Raku and Free Hero Mesh) (in Raku they called the secondary sigils as "twigils").
The meaning seems to vary depending on programming languages; some are used for similar purposes and sometimes they are used for different purposes.
In Perl, the sigil can indicate scalar vs array (but not numbers vs strings), and in BASIC it can indicate numbers vs strings (but not scalar vs array, which is differently).
`@array` - array of values.
`$array[1]` - get element 1 of the array.
`$array` - What do you think this does? Why can't we just `@array[1]`?
I think it will throw an error if you declared my @array
> Why can't we just `@array[1]`?
Because that could return an array or a hash if you are dealing with structures likes arrays-of-arrays (AoA) or arrays-of-hashes (AoH).
To my naive take, it makes much more sense to only identify high level objects to put them under one category (arrays, AoA, AoH -> @) then consider everything else as "uncertain" and default to $.
Otherwise, you would have to declare AoA and AoH differently (ex: my @@AoA; my @%AoH;) and then the interpreter could see @AoA[1] and %AoH[1] as valid but %AoA[1] and @AoH[1] as invalid.
I could see that as potentially having value to know at a glance what you are dealing with, but it might break many things, and casting to a new object with my %aoh_1 = %{ $AoH[1] } makes more sense.
@array[1] returns a single-element list-like thing. It mostly works, but you get a warning:
https://perldoc.perl.org/perldiag#Scalar-value-@%25s%5B%25s%...
There's a lesson here somewhere that most people don't generally want to understand stuff. So stuff that's the least bit different don't tend to go mainstream, things like Haskell have a hard time. Perl was a bit different but just happened to go mainstream anyway, and that probably coloured people's feelings for it, for better and for worse.
Because of slices. If you look at the complete table, you will never get confused again.
'array' is the variable.
'@array' gives me the list in 'array'.
'$array[1]' gives me the scalar ($) value at array[1].
`@array[3..7]` gives me the list (@) of values at array indexes 3-7, inclusive on both sides. (Why does Python use open ended ranges? <facepalm>) (Why is Python's slicing syntax an inflexible loop? <facepalm again>)
`@array[1]`, by the way gives me the list of values at array index 1, which is the same as `$array[1]`