[erlang-questions] variable exported from case in OTP 18
Richard A. O'Keefe
Fri Oct 2 04:24:04 CEST 2015
On 2/10/2015, at 1:38 am, zxq9 <> wrote:
> On 2015年10月1日 木曜日 22:35:09 you wrote:
>>> On Thursday 01 October 2015 19:28:23 zxq9 <> wrote:
>> Personally, I blame Wirth whose broken Pascal precedence
>> rules corrupted generations of programmers, including ones
>> who've never heard of Pascal.
> I've got ambivalent feelings about this statement. Partly because Turbo Pascal was the only real thing available to me when I was a kid, but mostly because the categorical breakdown of precedence operators makes its own kind of sense:
> 1. Negation
> 2. Multiplicative operations
> 3. Additive operations
> 4. Relational operations
Before Pascal there was pretty nearly a consensus that you had
COMPARISON operators (which bridge the gap between Boolean and numeric)
all at the same level
product, ratio, quotient, remainder
(a) Used the wrong operators for sets.
Union and intersection behave like OR and AND.
The Booleans *do* form a ring (isomorphic to Z/2) but the
operation that is analogous to addition is EXCLUSIVE OR,
not inclusive or.
(b) Used the wrong semantics for the logical operators.
By the time Pascal was developed, it was clear that
'strict' Boolean operators were of almost no use.
More precisely, ISO 7185 section 184.108.40.206 says nothing
about the operational semantics or AND and OR, but
section 220.127.116.11 makes it clear than in p(x) $ q(x),
q(x) may be evaluated before p(x) whatever operator $
is, so short-circuit AND and OR we do not get.
(c) Treats 'or' as if it were an 'adding operator' like
+ and -. But it is not. The Boolean operator which
is analogous to + and - (to both simultaneously, in
fact) is EXCLUSIVE OR.
(d) Provides an integer quotient operator and an integer
remainder operator THAT DO NOT FIT TOGETHER.
With all the questions about what exactly div and mod
should do, we surely expect that
(x div y)*y + (x mod y) = x
whenever the left hand side is defined. But in Pascal,
(-2) div 3 = 0
(-2) mod 3 = 1
((-2) div 3)*3 + (-2) mod 3 = 1 /= -1.
Nicklaus Wirth was a brilliant language designer but
whatever process led to *this* fiasco, I would hesitate
to call it design.
> Instead of just trying to make it easier to write a compiler I think he tried to logically group precedence by category (or rather, include logical operations within their proper categories).
In previous languages the operators *WERE* logically grouped by
semantic category (logical operators , mixed operators , numeric ones).
He jumbled them up in a very unhelpful way.
There are just three differences between Pascal and Algol 60
which cannot be explained in terms of making a single-pass
(1) Pascal has records and pointers
(2) Pascal has files and I/O operations
(3) Pascal has user-defined types
As for (1), that had been pioneered by Algol W and included in
Algol 68, which Wirth was consciously reacting against; Algol 68
also had standard I/O and user-defined types. Algol 68 had
unions which were *safe* at run time, and garbage collection.
Pascal sacrificed safety for compiler+run time implementation ease;
garbage collection ditto.
Of course Algol 68 didn't have sets, but it did have 'bits' and
'long bits', and realistically, that's all Pascal really had.
And Algol 68 *did* have strings that made sense. And while Algol 68
was strongly criticised for lacking a module system, it did pick one
up before Pascal did. (The module system in Turbo Pascal is not the
module system in the standard.) And Algol 68 didn't have enumerations,
but it *did* have closures (albeit ones that couldn't outlive their
creating context), and I know which I'd rather have.
Nope; Pascal was deliberately crippled to make it small and fast
at the expense of safety.
To this day you find programmers who think you *have* to put
parentheses around (x > y), all because of Pascal.
> But that does leave the relative precedence of `and` and `or` surprising and perhaps inconvenient unless you think about things this way. I don't know many people who think about operator precedence this way though, so in reality its a moot point and practically speaking Pascal's precedence rules are "just weird" because they don't mimic everything else.
They are weird because they trample on an earlier convention well
established in programming and mathematics that segregated the
operations a different way.
> Only being semi-serious here... what would be wrong with just ditching all those other constructs and using only funs and functions for conditionals?
That would take care of 'if' and 'case' but not 'try' or 'receive'.
>>> as a shorthand for lists:foreach/2 specifically to get side-effects is now
>>> actually supported as a an optimization.
>> But those effects do NOT include mutating variables. Each iteration
>> gets its own set of variables because that's the only way that the
>> variables *can* have different values in different iterations.
> True. Though we do have plenty of opportunities to effectively violate this whenever we want --
I'm not sure I understand you. Enlighten me.
- The file system is a global shared mutable variable.
- The pid registry is a global shared mutable variable.
- DETS and ETS are mutable data structures.
- Other data bases ditto.
- "The" process dictionary is a process-scope mutable variable
which could in principle be eliminated by threading a state
through all calls.
More information about the erlang-questions