Periodic Table of the Operators
mAsterdam writes "At his code blog Mark Lentcner writes:
"A while back, I saw Larry Wall give a short talk about the current design of Perl 6. At some point he put up a list of all the operators - well over a hundred of them! I had a sudden inspiration, but it took a few months to get around to drawing it..."
You might want to take a look at this and think about which operators are yet to be discovered."
http://www.ozonehouse.com/mark/blog/code/PeriodicT able.pdf
I the only one who saw the adobe acrobat plugin for firefox on his knees loading this?
Courtesy of Google:
e %3Ahttp%3A%2F%2Fwww.ozonehouse.com%2Fmark%2Fblog%2 Fcode%2FPeriodicTable.pdf&btnG=Zoeken
http://www.google.nl/search?hl=nl&ie=UTF-8&q=cach
user@host$ diff
A mirror location for the PDF of the periodic table: http://condor.madoka.be/various/PeriodicTable.pdf
I'm also hosting the PDF directly, here:
PeriodicTable.pdf
user@host$ diff
Mirror mirror on the (Larry) Wall...
.Mac
Bandwidth courtesy of
_______
2B1ASK1
Dude, you forgot the http bit...This works better :)
> Why is "&&" different from "and"? Ditto for "||" and "or", etc. Operator precedence. Look at perldoc perlop
Here it is.
You can't judge a book by the way it wears its hair.
Why is "&&" different from "and"? Ditto for "||" and "or", etc.
It's always been that way, at least for perl 5 (I have no earlier perl knowledge)
and and or have much lower precedence than && and ||, the idea being that the latter should be used for logical expression ($a || $b), and the former for a sort of concise control structure (using short circuit evaluation), i.e.Since they have such low precedence, it's (practically?) guaranteed that you can safely use them for that, and they will be evaluated only after the entire first operand.
A Minesweeper clone that doesn't suck
Why is "?:" spelled "??::" ? ... }
Because "?:" is a logical (short-circuit; control flow) operator. The newer spelling makes it look more like "&&" and "||".
Why is "&&" different from "and"? Ditto for "||" and "or", etc.
Precedence, my friend, precedence. That already exists in perl 5. The spelled-out operators have much lower precedence than && and friends -- so you can say
if( $a = shift and $a=~m/foo/ ) {
conveniently. ($a gets the shifted value, not the boolean AND of the shifted value and the match).
"." is now "~"?
Well, three good ones out of four ain't bad... IMHO this is dumb. The reason is that "->" is now "." (saving some keystrokes, I suppose) -- but I'd rather leave both operators as-is.
Charwise operators?
Yes, excellent stuff! I believe that this is actually driven by the PDL application -- there, you have large arrays (e.g. several million entries) and want to do vast vectorized operations on them. Currently PDL uses the perl 5 bitwise operators for vectorized ops -- but that's not a perfect fit, since sometimes you do actually want bitwise operations.
You obviously never studied mathematics, 3 and 2.999... are exactly the same.
Programming != what is theoretically true in math. All I got is these 32 or 64 or 80 bits and there isn't any mathemetician of any IQ that can make 2.9999... in IEEE floating point equal 3.0 exactly.
Vote in November. You won't regret it.
You're thinking about strongly typed languages e.g C, C++, Java, C#. In those language variables are only ever of one type. When copying from one type to another, or comparing different types, there are strict rules of "promotion" (i.e we always promote to higher-precision types).
Perl is a weakly typed language. There's three main variable types: scalar, list (array), and hash (associative array). Scalars can be both numerical and text strings at the same time. This is the reason that Perl has different equality tests for numbers and strings. The run-time has to to be explicitly told which comparison to use. For an example of how not to handle this situation, just look at the way PHP does it. When a language is weakly typed, the interpreter/run-time loses information about how certain things are to be done with variables. That information loss must be made up somwhere. In this case, it's the operators.
Stronger typing does not automatically solve this particular issue. Look at, for example, C.
...yep, there's one of them.
C is not strongly typed. It pretends it is but it isn't.
So yes, certain applications of strong typing lead to a potential way to trick the language into allowing you to perform the two different operations of string and numeric comparison with only a single operator.
This, almost by defition, is bypassing the type system. Here there be dragons....
However you have unfortunately in doing so introduced ambiguity into your definition of equality.
Perl gets this by default because it has the exact ambiguity you describe. Which side are you arguing for again?
However this then brings up the question of what happens if for some reason you want to do a numeric compare between two string objects. You have to somehow do a conversion to a different object type. Perhaps this is a bit clumsy.
Of course it's clumsy, it's a clumsy thing to want to do. The only language I know where conversion is something worth calling "clumsy" is Java. (Java is a damned clumsy language and is not a good one to study to learn about good syntax.) In most of the ones I can think of it's as simple as "int(a) == int(b)". You also get type protection if "a" isn't actually an "int" at all. Perl silently coerces "oiewjgew" into 0.
I think this is a good one: there are already far too many situations where an operator or function in Perl behaves in different ways depending on minor details of the context, we do not need another.
No, this is another. If you use == on a number, it works correctly. If you use it on a string, it first silently coerces it to a number. That's different behavior.
You need to expand your language horizons. For one thing, I'm not attacking Perl, I'm explaining it. If it looks like an attack, it's your lack of understanding of my explanation, not an attack. Perl will give you a very fuzzy idea of what "typing" is. It's OK for the language, but it hasn't helped you understand what "typing" is when other people talk about it. I recommend Haskell or OCaml. (Python might be OK too, but that's probably still not the best place to learn about typing.)
Perl is almost unique among the "real" languages for this peculiar context-sensitivity of strings vs. numbers, for good or for ill. As a result, as good as it can be to use sometimes, it's a really, really bad place to try to learn programming concepts. (Of course, that's typically true somewhere for any language, which is why expanding your horizons is necessary.)
Programming languages are a fairly miserable place to learn about type theory. A rigorous study of mathematics (computer science is not really a science, but rather just a collection of fields of mathematics) is far more useful for understanding the theory of types.
...
...
... all can manage to reuse a handful of operators without the sky imploding.
Although I have to confess there is something sort of amusing about ML coming up in a discussion about the plethora of operators in Perl, as there are an arbitrary number of operators in ML.
There is nothing especially novel about Perl's type conversion semantics. Let's just say that in a language X we have types S and T, and the semantics of X say that for any operator x : S -> 'a, if a morphism f : T -> S exists and has been designated then any context where x is applied to an instance t of type T, x will be applied to the application of f to t automatically.
We'll just call this your typical type-safe cast with implicit coercion. These are said to be type-safe because the operations are well-defined (you've defined how to construct an instance of T from an instance of S).
Now Perl has four scalar types, even though Perl pretends its basic types are scalars, arrays, and associative arrays. The four scalar types are integers, floats, strings, and references. It also has something sort of like a pseudo type class which we'll call reals, for which int and float are instances.
Perl defines a number of implicit morphisms between members of its scalar context, which I'll just give some examples with made-up names: str_to_real : String -> Real
str_to_int : String -> Integer
str_to_float : String -> Float
int_to_float : Int -> Float
real_to_str : Real -> String
Some binary operators:
- : Real -> Real -> Real
. : String -> String -> String
So when writing 'Dog' - 'Cat' the programmer acknowledges that they are writing str_to_real('Dog') - str_to_real('Cat'), which in turn will in turn call str_to_(float | int). In which this case the mapping of from a string that does not fit one of the handful of patterns for encoding reals as strings is to zero. So we have 0 - 0 => 0.
This sort of behavior may be considered stupid (in that it can result in all sorts of bugs), but it is a well-defined type-safe conversion. It's not isomorphic, but that's neither here nor there.
Now removing automatic casts doesn't necessarily reduce the number of required operators. ML is a good example of this. In order to not require type annotations (and to avoid intractable type inference from not mandating annotations) you end up with (in the case of O'Caml--Standard ML has a few exceptions that are special-cases that sometimes make polymorphism more verbose as a result) different operators with different names for any type which you want to perform the logical operation on. +, +., +*, or you get to operate with modules (Yeah! That'll be intuitive for the average person on Slashdot). Haskell improves on this with the notion of type classes, but it can't deal with using the same operator in disjoint type classes.
So back to Perl. Is Perl's operator bloat the result of implicit type casting? Well not really. Its problem is that it doesn't allow operator overloading, so it relies on a stupid, limited number of implicit type casts to obtain the behavior it desires. 'Dog' + 'Cat' => 0, because I can't and Perl doesn't define an operator + : String -> String -> String, and without rigorous exceptions it might be a real hassle (look at me make excuses for them!) for their implicit conversions to do anything valuable. Now operator overloading with multi-dispatch or mono-dispatch with type-safe coercion or reflection and exceptions, you'd have no problems expressing many logically-similar operations using the same operator symbol with disjoint types without as many problems. Python, Smalltalk, Common Lisp, Dylan, C++,
Perl is just a crappy language with bad semantics.
Thank you for the kind comments.
I used Omnigraffle 3 (standard edition) running on Mac OS X (10.3).
- Mark