nihil architecture blogs

content

Why I don’t think that Terran is currently significantly over-powered.

Yap, I actually play StarCraft II, as Protoss in fact, the one race full of whiners saying that Terran is OP. A stance with which I’m going to have to disagree.

Now, what’s often put forth is that there are no Protoss gateway units that can deal with marauders. Empirically if this was true then why don’t Terrans just always march in with only marauders at early game to take the game with nothing to stop them? Rationally it’s more subtle. A naïve error a lot of Protoss players make is too much faith in the Stalker, confusing it too much for the Dragoon of Brood War. Stalkers actually do only 10 damage per 1.44 time units, and 14 if the unit they deal against counts as armoured. This contrasts the zealots uniform damage of two attacks of 8 every 1.12 time units. For the marauder with 1 armour, this comes down to the Zealot doing 11.7 dps and the stalker 9. Of course, the zealot is melee and the stalker ranged and can thus be kited. But keep in mind that the marauder does double the damage to the stalker it does to the zealot because the stalker counts as armoured.

However, there is a crucial unit a lot of players forget, the Sentry, which is perhaps the one hard counter to the marauder the gateway has to offer. Keep in mind that the sentry is also ranged and does not count as armoured and more importantly, it offers an array of special abilities that do not only benefit itself but all units near it. Kiting becomes hard to do with a forcefield at your back. If you look at them, Sentries are extremely powerful units, their dps is very close to the Stalker versus unarmoured, and Protoss is the only race which gets a tier-1 spell-caster with impressive abilities at their disposal. Imagine if you could beat them without the Sentry? Surely then with the Sentry Protoss would be severely over-powered here? The sentry is your answer against Marauders, Zerglings and Roaches with force fields and against Marines and Mutalisks with the guardian shield. Of course, this requires some micro to pull it off. But then again, so does kiting and getting a good surround with Zerglings? Sentry does require click reflexes though.

Then the argument that’s often raised is Ghosts, who can EMP your units shields away and are supposedly too low in the tech tree. Yes, I agree that Ghosts are very low in the tech tree for their speciality and power. But don’t all races have things like that? When Protoss gets a cybernetic core down, it unlocks a plethora of upgrades including flyer upgrades. It allows for no less than three advanced structures to be built as well. And when we get the Robotics Facility down, we instantly get three units unlocked, and all three are quite specialized and powerful. The Ghost academy just unlocks ghosts. You might as well say that Zerg is OP because a hatchery is obviously superior to a nexus—we can’t really spawn like 7 probes at the same time, or things like roaches at nexus can we?—and costs less too. Of course, this is to make up for other deficiencies, such as that they can’t really spawn roaches at any other place.

The Tech Lab may not be required for the factory to be built, in the end, not getting one before it is a highly uncommon move, so you could say that after the Tech Lab they only have the factory and the ghost academy. While we have three advanced buildings. Of course, they get the orbital command and the bunker, but our turrets can also fire at the ground, and we don’t have to put infantry in them for them to function, of course, our turrets can’t shelter infantry either. Of course, the Tech Lab isn’t really comparable to the Core, its much cheaper and more easily built, but our Gateways don’t really stop producing when we build our Core do they? Also, we only need one, and not re-make it for every Gateway we put down. So in the end, Protoss has some other parts where our tech tree is quite luxurious.

The next thing of course is the dreaded MMMGV, the unstoppable ball of Marines, Marauders, Medivacs, Ghosts and Vikings, no Protoss army can withstand this, and depending on the size of this, I’d say it’s indeed very hard to withstand this. Just like an unstoppable ball of Zealots, Stalkers, Sentries, Immortals, Colossi and Phoenices is essentially unstoppable depending on how large it is. Especially when they think its twice as large due to all the hallucinations (people use this long not often enough). A way to stop either is simply having a lot of Dark Templar in your mix, for one. A huge ball of Brood Lords, Ultralisks, Hydralisks, Zerglings and Corruptors is probably unstoppable too. The issue is not as much how to ‘counter’ this as how to stop someone from getting such a deadly maxed-out army.

In the case of the more modest MMG versus High Templars and some gateway stuff, neither counters the other really, it’s just who shoots first, if the storms go down before the EMP does then Protoss wins, if EMP goes down before the storms and Terran wins. But again, having some Dark Templar in the mix here can really turn the tide.

Then there’s œconomy, say one manages to kill your workers, a really dirty trick like suddenly Infestors unborrowing near all your workers, and bam, a fungal growth, they burrow and unborrow again for a second and all your workers are gone. In the case of Terran your œconomy still has a drive with a sudden mass call-down of MULE’s. In the case of zerg, one spawn-larva later on all your hatcheries and you 21 drones back on track, but in the case of Protoss, you have to start from scratch, painfully chronoboosting Probes.

However, let’s say it’s in reverse, all your production facilities are dead in an attack but your workers and nexus remains, it takes only one probe of the line for a moment to get it all back provided you banked enough. Terran would have to keep 18 workers occupied, Zerg would just lose 18 drones to that. Or say someone suddenly heavily supply blocks you with some attack, Protoss, you just warp in eight pylons with one probe and sit back and wait as long as it takes for one pylon. With Terran you have to take off 8 SCV’s, with Zerg you have to sacrifice eight larva which could be other units.

I actually several times managed to become the victor after my entire base was raided while I was ahead in some sneaky thing like suddenly a lot of cloaked banshees appearing while I had a superior army and was wrecking the other’s base or a last ditch void ray effort or dark templar. You need just a couple of probes to survice to get yourself back on track if you’re Protoss and rebuild it all at your expansion or just a completely random place if you have the army to defend it until your facilities are back up. I once managed to get back from as few as 4 probes escaping the sudden sentry+dark templar warp in.

So why do people say Terran is over-powered? Even the statistics don’t really seem to back this up. Maybe it’s the parroting effect? Some people started to say it on the Battle.net fora and suddenly it was all over the place. Often when people start posts though complaining about it when you analyse the replay you find out that they made some severe errors and where behind in macro the entire time. Maybe with this new Terran is over-powered-thing, people have found a new way to blame their losses on?

The plaza close to Ground Zero

There’s been a lot of confusion and fighting over this so called ‘Mosque’ that’s being built at Ground Zero. Opponents noting the insensitivity, proponents saying this is religious freedom and one of the principles that Nation Under God was built on. Then there’s still the debate of Okay, it should be legal, religious freedom says it is, but is it wise?.

Well, wise, maybe not, probably not, but only because of the stupidity of man. Why is this ‘insensitive’? Is it ‘insensitive’, if a crime is done by Christian people to place a church close to that site? Many of the most infamous US criminals were Christians of course. Don’t ask me how they combine this, and don’t ask me how people combine Islam with suicide bombings either; people find their ways. There seems to be a sliding scale of acceptability of bigotry here. If your girlfriend was a bitch, to hate all women thenceforth is unacceptable and bigoted. If your boyfriend was one, to hate all men, well, that’s more acceptable. If you’re robbed by a black man, to then say all black people are scum goes too far and is præjudiced. But to think the same after being robbed by some obscure ethnicity such as Slovenes, that’s more acceptable again. To don’t trust punkers after a group of them beat you up, that’s just a nice argument to demonstrate why supposedly they [all] are scum.

So what is this ‘considering the sensitivity of the issue’ really but compromising for the bigots that can’t see the difference between different people who just happen to all profess being ‘Islamic’; that’s really all it is. Islam, unlike various schools of Christianity is not monolithical in nature, there is no One Supreme Authority such as a pope, there are no churches and people above churches, no bishops and so on. There are people who say they are Muslim, and they of course each all mean a totally different thing with it. For some, being Muslim is little more than faith into The One God and his righteousness and almightiness, and to others, this involves covering women in elaborate cloths. So basically, wise as it may be to be ’sensitive’ to avoid further polarization, it’s still basically giving people what they want for their bigotry and ignorance.

And ignorance is quite the word to describe what most people know of this place, on the right we have a picture of how it’s going to look. Looks kind of like modern architecture nay? And it’s more like a plaza than a Mosque really. These are some of its features accordingly New York Daily News:
The 'Mosque'

  • An auditorium
  • A theatre
  • A swimming pool
  • A child-care area
  • A basketball court
  • A performing arts centre
  • A book-store
  • A fitness centre
  • A restaurant, serving kosher dishes
  • … last but not least, an Islamic praying centre

Obviously this thing has more in common with a plaza than a Mosque, indeed it’s modeled after 92nd Y. It’s just a plaza with a place people can also pray, how insensitive.

To put matters worse, the thing is not planned at Ground Zero at all, rather so near, three blocks to be præcise… do we really have to pay that much for bigots that people who are part of some religion cannot built a modern art centre three blocks away from some sight that other people who are part of the same religion did some crime?

And I think the simple answer is yes, it’s stupid, but we have no other option. It will polarize people even more and lead to more deaths if they do not give. Just because people are so damned stupid and do so damned little research. Stupid people—alas—are surprisingly powerful when in large groups, and alas surprisingly numerous. Thank you Sarah.

Perpetration of myths

Friend of mine’s recently got a tortoise and commented to that he seems to reject food the information books and sides all say his species should really like, and seems to præfer food said media never even mentioned. But looking at such media like Tortoise Care the things that are immediately noticeable are:

  • The source does not refer to many rational arguments, nor to any empirical research that can make compelling its claims.
  • For a very large portion of the things the source claims, testing the accuracy of it scientifically would either be very unethical and tortoise-abuse, or simply downright theoretically impossible.

Which seems to be the trend on about all sites, books, professionals or what-ever that seem to deal in the care of pets or even children, many child psychologists and pædagogues will claim various things about child care that should raise the eye-brow ‘If they ever tested this hypothesis this means that they for 16 year long mistreated a group of children, lucky control group there…’, also, once in a while, these theories are outright rejected, again, with no real empirical or rational argument to support it. No-one nowadays will claim your child needs a substantial amount of physical punishment to grow up, nowadays that’s considered detrimental to the development of a child. Teenagers masturbating used to be a thing best prævented, nowadays part of a child’s ‘natural development’… I hope we all know that phrases like ‘natural’ are best avoided in serious scientific literature, especially when used to communicate a value judgement about some practice…

The term value judgement might be essential, all these sources are inhærently præscriptive; sure, they bring it as descriptive, as simply describing what actions supposedly hurt a tortoise or a child. But in the end the main effort of people communicating and originating such information is to change the way people behave, not to simply inform them with knowledge for the sake of knowledge. Researches into things which can cause certain things in animals that have no such præscriptive character tend to indeed be based on the actual scientific method, whence things such as your child should not be exposed to too much cursing come, I haven’t an idea. Or wait, I do, quite obviously people just don’t want their children to curse and go invent whole faux-sciences like ‘child psychology’ just to give this obviously moralistic notion some false illusion of a ’scientific character’.

Restrictions and clearer languages

After reading about this new C# language, some design choices of it baffled me, which were part of a new trend, I’m not talking about lambda abstractions, about some object oriented features, about things that drastically reduce performance, I’m talking about if(x = y) being illegal. Conditionals in C# apparently require their value to be of the type bool, if the compiler cannot prove they are of type bool, this is considered a static compile time error.

Now, to some programmers, if(x = y) would be naïvely perceived as a typo, or applying basic rules to a C-syntax. But it’s actually quite possibly intended code in many languages. C popularized an interesting concept, assignment wasn’t a statement, but an expression, it had a well defined value, namely, the value that was being assigned. This allowed for ‘chain assignments’ : a = b= c = d, and on most architectures this maps most efficiently to machine operations. It’s also a rather common way in JavaScript to loop over some list, and for that reason the ‘next’ operation yields null rather than an error if there is no next, stopping the loop.

It’s also to many programmers a source of frustration, typos can often lead to unintended code, if(x = 5) is of course always true. Though a lot of programmers have taught themselves to use if(5 == x) to catch those errors early. So C# has chosen to favour the latter problem, a restriction on power and expressiveness to protect people against themselves. Even though the problem could have just as easily been avoided by using := for assignment, oh well.

And this seems to be the trend more and more, restrictions and restrictions on power to protect people ‘against themselves’, my rants on psychiatry and society should make it clear that I am generally opposed to protect people ‘against themselves’. Let people do what they want, maybe they do a thing they’ll regret, maybe they’ll stop doing it afterwards. It’s better to teach a child to not touch a pan by letting it burn its fingers then by just saying ‘don’t do it’ and the child having grown up knowing it shouldn’t do it, but never really knew why. And this is also exactly what these restrictions do, instead of teaching people good programming, and the theory behind it and why they shouldn’t do certain things, you just don’t allow them to do it, they won’t do it because they have no choice, and they’ll never understand why they shouldn’t and they’ll be kept ignorant forever. My hunch is that there are more programmers on the planet that don’t realize why they use == ‘in an if-statement’ and = outside it than those who realize why this is done. Which really was one of the beautiful things of C, it gave the programmer choice, and indeed, at some points it does pay to be able to use assignment inside a conditional. while(obj = array[i++]) ... is code which I very commonly use in languages where accessing outside of the bounds of an array yields null rather than an error, and it probably was designed so for this purpose. If this C# idea catches on, people will probably be kept more and more ignorant and in the end completely be obscure to the fact that== is a binary operator, just like +.

A thing people often misunderstand about this issue is static versus dynamic typing, often things like In statically typed languages, variables have a type, in dynamically typed languages, values have a type. are uttered, quite a crude approximation. Static in most context is the same as ‘lexical’, a statically typed language is designed so that ‘types’ can be inferred from analysing source code alone without running it or computing any values. Static typing is older, and less powerful than dynamic typing, but also more restrictive. Static typing is also easier to implement, for this reason, when the first high level languages came, people had the interesting idea of coming up with ‘type declarations’, so that a compiler could analyse these during compilation and safeguard a programmer against errors whose result may be well defined in machine term operations, but whose result is also ‘nonsensical’ to any human reader. Applying float addition to integers is a perfectly defined operation that produces a new natural number in binary base which you can interpret as whatever you want, a character, an unsigned integer, a signed integer, a float, a four-character ASCII string, it’s all about interpretation of that scalar ordinal value. However in any of these interpretations, to human readers it’ll most likely not make any ’sense’. So if in the source code of programs variables of the ‘wrong’ type were used together, lexically, the code wouldn’t compile, and signal an error. In static typing, this can just be inferred from source code.

Dynamic typing is some-thing different, more powerful, and more dangerous, ‘dynamic’ in this context has the usual meaning of ‘only known when the code is run’, in dynamic tying, values carry a label, which is checked when operations are applied, if it doesn’t match, a runtime error or exception is raised. Dynamic typing was a novelty due to Lisp, a language in which source code itself was dynamic, a lexical analysis was insufficient to determine if types wouldn’t conflict, because the source code itself was no longer static. Other languages adopted this then-performance-costly idea because of the raw power it afforded, the downside is that programmers again had to manually verify their code and follow the logic of it to ensure that type errors would not occur. Which in statically typed languages can be proven by the compiler.

And proven is a very important word here, it can be proven by a compiler, but not decided, it’s theoretically impossible to decide if a type error is going to occur lexically. Where deciding means that all programs you reject will have type errors, and all you accept will not. Compilers only offer the guarantee that accepted programs will not have them. It’s quite possible that a rejected program will also not have it, but as long as the compiler can’t prove it, it will reject. This is a pretty awkward mentally. ‘I do not accept your program, for I cannot show it will work.’, rather than ‘I do not accept, for I can show that it will not work’, however, though the latter path is also possible, choosing it will necessarily leave open the option of type errors. A trivial example would be:

{int a, b; float c; a = true ? b : c;}

This will usually be rejected in statically typed languages, even-though a type error will never occur from this, of course, this example is quite useless but a more useful example would be:

function concact(x,y) {
if("array" == typoeof x && "array" == typeof y)
return (new Array).append(x,y);
else if ("string" == typoeof x && "string" == typeof y)
return x + y;
else if("number" == typoeof x && "number" == typeof y)
return x + y;
else return null;
}

Dynamically typed languages often offer facilities for runtime type-checking to choose a program flow, the same thing happened as above, a statically typed language would reject this example, even though for whatever input it may get, a type error cannot possibly occur within this function, a compiler has no way to prove this algorithmically from a lexical analysis. Lexically the function + which applies to two numbers is applied to the same variables in the same lexical environment whereon array_append which applies to two arrays is also applied. The compiler cannot prove no type error is going to occur. Many people who coded in ‘archaic’ static languages often felt the pain of having to re-write and overload functions that do the exact same thing that have to deal with both integers and floats, but templates and generics did offer a marginal solution.

The real rescue for this problem in statically typed languages is parametric polymorphism, where types are not constants, but variables. The function above is then ‘typed’ as simply ‘taking two identical types, producing a value of same type, or null’.

Static typing is not only a restriction on programmers to ‘protect them against themselves’, it’s also taking with it a lot of things that need no protecting. It’s banning cars because some of them are unsafe, and taking the safe one’s with it because you have no way to infer præcisely which are safe.

Other languages have evolved a different tactic, they aim to make their syntax ‘clear’, a well known and ridiculously failed example is a certain language where the now ubiquitously readable action of C++; would be similarly expressed as ADD 1 TO COBOL GIVING COBOL, as it turned out, use and conventions make readability, not natural language. Though the latter example is a lot clearer to people never having programmed. The sheer mass of exposure to the former form makes it immediately clear. A dynamically typed and less extreme example would be:

def factorial(n):
if x > 1:
return factorial(n - 1)
else:
return 1

Python, often using English words, some-what reads like English, define factorial in n: If x is greater than 1, return factorial of n minus 1, else return 1. It has shown that it helps some people to read the code aloud in their mind, one of the ancestors of Python has a wholly different vision:

(define (factorial n) (apply * (range 1 n)))

Or at least how I would write it, people often say that Lisp is ‘unreadable’ but I beg to differ, in my opinion Lisp code is exceptionally clear, consistent, there is no such thing as operator præcedence, not only is the delimiting of lexical blocks explicit, the limit of an expression is, the range of an operation is and so on, with syntax highlighting there is no confusion if the code you edit is still inside of the scope of your control structure and so on, the one thing is, it’s impossible to read it like English. Why does infix notation exist even though it’s inconsistent, is it more clearer due to conventions, or because x = y can be read as ‘x is y’ in English?

I know that to be able to read it as English or to be able to use layout indentation doesn’t work for me. I find myself counting invisible characters in Python and then summing them to determine block structure. I like the fact that in Scheme, what it does is clear from a simple rule that requires no thought at all, the value of evaluating a list is the evaluation of the head as an expression applied to the evaluation of the other forms. But I’ve found that most people like to see ‘a variable’ as being identical to the value, rather than evaluating to a value.

Another thing lately while discussing some features of Clojure is when I found that most Clojure programmers see ‘a list’ as ‘an ordered collection’ for all purposes not that different from a vector. Thinking about it that way just gives me shrivels when programming, ‘a list’ to me is a binary tree which on its outer right leave points to a special nil constant, or that constant itself. This is what I ’see’ conceptually when I work with lists, when I get their head or their tail. I also found out there an interesting differing view in that those that advocated against using cadddr in lieu of simply fourth found themselves translating ‘the fourth item of the list’ to ‘the head of the tail of the tail of the tail’ of the list. Where those that insisted on cadddr being clearer found themselves wanting ‘the car of the cdr of the cdr of the cdr of the pair’ and thinking ‘That would be uumm, the fourth of the list.’. The Zen of Python famously includes There should be only one obvious way to do it., I find that when people have such conceptions about ‘clear code’, they forget that different people have a differing view on ‘clear code’, many people’ll call APL, Forth or Lisp a mistake because the code is unreadable, users of either often passionately disagree and say a program is instantly readable and very clear. The fact that these languages have endured so long should point to this. But they do have in common that they can’t be read out loud in English. I’m a visual thinker, most people I know that defend Lisp are so likewise, maybe that explains some things. I never ‘read my code aloud’, I don’t think English is a very good language to express mathematical or sequential logic in. Notation like forall x forall y : ( forall z : ¬(z in y)) -> x + y = x is a lot clearer than ‘For all x for all y, if for all z, z is not in y, then x plus y æquals x’, but this is often shortened down to ‘x plus zero is always x, where we encode zero as the empty set.’ Still, that doesn’t define the idea ‘empty set’. I personally rather see code as what it is, a series of expressions evaluating to a value, that value then taken as the value of an outer expression to work with. Different people, different methodology. Which is also a reason I don’t think people should be restricted, different restrictions work differently for different people.

From my perspective though, seeing code as English is a bad idea and I can imagine that people make errors like if(x = y) where they mean if(x == y), once you see them both as binary in the same vein of + where the former simply evaluates to its second operant always and has the side effect of changing the value of the memory location the first points to that of the second. And the latter operation evaluates to true or false depending on the æquality of both. But some instead ‘choose’ to read if(x == y) a = b; as ‘if x is y, then a is b’, which is where the trouble begins is my hunch. It’s a very approximate and awkward simulation of assertive mathematics, programming language are not assertive and do not constrain their variables concordantly the truth of the termination value.

Of course, I said I was averse to protecting people ‘from themselves’, I have nothing against protecting people ‘from others’. I think it’s perfectly acceptable that an aviation company demands its software be written in a very type safe and very restrictive language. But ideally this should already be done by people who’ve learnt the hard way what a simple typo can cause and understand why the restrictions are there and what exactly they prævent. Many people nowadays start learning programming with C#, ideally people should be taught programming in a language without any type checking at all to firmly grasp the difference between float and integer operations.

General elections

General elections have just been in this district-less country, as it seems, The Christian Democrat Appeal (CDA), the People’s Party for Freedom and Democracy (VVD), and the Party for Freedom (PVV) have the majority they need by one seat in the parliament, they have 76/150 seats between them, enough to support themselves a coalition in our parliamentary constitutional monarchy. A thing some monkeys are satisfied with, and some other monkeys fear.

PVV being the important factor here, a party that’s spun of from the VVD, probably internationally, and nationally known best, nay only for its leader, the enigmatic, charismatic and controversial Geert Wilders; in the eyes of some monkeys, but not his own, a racist and most importantly Islamophobe. As people’d expect, he initially got most of its vote from the lower-educated ‘common man’, but this trend has been decreasing slightly recently. He is partially one-issue, focussing a lot on the problems Islam brings, but he also has other issues, some his voter-base don’t know for a large deal. For instance, he wants the Dutch flag standing proudly on all official buildings, wants to have baby monkeys sing the anthem when classes start, focus more on getting them to know Dutch history, but conversely, wants to look into abolishing the international Dutch football-monkey team. He’s a nationalist, pretty much, he just hasn’t realized that a powerful tool to instigate nationalistic pride are the European Cups.

Any sane monkey would outright object to these guys getting into coalition, the party is quite new, very new, all members have next to no experience, they were personally picked by Geert, while most parties have a quasi-democratic voting model to settle these internal issues, Geert holds are the ropes here, he’s the autocrat of the party he founded, what he decides goes. And consequently, no one really knows all these people, all they know is Geert. As a fellow monkey I am partially guilty of this, one simply doesn’t hear any thing of it in the news outside Geert.

This echoes a prævious situation, the situation with the Pim Fortuyn Party (LPF), no one really knew any but Pim, he hand-picked them all, and the party got in a coalition with same CDA, and VVD; it was about the shortest lasting cabinet ever. Except that in this case, they’re all even more faultering idiots than in the last case, the few exposures I had to these people seem to imply that they—including Geert—have no understanding of the Dutch political system what-so-ever.

The point it comes down to is if the VVD (largest party) and the CDA‘ve learnt from this mistake to enter coalition with a bunch of far-right, populist newcomers that have no idea of how the political system works. Assuming they chose not to, what then? They heavily favour each other, and it means they’ll have to get their majority else-where, the other option would immediately be the Labour Party, who is second in the elections and has more seats than the PVV, but Labour’s really not that eye-to-eye with VVD or CDA and is centre-left, opposed to their centre-right. To classify them, a thing I abhor, it would be liberal-right, Christian-democrat, and social-democrat respectively, the former two associatively ‘right wing’ in Dutch politics, the latter ‘left’.

What if they’d rather go with the PVV? They only have a one vote majority, a vote of no confidence will be very easy to get, and I and all the other high-educated monkeys are all expecting them to bumble and screw things up beyond a reasonable margin. It’s a complex situation, but it’s not half as bad as people think, the last four governments fell before they had their four years due, it all started with the change of climate, towards open xenophobia. It’d be lovely to add this government to that list.

On functional programming

Aah, functional programming, a source of elitism, to separate the common from the elite, or according to the common just intellectual masturbation. What it is no-one really knows, endless wars fought over which languages are functional and which are not…

Now, functional programming seems to have some intrinsic link to the lambda calculus, many programming languages even introduce functions by a  ’lambda keyword’ for no good reason at all, just to be different, for the rest of this discourse I shall use the notation (x.. . E..) in favour of λx.. . E..—I believe it suffices, it’s easier to type out, and nicely delimits the scope of symbols. That lambda was just an excluse to get a Greek letter into it any-way.

Well, I think that in the end, the relationship between lambda calculus and functional programming languages are completely overstated. In fact, I think lambda calculus has little to do with ‘functions’ in the mathematical sense, what is a function? Commonly a function in mathematics is just defined as a collection of pairs in such a way that no first element of those pairs is ever paired with two distinct second elements, though the converse needn’t be true. So it’s just obviously a pairing of elements from the domain of the function to the image of that function. Are lambda abstractions a collection of pairings? Maybe they are in some interpretation, but I more like to see lambda abstractions as a way to get those pairings, they aren’t functions, they’re algorithms, a completely distinct concept. They are instructions to compute functions. They’re just a list of instructions some-one or some-thing can follow, you start with a random first element of such a pair, follow the instructions, and you end up with the second. Algorithms can thus be used as a way to define functions, by simply giving their algorithms, this practice of course has the immediate advantage that using the function then becomes an easy task. A disadvantage is that algorithms are often very long and not all functions can be expressed in algorithms.

What is a lambda abstraction?

I’ve yet to come to a standardized and authoritative definition of the concept, but I think we can safely say that a lambda application (x. E) A with x a symbol and E string of symbols must be identical to E with all occurrences of x in that string replaced by A. Commonly written as E[x:=A]. That was one of the interesting things about lambda calculus, that all one needed to define all algorithms was just basically a way to re-order symbols. Obviously this simple identity is not satisfied any more by a lot of languages that use the lambda keyword to introduce function literals, in fact, a lot have a well-defined evaluation order because the Church-Rosser Theorem—which implies the order of evaluation to be irrelevant—doesn’t hold on those languages. Lambda calculus would become a lot more complex if an evaluation order had to be specified and one often cited beauty of it is its minimalism.

Purely functional languages

The poster child of ‘purely’ functional programming languages is often held to be Haskell, named after the guy who if it wasn’t enough already got the term ‘currying’ named wrongly after him. Haskell’s notation is a bit strange, to leech the examples from Wikipedia: (Hereby this document is licensed under the GNU Free documentation licence too)

-- using recursion
factorial 0 = 1
factorial n = n * factorial (n - 1)

-- using lists
factorial n = product [1..n]

-- using recursion but written without pattern matching
factorial n = if n > 0 then n * factorial (n-1) else 1

-- using fold
factorial n = foldl (*) 1 [1..n]

-- using only prefix notation and n+k-patterns
factorial 0 = 1
factorial (n+1) = (*) (n+1) (factorial n)

Here we have no less than five definitions of the same function in Haskell, we can group these in a number of ways, what’s interesting is the difference between the inner three and the outer two. The inner three are algorithmic, it defines it by giving a way to some reader who understands all those symbols but has an I.Q. of 0 otherwise to also compute the function for any value we want. The other two rely on pattern matching, that is, we simply give up a set of relations, two cases in each, with that function must satisfy and the implementation figures out its own algorithm, in fact, seeing that Haskell is purely functional, even though we could have specified an algorithm that was just inefficient, the implementation would be free to change our algorithm to something that’s more efficient, as long as the return value is the same, as long as the pairs end up being identical, clearly we’re not dealing with algorithms, we’re dealing with functions. It’s the hallmark of purely functional programming languages that algorithms can be changed by the implementation.

Some one once told me that the pattern matching version is just syntactic sugar for the if-then-else version. Well, what is syntactic sugar? I mean, you can in the end justify in some way that C, or even Haskell, is just ’syntactic sugar’ for assembly no? Clearly we need some restriction to that definition. One could propose that needing a Turing Complete model of computation to automate the re-write to what it’s supposedly sugar for exceeds the limits of syntactic sugar. Maybe even restrict it more, in any sense, it’s quite clear that in the C code array[index]—being sugar for *(array+index)—needs a less powerful re-writing system than all the pattern matching that Haskell supports, to begin with the order of the patterns in many languages that support pattern matching is irrelevant, and other functions patterns, or relationships can freely be put in-between. In effect, Haskell is a sharp turn away from algorithms, the word programming itself comes from a Greek root which will be more recognisable in an uninflicted form ‘prographien’, essentially Greek for the latin ‘praescribere’ or ‘to præscribe’, simply a set of instructions which tells some thing what to do. The English word ‘program’ also has a certain connotation to ‘a list in which the order of the items is very much relevant’.

Update:, some-one also pointed out to me correctly that case-statements and pattern matching are different than a true if-then-else in ML based languages because if-then-else’s require an else-branch whereas case-statements do not, which is essential for the type inference of ML-based languages showing that it cannot be replaced by a simple ‘internal-if-then-else’.

Often, people say that Haskell is based on System F, what is the difference between System F and other lambda calculi any-way? All I know is the type system, that’s it, so the only reason it could be based on System F and not simply typed lambda calculus or untyped, is the type system. And that’s more or less the case I guess, Haskell hardly works with lambda applications and abstractions as its main building blocks, but its type system is indeed based on System F. Indeed, it wouldn’t even be Turing Complete using only lambda terms and that type system, it has to be extended with other constructs.

That’s not to say that there’s at all a thing wrong with Haskell or other purely functional languages, or that it’s easy to do, it’s just not algorithmic and therefore it deals in functions and not lambda abstractions. Haskell’s notation is intended to read like definitions in mathematical textbooks, (a thing that’s always amused me is that they use if-else-then as a language construct, while surely in a purely functional environment it could simply be a three-argument function?)

The Lisp language family

One of the oldest language families still in use, and commonly credited with popularizing functional programming, and this is the point where I’ve lost any grip on the meaning of ‘functional programming’? I can see why purely functional languages are, because they don’t have subroutines as in C, they have functions in the very mathematical sense of the word, doing what functions do, they define pairs of input and output, nothing more. Lambda abstractions as established before do a bit more, they also tell you how to calculate that output from that input. But surely I can just keep my C subroutines free from side-effects—except main,of course—and have the very same semantics Lisps; on top of that, Lisps actually allow side-effects to occur. The lexical scope of most mainstream variants today allows for functions to lose their referential transparency by re-defining global variables they use in their body, some Scheme programmers see this as a mark of either supreme bad style, or simply having picked the wrong language, hence all procedures that allow for this all end in an exclamation mark, but Common Lisp programmers do this all the time and the language is a lot more tailored to this.

So why is it called functional programming then? and what’s the connexion people often point to purely functional languages and this? Is it some old relic because Lisp’s just that old and was far more functional than any other language in its early days? Or the back-then prætentious use of the lambda keyword to introduce literal functions? Is it that procedures are first class-objects that can thus be passed as arguments to functions, and dynamically generated at run-time? JavaScript has all those facilities, so why isn’t that functional? Because it simply uses the humble function keyword to introduce literals oppose to lambda?

Focussing on Scheme, the clearly more-functional of the two main dialects in use today. To again leech from Wikipedia to define the factorial:

;using recursion
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))

I’ll also throw in the other variants Haskell had in Scheme analogy too for comparison:

;using folding.
(define (factorial n)
(foldr * (list-range 1 n)))

;using list products
(define (factorial n)
(list-product (list-range 1 n)))

Before I could even start I had to write these (yes, I like coding in Scheme, why do you ask?):

;folds with right-associativity
(define (foldr binary-operator lst)
(binary-operator (car lst)
(if (null? (cddr lst)) (cadr lst)
(foldr binary-operator (cdr lst)))))

;create a product out of a list of elements
(define (list-product lst)
(if (null? (cdr lst)) (car lst)
(foldr * lst)))))

;make a range
(define (list-range start stop . step)
(let ((step (if (null? step) 1 (car step))))
(cons start
(if (>= start stop) '()
(list-range (+ start step) stop step)))))

Yeah, hate me you zealots of tail-optimization. Now, the difference of the algorithmic paradigm with the purely functional paradigm is quite clear. In Haskell and similar ML-derived languages, we use [1..n] showing that it’s meant to resemble mathematical textbook notation, it’s a built in language-construct of some sorts. Lisp is the antithesis of normal mathematical notation, the notation is purely algorithmic, and consistent above all, an implementation of Scheme will just execute my algorithm, the GHC would probably optimize all those variants to the very same algorithm.

Now, the result in each is the same, but the example I stole from that free encyclopædia is the præferred one by far, even if I had already written those other functions which would make those other implementations a lot faster to write. They both recurse twice, they first recurse to make that list, and secondly to fold a multiplication operator to it. The diligent reader also noticed that I used (null? (cddr lst)) instead of the more intuïtive (< = (length? lst) 2), the simple answer is that again, the entire list has to be traversed to get the length. Of course, this one will give an error if the length is 0 or 1, but folding a list to a binary operator with 0 or 1 elements has no meaning. And I tend to write my code very insecure with very little error-catching if that means I have to check each and every time, I’d make sure at another point that I’m never folding a list with less than two elements. I also claimed all functions were the same, that’s not true, some will give an error when trying to get the factorial of a number lower than two, not exactly sure how Haskell‘d handle this one. Of course, simply using:

;using apply
(define (factorial n)
(apply * (list-range 1 n)))

Also does its work, and is probably the most efficient option. Which is by the way what I find to be the true distinguishing strength of Lisps, not first-class functions, but homo-iconicity (what also helps is that multiplication can take as many arguments as it likes, it folds on its own). Interestingly, this implementation also returns the correct result for the factorial of 0. Because (list-range 1 0) just happens to evaluate to a list containing only the number 1. This is hardly a thing I intended when I made the algorithm, I didn’t care because placing the lower bound higher than the upper is just nonsense, I could have let it return an error, but this shows the functioning of algorithms, there’s no deep underlying mathematical principle behind the correctness of this factorial algorithm, it just works, and by sheer dumb luck.

So, at the least I’ve hopefully made compelling that ‘functional programming’, isn’t as much one paradigm as many people think. I’d personally say that Lisps are is closer to Fortran than they are to ML-derivatives like Haskell, and those again are in fact quite close to Prolog. In the former ‘functional paradigm’ we express algorithms, in the latter we define relations and query over them.

And lambda-Scheme?

To satisfy the idea of the lambda abstraction, we would have to remove the constructs define, letrec and obviously any-thing that ends with ! from the language. The last is obvious, the first two are more subtle, they enable a function to occur within its own defining instance, within a lambda expression, the symbol referring to that function is either bound in the ‘parent’ function, or simply free. In any case, the semantics are different.

…Or so we may be naïve to think, what if we just already had a symbol, let’s say fact that evaluated to the factorial function which we used in the definition of our local factorial function? We can easily just say that letrec without a symbol fact already bound in a higher scope has the very same semantics as let in our hypothetical situation. Some would say that we wound need letrec any way to make it. A: this is of course wrong, we can use a fixed point combinator; B: the same applies to any primitive function like +, we would need it defined to define it.

Problems with recursion

We know that in lambda calculus we have to use a fixed point combinator because we use symbols opposed to variables, all functions are literal and anonymous, the quæstion is if allowing a function to call itself in its body violates the notion of a lambda abstraction per se. One can call functions inside the body of a lambda abstraction, functions which needn’t have been defined before, in fact, this is a quintessential trait of many purely functional languages, use functions before one defines them, or rather, there is no ‘before’ and ‘after’, and I wouldn’t know, it depends on one’s definition of lambda-abstraction again. Though, allowing for it would make them more complicated than they traditionally were, again pointing to the minimalsm. Considering notation such as:

T := (x y. x)
F := (x y. y)
...

where the dots would be a body that enable our shorthand, this is often seen as just defining a quick substitute, what a lot of people seem to forget is that this can in fact be expressed without any meta-language, completely in the lambda calculus itself:

(T F.
...
) (x y. x) (x y. y)

Where again, the dots signal a the scope of the body of our shorthand, from the very definition of a lambda application, and of course recursion without fixed point combinators cannot just be reduce to a simple lambda application any-more. It’s not a definition, it’s a substitution, hence it are symbols, not variables.

What is the difference between a symbol and a variable then? A naïve and simple definition is that a variable is… variable, and a symbol is not. However, I’m personally in favour of a stronger distinction, that is, a symbol can always without change of meaning exchanged for its value. Therefore, symbols truly are just to make things more readable, they aren’t strictly needed.

ML-derived languages being based on the non Turing-Complete System F typed lambda calculus however even need variables in lieu of symbols to be Turing Complete, Lisps can evade this by using fixed points, but a fixed point combinator cannot even be implemented in ML-derived languages without functions being able to already refer to themselves before they are defined.

Does the term ‘functional programming’ have any meaning?

I’ve earlier on already drawn some comparisons between Scheme, and JavaScript, the former’s often held to be of the functional family while the latter isn’t. Many’d probably hate me for comparing what is often held as a work of art and elegance to the often-abused scourge of DHTML scripting, but humour me.

Exactly what functional facility does Scheme have that JavaScript lacks? Scheme doesn’t have pattern matching or type-inference like purely functional languages tend to have. It supports various features that a lot of C-style languages lack such as dynamically creating functions at runtime, functions that can consume or return functions, closures, anonymous functions, but really, so does JavaScript. JavaScript is often held to be object oriented, but Alan Kay, the man who coined that very term disputes this, and in fact said, ironically:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.

Alternatively, we could try to establish that control structures in Scheme are fundamentally different from JavaScript, we have: (if condition then-branch else-branch) in Scheme versus if (condition) then-branch else else-branch in JavaScript. At first the former appears to be like any function in Scheme while the latter seems to have a unique syntax to it, normal of control structures in JavaScript. However, the shared syntax is all it shares with functions in the first example, the Scheme specs are pretty transparent about it not being a function (procedure), in addition to not evaluating all of its arguments, it can also not be passed to functions as argument itself or just be returned from it, therefore even if it were a procedure, it isn’t first-class which removes any argument we could make about it in this context.

But obviously, even though the capabilities are the same, Scheme is traditionally used in a much more functional manner, JavaScript code is generally filled with assignment statements while a simple search on ! could provide us with a proof that a Scheme source does not contain any. But why? it’s fairly obvious that Scheme’s syntax lends itself a lot better to the functional paradigm, but why? consindering that

function factorial(n) {
var output = 1;
while(n > 1)
output *= n--;
return output;
}

Is in fact easier to do in the form:

function factorial(n) {
return (n == 0) ? 1 : n * factorial (n-1);
}

Of course, the same choice of flavour is even offered in C, but that doesn’t support first-class functions and closures, et cetera. Which leaves me but to wonder why the recursive expression of the factorial is often seen as a typical example of the use of functional programming, as many C‘ programs also use it. The latter example also shows that if-then-else can be treated as a proper expression, and of course:

function factorial(n) {
return arrayRange(1,n).fold(multiplication);
}

Is also supported, we would of course have to define arrayRange, prototype fold to arrays and create a function multiplication, as unlike in Lisp, there is a proper distinction between operators and functions, so maybe that’s it? I believe that ML-based purely functional languages also treat them differently though. In case you wonder why I didn’t make those functions here, I don’t like coding in JavaScript at all.

So, what is it? Maybe Lisp lends itself better for functional programming because of its use of lists opposed to arrays? Lisp has arrays though, they’re just called vectors, likewise, the OO paradigm of JavaScript allows for an easy implementation of lists. There seems to be a trend amongst languages associated with functional programming to use lists in favour of vectors so that could be it, they do make recursion a lot more convenient.

Though the comparison of Scheme and JavaScript naturally doesn’t hold for all functional languages against all procedural languages, it does show that languages themselves aren’t as much functional as the way people use them, often for no good reason. The true difference between Lisps and JavaScript to me is that the former’s homo-iconic. The obvious difference between Lisps and MLs being static typing, type inference and above all pattern matching.

And ‘declarative programming’?

This term also surfaces a lot, which I find quite possibly even vaguer than functional programming, accordingly Wikipedia:

Declarative programming is often defined as any style of programming that is not imperative. A number of other common definitions exist that attempt to give the term a definition other than simply contrasting it with imperative programming. For example:

  • A program that describes what computation should be performed and not how to compute it
  • Any programming language that lacks side effects (or more specifically, is referentially transparent)
  • A language with a clear correspondence to mathematical logic.

These definitions overlap substantially.

These are conveniently listed in ascending order of vagueness, and the first is pretty vague to begin with. The only sensible definition of the first I could give is to not use algorithms at all, this would make imperative programming synonymous with algorithmic programming, or simply… programming? As the word ‘imperative’ already hints, you tell a computer what to do. Purely declarative programming would thus be describing what relationships your solution must satisfy, and telling the computer to give it, an art in itself, no doubt. We can clearly see this in Haskell’s pattern matching and type inference. We just gave two relationships a factorial function must satisfy and Haskell gives us that function, or maybe not? Seeing the quintessential:

-- List reversing function
rev [] = []
rev (s:xs) = rev xs ++ [s]

To me, this is the on the line between algorithmic and non-algorithmic. The argument on the second function is given in a pattern, with s:xs standing for cons(s,xs), surely this is enough information to unambiguously tell Haskell that the argument must be a list, and to bind the head the symbol s and the tail to xs? In Scheme we would have:

;more obviously algorithmic
(define (rev lst)
(if (null? lst) lst
(append (rev (cdr lst)) (list (car lst)))))

How much does that decomposing argument compromise its status as an algorithm? the way it reads there is in fact a mathematical equation, a property it must satisfy, but could it just be syntactic sugar for a decomposition of the argument? Let us after all not forget that in Scheme in reality, all procedures are single-argument functions, they take a list as argument. Code like (lambda (x y) (+ x y)) can also be expressed as (lambda lst (+ (car lst) (cadr lst))), so clearly the list is bound to a pattern here, the only difference between these two literals is that the former raises an error on more than two arguments, and the latter simply throws the rest of the arguments away. So we could change our function to:

;without argument patterns
(define (rev . lst)
(if (null? lst) lst
(append (apply rev (cdr lst)) (list (car lst)))))

The difference in semantics is now of course that it expects (rev 1 2 3) instead of (rev (list 1 2 3)), the pattern matching also does not go infinitely high up, while (lambda (x y . z) expression ...) is acceptable in lieu of (lambda lst expression ...), (lambda ((x . y) z) expression ...) simply returns an error instead of a procedure that demands the list it is applied to for its car to be pair and its cddr to both exist and be (). It would also be worth nothing that in Haskell rev xs ++ [s] = rev (s:xs) isn’t allowed, so clearly this = symbol here is not our very symmetric mathematical identity relation. It’s often called a ’single assignment’, but how much can we really ‘assign’ a value to a function applied to an argument whose argument is a pattern which is decomposed in the value of the assignment itself? I’m not really sure what it is, it’s neither a true assignment as set! is, nor is it defining a true æquality relation.

However, in Lisp the notation (a . b)cannot be used to create a pair, Lisp’s syntax itself is composed of lists and therefore also pairs, it’s not an operation, it’s syntax. In ML-derivatives, a:b is an actual cons operation which may be used to return a consed value. The æquivalent in Lisp would be (cons a b) or alternatively (cons . (a . (b . ()))), which is evidently a completely different pair.

The second element on the list, having no side-effects is even more vague, of course this assumes our language has some intuïtive correspondence to the function or the subroutine, that a thing can be ‘evaluated’ to produce one in along with the value of its evaluation, what is a ’side-effect’? If I reduce (n. n (x. F) T) (x y. y) to T, then this would take me 3 reductions. How do I know this? Well, every reduction obviously had an extra ‘effect’ besides reducing, it also incremented a counter. And this brings us to the vagueness of ‘effect’, that abstraction cannot reach that ‘effect’ can it? The program can’t either, is expending cycles on a CPU an ‘effect’?

Referential transparency is more clear, it simply says the return value of the function or subroutine must always be identical given the same arguments, well, what are arguments? Depending on the context of that lambda term above, surely T may differ, see the above example. So sending out side-effects that one cannot reach can’t be defined and is related to other similar problems in metaphysics, How can I know if an Angel doesn’t die every time I take a dump if Angles are invisible to man?, and receiving side-effects can just be seen as arguments. Furthermore, side-effects which only happen inside functions to local variables may be algorithmically different, but not functionally, it results into same collection of pairs.

It may not be referentially transparent for instance in PHP to write:

// raises a global value by a given argument and returns the result
function raise_by($raise_by) {
global $global_value;
return $global_value+$raise_by;
}
echo raise_by(5);

As it’s not immediately clear from the instance of the function itself unless one knows the definition, but it does the same as:

// raises a value by a given argument and returns the result
function raise_by($value,$raise_by) {
return $value+$raise_by;
}
echo raise_by($global_value,5);

However:

// updates a counter by a given value and outputs the new value.
function increment_by($increment_by) {
global $global_value;
return $global_value+=$increment_by;
}
echo increment_by(5);

This is the point were we cannot reduce it any-more, it not only kills an Angel, it also has access to how many Angels it has killed. So clearly only outward, or only inward does not break referential transparency, but both at the same time surely do.

The third property is a good example of The Law of Joost There are things that are correct, things that are wrong, and even worse, things that aren’t even wrong any-more., first to formalize it gets an honourable mention in this blog that no one reads, and those that do either hate or not understand.

On grammar and shorter sentences

Some people reading this Blog might find my grammatical capabilities dubious, those will probably give up. In fact, I was told from childhood on I should make my sentences shorter in essays, and I could divide native speakers over the fact if my grammar in a given language was correct or not. I’ve lately taken an appreciation to realize that these are ultimately related, take this extreme example of a sentence I once posted in a thread about anti-piracy vs. anti-copyright.

So please, Micra, cut the holier-than-thou self-righteous attitude of that some how it’s a de facto moral absolutism that downloading is bad and your surprise that people here with tonnes more of rational arguments than your morally stagnated dogmatic view on the matter try to ‘justify’ its taking place. [...]

Some people would say that that is grammatically very bad, and all of those would not be able to point out why it’s so bad. A thing I always had, they said it was bad grammar, but they either admitted they couldn’t say why, or say they didn’t feel like it. Point is that it’s very much grammatically correct, allow me to show it by cutting it down and down:

First we remove some adjectives:

[...] Cut the [...] attitude of that [...] it’s a [...] absolutism that downloading is bad and your surprise that people here with tonnes more of [...] arguments than your [...] view on the matter try to ‘justify’ its taking place. [...]

Then we remove some embedded clauses:

[...] Cut the [...] attitude of that [...] it’s a [...] moral absolutism that downloading is bad and your surprise that people here [...] try to ‘justify’ its taking place. [...]

Finally the bare skeleton of the sentence:

[...] Cut the [...] attitude of that [...] it’s a [...] moral absolutism that downloading is bad. [A]nd [cut] your surprise that people here [...] try to ‘justify’ its taking place. [...]

Now, this is very obviously grammatically correct, and inserting extra adjectives and adpositional clauses surely shall not change this. So, what was wrong with it? It was just a very long sentence inside a very long sentence, maybe that’s hard to read, I can imagine that a lot of people would find a sentence to be grammatically incorrect even though they can’t point out why, simply because they can’t read it. One could call it a mark of supreme bad style in literature to write such sentences.

I can’t say I care, I don’t think about how I’ll word things or ‘prose’ when I debate, I write down what I have to say. Of course this is all defeating to the goal to convince an opponent if he-or-she can’t even read what I’ve to say.

I also don’t believe in ‘good style’, most rules of style were invented at whim by some person at some time any-way, like split-infinitives, that’s just nonsense. But I’ve also come to appreciate this very simple fact reasoning; I write those sentences without thinking or trying, most people find them hard to read, I don’t find them hard to read at all, so does this say a lot about my capability with grammar, or theirs? I’m not stupid in learning languages or seeing patterns, far from it, so, the often told rule of ‘making shorter sentences’, couldn’t it all just be a warped way to say ‘Keep account to the grammatical deficiencies of your audience?’, people that often make long sentences and are perceived as ‘chaotic’ by their audiences have a popular reputation to be quite intelligent nonetheless, what if people just perceive it as chaotic due to their own inability to perceive the more complicated patterns? I’ve made compelling the notion that my sentence was correct, even though a lot of natives would at first sight say that it obviously was not.

I’d find it a not-too unreasonable notion that children who’re told by their teachers to curb the length of their sentences are in fact being told implicitly ‘You’re smarter than I, therefore I find your sentences hard to read.’

But then again, who with half a mind’d deny the universal præsence of dubiousness in linguistic præscriptivism?

Salvation

In rough lines, the plot of The Terminator (1984):

  1. Android gets sent back in time to kill a woman
  2. Man gets sent after him to protect her
  3. Lots of explosions that barely damage the robot
  4. At the final end the android is caught in a huge explosion and and is finally visually severely maimed but continues its pursuit regardless
  5. Man sacrifices himself to slay the android
  6. Woman helps a little
  7. Robot dies

Terminator 2: Judgement Day (1991):

  1. Liquid gets sent back in time to kill a boy
  2. Android gets sent after him to protect him
  3. Lots of explosions that barely damage the liquid
  4. At the final end, by random chance the liquid falls into molten steal and is slain
  5. Android sacrifices himself to save the future

Terminator 3: Rise of the Machines (2003):

  1. Gynoid gets sent back in time to kill a teenager
  2. Android gets sent after him to protect him
  3. Lots of explosions that barely damage the gynoid
  4. At the end, by some huge explosion the gynoid is finally visually severely maimed but continues its pursuit regardless
  5. Android sacrifices himself to slay the gynoid

Terminator Salvation (2009):

  1. In the præsent, death row convict signs over his body to medical purposes
  2. Shit goes wrong
  3. In a post apocalyptic world, a human resistence forms against an oppressive AI bent on destroying / enslaving mankind
  4. Lots of explosions
  5. The death row inmate emerges from the wreckage of one of such
  6. Finds its way to the resistance
  7. EPIC PLOT TWIST, turns out to be an android similar to the one in the first film
  8. Denies this, but is finally shocked to see for himself that he’s been rebuilt.
  9. They, being racist fags, try to kill him, he escapes
  10. Finally wins their confidence by saving them
  11. Gets a job to infiltrate the AI with his cybernetics
  12. In there, realizes that the AI manipulated him the whole time, playing on his subconscious mind and using him as a spy apparatus
  13. Breaks free of the AI’s control (literally) and goes of to save the person he trapped
  14. Saves him from an android of the type of the first film, though he’s wounded
  15. Sacrifices himself at the end to save that man, who just happens to be the leader of the resistance, the boy from the second and third film and the son of woman and the man of the first.

Mainstream criticism on all films has been overwhelmingly positive, except the last one, let’s cite some examples:

Roger Ebert of the Chicago Sun Times:

After scrutinizing the film, I offer you my summary of the story: Guy dies, finds himself resurrected, meets others, fights. That lasts for almost two hours.

There is nothing visible in this world but a barren wasteland. No towns, no houses, no food, no farms, no nothing. Maybe they live on Spam. The resistance is run from a submarine commanded by Gen. Ashdown (Michael Ironside), who wants to destroy Skynet and all of its human POWs. Connor, who is not even human, vows to save them. Wait. That’s Marcus Wright (Sam Worthington), the guy from the past, who looks so much like Connor that maybe he only thinks he’s Wright. Marcus is a convicted murderer from the past, awakened from cryogenic sleep.

The first “Terminator” movie I regret (I suppose) I did not see. “Terminator 2: Judgment Day” (1991) was a fairly terrific movie, set in the (then) future, to prevent the nuclear holocaust of 1997. You remember that. It was about something. In it, Edward Furlong was infinitely more human as John Connor than Christian Bale is in this film.

Claudia Puig of USA Today:

Bale is surprisingly one-dimensional as John Connor, the leader of the human Resistance movement whose destiny is linked to the future of mankind in this doomsday action franchise. He seems to be simply recycling his gravelly Dark Knight growl.

Director McG (both Charlie’s Angels movies) is all about visuals and creating an ominous sense of disorientation, but he’s not as deft with storytelling or eliciting performances. Few characters ever say more than a couple of sentences at a time, and when they do, it’s often to assert the obvious. The predictable story feels as if it were written by a computer program labeled “sequel.”

I haven’t seen one of these films in full, just parts, action is not my style, I know most have, and you can probably look up the plot to confirm that the plots are really like that. Maybe Terminator Salvation does suck, I can imagine that it does, from what I saw from the other films, they all suck. However I don’t think these reviewers are truly honest with themselves and their audience, and I see this happening all the time. They’re trying to find a reason to hate it, they just hate it, for whatever reason, maybe subconscious, maybe they had a bad day when they watched it, maybe they just don’t like Christian Bale and it ruins the whole film for them, maybe it’s the power of suggestion in advance. But they just don’t like it and try to find some way to back this up and write it about it.

Criticizing a Terminator film on one-dimensional acting? What? In the first three films Schwarzenegger played the same character over and over again, he’s playing a robot for fucks sake, it’s one dimensional as can be and you can pardon him there for being a crap actor, especially at the end of Rise of the Machines it becomes so obvious that when he can’t use sunglasses to conceal his facial expression and actually has to make one it looks like a child attempt’s at acting.

And seriously, attacking it on not having enough plot? The First three films, all had the same basic plot. And in all three both time travellers die with the good guy sacrificing himself and in all cases the aggressor seems unstoppable and at the end always dies with some stupid dumb fuck luck deus ex machina, that’s right, it’s a bloody deus ex machina, it’s well hidden but crap, a helicopter out of no-where crashing on your enemy, your enemy randomly falling in molten steel? Seriously, that could have happened at any point in the film, there’s no progression whatsoever in any of those films, except maybe the end of them that usually reveals some strange often paradoxal plot-twist.

I’m not defending Salvation here, I’m criticizing these reviewers for not being honest with themselves and their audience, what-ever reasons they had for not liking it, it’s not mentioned in the reviews. It’s like school days all over again, you hate a classmate really for absurd reasons like his voice and then try to find a more tangible justification for yourself like that he’s an arse or that he’s arrogant while a lot of your friends are just as arrogant.

Which is in the end while film reviews or of art in general which have an opinion of the quality thereof are ultimately ridiculous as much as prætentious, one cannot give a true reason for hating these because it works more on the subconscious level than on ‘hard’ things like plot or acting or scenery. People just hate these things for some subconscious reason and then try to find arguments. Of course, giving a description of the film without a value judgement is a lot more possible. But in the end people want a hierarchy, they want to be able to say that some things are ‘better’ than others, and they want it to be a total order, they want to be able to place every film in it, and they want to præserve the idea that if film x is better than y, and y is better than z than x is also better than z. Even though clearly you can’t do this in art, people still make up ways around it like collecting reviews from mainstream critics and normalizing them. You really can’t go further then ‘I like it’, or ‘I don’t', as soon as you give a reason you’re lying to yourself and your audience.

Robert

Robert Spitzer, M.D. claimed in a 1975 criticism of Rosenhan’s study which sparked controversy regarding the professionalism of psychiatry:

If I were to drink a quart of blood and, concealing what I had done, come to the emergency room of any hospital vomiting blood, the behaviour of the staff would be quite predictable. If they labelled and treated me as having a peptic ulcer, I doubt I could argue convincingly that medical science does not know how to diagnose that condition.

Which is obscenely true. Just as it’s true that if you were to come there and complained about a stomach pain, got an interview and they labelled and treated you as having a peptic ulcer that would be irresponsible, and probably do more harm than good. Would medicine be effective if practised in that way? of course not, that’s why they do more than talk with you, they run tests on you via objective apparatus and instruments.

Psychiatry is tantamount to giving people radiation therapy for breast cancer because they claim they feel pain in their chest without putting an X-ray through them first. I’m not saying there’s a better way, I’m just saying that since most mental conditions are not fatal, moving like this is completely irresponsible and does more harm than good.

On altruïsm reversed

Kay, let’s say a random person murders a kitten or mistreats a child or beats up what-ever, naturally we—or most people—would beat that person up if we had the chance, or at least severely punch him in the face to make sure he does not carry out his intentions or threat to empty a can of liquid on the poor cat and drop an object warmer than said liquid’s ignition temperature on the cute critter.

Now, some would call this altruïsm or a desire to protect the cat or what-ever victim at stake here, can’t say I’m absolutely sure of that. I don’t mean the clichéd story of feeling better for yourself. I mean another facet to it, because people are simply too selfish to care that much about cats or even children or even their best friends.hat’s in any such of this cases always strangely præsent is that the people that are out to protect these people put a lot more focus on the aggressor than they do on the victim.

In fact—people seem to completely stop caring if there’s only a victim, but not a tangible aggressor, and seem to care a lot if there’s an aggressor, but not tangible victim, the so called ‘victimless crimes’ that exist in various jurisdictions that some (a few) people find stupid and should be repelled.

In the case that a certain person has some suffering going on but there’s no tangible aggressor, as in, it happened by pure accident or it was even due to downright bad luck, people tend to have a lot less of an emotional response. For instance, take these two examples.

  • A woman by sheer accident without any one really being at fault has nude pictures of herself thrown on the internet.
  • That very same woman is photographed in the shower and uploaded to the internet.

Now, in both cases the victim is humiliated, ashamed, a victim, but in the latter case, there is an aggressor, some-one whom we can blame for this thing. The latter always provokes fierce responses from most parties getting notice of it, often a desire for retribution, the first will merely provoke either a small dose of sympathy, fake sympathy, or simply laughing at that woman.

When I was quite young, seven years old I think, I saw a couple of people capturing frogs and bullying them. So knight in the shining armour that I was, I raced to there, liberated the frogs, and got beat up for that by the guys. A mate that was there with me wanted to follow them to beat them up, I was more like ‘You might call an ambulance first?’, he didn’t even think of that, he didn’t care for my suffering, he cared for making the person that caused it pay, not to help me who was lying pretty battered there.

However, looking back in retrospect, I also have to conclude another thing of myself: I would not have stopped to rescue those frogs if they got trapped on their own, and as hell not risked several injuries for that. Only the fact that there were some aggressors into play galvanized my desire to free those frogs, I wasn’t trying to help the frogs, I was trying to at some way compromise the action of the aggressors if I look deep down inside, and I think that almost all people would do the same.

Same with animal rights activist group, all their actions have one thing in common, the suffering is always due to human influence, due to some-one they can place blame on. They (read: we, I pay for that too and chain myself to fences) are not out to help animals they are out to compromise the efforts of people that are trying to hurt them, a completely different thing. Yet we (they) tell ourselves that we want to help animals, in reality we just want to make people pay we don’t like, don’t like for for instance doing cruel shit to animals. It’s also the same in every trial, in every news report about it, the news isn’t  about that some person has greatly suffered, the news is about that some person has caused great suffer to another.

Almost never is there a report about suffer in the news if it’s not done by some crime or some goof-up of some-one. The only exception I can think of to this rule are reports about mass natural disasters, and it makes you think why we all still remember 9/11, but have forgotten about natural disasters that caused so much more destruction hmm? There’s never news about some old grandmother sitting at home feeling like shit, but if she got into that position by some human error like the wrong drug præscribed oh as hell it would have come into the papers. We don’t care about suffering, we care about the people that cause it.

Then of course comes the even more interesting situation of an aggressor, but no victim. How can there be an aggressor but no victim? Let’s say you have this stereotypical really sweet girl that likes to help people, she cleans up for her boyfriend, makes him sandwiches, the whole she-bang, well, she doesn’t mind to that, it probably gives her a nice feeling, maybe she likes to cook, who knows? But still a lot of people will target their criticism at the boyfriend for ‘taking advantage of her’, regardless of her not minding. I’m not saying that he should take advantage of her, or that people shouldn’t target complaints, I’m just saying that they don’t target it to help the girl, the so-called victim, but to punish the guy, the so-called aggressor. It’s not about some-one getting hurt, it’s about some-one doing a thing people don’t like. They will most likely try to make the girl realize that she shouldn’t do that and should mind, now assuming they succeed in doing that, from an utilitarian perspective they’ve greatly failed then; the girl has lost one fun activity to do, and the guy get’s less sandwiches, no one-wins, every-body loses.

« Newer PostsOlder Posts »