I don’t think I would write something new to this topic because this year I kind of changed my sphere of action.

And to summarize the category I would like to post a link to the talk I gave on Adobe User Group Nederland.

It’s kind of embarrassing for me, because this video doesn’t put my presentation skills at the glance, but the content is quit interesting in my opinion. It is quit long though, it was a strange slot on this conference I got two hours. Too short for a tutorial and pretty long for a talk. But enough with explanations, here it is:

http://www.adobeusergroup.nl/site/list_messages/391

After watching this talk :
http://www.infoq.com/presentations/Design-Your-Own-DSL-with-Groovy

I remembered that I wanted to write about internal DSL in ActionScript.

So first of all what is DSL (for those who are to lazy to follow the wikipedia link)

DSL (Domain Specific Language) is a language that you use for some specific type of problems.
For example you want to draw stuff. You know that if you want to draw something you have to declare a shape that is described by points. The language you create for this one and only problem, should be very specific and clear, so that it is fun to read and write.

There are two ways of creating a Domain Specific Language and also two types of DSLs.

External DSL is a language with natural language syntax that you have to parse by RegEx or a parser.

Internal DSL created by appliance of the language you write this DSL with.

In the talk I have mentioned above, the speaker describes what are the possibilities to create an internal DSL with Groovy, and it is pretty cool ;) .

In my opinion ActionScript provides you with three posibilities of creating a DSL:

First: XML
If you think about it, MXML is also an internal DSL written in XML and read by MXMLC compiler. You could write a framework that could read XML and process something out of this. For example painted something on the stage.

<shape>
  <point x='10', y= '20'/>
  <point x='30' y='40'/>
  <point x='25 y='25'/>
</shape>

Second: Plane Text
Write your domain specific stuff in plain text and parse it with RegEx. Natural language is alway easier to read and write if you describe some simple rules or state.

Third: Object initializer
In my opinion it is the powerful one, because you can add behavior to your DSL

?View Code ACTIONSCRIPT
  var shape = {
     points: [
        {x:10, y:20},
        {x:30, y:40},
        {x:25, y:25}
     ],
     onClick: function(){
          trace(this.points)
     }
  }

As you can see you could create a framework as powerful as Flex that works on DSL created with object intializer syntax, that would look JavaFx like ;) .

Both languages are designed for UI declaration.

MXML is XML based representation of UI tree. Each XML tags represent UI components implemented in AS3 and you have many possibilities to embed AS3 code in MXML. Under the hoods the compiler will generate a number of AS files from one MXML file and compile them to a Flash Application (SWF file).

JavaFx is a complete new script language with AS3 like syntax. The representation of  UI tree is JSON like, so it’s not as verbose as XML. I am not familiar with the internal processing of “fx” scripts but after compilation you get a few “.class” files that represent the elements you declared in the script.

JavaFx is just a script language for JVM, like for example Groovy, that has some special tools for UI creation.

In my opinion those are the key benefits compared to ActionScript 3:
- Function signatures are strong typed

function(:Number):Boolean

- Static is banned in favor of Script Variable / Function
- Ranges are provided

for (x in [1..5]) {
   [x, x*x]
}

- first citizen value changed observer

var x = 0 on replace { println("x is now: {x}") }

- first citizen value binding

var y = 3;
function ten() : Integer {
   println("Called ten");
   10
}
def sum = bind ten() + y;
println(sum);
y = 7;
println(sum);

-immutable objects and elements
-Bidirectional Binding

If you are interested in details have a look at this URL:
http://openjfx.java.sun.com/current-build/doc/reference/JavaFXReference.html

A few weeks ago I was watching this talk. The speaker persuaded everybody to check out Erlang. I already heard about this language because of it’s concurrency paradigms, so I thought to give it a try.

After browsing thru the specs I found an interesting construct: Pattern and Guard.

It reminded me a little of my Duck class that I wrote for BehaveAS. Th idea behind Duck was to define expectation return value in a simple internal DSL manner.
So for example I am expecting that an array will have three entries and I am only interested in second item. Or a better example when I expect an exception with a certain error id. It’s quite complicated to do this stuff without Duck :) .

Here is an example of use:

?View Code ACTIONSCRIPT
package {
  import mz.behaveas.model.ducktype.Duck;
  import flash.display.Sprite;
 
  public class DuckTypeTest extends Sprite {
    public function DuckTypeTest() {
      var a : * = 23;
      var duck : Duck = Duck.type({_type_:String, toString:"23"});
      if(!duck.equals(a)){
      	trace((duck.getReport()));
      }
      var a1 : Array = [1,2,3,"asd"];
      var duck1 : Duck = Duck.type({1:2, 3:Duck.type({_type_:String,toUpperCase:"ASD"})});
      if(!duck1.equals(a1)){
      	trace((duck1.getReport()));
      }
    }
  }
}

As you can see you can also check methods for those return values (but only if those methods doesn’t need parameters ;) ).

So back to Erlang, Pattern and Guards. I thought it would be a great idea to use Duck as a Guard for input parameters in a function.

?View Code ACTIONSCRIPT
function foo(a: Array):void{
  var matcher : Duck = Duck.type({length:3});
  if(!matcher.equals(a)){
    return;
  }
  trace(a[2]);
}

But I am not sure about performance!

Static typing is a great thing. It makes a really good IDE support possible. It’s encourage you by developing, because your code is validated by compiler and you can write intuitive API’s.

But some times it is also cool to have dynamic typing.

AS3 is a very creative language also from this point of view. It let’s you extend code in many ways.
First and most convenient way is class inheritance. So you have a class A and it is extended by class B. Nothing special it is a rudimentary feature of an OO language.

Second and not convenient way of extending an instance of a class is to declare the class as dynamic (have a look at Object class).

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class MyClass extends Sprite {
    public function MyClass() {
      var a : Object = new Object();
      a.element = 30;
      trace('a.element: ' + (a.element));
    }
  }
}

But you can also extend a class that is final or not dynamic in AS3, because AS3 is not only Class based OO language but also Prototype based. That’s how we can implement so called monkey patching.

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class MonkeyPatch extends Sprite {
    public function MonkeyPatch() {
      Object.prototype.sayHello = function():void{trace("hello from " + this);};
      var myThis : * = this;
      myThis.sayHello();
      var s : Sprite = new Sprite();
      addChild(s);
      var myS : * = s;
      myS.sayHello();
    }
  }
}

When you declare a local variable in AS3 it turns out that it is visible for the hole scope it was declared in.
So for example you can declare a variable after its usage in code:

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class Decl extends Sprite {
	public function Decl() {
	  trace(a);
	  var a : String = "hello";
	}
  }
}

But the assignment will be executed as “expected” after the trace and that’s why you see “null” traced in the console.

You can also make a duplicate declaration of a local variable, if it keeps the same type.

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class Decl extends Sprite {
	public function Decl() {
  	  var a : String = "hello";
	  trace(a);
	  var a : String = "hello2";
	  trace(a);
	  // var a : int = 2; That would be bad!
	}
  }
}

Another interesting declaration behavior is the declaration of error variable in catch block:

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class Decl extends Sprite {
	public function Decl() {
	  try{
		trace(a);
		a.length;
		// trace('error: ' + (error)); Invisible			
	  }catch(error:Error) {
		var a : String = "error";
		trace('a: ' + (a));
		trace('error: ' + (error));
	  }
	  trace(a);
	  // trace('error: ' + (error)); Invisible
	}
  }
}

So error is only visible in the catch scope but the catch scope is not really a scope because if we declare variable “a” in the scope itself it is visible in the whole method.

Last funny example is about for-loop and static initializer.

?View Code ACTIONSCRIPT
package {
  import flash.display.Sprite;
  public class Decl extends Sprite {
    static var array = [1,2];
    for (var i : int = 0;i < array.length;i++) {
      trace(array[i]);
    }
    public function Decl() {
      trace(i);
    }
  }
}

The problem with this code is that variable “i” is declared inside of class declaration and that means that it is a field. It also not declared with static modifier and that’s why you can’t use it in your static initializer code.

ActionScript3 does not support method overloading, but why do you want to overload methods?

In my opinion there are two answers:

  1. You want to pass the same method different amount of parameters
  2. You want to have methods with same name but different behavior

In first case AS3 provides you the feature of default parameter values:

?View Code ACTIONSCRIPT
function foo(var a : String, var i : int = 0): void{
  for(;i&lt;=0 ; i++){
    trace(a);
  }
}

So you can call method foo with one parameter “foo(‘hello’)” or with two “foo(‘hello’, 2)”

Let’s talk about the second case: same name different behavior.

In this case you can use namespaces.

?View Code ACTIONSCRIPT
package my {
 
	public class NamespaceExamp {
 
		namespace NS1;
		namespace NS2;
 
		NS1 function foo() : void {
		}
		NS2 function foo() : void {
		}
	}
}

The interesting part of namespaces is also that those are not declaration but URI based (like in XML).

Have a look at this example:

?View Code ACTIONSCRIPT
package my {
 
	public class NamespaceExamp {
 
		namespace NS1 = "myNS";
		namespace NS2 = "myNS";
 
		NS1 function foo() : void {
		}
		NS2 function foo() : void {
		}
	}
}

In this case foo is a duplicate method and it doesn’t matter that we declared two namespaces, their URIs are same so both foo declarations are in the same namespace. BTW if you don’t declare URI explicitly as in the first namespace example than the runtime will generate a namespace by the location of declaration (complicated stuff).

Another interesting fact is that the keyword “public” is also a namespace, but with empty URI.

So this is also a duplicate declaration:

?View Code ACTIONSCRIPT
package my {
 
	public class NamespaceExamp {
 
		namespace NS1 = "";
 
		NS1 function foo() : void {
		}
		public function foo() : void {
		}
	}
}

ActionScript 3 has a keyword static that turns methods, fields, getter and setter into class members (not instance members).

It is a useful feature in languages as Java, where you have no top level functions and variables (btw. in JavaFX static is deprecated).

AS3 has both – static members and top level functions/variables (as JavaFX), so it is kind of an overkill in my opinion.

If you want to have a structural aggregation you can put all top level functions/variables in a special package.

For example there is a convention in CoreLibrary for constant carriers (have a look at the “StageAlign” class in “flash.display” package).

These carriers represent the possible input values for a property of a class. In the case of “StageAlign” it is the property “align” of the class “Stage”. (btw. FDT has a special auto completion for this conventional constant carriers)

It is possible to place all these constants in a package “flash.display.Stage” so you don’t have to write :

“StageAlign.LEFT” but just “ALIGN_LEFT” for example.

First of all let me introduce you the “Compilation Unit”. Compilation unit is the smallest code entity that can be compiled properly (to SWF file).

In ActionScript3 those entities are “as” or “mxml” files. (I skip “mxml” because it’s own topic )

The “as” files must be structured as following to become a compilation unit:

–Package declaration
— Class | Interface | Function | Variable | Constant | Namespace declaration
—- (if Interface) Method | Getter | Setter declaration
—- (if Class) Method | Getter | Setter | Constructor | Field | Constant | Namespace declaration
-Local Class | Interface | Function | Variable | Constant | Namespace declarations

So you need a package declaration with an element inside to make it a compilable entity

?View Code ACTIONSCRIPT
package {
  var a;
}

And you can hide declarations from anybody when you put them outside of package declaration

?View Code ACTIONSCRIPT
package {
  public const KingOfPop : Michael = new Michael();
}
class Michael{
  public function dance() : String {
    return "Moon Walk";
  }
}

By the way this is the one and only good implementation of Singleton Pattern in AS3.

But it’s not what I want to show here. What I want to show is that my first definition of compilation unit was wrong because you can write statements between listed declaration and those will be executed as static initializer code.

So check this out:

?View Code ACTIONSCRIPT
package{
  trace("A");
  import flash.display.Sprite;
  trace("B");
  class Test extends Sprite{
    trace("C");
    public function Test(){
       trace("D");
    }
    trace("E");
  }
  trace("F")
}
trace("G")

Can you tell what will be traced? :)

Last but not least conclusion – with this info in mind you can use AS3 as a “real” script language:

?View Code ACTIONSCRIPT
package{ import flash.display; class A extends Sprite}
var a = 10;
var b = 20;
trace("a+b="+(a+b));

Classes in AS3 do have Properties but with some limitations. This code will compile fine:

?View Code ACTIONSCRIPT
package {
  public class ClassA {
 
    var _max : String;
 
    public function get max() : String {
      return _max;
    }
 
    private function set max(max : String) : void {
      _max = max;
    }
  }
}

But this won’t:

?View Code ACTIONSCRIPT
package {
  public class ClassA {
 
    var _max : String;
 
    public function ClassA() {
      trace('max: ' + (max));
    }
 
    public function get max() : String {
      return _max;
    }
 
    private function set max(max : String) : void {
      _max = max;
    }
  }
}

Looks like if you mix property visibilities you can’t refer to it any more.

© 2011 Max Blog Suffusion theme by Sayontan Sinha