Tuesday, July 29, 2008

peeve no. 259 is calling supernatural stories "sci-fi"

Of all the mislabeling of entertainment that goes on, none sets me on edge quite like "sci-fi" referring to stories that contain the supernatural. I appreciate that authors don't feel obligated to confine their ideas into neat little categories (nor should they!) and that consequently none is adequate. I recognize that almost from the very start sci-fi, science fiction, bifurcated into stories based on the one hand on the "hard" science of experimentally-verified theories, and on the other hand on "soft" scientific or technological speculation. Moreover, a work's scientific "hardness" lies on a fuzzy spectrum because some of its ideas could be hard and others soft. If the work is episodic, then each episode could be different on the scale. I enjoy both hard and soft sci-fi, although I prefer that a story strives to stick to its chosen hardness rather than leaping sloppingly over the line and back.

My limit is really pretty simple: once a story is so soft on science that it includes the supernatural, its sci-fi credentials should be revoked at least temporarily. I'm okay with exposition like "the 'telepathic' race communicates with one another through radio waves". I'm not at all okay with "the being made of energy can create and transform matter at will". Or rather, I'm not okay with that character's story to be known as "sci-fi". Science's relevance to that story is slim.

The dividing line shouldn't be that hard to distinguish. If a story entails a concept that science contradicts, casts doubt upon, or dismisses from consideration, then the story shall not be deemed science fiction. If a story's suspension of disbelief involves jettisoning the conventional scientific perspective, then the story is outside science--beyond it, if you prefer. It's a supernatural story. Such stories might have value for any number of reasons, but worthiness of the "sci-fi" description isn't one.

Tuesday, July 22, 2008

musings on I am a Strange Loop, part 4

I am a Strange Loop is a book about consciousness that displays unashamedly the imprint of the author. Its examples come from his life. It's far from emotionally sterile, since it includes his reactions and opinions. It offers glimpses of where his ideas originated. It includes excerpts from his letters. It shows his sincerity.

It advocates vegetarianism. To his credit, the author honestly relates how his attitude has developed and also when he has and hasn't eaten accordingly. He justifies it better than most vegetarians I have met, who focus either on the notable health benefits or on reminding everyone around them that meat does, in fact, come out of slaughtered creatures, as if the embedded blood and bones weren't sufficient clues. Belief in consciousness as a strange loop is intriguingly novel fodder for the vegetarian assertion that greater similarity in form between a human and a creature implies greater similarity in the experience of existence, pain, and death. The more that a creature's capability of awareness approaches a strange loop, the closer the creature is to being conscious, i.e. closer to being like us mentally. Monkey brain is therefore even less palatable than before.

My stance, to the extent I have one on the topic, is that consciousness and strange loops aren't pertinent to the decision of vegetarianism. Pain shouldn't be inflicted recklessly, regardless of the victim's intelligence, and power to take an action doesn't excuse it. Nevertheless, consuming other creatures ("ingesting flesh", as a vegetarian might say) doesn't have to violate those maxims, in my evaluation. Killing or torturing a creature in brutal fashion would be unethical. Killing a creature for no purpose than fun or sport would be unethical, too. Excessiveness to the point of eliminating a species, no matter the "mildness" of the individual deaths, would be unethical. A person participating in the food chain, without malice, is merely natural. Color me a concerned omnivore...an omnivore who doesn't eat a lot of meat due to the nutritional hazards, which are aggregately dire.

Besides vegetarianism, the book advocates something else: Bach. A writer can extol any composer he or she wants; that's a prerogative of writing. I won't object to the suggestion that musical preference is often symptomatic of someone's sense of identity, because music is perhaps the most vivid expression of a culture and cultural identity can be instrumental (pun intended) in self-identity. I'm agreeable to the still-stronger hypothesis that the deep "shape" of someone's consciousness interlocks more firmly with some individual musical pieces than others, depending on the piece's use or abuse of rhythm, melody, tempo, tone, harmony. However, I don't accept that the amount of attraction toward particular music is reliable for gauging a consciousness on any scale of measurement. The relationship between consciousness and musical appreciation is too nuanced, too dependent on other factors--multivariate. Having said all this, I don't care much for Bach, though I enjoy isolated compositions. That's a low measure of praise, considering I enjoy isolated compositions in almost every genre I've heard.

Finally, fittingly enough, is the epilogue, "The Quandary". It's a good summation of the book's major points, but what I like (the strange loop remarked as it contemplated its past contemplations) is the admission that the concept of consciousness as a strange loop isn't immune to the perceptual gap separating inner and outer life. A consciousness convinced that it has no independent existence remains a consciousness that assumes it has independent existence! Moreover, one of the ingredients of a coherent whole of consciousness is the inability to perceive its parts. (Of course, it's rather circular, anatomically speaking, to picture the brain having a meta-nervous system devoted to sensing the activity of its neurons.) Without the unconscious and the subconscious, consciousness would be too distracted by itself to react to its surroundings, a situation which mental illness abundantly demonstrates.

Thus, all theoretical derivations of consciousness are doomed to failure in presenting a model that convincingly matches human experience, i.e. "common-sense". Scientific theories for epiphenomena and illusions tend "to ring hollow" anyway, no matter how much support the theories have. Counterintuitive theories are like complex numbers and transcendental numbers. Simple questions can have correct answers that defy expectations. Whether to respond to these answers with dismayed doubt or energized awe is the choice of the learner. Hofstadter has undoubtedly made his.

Monday, July 21, 2008

musings on I am a Strange Loop, part 3

As I was reading I am a Strange Loop, I was surprised that two aspects of consciousness weren't deeply discussed or further emphasized. The omissions may reflect a disagreement between Hofstadter and me, or the admirable goal of keeping the book short and focused. The first aspect is the importance of language. "The Elusive Apple of My 'I'" is the chapter that explores the nature and development of "I" (self-identity). Its descriptions seem plausible, but my inclination is to more explicitly tie consciousness to language. Consciousness, abstract thought, language, and sophisticated interpersonal relations all are among the most distinctive characteristics of humanity (although many species have these qualities in lesser magnitude). Interpersonal interaction is connected to language, language is connected to abstract thought, and self-identity is an abstract thought. Language's first purpose is communication, yet it has other uses. Otherwise, why would people "think out loud" or "talk to themselves"? It's a ready method for analyzing and ordering thoughts. It's commonly used to construct cognitive "feedback loops" of putting a thought into words, then reacting to the words with more words, etc. (Thank your long-suffering counselor or therapist today!) It's a way to expand one's memory with external storage, through reminders, notes, voice recorders, or just repeated muttering that marginally extends the time period of short-term memory. What's most important, it allows for fiction: discussing and inventing the nonexistent. I don't mean to disparage nonverbal abilities such as visualization and intuition, but the superior information encoding of language, predicated on a combination of rules and flexibility, has furnished humanity with the means to construct ever-higher towers of knowledge ("standing on the shoulders of giants" and whatnot).

Language doesn't trap thoughts. Language is a tool. However, language does guide thoughts and train thoughts along well-worn paths. Each time someone forms a valid statement, the same rules of language that enable it to be comprehensible conform the communicator's expressed thought: choices must be made as to subject, adjectives, verb, adverb, prepositions, etc. Thus, merely in order to communicate a headache presumes the existence of "I" (or "my", "me", "Yo", "Je"). At some earlier time, other people said "I have a headache" or asked "Do you have a headache?" or "Does your head hurt?" Consequently, when I feel pain localized in my cabeza, it's simple to swap out the subject slot with "I", and the more adept that people become at such subject-swapping the more they learn what self-identity (consciousness) is all about. "I" ("me"?) is a set of sensations, emotions, and actions appropriated from the rest of society to be able to label the individualized stuff, the subject-ive. When I'm a member of a group, one definition of "I" is "the group member whose face I don't see" (and whose hands I control, whose voice I use). If a member of a group caused a collective project to fail by slacking off on an assignment, and the consensus is that this member is designated by the name "Terry", then it's logical for Terry to make the conceptual leap to "I am a slacker", assuming Terry doesn't deploy a range of coping mechanisms. Like any other human creation, "I" is spread from one person to another, one generation to another, which is why it's curious to question the evolutionary value of consciousness: "I" is a linguistic, social epiphenomenon that was and is discovered and disseminated through joint efforts of human groups. Natural selection bore intelligence and language; consciousness was a by-product. Hypothetically, a completely solitary human wouldn't have or need "I".

Additionally, a tie between language and consciousness supports the notion that "I" could be at least partly an illusion. The illusory effect of language has been noted by philosophers who professed the persuasive axiom that philosophy's prime questions are examples of misapplying words out of meaningful context: absolutes created through questionable manipulations of real statements. For instance, pondering if "purpleness" exists despite "purple" is clearly an adjective. While the level of reality of "I" is closer to that of a theory or generalization than of a literary fabrication, its tenacity on the mind and its seemingly rock-solid existence are similar. Just as Good, Truth, and Reality are simultaneously undeniable to all and nevertheless extremely hard to define satisfactorily in concrete and absolute terms, "I" is evident and ethereal at once.

The second understated aspect of consciousness is the importance of the separate brain areas and functions whose collaboration is the content of consciousness, if not the bedrock. Neuroscience is prone to repeatedly shattering the image of the brain as a single entity. True, it's one organ in one area of the body. But this one organ isn't homogenous. The "wiring" for receiving and interpreting sensory data is both highly significant and not fully understood. Each hemisphere has its specializations. Speech centers play a starring role. The amygdala and hypothalamus are just two of the regions whose activity can dominate consciousness. Then there are the functions that are so commonplace that people tend to notice them only during failures, such as motor control related to the cerebellum.

At those times, "I" abruptly becomes atypically ineffectual, and it's harder to picture "I" as an aloof, absolute dictator of the body. Other kinds of brain damage reduce consciousness in more drastic details like personality changes, memory problems, and speaking difficulties. The book mentions Alzheimer's, which I too have observed up-close in relatives--the gradual erasure of what makes the individual unique. All these afflictions, whether temporary or permanent, present a conundrum for the perspective that consciousness is metaphysical. In my experience, people with that belief respond by alleging either that the consciousness is "trapped" down deep inside a frail body or that the consciousness has partly let go. They may also say the consciousness will be its former "self" in the afterlife. I haven't received an explanation of why or how the consciousness would accomplish its reversion to a previous state, but I'm not heartless enough to demand one.

The point is that regardless of the connection between consciousness and strange loops, the harmonious froth in the brainpan between all the parts is key to what goes on. A theme of this book is the difference between the macroscopic and microscopic ways of examining objects and object interactions; microscopic physical particles and nerve cells underlie the macroscopic items that are more meaningful to us, and consciousness is best analyzed in the macroscopic domain as an epiphenomenon. Brain tissues and regions fit in a middle tier. This middle tier has more than enough to fill its own book, so its absence is understandable.

Leftover musings on I am a Strange Loop, on the other hand, fit in a part 4 tier.

Sunday, July 20, 2008

musings on I am a Strange Loop, part 2

The chapter "Killing a couple of sacred cows" argues against the use of or need for "free will". Human behavior is bounded from the outside by a sizable set of unchangeable constraints and motivated from the inside by a sizable set of desires and goals. Then why is a ghostly factor known as "free will" posited to explain decisions? When someone chooses, one desire has simply won out over another. How is human dignity in any way amplified by the notion that people can execute purposeless (essentially random) actions?

Although I see the point of this stance and I follow its line of thought, I must extend from where it ends. I believe that it is too dismissive of the degree of complexity and unpredictability that surrounds uniquely human choices. I'd venture that some human choices involve thought that is strange-loopy complicated, in fact, with categories building on categories (or, say, a categorical imperative?). A moldy-old observation about human nature is that, unlike beasts, a human who is ordered to do something might refuse merely because he or she was ordered. It doesn't matter what the concrete incentive or disincentive is--it's the "principle" of it and the principle is on an outer meta-level of moral meaning. A second observation as old as the first is that humans are the only beasts who kill each other based on differences in abstract beliefs, not just over mates or resources or retaliation for past injuries. In short, the arbitrary complexity of thoughts and categories that strange loops enable also enable choices to be arbitrarily complex. Moreover, the mental flexibility that makes dilemmas thorny concurrently makes highly creative solutions possible. People can compromise and mediate. People can dream up nuanced laws in an attempt to evenly balance competing concerns. The concept of free will may be misleading in saying that people are either free or willful, but free will is an exaggeration of the concept of abstract will. Humans can will ideas. Humans can love love. They can weigh the pros and cons of buying insurance.

A different proposition, just as elusive as free will, is presented in some other chapters: the proposition that a consciousness can be housed at multiple points in space and time. I prefer to use the label "consciousness" whereas the book often uses "soul". In my estimation, "soul" is too heavily loaded with previous associations to be reused without misunderstanding. After all, according to this book an instance of consciousness is a strange loop of symbols, i.e. a pattern, which is a far cry from what most would call a soul. And as politics has proved, terms matter--it's easier to convince people that a pattern, not a soul, can be copied and stored across space and time. On the Internet, data patterns (what did you think a file is?) flow continuously through time and space. Why couldn't the pattern of a consciousness?

In part 1 I agreed that an exact duplicate of the "host" of a consciousness--a person's body--would be an exact duplicate of the "hosted" consciousness too. Thus, I have no qualms about agreeing that an inexact duplicate of a consciousness' pattern, stored in another time and/or place, is an inexact duplicate of the consciousness. However, once again I diverge: I can't accept the application of this corollary to human relationships, no matter how superficially. It's too far-fetched to suppose something as multi-layered as a consciousness can be known by another consciousness, or stored alongside. One person cannot simulate a second person (to be fair, the book doesn't make this claim in so many words, although it does liken brains to Universal Turing Machines). Neither can one person know a single complete thought of a second person. Communication is too imperfect for the task: its bandwidth is too narrow, its encoding too imprecise. Not only that, but each communicator is working on a basis of strange-loop, high-level, guess-work knowledge about his or her own thoughts. The talker can't necessarily state for certain why item A reminded him or her of item B! The most accomplished storyteller can fashion a virtual reality through a story, but the reality experienced by the storyteller is not the reality virtually experienced by the listener. A storyteller who says that "I was devastated by the news", besides violating the show don't tell dictum, can't possibly communicate how he or she felt exactly. But a good listener can imagine an experience that approximates it, though too much imagination will lead to an embellished version. People can "grow close" but ultimately each consciousness only has an indistinct, shallow sketch of any consciousness besides its own. These rough sketches shouldn't be construed as capturing any more than the most rudimentary caricature of a consciousness pattern; the deceased don't "live on in memories" in any sense that merits the terminology, but they are remembered. People say they sympathize, but to authentically know someone else is an incredibly hard (and perpetually unfinished) undertaking that requires a huge trial-and-error effort by the knower and the known. Not everyone can.

The level of empathy in a person's consciousness ("soul") is one of the scales the book tentatively suggests for judging the person's degree of consciousness. If that is so, I don't see how. The book's first tenet is that consciousness is a strange loop originating from thought and perception. A relative lack of aggression toward fellow beings and a talent for intuiting a fellow being's perspective are good qualities, yet the two aren't correlated with the skills of thought and perception. Aggressive geniuses exist. Gentle dunces exist. People who are excellent at analysis and categorization might not be good at relating to people (they might have no more emotional range than a teaspoon). Others who are easily confounded by elementary math might be excellent at appraising people within ten minutes of meeting them. Moreover, an individual who has a natural knack for perceiving a psyche's pleasure and pain points may choose not to be a humanitarian but to be a master manipulator who expertly uses people to achieve selfish goals.

Drat! The cornucopia of food for thought furnished by I am a Strange Loop entices me to ruminate some more to come...

Saturday, July 19, 2008

musings on I am a Strange Loop, part 1

I am a Strange Loop by Douglas Hofstadter isn't GEB II, as the author ably explains in the preface. While GEB touched on many topics that apply to Hofstadter's perspective on intelligence and illustrated those topics with Dialogues, this book has tighter focus on consciousness and strange loops. It has a couple Dialogues, much fewer visuals, and mostly photographs in place of artwork (with some great color pictures in the middle). Escher and Bach have fewer appearances. But Gödel and his Theorem are still prominent, which is fitting given the applicability to strange loops. The writing tone remains frank and conversational and it brims with extended analogies, in my opinion too many. I particularly dislike the analogies whose length is excessive, or whose connection to reality is threadbare, or whose wordplay is nauseatingly cute (Hofstadter is remarkably bold here and in GEB--I wouldn't have the chutzpah to mention the coincidental similarity between "Gödel" and "God"). It also felt repetitive to me in its insistence on restating the same conclusion in several ways, but I respect the effort to thoroughly explain rich yet abstract notions. For intangibles, especially directed at a general audience, too verbose is probably better than too terse. At any rate, I believe that I understood what I read, which counts as praise to any nonfiction author. Also praiseworthy is the undeniable pleasure I experienced through the reading. I hope it's not gratuitous to express my gratitude for the gratification, and I hope that it gratifies the one responsible for the gracious gratuity of an additional book beyond GEB.

But like my other "reviews" I'm less interested in critiquing style than musing on ideas. The book's title is apt, since the topic is the big questions about consciousness and the primary answer is strange loops. A strange loop occurs when multiple "levels" exist but the levels mutually intertwine such that repeatedly jumping "outwards" from level to level results in a return to the starting level. All the "level-jumping" in a strange loop appears to be paradoxical until viewed in a larger context, where the strange loop is clearly seen to in actuality be a circular entity (a loop) dependent on outside support for its creation and/or maintenance. An unofficial strange loop that I thought of is the (childish) economic question "where does a factory worker's money come from?". Well, the worker receives money from the level of a manufacturer, the manufacturer receives money from the level of a distributor, the distributor receives money from the level of a retailer, the retailer receives money from the level of a customer such as a plumber, and perhaps the plumber received payment from the level of the factory worker...

Gödel-like self-reference is a more subtle example because it consists of jumping between levels of meaning. To not be patently meaningless, a "self-referential" statement must jump to a new level of meaning. That is, self-referential statements must be considered as meta-statements. Assuming I comprehend him correctly, Hofstadter asserts that consciousness is a similar instance of a self-reference. Consciousness happens when the capability to think and perceive is sufficiently powerful to have its object be thinking and perceiving. The strange loop of consciousness is a thinker who thinks about his or her thinking, thereby "jumping out" to an enclosing level of context/meaning, and then possibly thinks about thinking about his or her thinking, and then possibly thinks about thinking about thinking about his or her thinking (as an aside, I wonder precisely how many meta-levels a book about consciousness has?). One of Hofstadter's objectives is to show that the strange loop of consciousness isn't really infinite, paradoxical, or otherworldly, but it is a natural epi-phenomenon which is a consequence of the symbolic, abstractive power of the human brain attempting to "wrap around" onto itself like how a Gödel theorem wraps a symbolic logic system around onto itself.

This means that consciousness is a highly convincing illusion. I like the comparison of consciousness' reality to the reality of a rainbow. A rainbow appears to be definitely located and as colorfully vivid as a flower, but if the viewer or the light moves or the water stops then the rainbow vanishes. I was a bit relieved to read someone else writing that consciousness is illusory because I've thought the same thing numerous times. Consider how little consciousness/attention a learned or practiced behavior requires. Consider that in split-hemisphere experiments the verbal hemisphere claims to have performed an action that the nonverbal hemisphere just did by itself. Consider the many, many cases when people "unintentionally" express or "betray" their "true" beliefs/feelings. Consider the many, many "gaps" in consciousness that a typical person experiences: sleep, intoxication/sedation, hypnosis (I remember going through a childhood stage of not wanting to fall asleep due to anxiety about the accompanying lack of consciousness). Consider how many of consciousness' conclusions are post-hoc--"I snapped at someone, therefore I must be cranky". Finally, consider the often-abysmal accuracy of people about themselves, the pleasant fiction they cling to--if you doubt whether someone is innocent, just ask him or her, they'll tell you.

To categorize consciousness as illusory is to conflict with dualist perspectives on consciousness. Some of my favorite parts of the book contain patiently logical dismantling of dualism. Its words again mirrored some of the deductions I have reached independently. Belief in objective and physical causality (is there another kind?) implies that a consciousness, a soul, is an unavoidable and convenient mental/social concept rather than a "known unknown" that in some magical way exists separately from reality yet simultaneously impacts it. Before reading this book I've pondered the question about whether unique self-identity is preserved after a perfect clone emerges from a vat or a traveler from a teleporter, and I reasoned that an exact duplicate must exhibit the "same" soul/identity as the original. If no practical method exists to make the distinction between x and y, x and y are for all purposes as identical as 3 and 2.999999999... The same proof applies to distinguishing a machine's or zombie's thoughts from a human's thoughts, which is another question that I encountered before reading this book--if the machine or zombie shows every indication of being as conscious and capable as a human, then it's reasonable to say that the machine or zombie has a claim to a consciousness/soul every bit as much as a human does.

I have more musings to be covered in subsequent parts.

Friday, July 18, 2008

the Woven cipher

Like the previous other two ciphers, the Woven cipher isn't great at encrypting, but nevertheless it was an engrossing hobby project that had a few fascinating wrinkles (is it any wonder I sometimes have trouble explaining to other people how I spend my time?). The basic idea behind this cipher is to convert all the characters of the plaintext into binary digits (bits), combine the bits of adjacent characters by alternately taking n bits from one then the other, and then iteratively mixing the resulting adjacent bit sequences in the same manner until only one remains. The key is the set of n values to use, which the algorithm cycles. Forming an intact whole out of little parts through an alternating process is analogous to weaving, hence the name "Woven". A second excellent name, perhaps more accurate but less appealing, is "the Multiplexed cipher", where the multiplexing is done using fixed data lengths, as opposed to fixed time periods for instance.

To work, the algorithm can't be quite that simple...
  • Most of the time, when the numbers don't match up exactly right, a source sequence won't have enough bits. When that happens, the strategy is to instead use an extra 0. Since the "weaving" happens from right to left, least-significant to most-significant, these are leading 0s so the numerical value of the original sequence is unchanged. Of course, the intermediate sequences aren't numbers so the leading 0s matter very much. And if the very last sequence, or each chunk (7 bits long?) that rather long sequence is broken into, must be interpreted as a fully-representative binary numeral, there would need to be an additional convention like always prepending an extra 1. Extra 0s are needed if the sequences are different lengths, like a space's 6 compared to a letter's 7, and/or the sequence isn't evenly divisible by n. These filler 0s cause the encrypted (i.e. transposed?) message to be longer than the original. Unorganized testing shows that the amount of expansion for short sentences is commonly 100% or more, probably an exponential-like effect of extra 0s requiring still more extra 0s in successive iterations.
  • Another extremely common complication is an odd quantity of sequences to be woven. The coping technique I eventually settled on was to spontaneously create a "null" or "empty" sequence of length 0 to pair up with the loner. Loner or not, the quantity of data sequences to be woven is half the previous quantity of sequences, rounded up. For instance, 10, 5, 3, 2, 1. Or 8, 4, 2, 1. The rounding--throwing away information-- implies that when decryption happens, the encrypted message and the key aren't enough to reconstruct the original. This is one reason why the third decryption input, the original number of characters, is necessary upfront (the other reason is to let the decryption algorithm know for certain when to quit unraveling sequences).
I wrote the encryption and decryption using generators, which fit a lazy, functional paradigm. As Wikipedia says, a generator "looks like a function but behaves like an iterator". I think of it as an "on-demand" stream of values, potentially infinite, that you only receive when and if you ask for 'em--that's why a generator is "lazy". A generator function, to fulfill the role of an iterator, must have enough state to remember its "position" in the "stream" in-between individual requests for values. A closure meets that requirement--by definition a closure retains its own copy of the variables from enclosing lexical function scopes at the time of closure definition/creation. A generator implemented with a closure is then a function created by still other functions, so in addition to being lazy it's "functional". By the way, creating generators with closures, whether or not the generator is referred to merely as an "iterator", is covered extensively in Higher-Order Perl (finish making the book available on-line, already!). My choice to use generators came from a few silly motivations: 1) the old easy-peasy procedure for decimal-to-binary conversion--repeatedly divide by two and use the remainders--happens to produce an answer bit by bit; 2) I like functional programming and attacking problems through recursion, when I can get it to work; 3) once I start to solve a problem one way I'm reluctant to abandon it for a different way (that would feel like surrendering to failure and wastefulness), especially when I don't have a deadline.

In the encryption and decryption, the role of each bit sequence is filled by a generator. This includes the special-case generators at the start and finish, described in the code as "Initial" or "Final". These generators are somewhat similar to the rest but perform additional conversion tasks and/or obtain data directly from arrays. As a result the program's high-level design is also functional: first it constructs one or more function(s) that will produce the answer (bit by bit) and then it repeatedly calls the function(s). By contrast, the imperative design would be to manipulate actual bit sequences, not generators, by using one set of sequences to create the next set of sequences, etc. The loops are virtually the same in the imperative and functional designs, but the functional equivalent has generators in place of bit sequences--each set of generators is the input for the next set of generators. And each generator (a closure) only knows about the generators that were explicitly placed into its scope at creation.

Encrypt generators merge the output of two encrypt generators: they have two parents and one child. Decrypt generators do the reverse, requesting solely "half" of the output from one source decrypt generator and then dividing it up so that it can return the "left" half to one destination decrypt generator and the "right" half to another destination decrypt generator: they have one (-half?) parent and two children. Encrypt generators act like multiplexers. Decrypt generators act like demultiplexers. The individual generators know and do very little:
  • When an encrypt generator is created, it's passed a 'left' source generator, a 'right' source generator, and the number of bits to read from a generator before switching to the other--this number is one of the digits from the key, so only digits 2-9 are admissible in the key. The encrypt generator keeps a running count of how many bits it has processed, whether it is currently reading from the left or right, and whether either of the generators has run out of bits. If both generators are empty (i.e., return '') then the generator returns '', the empty string. If the generator set to return the next bit isn't empty, then return that bit. If the generator set to return the next bit is empty but the other generator is not empty, return a '0' for filler. Encrypt generators take one 'op' parameter. If the op is 'peek' then the generator skips updating any variables (and it also passes 'peek' if it needs to ask a source generator for the next bit) , otherwise it increments the bit counter and then switches which generator to read if the counter modulo the key value is 0.
  • When a decrypt generator is created, it's passed one source generator, which "side" of bits the decrypt generator will always ask for from its source generator (left or right), and the number of bits to process before switching the side that should receive the next bit coming from the source generator--once again, this number is a key digit. Decrypt generators take one parameter, the "side" that is requesting its next bit. The decrypt generator keeps a running count of how many bits it has processed and whether the next bit it reads from the source generator should be returned as a 'left' bit or 'right' bit. It also keeps short queues for left bits and right bits. If it's asked for a bit for a side whose queue isn't empty, then it returns from the queue. Else, it checks which side should receive the source generator's next bit. If the side matches, get a bit and return it. If the side doesn't match, fill up the queue for the opposite side with bits from the source generator, then return the next bit that does apply to the requested side. Naturally, at any time the source generator sends a bit, update the bit counter and toggle the "side" variable if counter modulo n is 0. When the requested side is "all", the decrypt generator does nothing more than return the next bit it receives from its source generator (which is always just from one "side"). The "all" case is purely for the last stage of decryption, when no more "unraveling" is necessary.
The "direction" of iteration over the key's digits (to determine the n for each generator) alternates between sets of generators. For example, if for one set the index into the key starts at 0 and increases, then in the next set the index starts at the maximum and decreases. This behavior is so all the key values are more evenly used among the sets.

My Javascript implementation of the Woven cipher is part of the blog layout, down at the bottom on the right. In the page source, search for 'wovencipher' (one word). If you use it or download it I am not responsible for any awful consequences. I don't advise you to use it for encrypting anything important or unimportant. Legal disclaimer, etc. It's purely for entertainment, educational, and/or edutainment purposes.

Thursday, July 17, 2008

hey genious, you misspelled something there

I know it's just mean to laugh at spelling mistakes. The point of writing is to successfully communicate, and most of the time minor errors don't hamper that. (On the other hand, if it's a setting in which correctness matters--e.g., formal messages or applications for jobs that involve writing them--little oversights might rightly or wrongly communicate subtle secondary information about the incompetence or apathy of the author!) Also, each time I jibe I'm inviting fate to trip me next so as to restore the Universal Balance. Yes, I know there's no such thing, but in case humanity does someday discover it I figure I should be prepared.

However, I draw the line at "genious", because that's just too hilarious and self-referential to pass up. Ha ha ha! I can think of some related quotes: "Judge a pig contest? I don't know, I'm no super-genius... or are I?" by a Mr. Homer Simpson. "Me fail English? That's unpossible." by Ralph Wiggum.

Tuesday, July 15, 2008

peeve no. 258 is dynlang users who disrespect Perl

Before I get my rant on, I'll do the lawyerly thing and attempt to clarify my terms to avert misunderstanding.
  1. "dynlang" is 9 characters shorter than "dynamic language", the name of a fuzzy category of programming languages that allow, support, and exploit the capability to make run-time changes to a program's very structure--its data types, classes/data structures, method/function dispatch. Although program interpretation is quite better suited than compilation to implement such a capability, it's too simplistic to assume that all dynamic languages are necessarily interpreted and all static languages are necessarily compiled, and for that matter too simplistic to assume that a particular language implementation never does both. (Groovy cheerleaders are fond of mentioning that their dynamic language is compiled, while compiled Objective-C code sends object messages at run-time.)
  2. "Disrespect" refers to an attitude, not to an engineering-like objective evaluation of trade-offs. An example of the latter is "Java's static typing nature can result in code that is difficult to adapt to unanticipated purposes." An example of disrespect is "Java sucks. And one of the reasons it sucks, and the people who choose to use it also suck, is that the stupid types strewn throughout a class do nothing but get in the way when I just want to pass in an instance of MyTempObject, and get the idiotic compiler to stop tying my hands on my behalf". (By the way, I apologize for the inaccuracy. This example of Java disrespect is a bit too lucid and courteous to match the corresponding real statements elsewhere on the Web.)
Disrespect is not the same as disagreement. I'll be frank: I realize Perl's syntax and semantics are a jumble of accretions, some of which are helpful more than not and some of which are harmful more than not. Quick, what values are false in Boolean context? What does the '...' operator do in scalar context? Which __special attribute__ do you use to define accessors and mutators (oops, that's Python)? Whenever I've written Perl, I've mentally chosen one of two "write modes": messy mode or neat mode. Messy mode, such as using the Perl monkey command line 'perl -ape', is good for processing one-time text files, but not much else. Neat mode should weight the concerns of readability and development speed differently than messy mode because programs that are used regularly spend much more time undergoing future maintenance than initial development. Neat Perl is choosy about what features to use. I agree that Perl code is frightening in wrong or reckless hands, i.e. in the grip of someone who only has messy mode. However, it's laughably naive to place most of the blame on the dollar signs and slashes...it's in the same league as being too distracted by the parentheses of Lisp-family languages to notice the self-referential power of expressing both functions and data structures as lists.

So I know that Perl has its problems. In fact, my encounters with Perl nowadays stem from two sources: 1) ad-hoc administrative tasks and/or data processing (but if I need to interact with one or more of standard formats, databases, JVM APIs then I switch to groovy), 2) upkeep of legacy Perl that acts either as "glue" between systems or as rough internal CGI interfaces for simple yet vital business tasks (I'd also note that the "legacy" Perl has no firm date for replacement). I'm not bothered when language cheerleaders call attention to Perl's weaknesses; this practice is hardly a new phenomenon, and when the latest critic repeats the same years-old tired refrain I can barely manage to react at all. No, what gets me worked up is when someone is dismissive, contemptuous, or mocking toward Perl, which has on numerous occasions, despite its acknowledged icky portions, served my purposes, enabled me to achieve unconventional solutions, and taught me intermediate-to-advanced programming concepts. Without Perl, I might have had to hack together a comparatively ugly combination of grep, find, sed, awk, etc., and shell script. (At the time I'm describing, pretty much the only other programming language available on the system was C or C++, and later Java.)

I'm not too irked by cheerleaders for static languages who throw rocks at Perl for fun. Their derisiveness is a subset of their general antipathy for dynamic languages. If Perl was the epitome of language design perfection then they would still pronounce it junk because of characteristics that by definition apply to any dynamic language: performance overhead, lack of mandatory type enforcement, multiple inheritance, chaotic data structures that are modifiable at will, and so on.

As the title says, the true irritants are dynamic language users who explicitly or implicitly assert that Perl is horrible, terrible. These users know the advantages (and disadvantages) of a dynamic language. They know Perl is a dynamic language. They know that they would probably rather use Perl rather than a static language to solve the same problems (okay, maybe some of them would instead use ML-family, Haskell, or statically-compiled Lisp-family--just maybe). Moreover, the reasons they give for why Perl is abominable sometimes strongly resemble the reasons static language cheerleaders give for avoiding dynamic languages altogether: too many operators and punctuation in general, syntax features that can interact in complicated ways, too few built-in data types (no "official" numbers or strings, just scalars!), the choice to use or ignore OO, special variables that affect execution, accumulated design cruft that makes some tasks too awkward or tricky. The stranger cases are dynamic language users who formerly used Perl primarily, but after changing their habits suddenly stop recognizing anything valuable about Perl at all. Perhaps they used Perl for the general benefits of a dynamic language, all the while having strong distaste for the actual "Perl-ness", and as soon as they could obtain a dynamic language without that flavor they were glad to kick it to the curb. Or (shudder) perhaps some current dynamic language users spent a long time solely in the static language camp, where they grew accustomed to decrying Perl as a mysterious, confounding mess, but after using and liking a dynamic language they continued to denounce Perl more out of habit than out of scorn for dynamism anymore.

Perl is what it is (except when it purposely breaks compatibility in some ways for Perl 6), though it does keep changing and code written using current recommended practices is superior to what you might remember. All I wish is for dynamic language users to give Perl the credit it's earned, is still earning, will earn. Stop mercilessly bashing it as if it ate your parents. But know that I join you in disliking sigils, list/scalar context distinctions, and autovivification.

Tuesday, July 08, 2008

performance dunderheads check this first...

(Note that even the best people are dunderheaded from time to time.) If an application has been deployed to a new environment but its performance is, say, 8x worse or more, ensure that the relevant database indexes are functioning properly. The hardware may be magnificent and the database well-tuned, but a sequential scan of many records will deliver a gut-punch to performance. It's also obviously not well-suited for caching.

Bonus tip: a good database engine has the ability to show the plan/strategy it computes for a query. Start there to find query optimizations that matter.