Wednesday, August 12, 2009

the importance of syntax sugar, ctd.

A while ago I ranted that the common term "syntax sugar" minimizes the practical importance of programming language syntax. One example is when people sometimes state (or imply) that their preference for dynamic languages is tied to the languages' sweeter syntax.

While that may be true, it's a mistake to assume that the saccharine in the syntax is dependent on a language's dynamic typing. This point is amply demonstrated for those who've been keeping up with the development of C#, a static language whose syntax is sufficiently honeyed that the below snippet is remarkably comparable to the Javascript version after it. I tried to match up the code as much as possible to make the comparison easier.

C#

public class myClass
{
public string myProp { get; set; }
static void Main(string[] args)
{
var myc = new myClass() { myProp = "English" };
myc.manhandleStr();
System.Console.Out.WriteLine(myc.myProp);
}
}

public static class ExtMethodClass
{
public static void manhandleStr(this myClass cl)
{
var palaver = new
{
myName = "Nym",
myTaskList = new List<Action<string>>
{
next => { cl.myProp = next + ".com"; },
next => { cl.myProp =
next.Replace("l","r").ToLower(); }
}
};
palaver.myTaskList.ForEach(task => task(cl.myProp));
}
}

Javascript

var myc =
{
myProp: "English"
};

myc.manhandleStr = function() {
var palaver =
{
myName: "Nym",
myTaskList:
[
function(next) { myc.myProp = next + ".com"; },
function(next) { myc.myProp =
next.replace("l","r").toLowerCase(); }
]
};
palaver.myTaskList.forEach(function(task) { task(myc.myProp); });
}

myc.manhandleStr();
alert(myc.myProp);


By the way, other C# programmers might scold you for writing code like this. And yes, I realize that fundamentally (i.e. semantically rather than superficially) the dynamic Javascript object "myc" differs from the static C# instance "myc". Keep tuned for the "dynamic" keyword that's on the way in C# for duck-typing variables going to and from CLR dynamic languages.

Saturday, August 08, 2009

please state the nature of the medical emergency

The words of the title echo through my mind every time I read some blog or other about the efficient market hypothesis. And if the blog analyzes the Reconstruction Finance Corporation then I start thinking about Internet protocol definitions. Even if its topic is just purchasing power parity, I hear a faint sequence of whirs, clicks, drones, and static.

Monday, July 27, 2009

the most incredible spell in "Half-Blood Prince"

Early on in "Harry Potter and the Half-Blood Prince", the wizard Dumbledore enters a room which is in disarray - items wrecked and disorganized, walls and ceiling missing pieces - and waggles his trusty magic wand. Everything is restored, repaired, and repositioned back to what appears to be the original state of the room. (It trounces Mary Poppins' finger-snap trick.)

This has to be a contender for the most incredible spell in the entire movie. Illumination on demand, movement controlled from a distance, and fire-throwing are great and all, but aren't that fantastic, relatively speaking, from the standpoint of the current level of technological progress. The rollback of the room is more astounding because it reduces entropy without expending energy. Maxwell's demon, thy name is Dumbledore (and you have our condolences).

There's no physical obstacle to roughly accomplishing part of the effect of this Entropy Reversal Spell. Sure, if an automobile crashed into my living room (just posit that I exist in a sitcom and the probability shoots way up!), I or more likely a contracted team of workers could remove the rubble and rebuild the wall to an approximation of its former glory. The energy (and currency) to do so would far exceed zero even apart from questions of efficiency, so reducing the entropy level here would merely increase the entropy level somewhere else.

Instant home repair would still be inferior to the Entropy Reversal Spell, though. To exactly reverse the breaking of a solid or the spill of a liquid first requires the retrieval of all the involved atoms and molecules then the restoration of the orientations and interactions between. Assuming nanotechnology or another technique is up to the task, one of its necessary inputs is an information representation of all those mutual orientations and interactions. Unfortunately, this is a clear case of combinatorial explosion, with the accompanying space and time problems inherent to the data processing. (It'd be a good opportunity to try out your quantum computer.)

Of course, the possible uses for the Entropy Reversal Spell extend far beyond perfect housekeeping. For instance, imagine that an engine - a Carnot heat engine, say - converts a temperature change into usable work. Then, at the tail end of each cycle through the casting of the magic of entropy reversal, the atoms could be restored without energy cost from the less-useful low-temperature state back to the handier high-temperature state. Presto! No more fuel necessary for all time and no harmful emissions, either.

But perpetual motion machines are still thinking too small. Consider the general notion of reversibility. Rolling a pen across my cubicle counter is quite reversible without trouble; just tap it with a finger to move it a few inches then tap it with a different finger to move it back. Putting the pen back on the counter after it falls on the floor takes more work and energy, both because it's a longer distance and because it's working against gravitational force (yeah, yeah, call me lazy for complaining). When the pen falls it moves from a higher (potential) energy state to a lower - the entropy increases and it's more work to reverse. Generally, the greater the entropy change of any occurrence, the harder it is (more work and energy) to reverse, and in any case the reversal ends up increasing overall entropy and energy loss still more because the reversal's energy-efficiency isn't perfect. In contrast, with an Entropy Reversal Spell, entropy isn't a factor anymore and theoretically any occurrence can be reversed without significant penalty. Feeling older all the time? Reverse it and forget about it. Father Time can suck it!

Although entropy reversal is a nifty feat when one can manage it, teleportation should at least get an honorable mention. Yet it's not quite as awe-inspiring since all one needs to do is somehow get all the information describing the object, transfer it elsewhere, and use the information to reproduce the original. Note that you'll need to get your hands on a Heisenberg compensator (find the details online).

Oh yes, I am a nerd.

Monday, June 29, 2009

DVCS and good merges

While it may be true that a DVCS (i.e. multiple repositories) implies good support for branching and merging else the DVCS would be a nightmare to use, it's incorrect to logically conclude that good support for branching and merging implies that someone must be using a DVCS (A -> B does not mean B -> A). Decentralization or support for multiple repositories is a different question than whether the version control system has "dumb" merging. The benefits of easier collaboration (we can pull and push work-in-progress to each other without committing to the "canonical" repo) and offline work are more honest justifications for DVCS than mere good merges.

Monday, June 22, 2009

my favorite word for today is complexify

It ends in "-fy", it's a neat opposite to "simplify", and it's satisfying to have the word itself be a bit cumbersome to say and understand. Call a consultant today to help you complexify your infrastructure!

Friday, June 12, 2009

I'm GLAD I'm not programming in natural human language

At least one of the hard and undeniable facts of software development doesn't really swipe a developer across the face until he or she starts work: the difficulty of extracting good information from people. Someone may say "the bill is a set rate per unit" but a mere five minutes later, after further interrogation, is finally coaxed into saying "customers pay a flat rate for items in categories three and four". Similarly, the reliability of the words "never" or "always" should be closely scrutinized when spoken by people who aren't carefully literal. (On the other hand, xkcd has illustrated that literal responses are inappropriate in contexts like small talk...)

I'm convinced that this difficulty is partially caused by natural human language. It's too expressive. It isn't logically rigorous. By convention it supports multiple interpretations. While these attributes enable it to metaphorically branch out into new domains and handle ambiguous or incompletely-understood "analog" situations, the same attributes imply that it's too imprecise for ordering around a computing machine. Just as "I want a house with four bedrooms and two bathrooms" isn't a sufficient set of plans to build a house, "I want to track my inventory" isn't a sufficient set of software instructions to build a program (or even a basis on which to select one to buy).

Every time I perform analytical/requirements-gathering work, I'm reminded of why I doubt that natural human language will ever be practical for programming, and why I doubt that my job will become obsolete any time soon. I can envision what the programming would be like. In my head, the computer sounds like Majel Barrett.

Me: "Computer, I want to periodically download a file and compare the data it contains over time using a graph."
Computer: "Acknowledged. Download from where?"
Me: "I'll point at it with my mouse. There."
Computer: "Acknowledged. Define periodically."
Me: "Weekly."
Computer: "Acknowledged. What day of the week and what time of the day?"
Me: "Monday, 2 AM."
Computer: "Acknowledged. What if this time is missed?"
Me: "Download at the next available opportunity."
Computer: "Acknowledged."
Me: "No, wait, only download at the next available opportunity when the system load is below ___ ."
Computer: "Acknowledged. What if there is a failure to connect?"
Me: "Retry."
Computer: "Acknowledged. Retry until the connection succeeds?"
Me (getting huffy): "No! No more than three tries within an eight-hour interval."
Computer: "Acknowledged. Where is the file stored?"
Me: "Storage location ______ ."
Computer: "Acknowledged. What if the space is insufficient?"
Me: "Remove the least recent file."
Computer: "Acknowledged. What data is in the file?"
Me (now getting tired): "Here's a sample."
Computer: "Acknowledged. What is the time interval for the graph?"
Me: "The last thirty data points."
Computer: "Acknowledged. What is the color of the points? Does the graph contain gridlines? What are the graph dimensions? How will the graph be viewed?"
Me: "Oh, if only I had an analyst!"

Tuesday, June 09, 2009

your brain on CSPRNG

Not too long ago I used a cryptographically secure pseudo-random number generator API for assigning unique identifiers to users for requesting an unauthenticated but personalized semi-sensitive resource over the Internet. They already have the typical unique organizational IDs assigned to them in the internal databases, but these IDs are far from secret. As much as possible, the resource identifier/URL for a particular user had to be unpredictable and incalculable (and also had to represent sufficient bits such that a brute force attack is impractical, which is no big deal from a performance standpoint because these identifiers are only generated on request). Also, we've committed to the unauthenticated resource itself not containing any truly sensitive details - the user simply must log in to the actual web site to view those.

Anyhow, as my mind was drifting aimlessly before I got my coffee today, I wondered if the CSPRNG could be an analogy for the brain's creativity. Unlike a plain pseudo-random number generator that's seeded by a single value, the CSPRNG has many inputs of "entropy" or uncorrelated bits. The bits can come from any number of sources in the computer system itself, including the hardware, which is one reason why the CSPRNG is relatively slow at processing random numbers.

But like a CSPRNG algorithm the brain is connected to myriad "inputs" all the time, streaming from within and without the body. Meanwhile, the brain is renowned for its incredible feats of creativity. It's common for people to remark "that was a random thought" and wonder "where that came from". Given all these entropic bits and the stunning network effects of the cortex (an implementation of "feedback units" that outshines any CSPRNG), should we be surprised that the brain achieves a pseudorandom state? I hesitate to call it true randdomness in the same way as someone who believes the brain relies on quantum-mechanical effects; people who try to recite a "random sequence" tend to epically fail.

I'm not sure that this makes any real sense. I'm not suggesting that a CSPRNG is a suitable computational model for human thought. It's merely interesting to ponder. It's another reminder that just as software isn't a ghost-like nebulous presence that "inhabits" a computer - a microprocessor engineer would tell you that each software instruction is as real as the current that a pacemaker expels to regulate a heartbeat - our thoughts and minds are inseparable from the form or "hardware" of the brain, and the brain is inseparable from the nervous system, and the nervous system is inseparable from the rest of the body.

Tuesday, May 19, 2009

resist the temptation

Memo to the universe at large: resist the temptation to mention one or more of the words ["id","ego", "superego"] in discussions of the relationship among ["McCoy","Kirk","Spock"].

It's been done. To Death. Repeatedly.

Saturday, April 25, 2009

amarok 2 and "never played" playlists

Hey, Amarok, here's a tip: the 2.x series wouldn't be useless if I could order it to randomly append a never played track to the playlist...and have it work.

UPDATE
(May 6): After switching to a more recent beta, I can obtain the behavior I want. And the "playlist layout" customization allows me to view the actual play count. Now I just wish that I could search my collection based on play count or last played date...

Monday, February 09, 2009

Haskell comprehension measured through WTF/min

The top compliment I can give to Real World Haskell is that it manages to finally teach me the aspects of Haskell programming that I previously assumed to be both impenetrably complicated and useless. As I read I'm also reminded of what it was like when I first tried to comprehend Haskell code. I've concluded that the most noticeable sign of greater Haskell comprehension is a noticeable drop in my WTF/min when I'm figuring out a given code example.

WTF/min is "WTFs per minute". According to a highly-linked picture, this unit is "the only valid measurement of code quality" and it's determined through code reviews. My initial experiences of Haskell definitely exhibited high WTF/min. The following are some of the past Haskell-related thoughts I can recall having at one time or another.
  • Infinite lists like [1..]? WTF? Oh, lazy evaluation, right.
  • Functions defined more than once? WTF? Oh, each declaration pattern matches on a different set of parameters. It's like method overloading.
  • The underscore character has nothing to do with this problem domain but it's being matched against. WTF? Oh, it matches anything but discards the match.
  • Why is the scoping operator "::" strewn throughout? WTF? Oh, it's being used for types, not scopes.
  • Even a simple IO command like "putStrLn" has a type? WTF is "IO ()"? Oh, it's an expression with IO side-effects that evaluates to the value-that-is-not-a-value, ().
  • WTF? What is this ubiquitous 'a' or 't' type everywhere? Oh, it's like the type parameters of generics or templates.
  • Functions don't need "return" statements? WTF? Oh, all functions are expressions anyway.
  • WTF is going on with these functions not being passed all their parameters at once? Oh, applying a function once produces another function that only needs the rest of the parameters. That'll be helpful for reusing the function in different contexts.
  • This function definition doesn't have any parameters at all, and all it does is spit out the result from yet another function, a function that itself isn't being passed all the parameters it needs. WTF? Oh, "point-free" style.
  • Now I understand all those -> in the types. But WTF is this extra => in front? Oh, it's sorta like a list of interfaces that must be met by the included types, so the code is tied to a minimal "contract" instead of a particular set of explicit types. That's good, but how would I set those up?...
  • Ah, now this I'm sure I know. "class" and "instance" are easy. WTF?! How can that be it? Just more functions? Can't I store structured information anywhere? Oh, tuples or algebraic data types.
  • I like the look of these algebraic data types with the "|" that I know from regular expressions. Unions and enums in one swell foop. WTF? How do I instantiate it? Oh, what appear to be constituent data types are actually constructor functions.
  • After a value has been stuffed into the data type, how can my code possibly determine which data type constructor was used? WTF? Oh, just more pattern-matching.
  • WTF? Record syntax for a data type declaration results in automatic accessor functions for any value, but we use these same function names when we're creating a new record value? Oh.
  • I've acquainted with map and filter. WTF is foldr and zip and intercalate? Oh, I'll need to look over the standard list functions reference.
  • What's this "seq" sitting in the middle of the code and apparently doing jack? WTF for? Oh, to escape from laziness when needed.
  • WTF? How can a function name follow its first argument or a binary operator precede its first argument? Oh, `backticks` and (parentheses).
  • How come there's all these string escapes in the flow of code? W...T...F? Oh, lambda. Cute.
  • I've always been told that Haskell is heavily functional and pure. WTF are these do-blocks, then? Oh, monads. Wait, what?
  • Functor, Monoid, MonadPlus, WTF? Oh, more typeclasses whose definitions, like that of monads, enable highly generalized processing.
  • A way to gain the effects of several monads at once is to use "transformers"? WTF? Oh, when a transformer implements the monad functions it also reuses the monad functions of a passed monad.
  • Finally...I know that the ($) must be doing something. But what? Why use it? WTF? Oh, low-precedence function application (so one can put together the function and its arguments, then combine them).