John Cromartie's Tumblr

May 15

Memoized Blocks in Smalltalk

I came across this post on memoization in Smalltalk by way of this, but it was lacking in actual code!

So, without delay, I fired up Pharo and whipped up an implementation.

It’s very simple, in typical Smalltalk fashion. It’s just a method of BlockClosure:

memoized
    "returns memoized version of an unary function"
    | cache |
    cache := Dictionary new.
    ^ [ :x | cache at: x ifAbsentPut: [ self value: x ] ]

And it’s used like this:

#(1 2 3 1 2 3) collect: [:x | Transcript show: x asString; cr. x + 1] memoized.

That will only display “1 2 3” once in the Transcript, thanks to memoization, and returns the correct result.

Apr 19

What kind of idiot…

…accidentally buys DDR3-1066 (PC3-8500) when he meant to buy PC3-10600 (DDR3-1333)!?

This is why I am not a “hardware guy”. I have no patience for figuring out some rather obtuse and arcane combinations of numbers and letters that mean the difference between a computer working correctly or not working at all. Oh wait. That sounds like code.

Mar 13

Yahoo! Goes Nuclear

Well, we can say without a doubt that Yahoo! is done now. They are resorting to leveraging patents like this:

wireframe of every website ever

This is what anybody developing an ad display system would do. How could any moderately serious site not order ads by their click-through rate or price-per-click? That would be silly to omit, and it’s completely obvious to anybody who has spent any time on the Internet.

Feb 27

What Happened to TileStack?

Every once in a while, a blog post or some article will ignite a HyperCard nostalgia trip among the programming community. Everybody remembers how awesome it was, what was possible with it, and how Apple pulled the plug. Then people start prognosticating on how to build a new and more modern HyperCard, that would be like the original but even more awesome, with features X, Y, and Z, and everybody would love it and be transported back to that magical time again.

Well, I never used TileStack, but it’s gone now. It looks like they tried earnestly to pull it off. Only an insider could offer the real story on why they shut down.

Based on YouTube videos, it looks like TileStack tried to implement HyperCard’s vocabulary of stacks, cards, buttons, fields, scripts, handlers, and functions. They even implemented the HyperTalk programming language, and could even import actual HyperCard stacks.

At the same time, the UI lacks the stripped-down elegance of the original HyperCard, where viewing a card is a no-frills affair, and the card is presented by itself with no fanfare. Editing the card means opening a menu (optionally tearing off a tool palette) and descending, hierarchically, into different levels of detail for the selected element. You go from the card itself, to a button or field’s properties, to the script

TileStack appears to have taken the smartly modal/hierarchical interface of HyperCard and “flattened” it, enshrining modelessness. In HyperCard you open an object’s Info dialog to edit it. In TileStack you simply focus it and use the large dynamic toolbar area above the stack. It is a staggering array of options, where everything is visible all the time, but only a few options are actually available.

Just some thoughts.

This is happening.

This is happening.

Feb 25

Oops! I don’t care!

I’ve left a half-finished pre-alpha thingamajig running at http://smarterseating.com for about 6 months now. It’s actually been running in a Clojure REPL in a SSH session since I first started it. That’s a nice testament to how long a Clojure web app can run, but it’s not the point.

It started when a friend wanted to solve this problem for his wife (a school teacher) and I came up with a solution. I thought I’d throw something out there that just worked, and that this would be some kind of magic kick in the entrepreneurial pants, and I would turn it into something that made money. I thought it would be useful for people who need to seat classrooms, wedding receptions, and other things.

But the thing is, I just don’t care. I don’t have any need for it. I don’t think it’s going to make the world a better place. I don’t have intimate domain knowledge here. The market is probably small.

So, yeah. Don’t do that.

I can see two reasons why I would build something I don’t care about:

  1. Someone is paying me lots of money for it.
  2. Someone will pay me lots of money for it.

So I’ll be recycling this Linode box for some other projects.

Feb 24

Why do remote controls still exist?

The post TV Is Broken reminded me of something that I’ve been thinking about for a while. It’s only tangential to the problem of content on TV.

I don’t buy a lot of consumer electronics, but it so happens that I have six devices that can comfortably browse the web from my couch. They are usually within reach when I’m operating the TV or its cohorts (a receiver/amplifier and a PlayStation 3). Many of the things connected to my TV, including the TV itself, are connected to my home network.

So, why do we still have remote controls? Why can’t I control my interconnected devices with a web interface which advertises itself on my WiFi network (via Bonjour, for example), which my iPad can pick up and browse?

Why can’t I coordinate my media sources and my output options from one device without insane ugly hacks (I’m looking at you, Logitech Harmony)?

There’s probably a big opportunity licensing and implementing something like this for TV and set-top/DVR/game devices.

On to level 4!

level 4 welcome screen

I have to say I’m a little bit proud of myself for figuring out level 3 on Stripe’s Capture the Flag challenge.

Good luck to everybody out there trying this, too.

Jan 28

Struggles and Success With Cygwin

While PowerShell is a great thing for Windows management, it still has a long way to go to catch up with the sheer flexibility of Bash and the staggering array of tools centered around manipulating simple streams of text.

This post on StackOverflow contains a few great bits from different perspectives: even from the creator of PowerShell itself.

I just wanted to share some of the problems that came up with my attempts to integrate various open-source tools into our Windows-based development environment. Finally I’ll share some tips/observations that led to an enjoyable environment.

Problems

Permissions

Easily the most frustrating part of Cygwin is when it attempts to imitate POSIX permissions on NTFS volumes by manipulating the ACLs. Frankly, Cygwin does a terrible job at this. It only serves to cause massive headaches.

TURN THIS OFF before you do anything else in Cygwin.

You can avoid permissions issues by setting up your NTFS mount points with the “noacl” option. This is easily accomplished by configuring them in fstab with the “noacl” option, like so:

none            /cygdrive       cygdrive        binary,posix=0,user,noacl       0       0

This line will cause Cygwin to simply leave the default Windows permissions alone. They are good enough in 99% of cases, and I’ve found that they are better than what Cygwin does to permissions (it’s not pretty) in nearly 100% of cases.

Forking

This is a problem that can be harder to work around, due to the fact that Windows doesn’t allow easy forking of processes. Cygwin’s version is very slow (by necessity). The maximum forking performance of Cygwin is about 2% of my comparable Mac OS X machine’s speed when executing Bash commands in a loop. Here’s a useful mini-benchmark to see for yourself:

while true; do date; done | uniq -c

One way around this limitation is to use a programming language like Perl or Ruby for scripts that need to iterate over large numbers of files, etc.. Ruby has a very handy standard library with good file handling utilities.

Rebasing

Sometimes, after an update, Cygwin programs are not linked correctly anymore. This is solved with a rebase. This operation will update your Cygwin binaries/libraries to be able to find the right functions in linked libraries (like the all-important cygwin.dll).

Background Tasks

The cygrunsrv tool lets you install any cygwin program (script or .exe) as a Windows service. This is a godsend, as you can easily get useful servers like rsyncd, git --daemon, simple Ruby web servers, or any other background task up and running with little trouble.

Ruby

Arguably the best part of Ruby is the RubyGems packaging system. Many of the best gems, however, require native extensions to be built. While some gems have pre-built Windows binaries, many do not. Cygwin makes this easy by making GCC and many of the dependent libraries available. I’ve never run into a gem that couldn’t be built under Cygwin with anything more than grabbing the right libraries through the package manager.

Dec 21

Jenkins, Cygwin, Windows 7, and permissions

Cygwin is a godsend for controlling your workflow and putting together the sort of tools that keep devops humming along. And Jenkins is a great freeform build tool for managing pretty much any software CI/build process.

But Cygwin and Windows permissions don’t always play nicely, especially when you add intermediary processes like Jenkins to the mix. My build scripts were copying various folders into the Jenkins workspace, among other things. However, the files and directories ended up having all sorts of nasty permissions issues. Certain users (like the ASP.NET app pool identity) could not read files, and overall things looked pretty weird.

So, Icacls to the rescue! Right?

icacls the-dir /reset /T /C /Q
... <snip 5000 lines of Access Denied errors>

I was getting “Access Denied” errors on every file in the directory, even when I made sure to run cmd.exe as Administrator. Icacls was not working to take ownership either, so I tried Takeown. It worked to take ownership where Icacls did not.

takeown /F the-dir /R
icacls the-dir /reset /T /C /Q

All is well now. I hope this might help someone with the same issues.