Max Blog My Blog

8Feb/100

JavaFx vs. MXML syntax and language design

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

16Jan/100

Duck type

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!

24Dec/090

To type, or not to type

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();
    }
  }
}
22Dec/090

Those funny declarations

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.

14Dec/090

If you can’t overload them, namespace them

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 {
		}
	}
}
13Dec/090

The uselessness of static

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.

21Nov/092

You can run and you can hide

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));
14Nov/090

Share your property

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.

8Nov/090

Don’t lose your keys

Every programming language has keywords and AS3 has lots of those. They are even categorized in three groups. Have a look at my favorite website but now under the topic: Keywords and reserved words

You see three categories:

  1. first says - don't you dare to use me in your code in different context as I meant to be
  2. second says - wellll, I am a keyword but only in some context, so do your best
  3. third says - I am not a keyword, but I could be - don't you touch me

So, our conclusions - this code is ugly but correct:

?View Code ACTIONSCRIPT
function get get():int {
    return 0;
}
var namespace : Namespace;

Another logical conclusion from the first group is that packages should not be named as keywords. Because if you have a class in such a package than a keyword will appear in your code as identifier in an import statement. Sadly logic is relative from creative point of view. You can name a sub package "default":

?View Code ACTIONSCRIPT
import my.default.MyClass;

But on the over hand this won't compile:

?View Code ACTIONSCRIPT
import default.MyClass;

:)

7Nov/090

AS3 and the kids

AS3 is a proud holder of three inline languages:

  • XML
  • E4X
  • RegEx

I posted a references to usage of E4X in previous post. And here are two reference for usage of RegEx:

http://donttrustthisguy.com/2008/02/29/utilizing-regular-expressions-in-as3/

http://gskinner.com/RegExr/

But what I would really like to show you in this post is some syntax wonders of inline XML. Have a look at this code:

?View Code ACTIONSCRIPT
<root/*an AS3 comment*/>
    <!-- XML comment--> some text
</{(trace("let's close this tag"), "root")}>

It is compilable code. And yes you can use AS3 comments and XML comments inside of inline XML.
You can also embed inline AS3 inside of inline XML and it will be evaluated at runtime. So the close tag is correct in this example.

I hope the parenthesis syntax is familiar from the previous post.