Showing posts with label work. Show all posts
Showing posts with label work. Show all posts

10 March 2010

Addicting games & computer engineering

Cracked.com has an article on 5 Creepy Ways Video Games Are Trying to Get You Addicted. I think this is a bit sensationalistic, but some interesting things to consider.

Now this may seem completely unrelated... From Google’s blog, Helping computers understand language:

An irony of computer science is that tasks humans struggle with can be performed easily by computer programs, but tasks humans can perform effortlessly remain difficult for computers.

I wouldn’t call this “irony”. Rather, I think I’d call it the fundamental truth of computer engineering. Our task as engineers is to enable human and computer to work together. The computer should be doing the parts of the task that computers are good at, and the human should be doing the parts of the task that humans are good at.

The thing that is odd to me: It seems like a lot of games are getting people to do exactly the sorts of tasks that I’ve dedicated my professional life to automating so that people don’t have to.

12 November 2009

The problem with Javascript’s map

This is about Javascript programming. If you’re not interested in Javascript programming, bail now.

Say you have a Javascript array of strings that you want to convert to numbers.

['1', '2', '3'].map(parseInt) ⇒ [1, NaN, NaN]

Hmm. Why didn’t that work? Because parseInt takes an optional parameter (the radix)...

parseInt('ff', 16) ⇒ 255
parseInt('2', 1) ⇒ NaN // Because a radix of 1 always returns NaN
parseInt('3', 2) ⇒ NaN // Because 3 isn’t a valid binary digit

...and map passes an optional second parameter (the index).

[1, 2, 3].map(function(n, i) [n, i]) ⇒ [[1, 0], [2, 1], [3, 2]]

Occasionally it is very handy to have map give you that index. Often, however, I want to give map a function—like parseInt—that wasn’t explicitly designed to be used with map.

Here’s how to fix it.

['1', '2', '3'].map(function(_){return parseInt(_);});

Yuck. Not only is that verbose, it looks downright silly since the closure looks pointless.

Expression closures can address the verbosity...

array.map(function(_) parseInt(_));

..., but (currently) only Firefox versions 3.0 and later support that. Plus, it still obscures why you’re doing it.

In Scheme, I’d use cute from SRFI 26. It allows you to specify some parameters of a function. The “<>” is used for parameters that you don’t want to specify.

(map (cute string->number <> 10) '("1" "2" "3"))

Of course, while string->number takes an optional radix parameter like parseInt, Scheme’s map doesn’t pass the index, so this isn’t necessary.

Back to Javascript. A “unaryize” function looks nicer than an explicit closure and makes what you’re doing clearer.

function unaryize(f) {
return function(_) {
return f(_);
}
}

['1', '2', '3'].map(unaryize(parseInt)) ⇒ [1, 2, 3]

We could generalize unaryize to naryize.

function naryize(f, n) {
return function() {
return f.apply(null,
Array.prototype.slice.call(arguments, 0, n));
}
}

['1', '2', '3'].map(naryize(parseInt, 1)) ⇒ [1, 2, 3]

In practice, I’ve run into uses of unaryize several times, but I haven’t yet run into a need for naryize. Also, naryize is less efficient than unaryize.

What if we want to specify a radix? We could create a Javascript version of cute. I’ll use undefined instead of “<>” for the slot specifier.

function cute() {
var cutargs = Array.slice(arguments);
var f = cutargs.shift();
return function() {
var args = Array.slice(arguments);
var fargs = [];
var i;
for(i = 0; i < cutargs.length; ++i) {
if(undefined === cutargs[i]) {
fargs.push(args.shift());
} else {
fargs.push(cutargs[i]);
}
}
return f.apply(null, fargs);
};
}

['a', 'b', 'c'].map(cute(parseInt, undefined, 16)) ⇒ [10, 11, 12]

Again, I haven’t yet run into many cases where I’d want to use cute that unaryize doesn’t suffice. In this specific case, I think I’m happy with the explicit closure.

['a', 'b', 'c'].map(function(_){return parseInt(_, 16);});

Additional notes:

Array.map can be implemented in Javascript and added without any changes to the interpreter. I’m using Prototype’s.

Expression closures can’t be added without changes to the interpreter, but they can be faked with strings. See Functional Javascript

While cute can be implemented as a function, SRFI-26’s cut has to be a macro. Likewise, a cute macro is more efficient than the procedure implementation.

21 May 2009

The new command line

Coding Horror had an article called: The Web Browser Address Bar is the New Command Line

I once developed the “perfect” search GUI. It had all the power and flexibility you’d want, and it was all visible.

My boss and mentor said even he found it intimidating. Intimidating the user was not what I was going for.

So, I went about applying progressive disclosure. The power wouldn’t hit you all at once, but would be made visible in little pieces. I hoped in a natural way that wouldn’t prevent people from finding the power when they needed it.

(Aside: Progressive disclosure is in direct conflict with visibility. Too many times these days visibility is being sacrificed. Users either don’t know about a feature or get frustrated trying to find it. Progressive disclosure is a good tool, but it needs to be used carefully.)

My boss’s answer? The same one Google would come up with. A simple field and search button backed by an engine that would just return the answer the user wanted without the user having to figure out how to properly form the query. No GUI for forming the query. No special syntax for forming the query. Just a box and a button (and a smart engine). He was right.

I loved a to-do list application I used that had a simple text field for deadline. I could type “today”, “tomorrow”, “Friday”, or any number of other simple and direct ways of expressing it and the application would figure out the appropriate date. I was disappointed when the “upgraded” it to a fancy calendar control.

Something similar came up at work recently: Do we give the user a multi-select box full of choices or just a text field to list choices separated by commas? In this case, the text field really was the better choice.

I started this post before I’d seen it, but I am now reminded of Guy Kawasaki’s interview with the author of In Pursuit of Elegance: Why the Best Ideas Have Something Missing.

26 March 2009

Scheme in the browser (again)

I found myself reading “Popularity” over at Brendan’s Roadmap Updates...again.

This time, a comment by Mike Ivanov stood out to me:

It took almost a decade for ‘average developer’ to grok JavaScript. Now it is understood, at least. How much time would pass before Scheme achieved the same level of acceptance? I bet forever.

Which again has me questioning that. I can’t believe that anyone who has really “grokked” Javascript couldn’t have grokked Scheme. After all, Javascript essentially is Scheme with C syntax. Grokking the language behind that syntax is much more difficult than grokking the syntax.

I think that Javascript was in a unique position. I suspect almost no-one learned Javascript for its own sake. People learned Javascript because it was (essentially) the only game in town for the role it played. (Indeed, it is still too difficult, IMHO, to use Javascript outside that role.)

That’s certainly why I learned it. At the time, I would’ve much rather used Perl, but my customers had Javascript built into their browsers. I wasn’t going to ask them to install client-side Perl.

Likewise, I suspect that Javascript is one of those languages that was the first programming language for a lot of people. Those are people who aren’t coming in with syntax-bias.

Which may be pointless speculation, but that’s what thinking-out-loud is for. I still give thanks to Brendan that I’m required to regularly, at work, program in Scheme/Self even if it is with C syntax.

10 July 2008

Programming and chairs

Coding Horror: Investing in a Quality Programming Chair

As much as I’d like to argue that my productivity demands an expensive chair, I have to believe this is an individual thing. The cheap chair in my cube fades away while I code. All the cheap chairs I’ve worked in do. Yet I often find myself sqirming in the Aeron chairs we have in one conference room.

18 January 2008

Tips for interviewing for a C programming job...

Don’t come to an interview for a C programming job if you can’t do simple type analysis. Just stay home. If I ask, “Given void *p, what are the types of the expressions p, *p, and &p?”, you should know the answers. Furthermore, you should know that—in that context—return *p is a compiler error and why. You should not be confused or scared by char **x. You should understand why printf("%p\n%p\n", ((char *) p) + 1, ((char **) p) + 1) prints two different numbers.

06 November 2007

Promoting hardware

Our hardware team has been a big factor in TippingPoint’s success. The other day I was talking with a coworker about some of my previous jobs, & about one he asked if we’d considered custom hardware. As far as I knew it hadn’t been, & I think he was right that it probably should have been. I think software engineers tend to be blind to when hardware should be considered. It just isn’t on our radar except in a few specific cases. (e.g. graphics & cryptography) Even if we know what an FPGA is, & I’d how many of us do? Especially considering how many working programmers these days aren’t even familiar with many important software concepts. But as the more general purpose engineers, who are going to be in on a project first, we really should be on the look-out for hardware opportunities. Hardware engineering needs a good marketing program to get software engineers aware of when it should be considered.

19 October 2007

Inheritance is over-rated

Some more observations based on my experiences with EcmaScript (a.k.a. Javascript) as compared to C++ and Java:

(I suppose I could try to generalize and consider EcmaScript a representative of the Smalltalk tradition versus C++ and Java as representatives of the Simula tradition; but that probably opens a lot of other issues.)

It occurs to me that most classes I’ve written in C++ or Java have not needed inheritance. They provided only encapsulation. (Which I can do just fine in C—no object-orientation required.)

When I have needed inheritance, it has most often been for polymorphism. In EcmaScript, you don’t need inheritance for polymorphism.

(With C++, you can have polymorphism without inheritance, but that requires the complexity of templates. Likewise, in Java you can use reflection to achieve the same sorts of things, but you get more complexity with it.)

Sometimes I’ve abused inheritance in C++ or Java to work around limitations. Such as adding additional methods to an existing class. In EcmaScript, I can add methods to objects (or objects serving class-like roles) directly.

In EcmaScript, I only really need to use inheritance when I need to share an implementation, and that just doesn’t seem to come up as often in my experience.

(Moreover, I find closures—which EcmaScript has but C++ and Java lack—extremely useful.)

Now, there are—of course—trade-offs involved. EcmaScript isn’t all roses by any means. Give it a static debugger (like MrSpidey/MrFlow), and I think it could hold its own versus C++ or Java for many applications.

Give it hygienic macros (on the road-map for Javascript 3) and first-class continuations, and it starts to stack up well against Scheme as well.

08 October 2007

EcmaScript, IF, and DSLs

Since I’ve been programming so much in EcmaScript (a.k.a. Javascript) at work, I decided to install the stand-alone version of Spidermonkey at home. That’s the EcmaScript implementation from Firefox. Partly because I’m interested in being able to write web applications that use the same language on both the browser-side and the server-side.

Of course, there are a few server-side EcmaScript solutions out there, but I’m used to rolling my own light-weight version when investigating such things.

I didn’t want to jump right into that, however, so I tried to come up with an idea for a command-line program I could start with. Spidermonkey comes with a command-line interpreter, but it is very minimal. Hardly more than readline and print.

So, I thought of text adventures (a.k.a. interactive fiction). I had the basics of Cloak of Darkness mocked up PDQ. It went faster and farther than I think any of my other attempts at such a program has gone in any language. My opinion of the EcmaScript is continuing to increase. I began to think I should break out some of my old text adventure ideas.

The thing is, though, I’d have to make some significant enhancements to Spidermonkey’s command-line interpreter to really make it practical for IF. It would make a lot more sense to just use browser-based EcmaScript (instead of command-line) or to use Inform, so that people besides just me could actually play it.

Inform is a DSL (domain specific language) for interactive fiction. That’s fancy computer geek jargon for a language specialized for a specific purpose.

C, C++, Java (no relation to Javascript), Perl, Python, Ruby, Lisp, and Scheme are general-purpose programming languages. They can be used to build programs for a wide range of applications. (Although, certainly, some are better for some applications than others.)

HTML and Postscript are domain specific languages. (Incidentally, HTML is not a programming language, but Postscript is.)

EcmaScript isn’t really a domain specific language, but as it is most widely and most easily used within web browsers, it often tends to be one in practice.

I’m all for DSLs, but the problem I have with most of them is that they’re wholly new languages. Ideally, a DSL—unless really simple—should be an extension or a subset of an existing language. This is the resistance I have towards using Inform.

The Lisp and Scheme advocates like to point out how they often extend their languages to create DSLs within them, which I’m finding to be a very compelling argument.

18 September 2007

And now for something completely different

Wouldn’t you know it! My first attempt to modify a Python program, I get bit by significant white space. I got a syntax error because the editor put a tab character in the file instead of spaces. (>_<) Which is such an esoteric thing I’m not even going to try to explain to the non-programmers.

28 August 2007

Step 3: Profit!

People keep telling me that businesses have only one motivation: Money. I don't buy it. Sure, there are companies that are only motivated by money. There have also been plenty of companies that were clearly not motivated by money at all. (Like...I dunno...a good percentage of the dot-com bust casualties.) In my experience, though, most companies are motivated roughly equally by money & a vision. And it's not just that sticking to a vision may mean more money in the long term. I have seen & been a part of companies deciding to take a course that might mean less (though still positive) profit because it better fits the vision. When it comes right down to it, most entrepreneurs I've known have been more interested in building something--a product & a company. Money is important to them--no doubt about that, but only up to a point. They're driven to work & to build. No amount of money will convince them to retire.

20 August 2007

A cube with a view

I moved into a window cube today. Here's my view of the parking lot.