Lazy Evaluation in AS3

Posted by Dan Fast on June 24, 2009 under Flash - 0 Comments

Lazy evaluation is a useful practice for any programmer who wants to cut down on unnecessary processing. There's no need to break it out if it's not necessary; especially if the language (Actionscript) is ill suited to it. There are cases though where delaying computation until the result is required lets lazy evaluation slice off the extra computational gristle that's slowing down my code.
I ran into a situation a few days ago that really benefited from the lazy approach. I had a class named Vector2 which handled 2-dimension computation, as described below.

//Vector2 with Eager Evaluation
public class Vector2 {
	
	private var _x:Number;
	private var _y:Number;
	private var _length:Number;

	public function Vector2( x:Number = 0, y:Number = 0 ) {
		setXY( x, y );
	}

	public function setXY( x:Number, y:Number ):void {
		_x = x;
		_y = y;
		_length = Math.sqrt( _x * _x + _y * _y );  //length is computed as soon as x and y are set
	}

	public function get x():Number {
		return _x;
	}
		
	public function get y():Number {
		return _y;
	}
	public function get length():Number {
		return _length;
	}
} 

The issue arose when dealing with the _length value in a Vector2. The square root in determining the _length of a Vector2 was computationally intensive and often unnecessary. It was a rare occasion when I needed the length of a vector; most of the time I produced vectors for minor computations that never needed a calculation of length. Therefore, I wanted to delay the computation of the length of the vector until it was absolutely necessary.
Simultaneously, I didn't want a getLength() function, because I didn't want to have to recompute the length every time I asked for it. I wanted to compute the length once, the moment I asked for it, and save that result for future references. However, if in the future I changed the _x or _y, I needed some way to tell my program that the length of the vector needed to be recomputed the next time I requested it.
Lazy evaluation magically fulfills all my requirements.

Implementing Lazy Evaluation

Flash is an Eagerly Evaluated language though, how can one implement Lazy Evaluation?

//Vector2 with Lazy Evaluation
//Code not directly applicable to the example has been removed
public class Vector2 {
	
	private var _x:Number;
	private var _y:Number;
	private var _length:Number;
	private var lengthFunction:Function;

	public function Vector2( x:Number = 0, y:Number = 0 ) {
		_x = x;
		_y = y;
		lengthFunction = function() { 
			_length = Math.sqrt( _x * _x + _y * _y ); 
		};
	}

	public function set x( newX:Number ):void {
		_x = newX;
		lengthFunction = function():void {
			_length = Math.sqrt( _x * _x + _y * _y );
		}
	}
	public function set y( newY:Number ):void {
		_y = newY;
		lengthFunction = function():void {
			_length = Math.sqrt( _x * _x + _y * _y );
		}
	}
	public function get x():Number {
		return _x;
	}
		
	public function get y():Number {
		return _y;
	}
	public function get length():Number {
		lengthFunction();    //recomputes the length of the Vector2 if necessary
		lengthFunction = function():void {}    //replaces the length function with an empty function call
		return _length;
	}
}

The Vector2 class written above achieves lazy evaluation through Flash's Function class. When I request the length of my Vector2, the lengthFunction (an object of a function) is called, and the length is returned. The lengthFunction is where all the lazy magic happens.

Whenever the _x or _y value is altered, the lengthFunction is set to Math.sqrt( _x * _x + _y * _y ). Once the length is evaluated however, it reassigns itself to an empty function. Next time I ask for the length of my Vector2, the processor will run through an empty function call rather than the computationally intensive square root calculation.

This class uses a number of getter and setter methods which I have heard are rather slow, but that doesn't detract from the practical merit of this practice. It's like helping a friend move into a new apartment, you have to know when to avoid the unnecessary heavy lifting.

Setting Up a Shared Remote Git Repository

Posted by Ryan Coyner on May 25, 2009 under Git - 0 Comments

Here is a good article on setting up a new remote git repository. Here are additional steps to create a shared repository which allows multiple users to contribute to the same repository. First, add sharedrepository = 1 in the config file of the repository:

[core]
    repositoryformatversion = 0
    filemode = true
    sharedrepository = 1

Create a new system group for users who should have access to the repository. Add the users into the group:

$ groupadd git
$ gpasswd -a ryan

Next, set up secure permissions on the repository. Start by changing the ownership of the files in the repository to root and the group specified above:

$ cd /var/git/project.git
$ chown -R root:git .

Remove access to the repository from everybody except the user and group:

chmod -R o-rwx .

The group should have the same permisisons as the user:

chmod -R g=u .

Add the s flag on the group permissions for all directories in the repository. This will give processes that tries to access the directories the necessary privileges to add and modify content within the directories. This is necessary to allow multiple external users to commit to the repository:

find . -type d | xargs chmod g+s

That's it. The repository should be set and good to go.

Delay Function Call in AS3

Posted by Dan Fast on April 13, 2009 under Flash - 1 Comment

I have a confession to make - I've been seeing another language.
I'm sorry AS3, but Scheme is just so much more elegant that you.

I've decided to focus more on the functional aspects of AS3 after fooling around with Scheme for the last semester or so. All of what I'm about to say could be done with more explicit objects, but I think that would be masking the idea behind this code.

I'm working on a new game where a little man on a raft is hunted by God. God, in his old testament (and vaguely Zeusish) rage, hurls bolts of lightning, summons storms, and calls really enormous fish to smite this poor little dude. I wanted my lightning strikes to come in delayed intervals (first bolt at 1 second, second bolt at 3 seconds, etc... ), but I didn't want to explicitly call a timer every time. I wanted a more general solution to the problem. Then I found out that AS3 was pretty good at passing functions as objects.

Code

The following code sets up our example. Cut and paste it into the timeline to run it.
//Create a new Sprite that is a child of the stage
Var testSprite:Sprite = new Sprite();
addChild( testSprite );

//draw a rectangle in the sprite
testSprite.graphics.beginFill( 0x0000FF, 1 );
testSprite.graphics.drawRect( 0,0, 200 200 ); //the function we're going to delay
testSprite.graphics.endFill()

Now we're going to delay the function call drawRect(...). Replace your previous code with the following.
The Function object has an .apply function, which takes the object the function is called on, and the arguments (in the form of an array) passed to that function.

//Create a new Sprite that is a child of the stage
Var testSprite:Sprite = new Sprite();
addChild( testSprite );

//draw a rectangle in the sprite
testSprite.graphics.beginFill( 0x0000FF, 1 );

//you'll notice that we're not calling the function, just passing its reference.
Var delayFunction:Function = testSprite.graphics.drawRect;  

//the arguments provided for the function
var arguments:Array = [ 0, 0, 200, 200 ];

//a simple timer to delay the function call
var timer:Timer = new Timer( 1000, 1);
timer.addEventListener( TimerEvent.TIMER, runFunction );
timer.start();

//our function that listens to the timer, waiting for it to ring before running
protected function runFunction( event:Event ):void {
			
	delayFunction.apply( testSprite.graphics, args );
	testSprite.graphics.endFill()
			
}

Warnings about this method of programming. Make sure your object doesn't get dereferenced between when you create the function and when it gets applied (that should throw you some errors). Now for the more general case. Here is a little class I programmed that delays function calls.

package {
	
	import flash.events.Event;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
	/**
	 * Delays before running the function
	 * @author Daniel Fast
	 */
	public class WaitThenDo {
		
		protected var timer:Timer;
		
		protected var delayFunction:Function;
		protected var args:Array;
		protected var obj:Object;
		
		/**
		 * delay a number of seconds before running the function
		 */
		public function WaitThenDo( func:Function, obj:Object, args:Array, delay:Number, repeat:Number = 1 ):void {
			
			this.args = args;
			this.delayFunction = func;
			this.obj = obj;
			
			timer = new Timer( delay * 1000, repeat );
			timer.addEventListener( TimerEvent.TIMER, runFunction );
			timer.start();
			
		}
		
		protected function runFunction( event:Event ):void {
			
			delayFunction.apply( obj, args );
			
		}
		
	}
	
}

Recent Entries

6/24/09 - Lazy Evaluation in AS3

5/25/09 - Setting Up a Shared Remote Git Repository

4/13/09 - Delay Function Call in AS3

4/13/09 - Formatting a USB Stick in Arch Linux

2/22/09 - Django Benchmark: mod_python vs. mod_wsgi

Recent Comments

5/12/09 - Delay Function Call in AS3

4/22/09 - Formatting a USB Stick in Arch Linux

4/12/09 - Building Packages in Arch Linux

1/25/09 - Backup and Synchronization with Git

1/17/09 - How User Interfaces Ruined My Life

Delicious