alan dipert RSS

github / twitter / resume / email
Mar
10th
Wed
permalink
Comments (View)
Mar
8th
Mon
permalink

NCSA Mosaic on Github

NCSA Mosaic 2.7 viewing GitHub.com

In 1994, when I was in fourth grade, my dad brought me along with him to see a friend of his in the CS department at the University of Buffalo.  My dad’s friend, Bill Rapaport, was running NCSA Mosaic on a Sun workstation.  I vividly remember the moment he brought up the Louvre’s website and a beautiful full color image of the Mona Lisa was magically beamed across the ocean from Paris, and onto the screen.

My dad had shown me gopher before, but nothing was ever in color.  In fact, everything I’d seen about computers up to that point seemed pretty boring.

The moment I saw the Mona Lisa in full color on a computer monitor was one of only a handful of moments that led me to where I am now, which is a state of continual curiosity and wonder about these things, these machines, these computers.

Thanks in great part to the work of others, I was able to pretty easily get Mosaic to compile and run on my machine, and to relive for a moment my childhood renaissance.

What is the Mosaic, the Mona Lisa, that we can show children today?

If you’re on GNU/Linux-Ubuntu (or something else, and you know your way around your package manager) you can compile and run NCSA Mosaic yourself: http://github.com/alandipert/ncsa-mosaic

Comments (View)
Feb
13th
Sat
permalink
Comments (View)
Jan
30th
Sat
permalink

Rich Hickey talks about the Clojure in Clojure project

Comments (View)
Jan
17th
Sun
permalink

Passing Methods like Blocks in Ruby

Ruby’s Functions

Ruby has four flavors of function, each with various nuances: methods, blocks, Procs, and lambdas.

A Simple Example

The object Array has a bunch of methods on it that take blocks.  Normally, you write these blocks inline:

[1,2,3].map{|x| x+1} # → [2,3,4]

But what if you have a method you’d like to pass to map?

def addone(n)
  n+1
end
[1,2,3].map(addone) # → Doesn't work

The above example doesn’t work because map is expecting a block.  We’re not passing it one; instead, we’re invoking addone with no arguments and attempting to pass the result of that invocation to map.

To get a value representing the addone method, we can use Object.method, which takes the symbol of the name of the method as an argument:

def addone(n)
  n+1
end
[1,2,3].map(method(:addone)) # → Still doesn't work

That still doesn’t work, but we’re close.  Map expects a block, but we’re passing it a Method. The key to this conversion is the unary ampersand &, which will convert anything to a Proc that has a to_proc method, and then convert any Proc to a block.

Let’s give it another shot:

def addone(n)
  n+1
end
[1,2,3].map(&method(:addone)) # → [2,3,4]

Voila! The point? This is just another way to consolidate and modularize code.  If you find yourself writing the same block over and over, and if it makes sense, you can write a method and reference to it.

Getting Complicated

Here’s a Polish notation calculator that groups operators and arguments as S-expressions, with Arrays:

def evl(exp)
  if exp.is_a? Array
    exp.slice(1..-1).map(&method(:evl)).inject(exp.first)
  else
    exp
  end
end

evl(3) # → 3
evl([:+, 4, 5]) # → 9
evl([:+, 1, 2, [:-, 10, 7]]) # → 6

If the input to evl is an Array, evl maps every element of the Array except the first to itself, and then reduces the resulting Array with the first term, which should be a Symbol representing a binary function.  evl takes advantage of the fact that inject automatically casts Symbols to blocks.

This example is different from the one above, in that &method(:evl) occurs inside of evl, which doesn’t actually work in Ruby 1.8.7.  It seems to work in 1.9.1, though.

Comments (View)
Jan
13th
Wed
permalink

Lazy Sequences in Javascript

I’ve played around a bit more with the Lazy Function Definition pattern I mentioned in my last post, and implemented a Javascript object for creating lazy sequences.  Here’s what the fibonacci sequence looks like, a nearly direct port (minus destructuring) of Christophe Grand’s Clojure version:

function fibo() {
  return new LazySeq(
    function(pair){
      return [pair[1],pair[0]+pair[1]];
    },
    [0,1])
    .map(first);
}

fibo().take(10);
//0,1,1,2,3,5,8,13,21,34

LazySeq.map is itself lazily applied, and values are only actually “realized” with either LazySeq.take or LazySeq.nth.

For the LazySeq code, check out the Gist.  It doesn’t include my crappy Array.prototype.reduce implementation, but you could easily substitute in Underscore.js’s reduce.  Happy Javascripting!

Comments (View)
Jan
12th
Tue
permalink

Lazy Function Definitions and “Undo” in Javascript

Implementing Undo/Redo in Javascript

I’ve been working on a Javascript project for class that includes “undo” functionality.  ”Undo” is a feature I take for granted in many different applications, but it’s a really interesting problem and has been really fun to implement.

My approach uses what I call an “Agent,” an object that wraps some piece of data.

Agents provide undo(), redo(), and apply().  apply() takes an object with two function properties as its argument:

  • .apply(): A function taking one argument, the data, and returning the changed data.  Stored on the “redo” stack inside of the Agent, and run immediately.
  • .unapply(): A function taking one argument, the data, and returning the changed data.  Stored on the “undo” stack inside of the Agent.

So, to change the data inside the Agent you supply the Agent with a function to change it, and a function to change it back.  By storing these two functions on stacks internally, undoing or redoing is as simple as popping previously stored functions from their respective stacks and executing them.

My whole approach here was influenced heavily by Rails migrations, which accomplish basically the same thing.  More generally, what I have going is a memento pattern.

Lazy Function Definitions

Because the state of the application might have changed since .apply() and .unapply() were passed to the Agent for storage, it was important that they contained enough information about the application’s state when they were first run to successfully run again later.

Luckily, there’s a way in Javascript to describe a function that can “cache” values.  The first time these kinds of functions are run, they do something and store it.  The next time they’re run, they use the cached value.  The pattern is called Lazy Function Definitions, and I didn’t invent it.  But here’s an example, courtesy Peter Michaux:

var foo = function() {
  var t = new Date();
   foo = function() {
    return t;
   };
  return foo();
};

“When foo is called the first time, we instantiate a new Date object and reassign foo to a new function which has that Date object in it’s closure. Then before the end of the first call to foo the new function value of foo is called and supplies the return value.”

Lazy Undo/Redo

Instead of creating a new Date(), my application reaches into the DOM API to fetch some user inputted value from a text box.  Because the contents of this particular text box will change over the application’s lifetime, it’s important I only fetch it once.

Here’s what calling Agent.apply() looks like, using a lazy function definition:

agent.apply({
  "apply" : function(node) {
    var cachedValue = document.getElementById('newText').value;
    this.apply = function(node) {
      return node.appendChild(makeElem(cachedValue)).parentNode;
    }
    return this.apply(node);
  },
  "unapply" : function(node) {
    return node.removeChild(node.childNodes[node.childNodes.length-1]);
  }
});

Javascript is Cool

Javascript is a really fun language.  To see this all in action, check out my undo/redo demo.

Comments (View)
Dec
30th
Wed
permalink
Good coders are a special breed of persistent problem-solvers who are addicted to the small victories that come along a long path of trial and error.
Comments (View)
Dec
29th
Tue
permalink

Polyglot Folding (Ruby, Clojure, Scala)

fold in a nutshell

It’s common to use the fold family of higher order functions (inject, reduce, and friends, depending on the language) to “reduce” some sequence to a single value through sequential application of a function taking two arguments.  It’s often used to do things like sum an array of integers.  Because this usage is so common, fold is often thought of as a “destructive” or “information-losing” operation.

It doesn’t need to be.  Below you’ll find examples offered up in Ruby, Scala, and Clojure that demonstrate use of an explicity supplied accumulator value.  This technique allows for more powerful folds and serves as a way to more concisely write what in imperative languages would involve a loop and a temporary variable.

This post is probably more for me than for you, but I hope you enjoy it nonetheless, and I welcome comments and suggestions.

Read More

Comments (View)
permalink
lemonodor:

Spotting a hidden handgun.  From Aaron.

lemonodor:

Spotting a hidden handgun.  From Aaron.

Comments (View)