Whats with the ‘Fx’ prefixing?

If you follow the commits in the Gumbo SDK trunk, you may have noticed that about a week ago, a series of name changes were checked in. Additionally, a bunch of Gumbo specs and the Gumbo component architecture whitepaper are being updated on the Flex open-source site to reflect several name changes. A big chunk of these name changes were polish – temporary names like ‘skinZZ’ were changed to something less embarrassing (‘skinClass’ for those who want to know). Additionally, our API review board (yes, we care that much!) blessed many of the Gumbo ActionScript API’s and this resulted in some API changes that finally got checked in. But, the big change, which drove our build-engineer insane for a few days, were the numerous class re-namings that were checked into trunk.

Let me rewind for a second.

Gumbo introduces many new classes, and some of these new classes are re-implementations of existing Halo classes. For example, there’s a Gumbo Button and a Halo Button that follow the Gumbo component architecture or the Halo component architecture respectively. Prior to the name changes, the Gumbo Button lived in flex.components.Button while the Halo Button lived in mx.controls.Button. Collisions were avoided by the use of packages and namespaces. Namespaces in MXML are used to specify the language version and provide scope when mapping MXML tag names to class names. In Flex 2 and Flex 3, the MXML 2006 language namespace (http://www.adobe.com/2006/mxml) contained mappings for all of the Halo components. With Gumbo, we introduced the MXML 2009 language namespace (http://ns.adobe.com/mxml/2009) which introduced mappings for all of the Gumbo components and the new Flex graphics primitives. So, by cleverly using namespaces, you could write an application that inter-mingled Halo and Gumbo components, like so:

<?xml version=”1.0″ encoding=”utf-8″?>
<Application xmlns=”http://ns.adobe.com/mxml/2009″ xmlns:mx=”library:adobe/flex/halo”>
<mx:Button />
<Button />
<Rect width=”100″ height=”100″>
<stroke>
<SolidColorStroke color=”0xFFCC00″ weight=”5″ />
</stroke>
</Rect>
</Application>

This markup would create a Gumbo Application where the first child was a Halo Button, the second child a Gumbo Button and the third child a new Gumbo rectangle graphics object. Note, in that example, the ‘mx’ prefix is associated with a library url that points to a Halo manifest that contains only the Halo mappings. That prefix is used to disambiguate the two Button tags, and instantiate a Halo button when the MXML tag is prefixed with ‘mx’.

After a fair amount of back and forth between FlexBuilder, Thermo, and SDK alike, we figured all of this namespace stuff was too complicated. It became clear that though packages and namespaces were useful features for disambiguation when a collision occurred, using them as a crutch to allow collisions to occur when they could be prevented was wrong. After running through several options, we decided that prefixing new classnames to avoid collisions was they way to go. The prefix we chose was ‘Fx’ and this change is currently reflected in the Gumbo SDK trunk. The main “pro” for prefixing was that we could unify the Halo and Gumbo mappings into a single namespace, the MXML 2009 language namespace. So, under the MXML 2009 language namespace, you can instantiate a Halo Button the way you always have, via the <Button /> tag and you can instantiate a Gumbo Button via the newly prefixed MXML tag, <FxButton />.  Similarly, the new animation classes in Gumbo also follow this prefixing policy. A Halo resize effect is instantiated via the <Resize /> tag while a Gumbo resize effect is instantiated via the <FxResize /> MXML tag. Those tags totally new in Gumbo, like the Flex graphics primitives, don’t need any special prefixing since they do not have equivalents in Halo.

So, the example above should now look like this (in order to compile in the current Gumbo SDK trunk):

<?xml version=”1.0″ encoding=”utf-8″?>
<FxApplication xmlns=”http://ns.adobe.com/mxml/2009”>
<Button/>
<FxButton />
<Rect width=”100″ height=”100″>
<stroke>
<SolidColorStroke color=”0xFFCC00″ weight=”5″ />
</stroke>
</Rect>
</FxApplication>

We’re currently working on bringing our specifications up to date to reflect these name changes, as well as other class re-namings so please bear with us for about another week and things on the Gumbo open-source site should be up to snuff.

Thoughts, questions, concerns? Comment away!

–ADDENDUM–

Wow, love the passion!

Let me take some time to enumerate the reasonings and complexities behind the prefixing decision. There were 3 obvious hardships that came out of investigating using namespaces and packaging for disambiguation:

1.CSS namespaces
We would have had to have introduced namespaces in CSS in order to distinguish styles applied to a Halo component vs a Gumbo component (since type selectors use the leaf name of an MXML tag). Introducing namespaces in CSS is a beast – very tricky for the compiler and the tools. Developers would have needed a new CSS syntax to target styles for sets of components based on the namespace of the component set. This would have required updating the internal CSS parser to be aware of CSS namespace syntax, at least for element selectors, as well as updating the Flex compiler to track style namespaces. Additionally, support would have to be added such that Flex styles could, at runtime, be updated to handle namespaces. Even if all of this work was undertaken, other issues crop up. Since CSS does not support packages, if we tried using packaging to distinguish styles applied to a Halo button vs styles we want applied to a Gumbo button, like so:

mx.controls.Button
{
}

flex.components.Button
{
}

we would still be out of luck because dots (.) in CSS have pre-existing meaning. And, if we did add CSS namespace support, migrating pre-Gumbo code to Gumbo would be more difficult, something we try to avoid when possible. Additionally, there is an inherent trickiness with avoiding code bloat when depending on namespaces to control style inclusions. Because of naming collisions, you’re almost guaranteed to bloat your SWFs due to styles for one component being pulled in even if that component wasn’t in use in your application.

2.ASDocs
Providing clear documentation by using namespaces or package names for disambiguation would be difficult. We need to provide documentation for both Halo and Gumbo classes (Halo is not going anywhere till Gumbo has full functional parity with Halo). If we used packaging to differentiate, you would have to look in different directories for documentation depending on which control, Halo or Gumbo, you wanted to reference. If we used namespaces for disambiguation, you would then have Button/Button or CheckBox/CheckBox living in the same directory - one entry providing documentation for the Halo Button, the other for the Gumbo Button. We already have anecdotal complaints around the RPC services which used packaging to differentiate RPC base classes from RPC classes enhanced for MXML use, and don’t want to repeat those mistakes again.

3.ActionScript/MXML namespaces
Even if we used namespaces to aid in disambiguation, explicit scoping is still necessary. For example, in MXML, which namespaces are added by default? In the ActionScript world, when you write: var b:Button = new Button(), which Button do you mean? You either have to explicitly import the right Button class, or the system (code hinting) will have to prompt you to chose which Button you wanted to instantiate and add the explicit import directly. In the Gumbo timeframe, we are hoping we will improve code completion to assist with this so that you don’t have to type ‘Fx’ all the time. Imagine a code-hinting world where you type ‘Bu’, and ‘FxButton’ and ‘Button’ drop down. Completing that will insert FxButton; if you meant to instantiate a Halo Button, you just have to select it in the code hinting dropdown.

These 3 hardships defined a burden on the developer (as well as compiler, tools, and documentation generators). Additionally, the fact of the matter was that namespaces, though they help to disambiguate when a collision occurs, don’t actually *avoid* collisions all together. Onus is still on the developer to decide which component they meant to instantiate. Prefixing actually avoids collisions all together.

Because namespaces and packaging didn’t eliminate these problems 100%, we chose the prefixing route. Now, we don’t love it ourselves - there are definitely people on the team who dislike prefixing for a lot of the reasons described in the comments. You would be surprised at the hundreds of man-hours that have been spent on this issue, and the prefixing solution was the one ultimately settled on. While I can’t say that the prefixing solution is temporary, if a better or more elegant solution comes up, you  bet we’ll consider it. But right now, in order to avoid bulking up SWF’s, avoiding hard to track bugs, and adding CSS and tooling challenges, we settled on the prefixing route for collision avoidance.

And finally, I didn’t make this clear in my post, but the rule about what is decorated with an ‘Fx’ prefix is as follows: If the component is a *skinnable component* in the new Gumbo architecture, it is prefixed with ‘Fx’. Now we did break this rule in one place, to avoid collisions between new Gumbo animation classes and Halo animation classes, but that general rule stands firm. So, in future versions of Flex, when we add a new skinnable component, it will be prefixed with ‘Fx’. As for why there are other classes new in Gumbo that are not prefixed, that is because they are not skinnable components in the Gumbo architecture but instead are graphic elements, new classes, etc.


About this entry