« May 2009 | Main | November 2009 »
June 03, 2009
Prefixes vs. Namespaces... Conclusion
There are two sides of a coin. I'm not blinded by my bias against (custom) namespaces. I can't say the arguments of namespace solution supporters has no merit. And I'm a realist, what's done is done, I don't expect anyone at Adobe having a revelation after reading my posts. So why have I been posting about this, if this is beating a dead horse?
I'm not even a Flex guy, and I currently have no intention to become one. But for the future of Flash, I believe Flex should be as simple as possible and entry level should be lower. I also fear anything done "wrong" in Flex may find its way to Flash... Anyway...
I have a solution proposal, which I'd say will give us the best of both worlds.
When designing an application, when you can't really decide on something, you make it optional. (This may not be optimal but may be your only option).
Can we have the components in their namespaces (as they are now) and still ignore the namespaces?
- With prefixes, you'd have components in global namespace. This would give simplicity. You wouldn't need to use, think of (or really be aware of) namespaces. But prefixes create ugly names.
- With namespaces, you can have a better organization. Sometimes minor benefits are huge, like seeing contents of a namespace while coding, or avoiding ugly naming.
I want to keep this short, so I'm coming to the point.
I'm proposing: A special default component namespaces list, with overriding and hiding behavior.
- It's a special list of namespaces of components, that will be considered imported by default and as early as possible (meaning, if you have "mx" in the list [1], you can write "Button" -without a namespace- and it will mean "mx:Button").
- It will have overriding behavior. (meaning, if you have both "s" and "mx" in the list, you can write "Button" and it will mean either "mx:Button" or "s:Button" depending on the order of the list. If "s" is listed first, it will mean "s:Button", if there is no "Button" in "s", it will mean "mx:Button").
- It will have hiding behavior. (meaning, After a "Button" is first found in one of the namespaces in the list, other "Button" definitions will be ignored. Namespaces in the list will have priority over others -regular ones- and any name found in the list will hide further definitions. This way, you will be able to continue using names from the namespaces in the list without a namespace qualifier, along with the same names in other namespaces you use with namespace qualifiers: a "Button" with no namespace specified will always resolve to the same name [if found in one of the namespaces in the list]. If you need to use another "Button" you will need to specify the namespace for it, but not for both).
- The list can be empty, and you will get current behavior, hence it's optional
- Obviously, code written with namespaces will still work in any case, as before. The list will be used for resolving unqualified names.
I don't really know that much about Flex, so my solution is just theory, but makes sense to me (and it's not something I can take credit for, similar solutions are used in many places and it's not really something hard to think of). Assuming my solution really does make sense, I admit I don't have a clue where would be the appropriate place to define this list (in Flex/MXML).
We already have the namespace solution and all its benefits. With this list we can get additional benefits without really breaking anything and for the worst case, it is optional.
A newcomer will not have to deal with namespaces. If a "Form" component does not exist in "s", the one in "mx" can be automagically used. It will work exactly as if the components in the list are defined in the global namespace.
If the list solution turns out to be not ideal for whatever reason, how about this:
A feature to define just one namespace as default with hiding.
This will be like promoting that single namespace to global namespace level.
Normally, if you have the same name, say "Button", defined in more than one namespace in your scope, you have to use namespaces, because the compiler cannot know which "Button" you mean. So every time you use "Button" you will need to use the namespace, like "mx:Button" or "s:Button".
If there was a "default namespace with hiding", you could use the names in that namespace, without specifying any namespace. For other "Button"s, you would use the namespaces, exactly as before. With the default namespace set as "mx", you could use "Button" (which will resolve to "mx:Button"), and "s:Button" (and also "mx:Button" if you want though the namespace part would be redundant).
Then when you have Spark components namespace as the default, you won't need to use any namespace when using Spark components. It will be like the components are in the global namespace with no prefix. And this will be optional - if you see any drawbacks, you can just not use it.
This may even be an already existing feature I'm not aware of. Would any Flex guru care to comment?
[1] I'm assuming you know which namespaces I refer to when I mention "mx" and "s".
June 3, 2009 in Flash, Flex, Language design | Permalink | Comments (3) | TrackBack
June 02, 2009
Prefixes vs. Namespaces... Why would the prefix solution have scaled better?
Update (2009/06/02): It turns out some of my understanding about this issue was wrong. I've never been a Flex guy. I will keep this post as is below. My current understanding is that "promoting components to the global namespace" was not a goal, but only a side effect. Albeit a very important one IMO. So, this post still has a point.
The prefix solution would have scaled better? Yes. And this does not contradict with what I wrote about how similar both are, in my previous post.
With current namespace solution, every new major component-set version will get a new namespace. Does that solution scale well? What will happen with the 100th major version? (I'm aware that probably we won't see 100 major versions, this is a way of thinking to test if the solution really scales or not).
How are major versions decided? Arbitrarily? It seems so, because you can mix both versions we have now. Maybe "arbitrary" is not the correct word, but I can say "not rationally from a certain point of view".
What will you do when you have 1.01 bug fix version of a single component? You will replace the old one (overwrite). OK, what will you do when you have the 1.3 version of the component that is not compatible with the old version? Overwrite and you will break old apps, rename and you will get a new component. OK, not a big deal. What will you do when you have version 1.9 of the component, which is not compatible with the old version and is on the verge of being a new major version? Is changing the version to 2.0 and opening a new namespace for new version of component the best solution?
What will you do when you have major updates of some components, but not all? Put the new components in a new namespace, and let users use the current (but old) version components from the previous namespace? (This is the current situation - namespace soup in formation, it's manageable for now).
Namespaces, are like file system folders, that's how I visualize them most of the times.
Namespace solution does not scale as a whole, it does not take care of name collisions caused by minor updates, it doesn't really take care of major updates.
Actually, I think this could be a text book example of a solution which does not scale well at all.
"Put the new files into a new folder" is a simple solution (so far, so good). You can't expect it to solve all your problems, you can't expect it to scale well. It just keeps your root folder clean and, yes, it provides some level of organization, though I'd call more arbitrary than rational.
And this is the current policy, thanks to community feedback.
Is there a better solution? I think there is, and if prefixes were used, that solution would have been reached inevitably.
Global / top / root namespace is not different than other namespaces, but in one aspect. You can have only one of it.
My better solution applies to all namespaces, including the global namespace. (That's a good sign that the solution makes sense).
Here's is the solution:
- Have current version of components in one namespace.
- If there's an update to a component, that is not compatible with the current version or if you need to keep the old functionality for some reason, move the old component to a new, child, namespace. (Remember the XML class?)
- That's it. What's left is just deciding on a naming convention for new namespaces, which will host old versions.
This way, current version of components are always in a single namespace. One namespace to rule them all, no need to deal with multiple namespaces. (And if you use the global namespace [1], no need to deal with any namespace at all).
You may think that this solution can cause problems when migrating old code. Every solution has its drawbacks. You have to prioritize your goals. It may seem it's better to have old code compile as it did and then upgrade to new components step by step, or, maybe it's easier using new components by default and then fixing any problematic areas and even falling back to older versions if necessary...
Some code was compiled with a certain version at a certain point in time... I don't consider it as the top priority, to be so much backwards compatible that it should compile the same now and ever, without any effort.
Backwards compatibility is a tricky subject, I'm all for backwards compatibility, but when not done wrong.
This solution scales well, because you don't have to know about any other namespaces unless you need to use an older version of a component. If you have a total breaking change with the whole component set, not compatible with the older version in any way, then you should move the old version to a new namespace and have the new version where it should be (that is, the one and only namespace where you have your current version). Not a special case. Simple and simply beautiful.
(You can still apply this solution to the current namespace components are in),
Anyway, you can argue if this solution is better or not (I really don't have the time to elaborate on this at the moment).
If prefixes were used, in the global namespace, this solution would be implied, as you can't open another global namespace for a new set of components, and it will easily occur to anyone having Fx2, Fx3, whatever prefixes is not a good solution. (But somehow people think having new namespaces like s1, s2... is better [2], or will not ever happen - and you could have chosen a one letter prefix too).
In summary, IMO namespace solution not only ruined the initial goal (of promoting components to the global namespace), it ruined the way how new components should be handled. Welcome to the namespace soup!
[1] Obviously I'm assuming there will be one set of components in primary use.
[2] With namespaces, compiler can ease some syntax issues. Nevertheless, if you are in a position to use Fx3 as a prefix, then s3 would be the correct corresponding namespace name to use.
June 2, 2009 in Flash, Flex, Language design | Permalink | Comments (1) | TrackBack
June 01, 2009
Prefixes vs. Namespaces... You need to ask the right question to get the right answer...
Update (2009/06/02): It turns out some of my understanding about this issue was wrong. I've never been a Flex guy. I will keep this post as is below. My current understanding is that "promoting components to the global namespace" was not the goal, but only a side effect. Albeit a very important one IMO. So, this post still has a point.
Without any rant on (custom) namespaces, here's why I think using prefixes would have been the right decision, and probably the only viable choice.
First of all, using prefixes (or suffixes or any other naming convention) is not too different than using a namespace.
With prefixes, you are creating a namespace yourself without the compiler knowing about it. With namespaces, compiler knows about this, so it can provide some minor benefits in return (like access restrictions, or some easy syntax).
That's all the difference there is, other than of course you may think namespaces are neater.
Many file systems solve name collision issues using folders/directories. Folders (read namespaces) are helpful for organizational purposes too. You may prefer all your files in a single folder, or you may create folder in folders in folders until each final folder contains a single file. That usage is not related to solving name collision problems.
You don't usually think about namespaces when using folders, like "Now, I'm copying this file into this folders namespace", you just "copy the file into a folder". In the real world, we name different things the same all the time, and we solve name collision issues that follow without thinking about namespaces.
In nearly all computer languages, there are namespaces that the compiler or interpreter deals with whether you are aware of it or not.
So, if namespaces are already in the language, when can a prefix be a better solution? Is this just a personal preference (ignoring minor benefits each provide)?
Let me first state again that there are no problems with using prefixes that would be a disadvantage for long term use, that namespaces don't have, as far as name collisions are concerned, because they are not that different. (If there comes a time you feel you need to change the prefix like to Fx1 or to Fx2, that's also exactly when you would be changing the namespace if you used namespaces).
The Right Question
I'm not a Flex guy. As I see it, on the surface, the question asked is/was:
"There may be a name collision issue, how should it be fixed? Using prefixes or namespaces?"
And the natural answer is "Why not use namespaces? Their main use is avoiding name collision issues and they are there in the language".
But why was there a possibility of name collisions, in the first place?
You don't have name collision issues everyday, because usually the languages provide default namespaces using the file system structure, this handles them well and transparently. AS3 and similar languages use the whole path from the root, so you cannot have files in arbitrary folders. In many languages, only file name is used. In that case, you can put your files in arbitrary folders as you like, but you cannot have two files with the same name in the same project.
So the question asked as "Namespaces or Prefixes?" needs more context, to get the right answer rather than a generic one.
Components were being promoted to the global - root - top namespace, where you wouldn't have to state the namespace at all. Identifiers in that namespace are first class citizens and this was a worthy goal.
When I had an Amstrad CPC464 as a kid (and a VIC20 before that), some of my friends had Spectrum 48Ks, some had Commodore 64's. To us, the computer was the keyboard. And, well, it was.
When I first heard about C, from a friend, he said: "Everything in C are functions, so cool. The language does not have any features, you use external libraries for everything". For us, at the time, a language was something that came with a standard library built into that language, just like having the computer built-in in a keyboard case.
Most of the time languages do have standard libraries, or certain built-in objects etc. You may see the difference, but you may also think of them as a part of the whole language experience, as a part of the language.
Functions you use without using a namespace, can be seen as a part of the language itself. This is not too wrong, with every class or function you write, you are extending the language (in a sense).
So, some class being promoted to the special, top namespace is something important. This is like not like moving a class from this namespace to that other ordinary namespace...
- GOAL: Promote these classes to the top, global namespace.
- OK, but what if we have a name collision issue there.
- Prefixing should solve this 99%.
- OK, but we have namespaces to solve name collision issues. They will also solve the issue 99%, and they are neater.
- Sure, but what was the GOAL again?
You see, if your goal is promoting some names to the special top namespace, you cannot solve any name collision issues you anticipate, by putting them in another namespace.
So, the question is not about prefixes vs. namespaces. Using another namespace is not a viable option for solving name collision issues in this case.
The correct question is: "Should certain components be promoted to the top/global namespace?". Using namespaces is just giving up on the idea. It's a defeat. Assuming, you want to do the change, because you don't like using prefixes, and because you care about name collision issues, you just abandon the feature.
You may argue that top/global namespace should be kept clean. I have a lot to say on that too, but in another post, if I can find the time.
June 1, 2009 in Flash, Flex, Language design | Permalink | Comments (4) | TrackBack