←Older revision |
Revision as of 01:45, 10 June 2010 |
Line 126: |
Line 126: |
| === [[Evolution]] (Versioning, Deprecation)=== | | === [[Evolution]] (Versioning, Deprecation)=== |
| | | |
- | There are strict rules for evolution of [[Java]] [[API]]. The [[Chapter 6]] touches on this topic slightly, moving methods up and down the class hierarchy, adding methods, etc. When doing library design, you need to adjust to the [[Java]] (or other framework) rules. When writing a [[DSL]] you are basically creating your own rules, aren't you Rich? | + | Jarda: There are strict rules for evolution of [[Java]] [[API]]. The [[Chapter 6]] touches on this topic slightly, moving methods up and down the class hierarchy, adding methods, etc. When doing library design, you need to adjust to the [[Java]] (or other framework) rules. When writing a [[DSL]] you are basically creating your own rules, aren't you Rich? |
| | | |
| It took me few years to understand the [[Java]] rules, how long it takes to specify own? There are tools which help you discover backward incompatibilities in [[Java]] like [[Sigtest]]. This all needs to be written from a scratch for [[DSL]] (btw. we would need something like that for [[Ant]] - as [[Ant]] [[XML]] build scripts supports overrides, inheritance, etc. - nothing like that is available, nobody will likely bother to write anything like that and rather we will rely on ''visual inspection'' and early testers to report bugs). | | It took me few years to understand the [[Java]] rules, how long it takes to specify own? There are tools which help you discover backward incompatibilities in [[Java]] like [[Sigtest]]. This all needs to be written from a scratch for [[DSL]] (btw. we would need something like that for [[Ant]] - as [[Ant]] [[XML]] build scripts supports overrides, inheritance, etc. - nothing like that is available, nobody will likely bother to write anything like that and rather we will rely on ''visual inspection'' and early testers to report bugs). |
| | | |
- | TBD...
| + | Rich: The great thing about DSLs is that you can completely change the syntax and semantics from version to version without breaking backwards compatibility. This is because you have complete control over the parser. |
| + | |
| + | The clearest example of this is in certain XML derivatives. In VoiceXML, for example, the root element has a version attribute: |
| + | |
| + | <vxml version="2.0"> |
| + | |
| + | VoiceXML interpreters can be compliant with both the 1.0 and 2.0 specifications by simply reading the root element, and then using different parsers depending on the value of the version attribute. |
| + | |
| + | In Apex, we do this a bit differently. Because all Apex classes are stored in our database, we simply have another column in the ApexClass table for the version. When users create a new class, this column defaults to the latest version number, but it is user-editable, in case they want to "upgrade" their class later to take advantage of new features. |
| + | |
| + | One example of a change that is versioned in this manner is the way Apex handles floating point literals. In a class with version 17.0, the literal |
| + | 12.4 |
| + | is a double. If you change the version of the class to 18.0, the same literal is a BigDecimal. If you want to specify a double literal, you'd type |
| + | 12.4d |
| + | |
| + | When implementing this change in behavior, we basically add an if statement to our abstract syntax tree like: |
| + | Object value; |
| + | if (currentVersion > 17.0) |
| + | value = new BigDecimal(parsedStringValue); |
| + | else |
| + | value = Double.valueOf(parsedStringValue); |
| + | |
| + | DSL versioning is a very powerful concept. Unlike in a Java API, we can completely remove concepts from the latest version of the language instead of deprecating them, keeping the semantics of the language clear and simple. We do this because the old parser logic is still there, and old code will always use the old logic. |