AlecMcE.com

Coding on the Flash Platform

AS4 Thought Experiment

View Comments

Introduction

At the end of last week, parts of the Flash community engaged in a twitter-based reflection on the state of ActionScript. Twitter isn’t the best forum for analysis, but it’s a fairly powerful tool for gauging perspectives, and it ought to cause Adobe some alarm that there was a significant body of notable Flash developers out there who feel that Flash is in danger of falling behind the likes of Silverlight and HTML5.

Part of this reflection was a consideration of the evolution of the language syntax; considering the question ‘What should AS4 look like?’. In one post Robert Penner (@robpenner) suggested an ActionScript syntax modification. This AS3

element.addEventListener(Event.CHANGE, onChange);

should be expressible as

element.change += onChange;

Penner argues that the event model has become unwieldy, and required pruning. He offers a solution that looks more like AS1, but keeps the concept of adding a stack of listeners to an event.

The elegance of the change ought to be apparent to everyone who has read this article so far. I want to consider it in more detail.

Missing Parameters

Let’s take this idea on a few stages, starting with the missing parameters. Years ago now, Grant Skinner (@gskinner) identified the problem with strong event listeners preventing garbage collection from doing its job. We may also want to add event listeners in the capture phase of the event, and give it a priority.

element.addEventListener(Event.CHANGE, onChange, false, 0, true);

We need to be able to make these tuning modifications. Would it be better to do

element.change += onChange, false, 0, true;

or simply one of

element.change.add(onChange, false, 0, true);
element.change.addEventListener(onChange, false, 0, true);

and accept that in the more complicated case, you don’t use the += operator? If so, then it’s a shame because as a matter of principle, I never define an event without setting the event listener as weak, so that I never need concern myself with the problems Skinner identified.

From Natural Language

Our Object-Oriented Programming languages borrow from our natural language. The objects of our language are given natural language labels (nouns) as we code, while their methods expose behaviours (verbs). It is preferable to express object.getURL() as object.url, because a url is a property of Object, and is used as a noun in code, not as a verb. object.load() clearly triggers something to be loaded, load is the verb; object.load without brackets feels wrong because it’s a verb but isn’t being used as a verb.

Events are problematic. If you have two classes, Line and Screen and you want to code a relationship such that when your line changes, the screen updates, you will inevitably use ‘change’ as both a verb and as a verbal noun.

Here I’m referencing the change but I wouldn’t expect the change to be triggered. This is when I’m using the name of the event as a verbal noun:

element.change += onChange;

but I could also imagine doing this

element.change(data);

since change is a verb, and that’s what you do with verbs. I would assume that the change is triggered by this syntax, since calling the method means the object ‘does’ the change.

I am uncomfortable having events expressed in the same way as other properties and methods. It might seem more simple to treat them as the same as other members in an object over the short term, but these sorts of distinctions exist in language because they are useful.

Following the example of namespaces and XML parsing, why not just find a different symbol for expressing the particular type of relationship? What about:

element#change += onChange;
element#change(data);

The hash (or whatever) would indicate that the string following is an event, not your common all-garden member variable or method.

A Fanciful Implementation

Staying within this thought experiment, I don’t want a definition of an event in code to be the same as defining a member variable, because they are different and particular things.

I also want to be able to trigger an event as parsimoniously as I can add and remove listeners to it. Above I suggested that you can use ‘change’ as a method (as a verb) as well as a property (as a noun). Why not make that the mechanism for dispatching an event?

public class Dragger extends Sprite
{
	private var startingPosition:Point;

	public event drag:DragEvent;

	public function Dragger()
	{
		#press += onDragStart;
	}

	private function onDragStart(event:MouseEvent):void
	{
		startingPosition = new Point(event.mouseX, event.mouseY);
		#mouseMove += onDrag;
		#release += onDragEnd;
	}

	private function onDrag(event:MouseEvent):void
	{
		var dX:Number = event.mouseX - startingPosition.x;
		var dY:Number = event.mouseY - startingPosition.y;
		#drag(dX, dY);
	}

	private function onDragEnd(event:MouseEvent):void
	{
		#mouseMove -= onMove;
		#release -= onDragEnd;
	}
}

Summary

This is, of course, a thought experiment, and reflection. The code has not been considered for a long time, and it probably won’t withstand scrutiny. However, the Flash community is considering making adjustments to a language, and I don’t see why we would constrain ourselves to considering changes that are minimal or conservative! I am interested by the change Penner suggested, and would love to hear what you think about my extension of that thought.

Written by alec

August 10th, 2009 at 12:18 pm

Posted in opinion

Tagged with ,

  • Thanks for all the feedback. There seems to be a consensus that ActionScript should be following C#'s lead for the event model. I agree with the sentiment, and probably got a bit carried away with my desire to reflect natural language into coding.

    Simone, while I'd love to overload operators, I'm a (sort-of) mathematician! I am a bit worried what over-zealous library creators would do with the ability to make % stand for anything they like. Code readability is bad enough in the Flash community as it is.

    One more thing:

    I notice that in editing I didn't follow through on my Line and Screen argument fully.

    I was thinking that in code we do the equivalent of saying "when the line changes, screen should do such and such...". In this case, 'changes' is being used as a verbal noun. The code equivalent is adding an event listener.

    Then, when the line actually changes you want to say "the line has changed". The code equivalent is dispatching an event.
  • What about introducing operator overloading in AS3 like you can find in C++?

    so then you can customize how you want to add event listeners :)

    maybe is not a great idea because we don't end up with a standard solution but I think it will give AS3 developers more freedom.
  • @Ben, can you elaborate one how the AS3 event system is more powerful than in C#? Is it the weak references and priorities?
  • @robpenner Thanks for the comment. I agree, weak listeners should be default, wonder if designers agree/care? http://bit.ly/UFCAa


    This comment was originally posted on Twitter

  • This += idea stemmed out of the "maybe use C# instead of AS3 in Flash." The benefit to that would be having access to a mature implementation of stuff like this that has been beaten on for a few years by a few hundred thousand people.

    For reference, C# delegates are described here: http://msdn.microsoft.com/en-us/library/ms17317...

    The AS3 event system is actually quite a bit more powerful, but they could still use +=/-= for the trivial case. And having delegates would be a great language building block. :)
  • I commented on “AS4 thought experiment” with events by @alecmce. Opt. addEventListener() args are annoyingly ordered. http://bit.ly/UFCAa


    This comment was originally posted on Twitter

  • Hi Alec,
    Great article, love the creative thinking. The #event syntax is clever.

    Line 4 is a bit too weird for me:

    element.change += onChange, false, 0, true;

    We could try to cut down on those arguments in a couple of ways.

    The useCapture Boolean is only relevant to DisplayObjects, and it's unfortunate that useCapture is enshrined in addEventListener() for all events. The event type itself could signal whether useCapture can be toggled or not. I.e., the compiler could know that MouseEvent and other DOM events can bubble. For custom events, useCapture should get out of the way.

    Also, it would be great if the useWeakReference default could be set in your event declaration. So you could make your choice and not have to pass three parameters just to change useWeakReference every time.
  • RT @alecmce: Just posted an as3+ thought-experiment extending idea @robpenner had re: events. http://bit.ly/WrWT0


    This comment was originally posted on Twitter

  • Actually this is similar to what C# does I think. That's where I assume the call for += syntax originally stemmed from too.
  • How about introducing an EventHandler object which decorates the handling function. Then an event setter would look to take either a function (which it would wrap in an EventHandler object internally) or an EventHandler object directly.

    element.change += onChangeHandler;
    element.change += new EventHandler(onChangeHandler, false, 0, true);

    Really not thought about the logistics of this too much, but creating a type would bring obvious flexibility.
  • RT @alecmce: Just posted an as3+ thought-experiment extending idea @robpenner had, pls knock down! http://bit.ly/WrWT0


    This comment was originally posted on Twitter

  • Just posted an as3+ thought-experiment extending idea @robpenner had, hope I’ve not distorted too much, pls knock down! http://bit.ly/WrWT0


    This comment was originally posted on Twitter

blog comments powered by Disqus