Posts about flex

Flex Compiler Slower on 64bit Mode Java on Snow Leopard

Ever since I upgraded to Snow Leopard, the my flex apps seemed to compile slower. Today, I finally had enough and took a look into this problem. First, there was the weirdness with Java on Mac in that even though the compiler is a command line application(non-GUI), it creates a application menu. I cracked open the mxmlc script, and added:
-Djava.awt.headless=true
to VMARGS. This solved that issue, but didn't make it compile much faster.
Then, after a bit of fiddling around, it turned out that putting java into 32bit mode:
-d32
fixed the problem! The difference was significant. I tested this in 2 different apps. For App 1, it took 45 seconds to compile on 64bit mode, only 9 seconds on 32bit mode. For App 2, it took 30 seconds on 64bit mode, only 7 seconds on 32bit mode. So, mxmlc performs 4-5 times slower on 64bit java than 32bit, java. Why would this be the case, I have no idea. If anyone has an idea, I'd love to be enlightened. If you come across this problem, the fix is to open up mxmlc, and edit the line that says:
VMARGS="-Xmx1024m -Dsun.io.useCanonCaches=false"
and change it to:
VMARGS="-Xmx1024m -Dsun.io.useCanonCaches=false -Djava.awt.headless=true -d32"
I hope that helps someone.
Posted by Toby 3 months ago about flex and programming (0 comments)

Adding Real Properties to FABridge

Although FABridge is a nice tool, it's got its shortcomings. I am going to fix one of them now, namely that it doesn't give you real properties, but uses Java's getter setter convention instead. In 3 out 4 browsers, the __defineSetter__ and __defineGetter__ methods are already usable, so why not take advantage? It's really easy as it turned out. Change the addPropertyToType method to:
    addPropertyToType: function(ty, propName)
    {
        var c = propName.charAt(0);
        var setterName;
        var getterName;
        if(c >= "a" && c <= "z")
        {
            getterName = "get" + c.toUpperCase() + propName.substr(1);
            setterName = "set" + c.toUpperCase() + propName.substr(1);
        }
        else
        {
            getterName = "get" + propName;
            setterName = "set" + propName;
        }
        function setter(val)
        {
            this.bridge.setPropertyInAS(this.fb_instance_id, propName, val);
        }
        ty[setterName] = setter;
        function getter()
        {
            return this.bridge.deserialize(this.bridge.getPropertyFromAS(this.fb_instance_id, propName));
        }
        ty[getterName] = getter;
        if (ty.__defineGetter__)
            ty.__defineGetter__(propName, getter);
        if (ty.__defineSetter__)
            ty.__defineSetter__(propName, setter);
    },
 And..., voila! You got yourself real properties. Now instead of writing:
app.getTextBox()
You will be much happier writting:
app.textBox
On non-sucky browsers that is.
Posted by Toby 5 months ago about flex, javascript and programming (0 comments)

Vector for ActionScript3

I just learned about Vector, it's a typed Array for Actionscript 3, like generics in Java or C#. However, in Actionscript 3, Vector is a one-off: it's the only class that uses the generics syntax, and developers cannot use generics in their own classes. Nevertheless, Vector gives a type-safe alternative to Array and promises big performance gains. Given that it can also give the type of the containing elements at runtime, I can use it now to drive JSON deserialization into objects too.
Posted by Toby 5 months ago about actionscript, flex and programming (0 comments)

Modifying Core Types in ActionScript 3 Using the Prototype Object

ActionScript 3 has a Javascript lineage. It was essentially a fork of Ecmascript. Plus, the Adobe team has worked hard on making the language a proper superset of the Ecmascript specification. This is why although ActionScript 3 was a major architechtural change from 2, and as a result became much more like Java than Javascript, it still has support for the prototype object

When I learned about the prototype object, it was a fresh air from traditional class-based OOP. Studying cool libraries like prototype.js made me realize that the prototype model makes javascript far more flexible than some other strictly class-based OO languages.

One of the cool things you can do with the prototype object in javascript is modify the core classes of the language, like Array, String, and Date. You can do this in ActionScript 3 too, for it conforms to Ecmascript 4. For example, let's say you want to write the collect function for arrays a la ruby. You would do:
Array.prototype.collect = function(f){
  var ret = [];
  for each(var it in this) ret.push(f(it));
  return ret;
}
There you see me using the nice  for each syntax. But, this is going to break the behavior of the array, because now the collect function is going to show up in the enumeration in the for each loops. We don't want that, so to fix that we are going to set the collect attribute of Array.prototype to not be enumerable:
Array.prototype.setPropertyIsEnumerable('collect', false);
This allows you to write the following code:
[1,2,3].collect(function(i){ return i * 2; });
// result would be [2,4,6]
It's kinda tedious to have to setPropertyIsEnumerable for every time we add a function to an existing type, so I wrote a convience function:
function addMethodsTo(cls:Class, methods){
    for (var name:String in methods){
        cls.prototype[name] = methods[name];
        cls.prototype.setPropertyIsEnumerable(name, false);
    }
}
Which you can use like so:
addMethodsTo(Array, {
    collect: function(f){
        var ret = [];
        for each(var it in this) ret.push(f(it));
        return ret;
    },
    anotherMethod: function(){
        ...
    },
    ...
});
This is sort of like the style prototype.js uses for extending/creating classes.

A Word of Caution
Before you consider going further with this, I must advice you to think twice before using this technique(however, I hope you do decide to use it afterwards ;). There are several caveats:
  1. The prototype-based style is a second-class citizen in the world of ActionScript 3 and Flex. The Adobe team as well as the community seem to be much more committed to the class-based approach. I will describe some of the rough edges below.
  2. You will give up compile time type checking for the portions of your code that use this style.
  3. Prototype inheritence is handled by a completely different mechanism than class-based inheritence in the Flash VM and is not as performant.

Where to put this Code?
You saw the code example above, but, where do you put it? Since I decided to use a helper function(addMethodsTo), the code cannot be directly pasted inside the class scope of a class unless the addMethodsTo function is declared to be static(you can only make a method call directly inside class scope if it is a class method). As, a general solution, I'd rather the code be portable. So it should be includable in both class and function scope, and also, I'd like it not to pollute any namespaces.

My current solution is to put this bit of code inside an anonymous function which immediately gets executed:
// contents of includes/Array.as
(function(){
    include 'addMethodsTo.as';
    addMethodsTo(Array, {
        collect: function(f){
            var ret = [];
            for each(var it in this) ret.push(f(it));
            return ret;
        }
    });
})();
The addMethodTo function is pulled into a separate file to be easily includable else where.
So, with this, I would do the following to include this Array functionality:
include 'includes/Array.as';
Head over to Github for the complete structure of the files.

These methods are added during runtime - at exactly the time the above line of included code is executed, and not a moment before. I like to do the include at the top level of the application, this way the entire program has immediate access to the new methods. Oh, and when I said entire program, I do mean the entire program - not just the files that happen to include the file. Well, this is good and bad. This means if you create components that use the array extensions you've created without explicitly including it(you've included it at the entry point of your program), then you have created an invisible dependency. If you try to take the component and use it in a different project without the array extensions, it will not work. Of course, you could also make the dependency explicit by including the file everywhere you are using them, but 1) that's kinda tedious/repetitious, and 2) there's nothing enforcing you to do this.

Pitfalls and Gotchas
As I mentioned, the prototype-based programming style is a second-class citizen in the ActionScript 3 world, and so, its use is not particularly well supported. First of all, the compiler does not recognize any of the methods added via the prototype mechanism, and thus cannot perform static type checking on them. But what is funny is the way the compiler copes with this - it depends...on the type in question. For Arrays, the compiler simply allows all method calls - you can call any method on an array, even if it doesn't exist, the compiler won't complain. So, for a call like:
[1, 2, 3].collect(...);
The compiler won't even say a word. But for Dates, it gives a warning message. This:
new Date().format()
would trigger this warning:
Warning: format is not a recognized method of the dynamic class Date.
But, for strings, it's a different story still:
'one, two, three'.csv2Array()
compiler says:
Error: Call to a possibly undefined method csv2Array through a 
    reference with static type String.
And the same thing with numbers:
(2).minutes().ago()
compiler says:
Error: Call to a possibly undefined method minutes through a 
    reference with static type int.
The work around for strings and numbers is to upcast it to an Object:
Object('one, two, three').csv2Array();
Object(2).minutes().ago();
or if you just have an untyped variable, it'll work just fine:
var x = 2;
x.minutes().ago();
See the full code example here, and the demo here.

What about runtime error handling? So let's see what happens if you don't include the extensions and run the code. When I took out the array extension methods, the runtime dutifully throw me the:
TypeError: Error #1006: collect is not a function.
This is good, just what I would expect. For Date, it works the same way. Now let's try taking out the string extensions:
TypeError: Error #1006: value is not a function.
Uhh, what? Not really sure what you mean. And as you would expect, it works like this for Number as well.

I have also seen cases where the runtime simply completely muffles an error when there's an undefined method being tried as someone documented here. But I am not able to reproduce this just now. Also on another note, the error stacktrace from the flash player(debug version) is not very helpful because although it gives the call stack, there are no line numbers. I am sure that you'd get a better experience using Flex Builder, however.

I think that about wraps it up. Although extending core types is fun, powerful, and elegent, it's also full of holes and flying scissors everywhere. Are you ready to jump into this brave new world?

A message to the Adobe Flex/ActionScript team: I implore you to put more effort into the prototype-based side of the language. It allows for many possibilities which its class-based counterpart cannot offer. I don't dislike the class-based approach. I think the two each have their own strengths and weakness. Which is why I love this hybrid aspect of ActionScript 3 which allows me to use either style in the same environment. I believe that if the prototype-based aspect of ActionScript were to improve and get more exposure, it would not only become a better language, but also a more wide spread language.
Posted by Toby 10 months ago about actionscript, flex, javascript, programming and prototype (10 comments)

Using the Flex-Ajax Bridge

The Flex-Ajax Bridge is a little javascript library bundled with the Flex SDK that allows you to use javascript to drive your Flex app. It can be really handy for debugging or experimentation when you use it with Firebug's console. For complete setup up instructions, see here. You do need to modify your Flex code to get the bridge to work. It's just a one-liner though.

To use it, first you get a reference to your flex app:
app = FABridge.flash.root()
To get a component by ID, you would do something like:
app.get('myDataGrid')
To find out the type of the component:
app.get('myDataGrid').typeName
You can call the methods of the component as you would in normal ActionScript. To access the component's properties though, you need to use the Java getter/setter convention:
app.get('myDataGrid').getSelectedItems()
This isn't so nice. Ideally, a seamless experience would allow you to write:
app.myDataGrid.selectedItems
I guess this is where the weakness of Javascript is coming through. There's no language support for properties(like those in ActionScript, C# Python, etc.) and also no way to do method interception(method_missing in ruby). But I digress.
To instantiate an object of a class in Flex-land, you'd do something like:
sprite = FABridge.example.create("flash.display.Sprite");
This would call the default constructor. I am not sure how you'd call a constructor with arguments, probably just add on the arguments to create()?
A really cool and useful thing you can do is pass functions as event handlers to into Flex-land. Try this:
app.get('myButton').addEventListener('click', function(e){
    console.log('button clicked!');
});
Now go click that button...cool, heh?

Anyway...in conclusion, the Flex-Ajax Bridge is really nice...especially when combined with Firebug.
Posted by Toby 10 months ago about firebug, flex, javascript and programming (0 comments)

Different Ways of Including Functions in ActionScript

This is another example of something that would have been a blog post creeping over to SO.
Posted by Toby 10 months ago about actionscript, flex and programming (0 comments)

A Custom Drag-n-Drop List Control

The List control supports drag-n-drop support out of the box - just not the way I want. What it does is allow you to drag something from another list or other type control and drop onto it there by transfering the object dragged into the list control itself. What I want is for something to be dropped onto an item in the list in question. This is how I ended up doing that.

By looking at the implementation of ListBase.as in the flex framework source code, I found that I needed to override some methods. So I create a MyList.as file which subclasses the List control. The methods I first needed to override were dragEnterHandler and dragOverHandler. Both of these methods in ListBase.as look almost identical, here is the source for dragOverHandler:
    protected function dragEnterHandler(event:DragEvent):void
    {
        if (event.isDefaultPrevented())
            return;

        lastDragEvent = event;

        if (enabled && iteratorValid && event.dragSource.hasFormat("items"))
        {
            DragManager.acceptDragDrop(this);
            DragManager.showFeedback(event.ctrlKey ? DragManager.COPY : 
		DragManager.MOVE);
            showDropFeedback(event);
            return;
        }

        hideDropFeedback(event);
        
        DragManager.showFeedback(DragManager.NONE);
    }
The showDropFeedback method draws a line in the List control that indicates where the new item would be inserted into the List. This doesn't apply to us anymore, so I overrode the showDropFeedback method, to just highlight the item under the cursor instead:
        override public function showDropFeedback(event:DragEvent):void{
            var item = findItemForDragEvent(event);
            var uid:String = itemToUID(item.data);
            if (item){
                drawItem(item, isItemSelected(item.data), true, 
			uid == caretUID);
            }
        }
Moreover, now we want to accept the drop only if the cursor is over a list item, whereas before it allowed for drops on empty parts of the List area. This what I did:
        override protected function dragEnterHandler(event:DragEvent):void{
            _dragOverHandler(event);
        }
        
        override protected function dragOverHandler(event:DragEvent):void{
            _dragOverHandler(event);
        }
        
        public function findItemForDragEvent(event:DragEvent):Object{
            var item;
            var lastItem;
            var pt:Point = new Point(event.localX, event.localY);
            pt = DisplayObject(event.target).localToGlobal(pt);
            pt = listContent.globalToLocal(pt);
            var rc:int = listItems.length;
            for (var i:int = 0; i < rc; i++)
            {
                if (listItems[i][0])
                    lastItem = listItems[i][0];

                if (rowInfo[i].y <= pt.y && 
			pt.y < rowInfo[i].y + rowInfo[i].height)
                {
                    item = listItems[i][0];
                    break;
                }
            }
            return item;
        }
        
        protected function _dragOverHandler(event:DragEvent):void{
            var item = findItemForDragEvent(event);
            if (item){
                DragManager.acceptDragDrop(this);
                DragManager.showFeedback(
			event.ctrlKey ? DragManager.COPY : 
				DragManager.MOVE);
                showDropFeedback(event);
            }else{
                DragManager.showFeedback(DragManager.NONE);
            }
        }
I wrote a findItemForDragEvent method to find the item that the cursor is currently under or null if none exist - the code was mostly stolen from the calculateDropIndex method in ListBase.as - then I accept the drop if I get a non-null value from it.
I think that's pretty much it. Here's the demo and the code.
Posted by Toby 11 months ago about dnd, flex and programming (1 comments)

Property Binding in Flex

I have been working more with Flex now, and I have to say: the data binding features(covered here) in Flex is beautiful. It's light years ahead of anything I've ever seen before. 

Example 1: You want a Text element to show the full name of current selected state from a drop down: 
    <List id="stateList" labelField="abrv">
        <ArrayCollection>
            <Object abrv="NJ" full="New Jersey"/>
            <Object abrv="MA" full="Massachusetts"/>
            <Object abrv="NY" full="New York"/>
            <Object abrv="NC" full="North Carolina"/>
        </ArrayCollection>
    </List>
    <Text text="{stateList.selectedItem.full}"/>
The code in the curly braces is some ActionScript code, but it doesn't just get executed once, oh no, you can look at it as an invariant, i.e. the content of the said text element will always contain the value expressed by stateList.selectedItem.full. Therefore, when you change the selection of stateList, the text element will immediately change with it. Here's the code and live demo for example 1.

Example 2: Let's try binding to a custom variable rather than to another control. We first make our counter variable public and bindable:
    <Script>
    [Bindable]
    public var counter:int = 0;
Then, we can bind a text control to it:
    <Text text="{counter}"/>
Next, we can periodically increment the variable like so:
        setInterval(function(){
            counter++;
        }, 1000);
And you will see the number in the text display count up: the display in the text element is syncronized with the actually value of counter. The code and live demo for example 2.

Next, let's try creating our own properties. ActionScript has support for Java-style OOP(as supposed to Javascript style), but, more interestingly, it's got direct support for properties. Add direct support of property change event bindings, and it's a beautiful thing. 
Example 3: You have a Page object that manages the details of paginating a set of data, and you need some controls to navigate between the pages as well as display what page you are on. You create a Page object:
    class Page extends EventDispatcher{
        public var number:int;
        public var size:int;
        public var total:int;
        ...
    }
A page has a page number, a page size, and the total size of the data set(used to tell whether a page exists). I instantiate a Page object:
    <Script>
    [Bindable]
    public var currentPage:Page = new Page(0, 10, 100);
    </Script>
I need a label that tells me the range of results currently being viewed:
    <Label text="{currentPage.from} to {currentPage.to}"/>
Here, the label binds to 2 properties: from and to. Let's implement these properties:
    class Page extends EventDispatcher{
        ...
        [Bindable]
        public function get from():int{
            return number * size + 1;
        }
        [Bindable]
        public function get to():int{
            return (number + 1) * size;
        }
        ...
    }
Notice the get syntax: this in ActionScript turns the function into a getter for a property of the same name. Also notice that I made these properties bindable.
Next, I need the previous and next buttons. I choose to sandwich the label in between them:
    <Button label="Previous" click="currentPage.prev()"/>
    <Label text="{currentPage.from} to {currentPage.to}"/>
    <Button label="Next" click="currentPage.next()"/>
Clicking on Previous will call the prev method and clicking on Next will call the next method. Simple. Here is the code:
        public function next(){
            number++;
        }
        
        public function prev(){
            number--;
        }
Compiled it, but it doesn't work. Clicking on Previous and Next does no change the display on the label at all. Oh! We need to fire the events! To fire a property change event, you'd do something like:
                this.dispatchEvent(new PropertyChangeEvent(
                    "propertyChange", true, true, 
                    PropertyChangeEventKind.UPDATE,
                    propertyName, null, null, this));
In our case, we are going to fire the change events for both from and to, because both of those must change after you flip a page. So we fire the changes:
        private function fireChanges(){
            var toFire = ['from', 'to'];
            for (var i = 0; i < toFire.length; i++)
                this.dispatchEvent(new PropertyChangeEvent(
                    "propertyChange", true, true, 
                    PropertyChangeEventKind.UPDATE,
                    toFire[i], null, null, this));
        }
        public function next(){
            number++;
            fireChanges();
        }
        public function prev(){
            number--;
            fireChanges();
        }
Ok, but I would like to disable the Previous or Next button when we are at the begining or the end of the dataset. No problem! We create a couple more bindable properties: hasNext and hasPrev:
        [Bindable]
        public function get hasNext():Boolean{
            return to < total;
        }
        [Bindable]
        public function get hasPrev():Boolean{
            return number > 0;
        }
Bind the buttons' enabled property to them:
    <Button label="Previous" click="currentPage.prev()" 
        enabled="{currentPage.hasPrev}"/>
    <Label text="{currentPage.from} to {currentPage.to}"/>
    <Button label="Next" click="currentPage.next()"
        enabled="{currentPage.hasNext}"/>
Make sure to fire the change events for them too when you are flipping pages(add them to toFire in the implementation of fireChanges) and we are done. The code: ex3.mxmlPage.as and live demo for example 3.

The end result of this is that you have very well separated MVC code. There isn't any code whose sole purpose is to sync the display like you get with jQuery code, for example. The code to do this is very minimal and naturally readable.

All code examples can be found here on Github.

Btw, I should mention that, the code inside of the curly braces does not allow any arbitrary ActionScript. There is some amount of flexibility, but not a lot. You can read more here.
Posted by Toby 12 months ago about actionscript, flex and programming (0 comments)

Making Flex Suck Less

This is a follow up to my last Flex post. As I am learning more about Flex I have learned ways to address all 3 of the items in the cons list.
  1. Development feedback - not as instant. I mentioned that Flex has a compile step in the development process, this cannot be fixed. But the lack of an interactive console can be addressed by using the Javascript bridge, with which you can use Firebug to script your Flex app. There are inevitably some limitations, of course(like, I don't think you can pass functions to and from Flex land; and you can't modify the existing code), but by and large it is extremely useful. The scripting ability alleviates the slower feedback problem even though it does not eliminate it.
  2. Mandatory Static Typing. I misspoke on this one. Actually the static typing isn't mandatory at all. I mistook the warnings from the compiler to be errors. You have the option of turning off the warnings. Now I can eliminate a lot of what I dim the unnecessary type declarations from my code. However, I will not remove type declarations entirely, because I believe static type checking is immensely useful for situations where 1) it takes some time for the program to start up, and 2) it takes some user navigation actions to get to the place you want to test. The type checker will catch a class of stupid errors, which if you encounter only after waiting and performing a series of mouse clicks and key presses, can make you irritated quickly. My rule of thumb for type declaration in ActionScript is: 1) declare function input and output types; 2) declare global variable types; 3) local variables may or may not be declared, depending on the situation(if the variable is used extensively in the function, then declare); 4) do not declare if the type is void(i.e. nothing). I've never really worked with a language that has optional type checking, this is fresh! The browsers in the future will have this too in Ecmascript 4. Another language that has this is Groovy, and I heard C# is adding this too, how exciting! I SOOO admire Anders Hejlsberg. (after seeing the video it seems it's more like a bridge to scripting languages/libraries)
  3. As for the mx: prefix, I've already figured out how to do without it. So you can write <Panel ...> rather than <mx:Panel...>
In conclusion, Flex is actually an even better development environment than I gave it credit for last time.
Posted by Toby about 1 year ago about flex and programming (0 comments)

FLEX: first impressions

At work I am required to write a web UI that has a rich-desktop kind of interface. Without getting into too much details, it's layout will look a bit like an older email application(e.g. outlook, the older versions). It also need to have drag-n-drop capabilities. I whipped up a prototype of the UI using prototype and scriptaculous, since that's what I've been getting fluent with. A couple of things about my prototype made me decide to give Flex a try.
  1. No draggable divider. The draggable divider - although not essential - is something that seasoned computer users have learned to expect when you give them interfaces that have multiple panels jammed onto one screen. Scriptaculous didn't have an draggable divider widget. YUI and ExtJS did, and I am not against learing a new library. But I get the vibe that their implementations might not be rock solid.
  2. Buggy drag-n-drop libary. Scriptaculous comes with a drag-n-drop library. I've used it in multiple occations. It's also been buggy for me on multiple occations. A lot of the bugs are attributed to differences in browsers.
I decided that I was tired of chasing down cross browser bugs, which will only grow exponentially the more complex my UI gets. Therefore, Flex could really be the answer to these problems.

I am probably 60% done with my port of the UI prototype from Javascript/prototype/scriptaculous to Flex. I am happy with it for the most part. Here are my first impressions of Flex. First the pros:
  1. Programming in Flex is suprisingly similar to programming in HTML/javascript/CSS. (Well, not as suprising as it could have been since I've heard Charles Lowe say the same on DrunkAndRetired.com podcast). You write a mxml file, which is like your markup - in place of your HTML; you write ActionScript inplace of Javascript; and there's a css 3 compliant stylesheet you can use to style the UI.
  2. Flex has a rich UI component model that similar to many of the desktop UI toolkits(Swing, GTK, MFC, etc), which is a departure from the HTML/Javascript model. This is a plus because you get a lot of widgets you can use out of the box with very little code. Using third party Javascript widgets is usually more involved.
  3. ActionScript is not much different from Javascript, so people literate in Javascript should pick it up easily. The only significant difference I've noticed so far is the type declaration syntax - ActionScript is statically typed. I believe ActionScript is compatible with a newer version of Ecmascript which has optional type declaration for variables and parameters. Type declaration in ActionScript(as far I can tell) is required on function parameters and global variables(errors out if you leave it), and optional on local variables(warns you if you leave it).
  4. Yes, you have to write XML, but it's not that bad. I have expressed my hatred for making programmers read and write XML by hand in the past. It's inhumane! Flex makes you do that. Yes. But! It's used in a way that's not as bad as some other ways in which XML have been used(build scripts, web configuration, for example). In Flex, XML is used for Markup (wow! a markup language used for markup? what a concept?). The XML declaratively defines the UI(such as in HTML), which, I my opinion, is the way UI's ought to be written, and not in a procedure way(such as in Swing).
  5. Flex components look good by default. For HTML/CSS you always have to design your own theme - even if you just want it to look half way decent. No such BS in Flex. Flex components look good out of the box(no CSS tweaks or includes required), because of this I believe you can prototype Flex UIs faster.
  6. A Flex app runs exactly the same on any browser it supports. This was the main sell for me. Nothing more needs to be said.
Now the cons:
  1. Development feedback - not as instant. Developer feedback loop is slower because of the compile step. ActionScript is a compiled language, and you need to compile your Flex programing to get a SWF file. Also, in Flex 3, they took away the eval() function(why oh why???). This means you cannot create an interactive shell in Flex like Firebug or the python shell.
  2. Mandatory Static typing. Although I have nothing against static typing in general. I don't like mandatory static typing(such as exists in Java, C#, C++). Haskell is a staticly typed language, it verifies all your types for you, and yet it doesn't require you to specify the types of all you variables and parameters because it can infer them all for you. I like that. This is not a big issue for me, it's just not as kosher as Javascript in this respect.
  3. It's annoying that you have to write mx: to begin all Flex component tags in the mxml spec. No such BS in HTML. I tried a hack to do without it, it didn't work so well.
    Update: Looks like I have gotten rid of the mx: problem. I guess I showed them ;)
Overall, the pros are worth more than the cons. Linguistically, I prefer Javascript to ActionScript and HTML to MXML, so it's not going to Change My Life(TM). But the UI component model and cross browser compatibility greatly outweigh those nags.

Posted by Toby about 1 year ago about flex, javascript and programming (0 comments)