Wednesday, November 12, 2008

functional languages and template engines: a StringTemplate docs quote

From the StringTemplate documentation (I started trying StringTemplate out just yesterday, when I was looking around for a currently-maintained template library for C#):

Just so you know, I've never been a big fan of functional languages and I laughed really hard when I realized (while writing the academic paper) that I had implemented a functional language. The nature of the problem simply dictated a particular solution. We are generating sentences in an output language so we should use something akin to a grammar. Output grammars are inconvenient so tool builders created template engines. Restricted template engines that enforce the universally-agreed-upon goal of strict model-view separation also look remarkably like output grammars as I have shown. So, the very nature of the language generation problem dictates the solution: a template engine that is restricted to support a mutually-recursive set of templates with side-effect-free and order-independent attribute references.

Sunday, November 02, 2008

stuff white people like, meta-midwest edition

After a recent conversation, I've discovered that white people based in the midwest U.S. enjoy Stuff White People Like. They appreciate reading wry observations about white people who differ from them. It allows them to feel better about not living like the people they see on TV, not raising awareness for popular causes, not buying the right devices, and not listening to public radio or appearing to enjoy classical music.

On the other hand, they fully relate to a fondness for shorts, dogs, apologies, living by the water (been to Michigan?), sweaters, scarves, outdoor performance clothes, etc.

Of course, midwest people in thriving urban areas or college towns just read Stuff White People Like because it is about them.

Saturday, October 18, 2008

maybe humans just swap out their thinking selves?

In the previous entry I questioned how much humans actually apply thought to their behavior. "First Person Plural", over at the Atlantic, offers another paradigm: humans switch between multiple selves that think differently. This very concept is reminiscent of I am a Strange Loop, which stated that the brain's many networked nodes commonly can and do house more than a solitary strange loop, which is the book's definition of a consciousness.

As I wrote previously in my response to the book, in my opinion the unitary self is an abstraction. It's a construct or a narrative. However, unlike the article I'm disinclined to replace the individual-self with a crowd-self, which to me seems like yet another helpful but ultimately imprecise metaphor for the reality within the functioning brain.

Instead of imagining a pair of rational and irrational selves, or the article's mention of the iconic angel and devil selves on one's shoulders, I imagine ephemeral electric storms competing to light up the brain. The brain's state is in constant flux. Observing our own brain state through the slim (censored) window of consciousness or others' through interpretation of their behavior, we categorize those states as selves. One self might be grumpy. A second, bashful. A third, happy. So these selves are no more than frames of reference for sets of associated behaviors. If a person's impatient self taps fingers or feet, then is tapping a habitual action performed by the impatient self or is tapping part of what defines the person's impatient self? It should be kept in mind that all of these supposed selves are exhibited by the same person.

Moreover, it then makes little sense to argue that all these selves are dormant or continually fighting for control. The described inner conflicts and the swapping out of selves are analogies for when some previously idle brain regions start firing more energetically. For instance, the tendency to suddenly start concocting inventive excuses when the time comes to carry out a presently unpleasant long-term plan isn't truly the substitution of one self for another. Perhaps nor is it the person reverting to a natural state of nonthinking, as I wondered in the previous entry. It's a concrete and immediate experience of displeasure galvanizing reactionary thoughts more strongly than the intellectually pictured goal.

In short, differing circumstances activate differing portions of the brain. Someone who has associated inappropriate actions with anger, maybe for many years, will have those actions prompted by anger and therefore appear to have a momentary angry self who acts differently than is typical. Since we are humans who are aware of our awe-inspiring capacity to store and retrieve a range of attitudes and impulses and reflexes, we should accept responsibility for them and attempt to mold them. Dividing up oneself into simplistic good and bad sides, then identifying with the good and striving against the bad is a faulty approach. There is only you, more specifically your brain and the networks and strange loops residing inside it, to blame for what you do. The road to freedom is taking charge of, exerting control over, your own brain.

Friday, September 26, 2008

how much do humans think, really?

Some realizations manage to be both obvious and mind-blowing, such as "much of the time, the majority of people don't apply thought to problems and actions". It explains a lot about human behavior, particularly for someone like me who at times has trouble correctly interpreting what others do. To clarify, "apply thought" refers to collecting data with a minimum of bias, analyzing and synthesizing the data, reaching a conclusion, creating a feasible plan that corresponds to the conclusion, and executing the plan. Since this is a description of the way in which people ascertain and manipulate reality, many examples exist of using it or not, across the wide spectrum of situations from choosing lunch to the most far-reaching decisions of rulers in the highest-ranking echelons.

One or more of those steps is usually skipped or botched. For instance, people substitute the conclusion step for the data collection step: "I don't need to hear anything more, I've already made up my mind". Or they disregard the analysis and synthesis step by reacting, shooting from the hip, doing a gut-check, winging it. They're ruled by their previously-trained mental associations to the stimuli. Or they mess up the plan creation step with faulty assumptions about how reality will respond to them. Or they know the plan but they do something easier instead.

On the other hand, I'm not naive enough to seriously suggest that the "apply thought" approach is all that anyone needs, all the time. It's slower, it can't operate when the data is insufficient, it requires effort, it's fallible simply because the thinker is fallible, it can prompt people to excessively trust their past conclusions and plans. For all these reasons, especially "slower" and "requires effort", people could quite reasonably argue that the cost outweighs the benefit to apply thought to tiny and small-term questions; I often agree. I even grant that large contingents of the population are, mostly through no fault of their own, ill-suited and disinclined to it. I'm also fine with the concept of other mental approaches as strong supplements.

The bit that depresses me is when humans just don't apply thought (as described here) to the questions that actually are complex and long-term, sometimes despite appearances. Those questions unquestionably merit it. And the mind-blowing fact is that someone who doesn't apply thought is someone who cannot be reasoned with. Arguments, details, etc. are all useless. They're speaking a different cognitive language, more or less. All someone can do is ensure they are "triggered" properly, not engaged in meaningful conversation.

The failure to apply thought may be most subtle, and yet the most apparent, in the case of habits. A habit is a succession of tiny and small-term conclusions and actions, and the succession as a whole is pivotal and long-term. Hence, the refusal to properly apply thought to one out of the bunch is minor and inconsequential, but the repeated refusal to properly apply thought to the aggregate is potentially catastrophic. The key is to perceive the invisible stakes stretching through time, not the minuscule visible stakes: this is the analyze and synthesize step. (I'm sure all casino gamblers realize that every "game" is by definition designed so most "players" lose, and in fact if someone devises an excellent strategy to win then the casino accuses him or her of "cheating"?)

It's revealing that a related expression, "just one more", is such a common catchphrase. A startling number of heart attack victims either don't change their behavior, change it too little, or change it for too short of a duration. When I'm most discouraged about humanity's future, I wonder if we're trapped in a deadly medium. Humans, or at least a few of them, apply thought sufficiently to empower themselves. At the same time they, or at least a few of them, don't apply thought sufficiently to handle the power well. (I'm not referring obliquely to the ethical use of power. I'm referring merely to using power non-stupidly, i.e. not being short-sighted.)

Saturday, September 13, 2008

you might be a Myers-Briggs INTP if...

...your immediate response to "INTP" isn't a variant of "What the...?" but "That one's easy: int pointer!"

If you then go on to start musing about how the INTP enforces the type of its referent, and how it handles overflow, well, there's even less doubt...

Thursday, September 04, 2008

the Algorithm will be incorrect

...and we the users (or maintenance programmers) write the pertinent definition of "incorrect". Software and hardware might execute flawlessly the exact steps proscribed by a set of exhaustive written policies. If that is the case, good jorb and a round of gold star stickers to everyone responsible. Still, the algorithm is incorrect each time it produces a different result than we think it should.

The way to cope is to plan ahead for inevitable incorrectness. As much as is reasonable, assumptions should be flexible. Options should be open-ended. Overrides should be available; users should be advised and protected from mistakes, but some users have their own good reasons to request something "incorrect".

A perfect algorithm will be incorrect. More poetically, a perfect algorithm is too good for this imperfect world.

Monday, August 25, 2008

8 perceptual metaphors for OOP objects

Why Learning F# Is So Difficult at got net? (I compliment the blog's subtitle "Kevin Hazzard's Brain Spigot") has an insightful explanation for why functional programming code is so confusing at first: usually, programmers don't have the necessary perceptual primitives, the prototypes, that would enable rapid recognition/comprehension of the code. They're expecting mutable variables, not immutable lists. They're expecting "foreach", not "map". They're not expecting statements, expressions, and functions to be somewhat synonymous. They're not expecting functions to be inputs or outputs of functions, nor are they expecting partial function evaluation. They're not expecting recursion to play a large role, perhaps because they assume it will blow the stack (which is a good opportunity to explain tail-recursion optimization). And, naturally, they're not expecting the operators to look and act so differently.

That said, the need to learn new perceptual prototypes as part of adjusting to a different programming paradigm applies to OOP, too. My experience of switching to OOP had its own moments of bewilderment, such as "Huh? Invoking a subroutine on this data type runs code two levels up in an 'inheritance hierarchy'?". I know of no less than 8 ways or metaphors for perceiving the most fundamental concept of OOP, objects:
  • Supervariables. The supervariable metaphor is most applicable to small classes that don't do much more than provide a handful of convenience methods for representing and modifying abstract data types. "Supervariable" emphasizes that an object not only stores a small conglomeration of data but also provides prefabricated code for common tasks on that data. An alternative name for this metaphor is "smart variable". A ComplexNumber object that has a produceConjugate method fits the supervariable metaphor.
  • Miniature programs. The miniature program metaphor is most applicable to classes that, like a control panel, expose intricate, full-featured capabilities. "Engine" in the class name could be a clue. (In practice, objects that are closest to "miniature programs" probably employ I/O and various other objects internally.) The point is that creating an object and running one or more of its methods can be similar to starting a program and directing it to carry out actions. Of course, the metaphor is explicit when a program specifically furnishes an "API object" interface in addition to GUI or command-line.
  • Nouns. The noun metaphor is the most straightforward and the most taught. The object represents a noun and simply consists of the noun's attributes and activities. It's a Car, a Square, a Dog (that inherits from Vehicle, Shape, Animal, respectively). It's an abstract simulation of its real counterpart in the problem domain. Since in nontrivial problems 1) the problem domain overflows with too many irrelevant nouns and 2) not all necessary parts of a program have real-world analogues in the problem domain, the noun metaphor isn't seamless nor self-sufficient. It's a good starting point for analysis and design, however.
  • Memo senders. One of the tricky mental shifts for OOP beginners is decentralization of control flow, especially when it's event-driven. Each object has its own limited, distinct responsibility and role, so the way to accomplish a larger purpose is collaboration and communication among objects. No object is inherently primary, though execution must start at one particular method. In OOP, the metaphor of object interaction isn't a top administrator dictating orders or stage actors enacting a script; it's a cooperative group of employees who send memos to one another in order to complete individual assignments. And "employees" shouldn't need to "send memos" to every other employee in the "building" - see Law of Demeter.
  • Lieutenants. From the standpoint of the memo-sending metaphor, the "lieutenant" metaphor is about the contents of the "memos". A lieutenant (or vice-president) isn't told exactly what to do (the "how") but the goal to be met (the "what"). The value of the lieutenant is in delegation. Objects shouldn't need to know much about other objects' work, as long as the objects do their "jobs". There's a good reason for this advice: the more an object knows and therefore assumes about other objects, the harder it is to modify and/or reuse each object independently. Effective error handling often requires a delicate compromise of an object knowing just enough about possible errors to respond the way it should - no more, no less (should the object abort, retry, ignore, fail?).
  • Instantiable scopes. Unlike the noun metaphor, the "instantiable scopes" metaphor is not likely to be included in introductory texts. It's one of the more obvious metaphors to seasoned programmers but one of the least obvious to novices. This is a rather literal and stark "metaphor", which is why it's of more interest to compiler and interpreter writers than to analysts. An object is a "bundle" of functions and variables whose implementation involves "this" (or "self") pointers and vtables. Sometimes, people involuntarily learn this metaphor when a serious problem occurs. Developers who are trying to add tricksy feature extensions to a language may need to think of objects in this way.
  • Data guards. Substitute "bouncers" for "guards" if desired. In this metaphor, objects are protective intermediaries between code and data. The object somehow mitigates the downsides of direct data access: checking that indexes are in-bounds, tying the disposal of acquired resources to garbage collection, etc. Like the lieutenant metaphor, a data guard object can separate an accessing object from dangerous knowledge, because the accessing object knows only as much about the data as the guard allows. This means, for instance, that the guard could change to obtain the data from a different source, or the accessing object could be reused in several different contexts at once as long as its data guard functions consistently. The obvious downside is that superfluous guards and multiple layers of guards complicate and slow the program.
  • Sets of behaviors. This is the most abstract metaphor of all. Many OO design patterns use it. According to this metaphor, objects represent actions instead of, well, objects. The object's focus is the execution of a specific algorithm, and not the expression of data. Therefore, the typical name of a behavioral object refers to the role it serves in the program: bridge, adapter, factory, iterator, strategy. Viewed through this metaphor, the important difference between all objects is behavior. Objects that have the same behavior shouldn't require multiple classes. The behavior of subclasses shouldn't violate the behavior expectations of the superclass. An object is what an object does.

Friday, August 15, 2008

something worse than missing sarcasm online...

...is assuming the online statement is sarcastic when it's actually sincere.

"My mistake. I figured that he or she couldn't possibly be so ignorant|silly|dumb|unoriginal|hateful|presumptuous|arrogant."

It also has happened when I try to adjust to common interpersonal communication after passing time reading forums. People think I'm acting arch just because I look at them quizzically after they say something that's flatly ridiculous and I'm genuinely unsure whether to take them seriously.

Monday, August 04, 2008

Tale of the Self-virtualizing Robot

Imagine a smart robot that can interact with its environment in complicated ways akin to a human. This robot is so smart that its mental model of the world is at a similar level of sophistication. Its senses, goals, and calculations all are different from a human's, but nevertheless it's more than capable of devising plans of action or correcting itself based on past mistakes, for instance. It also can theorize about the future.

Moreover, the clever robot can employ these abilities to perform a great trick: it can project its own thoughts and actions. That is to say, it has a perfectly accurate internal concept of its operation that it can apply to hypothetical data to determine what it will think and do. After successfully doing this once, it recognizes the value of incorporating self-prediction into its long-term considerations. It proceeds to run the self-prediction task more and more frequently, as data comes in. It's executing its program as part of its program. In effect, it's self-virtualizing.

But now the story takes another twist. Sooner or later, the self-virtualizing robot discovers that the computed action its "virtualized self" will take is suboptimal, or that the computed answer its virtualized self will produce is incomplete. It duly notes and accounts for this new information, thereby shifting its current and future thoughts and actions accordingly, as surely as the sum of 4 and 6 differs from the sum of 8 and 3 . Yet doesn't this mean that the robot perfectly predicted itself wrongly? Is this possible? Through bypassing and modifying its programming to decide differently, does this robot have as much freedom to choose as any human?

I think so. I'm convinced that the phenomenon that we experience as "choice" isn't a peculiar loophole in causality but instead a complex interplay of factors such as emotion (drives), reason, and creativity. The complexity is the first reason people assume it to be causeless, i.e. free. Second, the factors change within each person, sometimes gradually, sometimes abruptly (e.g. "the last straw" or psychoactive substances). Third, awareness of one or more factors can function as a factor--feelings about feelings, perceptions about perceptions. Fourth, people can ponder ideals, in a fact-value distinction. Fifth, they want to believe that they are in control. Sixth, they want to believe that their motives have superior subtlety.

If the self-virtualizing robot sufficiently mastered language to claim it could act independently of its programming, how would anyone convince it otherwise?

Saturday, August 02, 2008

questions about Truth in endlessly astounding reality

Truth was defined in the previous entry as nothing more than the measure of correspondence between specific ideas and reality. This (singularly unoriginal) stance provokes follow-up questions, whose answers serve to clarify what I meant. I wish I could properly categorize my concept of Truth, but I don't have sufficient technical knowledge and/or scholarship; pragmatism's seems similar.
  • Q: For someone to accept this definition of Truth, isn't he or she forced to assume the truth of the definition itself? A: Yes, but all definitions of Truth have the same "shortcoming". All definitions of Truth are statements, thoughts, etc., whose truth cannot be accepted except on "their own terms". Truth definitions can't be logically derived. However, one can assume the truth of the Truth definition and then apply it to itself. In my encounters with reality, to define Truth as the measure of accordance with reality is to define Truth in a way that has a high measure of accordance with reality, i.e. this definition of Truth hasn't been misleading. Hypothetically defining Truth as what Simon Says would fall apart as soon as Simon said something impossible, such as a self-contradiction (bad Simon!).
  • Q: What about the truth of "32 - 15 = 17"? A: That exact statement is neither true nor false. It doesn't correspond to reality--it's about "mental realities", symbols, generalizations. A remarkably similar statement like "separating 15 pennies on this table from the original grouping of 32 pennies will result in a grouping of 17 remaining pennies" is either true or false, but my reason suggests it is true. The utility of math, or any other formalized system of reasoning, is thanks to a human discovery: the assumption of an exceedingly small set of true statements and (formal) rules for truthfully combining statements enables an explosion of creative proofs of other true statements, "theorems". As long as the formalized reasoning system's symbols and rules indeed correspond to reality, the theorems produced should, too. The ideas known as quantities happen to correspond so easily, so well, so unambiguously, and so consistently to reality that we forget their existence is purely mental.
  • Q: Can't a proposition be true, and therefore part of the Truth, regardless of whether anyone is convinced it is true? A: Nope. If truth is the measure of correspondence to reality, that measurement (or judgment, etc.) must be executed and evaluated by someone who comprehends both reality and the proposition! No individual truth is "substantial", since it's a characteristic of the relationship between an idea and reality. Reality is "substantial". Reality is. In other words, reality doesn't "depend" on propositions. Reality's "realness" isn't contingent on the thoughts of humans. Truth is the extent by which people's thoughts succeed at agreeing with reality, not the extent by which reality succeeds at agreeing with people's thoughts.
  • Q: Given that Truth is this flimsy, and the people like us who judge it are known to make so many mistakes, how can any belief have "solid" truth? A: Quite right. This question has no easy answer, but that's expected in the face of endlessly astounding reality. The fact is, both the observation of reality and the accompanying checking of truths proceed using a plethora of methods and degrees of reliability. (A few are in wikipedia is not an epistemology silver bullet, the 12th blog entry.) As a result, some truths are more "solid" than others. The criteria to rank them is a procedural matter, not a philosophical or foundational one. Just as children learn to be skeptical after playful adults tell them lies for amusement, people continue gaining (heuristic) expertise at weighing truth. Even those who say they rely predominantly on reason to obtain truths aren't immune to making mental mistakes or starting from the wrong premises.
  • Q: To define truth's domain as the combination of thoughts and reality, doesn't that presume thoughts must be distinct from reality, i.e. thoughts are unreal? A: The terse answer is that, yes, thoughts are unreal, regardless of how true. The more elaborate answer is that although thoughts are unreal, thoughts that more closely correspond to reality (more truthful) are more "real", figuratively speaking. Note that thoughts that are at least somewhat true can still be useful, through analogy. True thoughts can act as close "simulations" of reality. In the most extreme case, thoughts that prove to be very true are what people designate as reality.
  • Q: Hey, wait a minute, now you're double-talking--if people's experiences of reality are thoughts themselves, how can people ever really determine the truth of all their thoughts versus "reality"? A: This is a variant of the age-old question "How can I know for sure that all of my experiences aren't illusory?". The absolute answer is "You can't". The practical answer is "Thoughts you can't ignore, thoughts that are most consistent, are the most true, i.e. the closest to being real and the most deserving of the convenient label 'reality', if only temporarily". Essentially, thoughts are the unreliable messengers of reality, and all people can do is compare the messages, assign degrees of truth, and in so doing compute a semblance of reality that's meaningful and usable. Think of it this way: if one thought is of a winged horse while a much more vivid second thought is of a computer screen, the second thought is likelier to be more true and "real". If turning one's head causes the thought of the computer screen to shift position, then the thought is considered still more true--among thoughts, direct sense perceptions are usually treated as true representatives of reality. But not all sense perceptions are true, and even the least ambiguous require significant interpretation...which reemphasizes the point that the heuristics of judging truth can't be simple and free of exceptions, due once again to reality being endlessly astounding.
  • Q: By defining truth as secondary to reality but refusing to unequivocally define reality, in what way does this scheme clarify what Truth is? A: Er...huh. The thinly-veiled motivation behind this standpoint isn't primarily to pronounce Truth's composition, but to promote reality through demotion of other philosophical items such as Truth. Reality is real; to be true (and figuratively "real") everything else must be based on reality. That which bears no relation to reality shouldn't be thought of as true--perhaps beautiful, good, even "correct" according to some standard, but not true. And reality itself needs no underpinnings.