iGetIt! Music

Online music education courseware for non-musicians who want to learn how to write their own rock songs.

My Photo
Name: Jim Plamondon
Location: Austin, Texas, United States

This blog documents the development of JIMS iGetIt! Music System (JIMS). JIMS' goal is to help you Understand Music in 24 Hours™, if you are (a) a non-musician (b) who wants to learn how to write your own rock songs. Requiring no instrument other than your own computer, and without using traditional notation, JIMS is being designed to deliver a deep understanding of tonal structure...in just 24 hours.

Tuesday, May 19, 2009

Federal Research Funding for Arts Education

Earlier today, I sent the following email to Arne Duncan, the head of the US Department of Education.

-------------------------------------

From: Jim Plamondon
Sent: Tuesday, May 19, 2009 1:59 PM
To: 'Arne Duncan'
Cc: 'Jonathan Levy'; 'Ruth Clark'; 'Tom Rudolph'; 'Wendy Free'; 'Michael McCaul'; 'Kay Bailey Hutchison'; 'John Cornyn'
Subject: Research Funding for Arts Education

Dear Mr. Duncan,

Is it the official policy of the Department of Education to continue to exclude arts education from its research initiatives?
I have copied Dr. Jonathan Levy, Program Officer for the Institute for Educational Sciences’ research programs into Education Technology and Cognition and Student Learning, on this email. According to the IES’ website, these programs remain focused – as they were under the Bush Administration – exclusively on “reading, writing, mathematics, or science,” thereby implicitly excluding the arts from any research funding.

I have also taken the liberty of copying my federal representatives – Michael McCaul, Kay Bailey Hutchison, and John Cornyn – so that they can be advised of this issue and, hopefully, its resolution.

I raise this question because I am aware of an innovation which has the potential to significantly increase the efficiency of music education in the K-12 environment, thereby reducing costs while maintaining quality. The potential impact of the ideas underlying the innovation may have application to the STEM domains (Science, Technology, Engineering, and mathematics) currently targeted by the Department of Education’s research efforts. However, the test-case for these ideas is arts-focused, and hence, apparently, barred from consideration for the Department’s relevant research programs, including the IES’ Education Technology Program and the IES’s Cognition and Student Learning programs, which I will now discuss individually.

IES: Education Technology
Is it the official policy of the IES, under the Obama Administration, to continue to exclude arts education technology from the IES’ Education Technology research initiatives?

Please allow me to suggest that this would be a significant oversight, for five reasons:
1. The arts appear to be bearing the brunt of state and local school budget cutbacks resulting from the current, ongoing economic crisis.
2. This places at risk the growth of the USA’s Creative Economy, which has been shown to be an important source of GDP growth and export revenue in recent decades.
3. Whereas music educators might not previously been willing to consider any changes to the technology of music education, the current crisis – which is putting their very livelihoods at risk – could make them more amenable to change. If positive change is the objective, now is a moment of great opportunity.
4. There exists at least one arts education technology, here in the USA, that has the potential to significantly increase the efficiency of music education (see this paper: www.igetitmusic.com/papers/JIMS.pdf). If the potential of “JIMS” is borne out by research, then it could reduce the cost of music education by half, or more. This is exactly the kind of dramatic efficiency improvement that cash-strapped American schools desperately need.
5. In addition to reducing the cost of music education, the development of efficiency-improving arts technologies here in the USA can also drive the emergence of a new high-tech American export industry, thereby saving and creating American jobs.

There is not yet any solid proof that JIMS (or other JIMS-like arts education technologies) can indeed deliver efficiency improvements of this magnitude. At present, JIMS is just a “thought experiment.” However, there is a strong possibility that such benefits are possible.

I have taken the liberty of copying two experts in arts education – TI:ME’s Tom Rudolph and the College Board’s Wendy Free – who can attest to the potential benefits of JIMS-like systems. Determining whether this potential can be borne out in practice will require research – exactly the kind of research that the IES exists to fund…if, that is, the IES’ guidelines did not prohibit its funding research into arts education technology.

However, the broader question is not about JIMS, but rather is whether or not the IES will continue, under the Obama Administration, to exclude arts education technology from its Education Technology research funding program. JIMS is just one example of the kind of arts education technology that is being excluded from funding as a result of this inherited policy decision.

IES: Cognition and Student Learning
Likewise, is it the official policy of the IES, under the Obama Administration, to continue to exclude arts education technology from the IES’ Cognition and Student Learning research initiatives?

Please allow me to suggest that this would be a significant oversight. As an expert in the field of educational cognition, you are doubtless familiar with Cognitive Load Theory, which divides cognitive load into intrinsic, extraneous, and germane categories. An American expert on cognitive load theory, Ruth Clark (copied), co-author of Efficiency in Learning, has agreed in principle that “notational load” may be an important component of a subject’s “extraneous load,” and that by reducing the notational load of a given subject, its educational efficiency could be improved. (See the brief discussion of notational load appended below.) JIMS provides one example, in principle only (given that its efficiency benefits have not yet been proven by research), of how the seemingly-intrinsic load of an apparently-complex subject can be exposed as actually being extraneous by reducing its notational load.

Furthermore, past examples of improvements to notation have not only increased educational efficiency, but also enabled new discoveries that were literally “inconceivable” without the new notation. JIMS exhibits this potential also, through its enabling of the recent discovery of Dynamic Tonality.

Should JIMS prove to be effective at increasing the efficiency of music education, then much of the credit will go to its reduction of notational load. This would be an important result, with potential impact not only on the arts, but also on science, technology, engineering, and mathematics. These domains might see similar educational efficiency gains and new discoveries – discoveries that can save and create American jobs, increase American exports, and improve America’s quality of life…but only if the impact of “notational load” can be proven, which will require research currently blocked by the Department’s funding policies.

Conclusion
As the originator of JIMS, I obviously have an interest in seeing if its benefits will prove to be as significant as I believe they might be. However, as I’ve mentioned, this email is not really about JIMS; it’s about the apparent exclusion of arts education research from the Department of Education’s research funding, no matter how significant and wide-ranging the potential benefits of such research might be.

In closing, I will re-state my initial two questions, and pose a third:
1. Is it the official policy of the IES, under the Obama Administration, to continue to exclude arts education technology from the IES’ Education Technology research initiatives?
2. Is it the official policy of the IES, under the Obama Administration, to continue to exclude arts education from the IES’ Cognition and Student Learning research initiatives?
3. If the answer to either or both of the above questions is “yes,” then what change in circumstances would need to be effected in order to make those answers “yes,” and what chain of events would be required to bring about that ultimate change in circumstances?

Hoping that this email will be received in the constructive manner in which it is offered, I am

Respectfully Yours,

Jim Plamondon
Austin, Texas

------------------------------------------------------------------

Appendix: Notational Load
I define notational load as the cognitive load imposed on a learner by the notation in which a concept is expressed, rather than by the concept itself.

As examples of notational load, consider:
  • Roman numerals vs. Arabic numerals: Arithmetic operations such as long division are much easier to teach, learn, and apply using Arabic numerals than Roman numerals. Indeed, the Romans’ numeric notation is often given as the main reason why the Romans contributed almost nothing to mathematics per se, whereas the Arabs made great advances in mathematics.
  • Chinese writing vs. Korean writing: The use of Chinese ideograms for Korean writing restricted literacy to Korean elites until the invention of the Korean-specific Hangul writing system, which made it possible for “a bright Korean-speaking student to become literate in one day, and a slow student in ten.” The Cherokee-specific writing system produced a similar jump in literacy rates.
  • The musical staff vs. neumes: Guido d’Arrezo’s invention of “sight-singing,” including the musical staff and solmization, is credited with reducing the training time of Church singers from ten years to “one, or at most two” – thus reducing the cost of music education by between 80% and 90% without sacrificing quality.
The development of other notational systems, such as calculus, the Periodic Table, and Feynman diagrams, have similarly contributed to significant increases in the efficiency of education.

Perhaps of even greater importance, the development of new notations has often led to new discoveries that were literally “inconceivable” using the previous notations, because notations invariably constrain, in addition to reflecting, patterns of thought. Examples include the Arabs’ use of their numerals in developing algebra and algorithms (the names of which reflect their Arabic roots), Mendeleev’s prediction of new elements based on “holes” in his Periodic Table, and Feynman’s use of his own diagrams in making major contributions to quantum mechanics.

Intrinsic or Extraneous?
Notational load seems to me to be an entirely extraneous load. In opposition to this position, one could argue that the mastery of a given domain’s traditional notation is required for communication with other professionals within that domain, and that this “communication conformity requirement” makes mastery of a domain’s traditional notation intrinsic. For example, without the ability to read traditional music notation, musicians cannot read the works of other composers.
Or…can they? Using modern music notation software, musicians can convert any given piece of written music to alternative, non-traditional notations such as guitar tab. These programs often support a “plug-in” architecture that enables the developers of alternative notations to retroactively upgrade the software to support new notations The potential availability of such notation-translation software, in any given domain, and the ease of distributing it over the Internet, significantly reduces the communication conformity requirement, supporting the claim that notational load is extraneous.

Changes in notation are not easy to effect in any domain, especially among tightly inter-connected professionals. However, a dramatic increase in learning efficiency may make it possible for non-professionals to rapidly gain knowledge previously restricted to a domain’s professionals. For example, more people in the USA now read Guitar Hero’s scrolling tablature than read traditional music notation, and are, as a result, learning more about music than they otherwise would.

Labels: , ,

Monday, May 18, 2009

Retained Mode Considered Harmful

I think I've made a small step towards figuring out how drawing works in Flex. Flex's drawing system appears to use a "retained mode" approach, in which the calls you make to "draw stuff" don't actually draw stuff. Instead, they (in effect) define a (new, hidden, secret, inaccessible) method which Flash/Flex uses to draw stuff whenever it feels like it.

Here's a tiny little test applet, called "bar" (because "foo" was already taken):







The above applet draws a small black circle that slides across the applet from left to right, eventually leaving the stage. No biggie...but it's drawing, which is big progress for me. ;-)

Here's a link to the above applet's source code, bar.as:
www.igetitmusic.com/blog/SWFs/bar/srcview/index.html

This source code is a minor variation of recipe 11.1, "Moving an Object," from O'Reilly's ActionScript 3.0 Cookbook.

In bar.as, a class bar is declared to extend Flash's Sprite class. (Yes, I know that bar should, by ActionScript/Flex convention, be capitalized as Bar, because it is the name of a class. Gimme a break. It's not germane.)

Every bone in my body tells me that this code is INSANE. All of the drawing code is in bar's CONSTRUCTOR, fer cryin' out loud. How can this code be *found*, let alone called, when an instance of bar is to be drawn?

I would expect that this drawing code would be placed in a draw() method of the bar class (i.e., bar.draw()), which would be called by Flash whenever an instance of bar was to be drawn, and that this draw() method would be an override of a draw() method inherited, ultimately, from Flash's DisplayObject class (from which bar's superclass, Sprite, descends). But neither DisplayObject nor Sprite have a draw() method, or anything similar to a draw() method. (They do have a RENDER event, but it is used to advise an object that it is about to be rendered; it is NOT a request that the receiving object now render itself.)

It gets weirder. Every time the Flash player needs to draw a new animation frame, it dispatches an ENTER_FRAME event. The bar class listens for this message in its onEnterFrame() method. No problems there. To animate the circle rightwards, I would expect bar.onEnterFrame() to (a) shift the location of the bar instance slightly rightward, and then (b) call bar.draw().

But nooooo! As I mentioned above, bar has nothing like a draw() method, nor does any of its super-classes. The only thing that bar.onEnterFrame() does -- and remember, I stole this code *directly* from the published, well-regarded recipe mentioned above -- is offset the bar object slightly rightward (more on that later). That's it. There's no drawing code in bar.onEnterEvent() at all, nor any calls to any other drawing code.

Somehow, the Flash player is accessing the drawing code that's defined in bar's constructor, and executing it sometime after bar.onEnterFrame() method is called.

WTF?

I see this pattern all over the sample code for Flash & Flex, from many different authors. Adobe's online documentation for Flex 3 is rife with it. They put drawing code in the class' constructor, or into a function which is only ever called by the class' constructor (to verify this, I've set breakpoints on such drawing functions, and seen that they are never called from anywhere except the constructor).

HOW DOES THE FLASH PLAYER FIND THIS DRAWING CODE, in order to execute it when it's time to actually draw the object?

I'm not sure, but I think I have identified a clue: "retained mode."

Apparently, the Flash player (and hence ActionScript and Flex) uses "retained mode" for all drawing. Unfortunately, only initiates into Adobe's secret society are taught the secrets of "retained mode." It's not documented anywhere that I've been able to find.


If you know where Adobe's use of retained mode is explained in detail, please
let me know where I can find this documentation.


The Wikipedia entry for "retained mode" is cryptic. The phrase "retained mode" does not occur in Adobe's online documentation for Flash, Flex, ActionScript, or Flex Builder. It's a big secret, and you can't really understand drawing in Flash/Flex/ActionScript unless you understand the Secret of Retained Mode. Or, at least, *I* can't. (Maybe I'm just stupid.)

Sure, I could just mindlessly copy other people's sample code, and put all of my drawing code into my classes' constructors. What the heck, it seems to work, right?

However, I've never been able to do that kind of "thought-free programming." It's one thing to reuse a well-documented component without understanding its implementation; that's what components (and their interfaces) are for. It is quite another to re-use a pattern without understanding it; that's a disaster waiting to happen. I want to understand. That makes me a slower "production" programmer initially, but eventually makes me more efficient and creative, because I come to understand how everything works, which allows me to make new and (hopefully) useful insights.

This Cartesian refusal to accept anything that one doesn't understand is *the* fundamental basis of all scientific advancement, fer cryin' out loud, so I'd think Adobe -- which had a strongly scientific culture, last time I interacted with it -- would give scientific skepticism a bit more respect by (for example) documenting its platform's architecture more clearly.

Here's what I think is going on deep in the secret bowels of Flash Player.

All "drawing" is effected by interacting with an instance of Flash's Graphics class. For example, in bar's constructor, the following code is called to effect the drawing of a circle:
this.graphics.beginFill(0x0000f, 100);
this.graphics.drawCircle(0, 0, 5);

this.graphics.endFill();

"this" is the instance of the bar class being constructed. Its graphics property is inherited from Sprite, which is bar's superclass.

Apparently, when you call the method of the graphics property -- such as the calls to beginFill(), drawCircle(), and endFill() above -- the methods don't actually draw anything. The method calls are simply recorded by the graphics object -- that is, they are retained. These method calls are (in effect) defining an implicit bar.draw() method (via delegation to bar.graphics), which Flash then calls whenever it needs to draw a bar instance.

In the bar.onEnterFrame() method, this.x is incremented by delta (initialized to 1 in bar's constructor).
this.x += delta;

Notice that incrementing this.x does not involve this.graphics, so it isn't "drawing code," per se. That is, it doesn't say what to draw, it just says where to draw.

Sometime after this.x is incremented in bar.onEnterFrame(), Flash calls the implicit (secret, hidden, retained) bar.draw() method that it generated from bar's calls to this.graphics's methods.

That is, I think, how drawing happens in Flash/Flex/ActionScript. If this is wrong in any significant way, please let me know.

If this is how it works, then it strikes me as being bad, bad, bad.

Retained mode is an example of self-modifying code, which always makes me nervous. It smells bad. Specifically, retained mode's implicit generation of a (secret, hidden, inaccessible) bar.draw() method makes it impossible to use time-honored object-oriented programming practices to modify a class' drawing behavior. In brief: I can't override a secret, hidden, retained draw() method.

I mean, really: drawing code in the constructor? The single-least-over-rideable method of any class? Are you insane?

I *must* be missing something, here. That just *can't* be right. I hope that someone will point out my misunderstanding and clarify how Flash player's drawing really works.

The opposite of retained mode is "immediate mode," in which calling the function drawCircle() draws a circle, right now. The Mac OS/Toolbox API, the Win32 API, the MacApp framework, the MFC framework -- every API I've ever worked with used immediate mode.

It is only by merest chance that I have any awareness of "retained mode" at all. I was on Microsoft's DirectX evangelism team back in the mid-1990's when Direct3D was first introduced. The first version of Direct3D used a retained mode API to improve efficiency (probably the same reason why Flash uses it). However, Direct3D's use of retained mode confused the heck out of game developers. As a result, they simply refused to use Direct3D, choosing to use OpenGL instead. The next version of Direct3D deprecated retained mode in favor of immediate mode, but it had lost so much mindshare in the meantime that it was a decade before Direct3D finally won over OpenGL's most vocal proponents.

Maybe all of this has changed since I stopped actively programming in 1992. Maybe now all Computer Science students are taught to think in terms of retained mode, so Adobe doesn't need to explain it anymore. Or maybe Adobe doesn't want to explain it; perhaps Adobe has too darn many ISVs already, and it wants to keep out the riff-raff by ensuring that only those who already know the secret "retained mode" handshake can get past the gate. That would be remarkably self-defeating, and although such self-defeating actions are surprisingly common, it doesn't sound like Adobe at all, but...what do I know?

Or maybe I'm barking up the wrong tree entirely, and Flash/Flex/ActionScript's drawing system doesn't used retained mode at all...in which case I'll apologize profusely.

Labels: , , ,

Thursday, May 7, 2009

iGetIt! Keyboard v.000002 (with source)

Now that I understand that Flex 3's View Source problem is an official bug, here's:

...the latest iGetIt! keyboard:









...and a link to its source code:
www.igetitmusic.com/blog/SWFs/TestApp1/srcview/index.html

Labels:

ViewSource: Officially a bug

It's official: the problem I've been encountering with Flex's ViewSource feaure is a bug. Here's the page from Adobe's official bug reporting system:
http://bugs.adobe.com/jira/browse/FB-19253

It had already been reported, and has been fixed in the next version, which is still under development (expected to be released in Q4-ish of 2009).

It is comforting to know that the next version will fix the problem. But I'm not just comforted; I am validated; encouraged; even elated -- much more than I had expected to be. Given my long hiatus from computer programming (and the failure of Thumtronics), my confidence is not what it once was. I tend to assume that everything that goes wrong is my fault; that I "don't get it;" that this stuff must be really hard.

Yet this ViewSource problem is not my fault. I did understand it. It's a bug. The beam is not in my eye, but rather, is a mote in my brother's. I was right.

That's encouraging! :-)

Onward!

Labels:

Wednesday, May 6, 2009

Offshore tech support

I've posted help-requests to a number of Flex developer forums (including Adobe's) without getting any satisfactory answers. So, I've started looking into hiring offshore Flex developers to help me with tech support questions on a per-incident basis.

On the one hand, using a (cheap) offshore tech support service could help me climb the learning curve faster.

On the other hand, it *does* make me wonder if I could make a living as a computer programmer in America anymore. If I can cost-effectively outsource my tech support questions to offshore developers, then I could outsource the development of entire components offshore, or perhaps even whole applications.

On yet another hand, it's one thing for me to send a tiny little test app to an offshore developer, asking him to fix a very clearly-defined bug that I just don't know enough to fix myself. It's quite another thing for me to draw up a spec for (say) my QWERTY keyboard control, or for my entire music education courseware. I thought up new functionality for the QWERTY keyboard component as I wrote it -- for example, changing the color of the buttons to reflect the current scale. That's going to affect the design of my other controls, too. I never would have included that in the QWERTY keyboard spec, because it was the process of developing the component myself that led me to think of it.

I've contacted ExpertsFromIndia and Catalytic Software. I also signed up as a buyer on RentACoder. I had a bad experience getting projects done on RentACoder before, but for little tiny tech support questions it ought to work OK.

From what I know now, I'd prefer to go with Catalytic, because I know and trust the folks who run it -- ex-Microsofties that I worked with Back in the Day. Will they be cost-competitive? I'm not sure. Catalytic's main added value is its American management, extremely skilled and knowledgeable staff, and its overall professionalism. Those things cost money. For any serious mission-critical, big-ticket project they would be my absolute first choice vs. anyone else anywhere in the world, but...for piddly tech support questions and a few little Flex components? I suspect that Catalytic might be overkill. I would be delighted to discover otherwise.

Labels:

Sunday, May 3, 2009

View Source Redux

Well, I'm getting closer.

If you click on this link:
http://www.igetitmusic.com/blog/SWFs/Tweener/Tweener.swf
...the Tweener app will come up. It doesn't do anything interesting.

Now, right-click (or, on a Mac, Command-click) on it, and a menu will appear; choose View Source, and voila, you're taken to a little applet that allows you to view Tweener's source, which it correctly looks for in http://www.igetitmusic.com/blog/SWFs/Tweener/srcview/index.html.

Coolness! Love it! Kudos to Adobe! :-)

But, if I embed Tweener's SWF -- using a reference to exactly the same file, mind you (i.e., http://www.igetitmusic.com/blog/SWFs/Tweener/Tweener.swf) -- into this blog entry, then the View Source menu item for the embedded SWF does not work, because it incorrectly looks for the source code in http://www.igetitmusic.com/blog/srcview/index.html.

Here is such an embedding of Tweener:







Bring up its View Source menu, select it, and voila! you're taken to the wrong @#$%& page.

Apparently, the Tweener SWF contains an algorithm -- generated by Flex Builder, not me -- that constructs a path to where it expects to find the source code for its View Source menu item. This algorithm appears to be based on the path to the file in which the SWF is embedded, rather than the path to the SWF file itself.

But...that's a bug, isn't it? If I want to embed a given SWF in (say) ten different web pages, then using the source-path algorithm than Flex is currently using, I'd have to copy the SWF's source code to each of those ten web page's servers...which I can't possibly know in advance. That's a major violation of information-hiding, isn't it -- in addition to being a huge pain in the posterior.

I would think that a much better default behavior would be to look for [somepath]/foo.swf's source code in [somepath]/srcview/index.html, no matter what the path to the html in which foo.swf was embedded.

What am I missing, here?

Labels: ,

Irony, or Abstraction?

The irony of my previous post is not lost on me. On the one hand, I am advocating that others learn music using a non-standard system (JiMS) due to the benefits of its higher level of abstraction, while at the same time choosing myself to learn a standard (programming) system despite the costs of its lower level of abstraction.

This analogy is misplaced, however, because a single level of abstraction removes the inconsistency.

Adobe's ActionScript/Flex/Flash toolset isn't the "standard programming system" today; today's standard is Java. Adobe's toolset is an alternative to today's standard that offers efficiency benefits in the development of Rich Internet Applications (RIAs). Therefore, if one views what I'm doing as learning to develop RIAs, then I'm choosing the non-standard, high-efficiency approach -- just as I am suggesting others do by using JiMS to do when learning to develop music (so to speak).

Labels:

Design Patterns Are Unimplemented Language Features

It seems to me that design patterns are nothing more (and nothing less!) than recipes for systematically maximizing the benefits of information-hiding (Parnas, 1972). Everybody knew that information hiding was good, but...how did you DO it, exactly? Design patterns provide well-defined recipes for many common architectural problems -- recipes that push an application's inevitable fragility out to its fringes.

It also seems to me that many of these patterns exist only to overcome the deficiencies of imperative, statically-typed programming languages.

Parenthetically -- I was always a bit of a language slut, and being Microsoft's evangelist for the .NET Common Languge Runtime ("Project 7") allowed me to indulge myself by interacting with Bertrand Meyer (Eiffel), Niklaus Wirth (Pascal/Modula-2/Oberon), Simon Peyton Jones (Haskell), Luca Cardelli (ML), Zoltán Somogyi (Mercury), and a host of others. We got their languages working on the pre-release version of the .NET Runtime and Visual Studio.NET, and used these implementations to identify architectural weaknesses in (and potential improvements to) .NET's design. I particuarly enjoyed working with Erik Meijer (on Haskell), whom I helped hire out of the University of Utrecht into Microsoft Research, where he developed LINQ. What fun! :-)

Back to the point -- each subsequent generation of programming languages succeeds by providing a higher level of abstraction over the previous problem-solving tools, thus making it brain-dead simple to do something that was previously difficult. For example, I'm old enough to remember hand-coding vTables in order to do object-oriented programming in C. Then, C++ coded vTables for me -- yahoo! C++ made it trivially-easy to code vTables, because the language did it instead of me. Likewise, Java trivialized programming interfaces (and other information-hiding techniques). Dynamic languages take this a step further, and functional programming languages another step after that. The rise of PHP, Ruby, Python, etc. are examples of the abstracting-away of programmers' pain-points. This is usually expressed in terms of "increased programmer efficiency," which is the result of such abstraction. (Importantly, Moore's Law makes the computing burden of these ever-increasing levels of abstraction affordable).

However, offering a valuable abstraction is not, in itself, sufficient to drive a new language to success. It also have to promote itself as the Gateway to a Proftable Career. Java's provides the clearest example of this. Objective-C is making a comeback as the de facto standard language for iPhone programming, due to the iPhone's popularity.

ActionScript 3.0 is a fairly old-fashioned declarative language, compared to (say) Scala. As such, it does not provide the asbtractions needed to trivialize the GoF's design patterns. Even if I were able to find a lovely little dynamic/functional tool suite (language, framework, IDE, etc.) for the Flash Player, there are no job openings for those who have mastered that tool suite, as there are (and will soon be even more) for ActionScript/Flex/FlexBuilder. Equipping myself with salable skills is an important sub-goal of this development project, so that I can help pay for the continued development of JiMS iGetIt! Music System through contract programming.

So, for now, I'm just going to have to wade through these design patterns, and learn to do them the hard way, like everybody else.

Sigh.

Labels: , ,

Saturday, May 2, 2009

Conservation of Fragility

In boning up on design patterns, I keep encountering claims that the proper use of design patterns reduces an application's fragility (or increases code reuse, or enhances its rubustness in the face of changes, or some such equivalent wording). I don't think that this is sttrictly true. Fragility is conserved; the more code you have, the more fragile it is. That's unavoidable; it's like gravity (more mass, more weight).

What design patterns give you, though, is a means of pushing that inevitable fragility away from an application's core, out towards its outer fringes, where the *consequences* of that fragility are lower. When code breaks at the core, it's expensive to fix, becuase the break affects all of the other code; but when code breaks at the fringe, it's cheap to fix, because only nearby fringe code is affected.

Labels:

The Shape of Frustration...

All I want to do is draw a frickin' arrow.

Clearly, this is a job for Flex's "Shape" class. So I write a nice little subclass of Shape called Arc, which draws a circle-segment from beginAngle to endAngle. The details aren't relevant, because the code never gets far enough for the details to matter.

In the test application's MXML code, I add an Arc object:
a:arc id="theArc" width="300" height="200" y="0" x="0"
No problems there; the Arc object is instantiated, its constructor is called, all is spiffy-keen. I'll just set the arc's radius to half of either the Shape object's width or height, whichever is less. No worries, right?

Except that, when the constructor is called, the width and height of the Arc are both 0 (zero). Excuse me? Well, maybe that's because its properties haven't been initialized yet. No worries; there's a handy-dandy event called "CREATION_COMPLETE" that one can listen for, just for this purpose.

But noooooo. CREATION_COMPLETE is an event of class FlexEvent, and Shapes don't post events of that class. Reading the documentation for the Shape class and its ancestors, there appears to be no equivalent event.

Well, fine, whatever, I'll write a brutal hack: in Arc's constructor, I'll (a) set the radius to NaN (Not a Number), (b) add a listener for events of type ENTER_FRAME (which ARE available to Shapes), and (c) in that listener's code -- which gets called very frequently, which is why this is such a brutal hack -- check the radius, and if it's NaN, set it to the proper value, based on the arc's width and height. Disgusting, perhaps, but it ought to work.

But noooo. When the code gets to the ENTER_FRAME event, the width and height of the shape are still zero. WTF? I check the Shapes docs, and yes, they have width and height properties. For some reason, they just aren't being initialized from my MXML.

This is totally bizarre...but it gets worse.

As a test, I set the width and height of the arc explicitly in the ENTER_FRAME code, as follows:
width = 162;
height = 100;

So, Mr. Smarty-Pants Flex Framework, you don't to initialize my parameters? @#$%^* you, I'll initialize them myself.

But noooo! I step through the execution of the code with the debugger, and to my amazement, the above code does not change the values of width and height! *Other* stuff changes; for example, the value of the Arc's inherited "transform" property, previously null, points to a flash.geom.Transform object after the call to "width = 162;" and the value of the inherited property "visible" changes from false to true...but the width property remains zero! Same with the height property. WTF?

OK, so I'll just step through the Shape code, and that of its ancestors as necessary, to figure out what the @#$%^*& is going on. Source code is the ultimate documentation, right?

But noooo! Shape's code isn't accessible using Eclipse's usual click-on-the-class-name-and-its-source-file-opens mechanism. Every time I do the click, instead of seeing the source code, I get a @#$%^ alert titled Code Navigation Error telling me that
"Source code could not be found for [the Flex class I clicked on] in /eclipse/Adobe Flex Builder 3 Plug-in/sdks/3.2.0/frameworks/libs/player/10/playerglobal.swc."

@#$%^*&! Mother-@#$%^&-ing piece of @#$%!

OK, fine, whatever. Om Mani Padme Hum. I am One with the Universe. That which does not kill me, and all that.

Screw width and height, anyway. Who needs 'em. I'll just draw an arc with hard-coded numbers.

Nothing is drawn.

Well, maybe my arc-drawing code is wrong. I'll just call the built-in drawCircle() method instead, just to see that i can draw SOMETHING.

Nothing.

Do I have my graphics environment set right? Yep, I'm calling lineStyle(5) to set a wide black line, and beginFill(0) to fill the circle with black. Nothing.

The source code for some of Flex's classes is available -- UIComponent, for example -- but not for others. Not for the ones I need now. Googling "Code Navigation Error" and "Source code could not be found for" has turned up no fixes, workarounds, or brutal but embarassingly-effective kludges.

So, I'm dead in the water. I simply cannot figure out how to draw a Shape in Flex.

Here's a stripped-down version of the app, with just a tiny MXML file and a short, heavily commented TestDraw.as class that shows the problems:



Of course, the application does absolutely nothing.

Furthermore, I still can't get the @#$%^&* "View source" menu item to work. In the sample app above, for example, it insists on trying to find a file at "http://www.igetitmusic.com/blog/srcview/index.html", even though the app is at "http://www.igetitmusic.com/blog/SWFs/Tweener/Tweener.swf". I have not been able to find *any* documentation -- not one word -- on how to set this pathname.

For example, the book "Flex 3: Training from the Source" -- which is not a bad book, overall -- has a chapter titled "Deploying Flex Applications." Sounds perfect, right? Unfortunately, like everything else I've been able to find on this topic, the chapter says "choose Project -> Export Release Build, and you're done!" -- when, actually, that's just the first step. Executing the "Export Release Build" command produces a bunch of files in the project's bin-release folder. Cool! But...now what? Which files need to be copied to the file server? How *exactly* do I tell a web page to include the resulting Flash doohickey? Should I tell the web page to include the doohickey.swf, the doohickey.html, or one of the other files in the doohickey project's bin-release folder? And how, for the Holy Love of God, does one define the path to the doohickey's source code?

I am not frustrated by computer programming. I LOVE computer programming. What is frustrating is NOT being able to do computer programming due to chickenshit problems like those above.

THAT is *incredibly* frustrating...

Labels: ,