From: "Geir Magnusson Jr." <[EMAIL PROTECTED]> > You can help with that :) > > The thing to straighten out is the part about 'what you are trying to do'. > What I mean by that is that you have a mental and working model of how > things should work. > > I have a different point of view, looking at the VelValue class as something > that can be used as a universal tool for comparison and valuation that would > require no special changes to the core of Velocity.
In many ways, this is mostly my fault in many ways. I was dragged in late for this particular phase of the project. What we were doing previously was leveraging the J2SE MessageFormat class to let the scripting users add variables to text. MessageFormat is little more than a fancy 'printf'. However, the users were wanting to add conditional clauses to the messages they were creating. So, the original proposal was for some ugly XMLesque '<if var="MYVAR"> ... </if>' thing that only supported Boolean values. All of the boolean values would be created within the scripting language before being sent to the Templating Engine. When it got dumped in my lap, rather than just nodding and saying "Yessu yessu", it just struck me that it was pretty silly to have to jump through a hoop to write the parser and lexer for this XMLesque IF statement. Because, it certainly was not XML. It wasn't anything. I had heard of Velocity as being a "simple template engine", and it seemed like it would be a better fit, and we'd get some more features for "free". Of course, I wasn't aware of the limitations of Velocity at that time, naively thinking it was more flexible than it is. Anyway, it was "approved", and down the slippery slope I slid... The first issue I noticed was that we couldn't compare anything but Integers. It didn't make sense to me to support ".equals()" but not ".compareTo()" for the objects, so I went through and made the comparison logic work with items implementing "Comparable". The slippery slope gets steeper. The problem with this is that I could pass in Any Olde Object into Velocity, and Any Olde Object could implement a "smart" .compareTo(). But Integers were not "smart". Although an Integer is Compareable, it's not Compareable to anything other than Integers (well, maybe it can compareTo Numbers, but I don't know). So, now if that stayed, I'd have to explain to the users that given this: $AOO = AnyOldeObject (preset from scripting language) #set($IntValue = 1) then this: #if ($AOO < $IntValue) will work as expected, but this: #if ($IntValue < $AOO) will fail. That is not something easy to explain to users. This is non-obvious behavior. That's a caustic case, but the core issue is that simply uplifting from "Integers" to "Comparable" for the < <= == => >'s doesn't solve the issue we would have without placing pretty silly restrictions for reasons that are not at all visible to the user. Now, all of this could have been usurped if we just passed Integers down, save for the fact that all the numbers in our scripting language are Doubles. Also, if we did that, we wouldn't have had support for working with String inequalities either. Finally, it seemed like it would be nice if the operations the scripters were used to doing in the scripting language would translate well over into the Template language. The Slippery Slope is pretty much vertical now. So, I felt once I had to bite the bullet on adding ANY other data type for the inequalities and to be able to add math, then I felt it was easier to make a Magic Value that was Very Smart about types and translations, etc. (and conveniently fit well into the structure of our scripting language), than it was to make a bunch of type specific code within Velocity to handle these extensions. Down the rabbit hole I go, and VelocityValue springs from the ether. I did VelocityValue in order to make Velocity more generic and isolate it from our system as much as practical. To this point, I hadn't had to touch the actual grammar or parser, I just played with the internal interpreter. My goal was to, as best as I could, keep Velocity working as it did before, particularly from a performance point of view. I didn't want my changes to impact the performance on folks who chose not to use them. But after we fed the first cut to the users, the first reaction was "Where are the floating point numbers?". This was important because a lot of the numbers come from a medical model, and it would be nice if the users didn't have to go through any shenanigans to use them. And believe me, I thought up some really contrived solutions to the problem. We finally settled on things like this: #(if $BODYTEMP * 1000 > 9860)You have a fever#end. But, anyone would look at that and say that its a pretty weak solution. Now there's no slope at all, just simple freefall. When confronted with a choice between changing the tool, and changing the user, it's almost always valid to look into changing the tool first. Adding Doubles to the parser took less than a 1/2 hour. An easy half hour spent that will save innumerable hours on the phone, in meetings, etc. For the Clinicians, #(if $BODYTEMP > 98.6) is downright intuitive. 99% of the time, the scripters are dealing solely with "scalars" rather than anything more sophisticated. In this context, Numbers, Strings, and Dates are all "scalars". Being able to do things like: #(if ($Date1 - $Date2) > 7) You're a week overdue for your examination. It was due on $Date2 #end is a Good Thing. I guess the guiding philosophy here is that everything that I want to do is "business" logic. Perhaps, the original idea of just passing in a slew of booleans calculated from within the scripting as was originally proposed would have better fit the model of what Velocity is. If Velocity didn't already have the comparison operations or simple math, then we probably would have just stopped right there and either adopted it, or abandoned it right away. But, since it had the simple operations, just sitting there teasing us and staying just out of reach, and since it wasn't that hard to adapt to the new datatypes and behaviors, I just dived in and did it. I certainly don't want to go against the philosophy of the community or the vision of the creators. I hadn't even seen Velocity before, say, two weeks ago. I only subscribe to the dev-list, not the user-list. But, to me, I guess the question that I need put forth is whether the vision for Velocity includes giving it the extensibility to where it can be turned into something that isn't within that vision? Are you all comfortable with extending Velocity to the point where I could make the additions I made, only with an add-on package rather than changes to the core? It seems to me that once you open up that gate, then next thing you know, you've got a FrankenVelocity that looks not like what the creators dreamed initially. I guess I just need to be clearer as to what the path is for Velocity, so I can see better where something like extensible Comparisons, extensible Math, and parsing Doubles can fit in. I understand the Slippery Slope. Y'all have settled on your core and nailed it to the mountain. "If we add Doubles, then they'll want X, and then Y, and next thing you know, we have Python or something!" I didn't mean to push it a little more to the edge, but, like I said, I just wanted to give something back that I thought would be useful to others. (And note that I distinctly only posted these changes to the developer list, not the Users list. That Masses don't know this exists, as I wanted tacit approval of the project leaders, leaving it up to y'all to give it to them...There was actual, calculated Madness to that Method...) If you can give me suggestions on where I can start looking to being able to make my changes more modular, then I can try to do that. But, at the moment, there's code in the interpreter. "If it ain't an Integer, then begone foul beasts" is pretty clear in its intention. Difficult to get around, IMHO. And it's not clear I'm allowed to change that code. (For assorted definitions of "allowed"). Basically, I'm stuck. I'm keeping MyVeloctity-1.2 as is, becuase we have users using it and *shock* documentation on how to use it. There's code being made now against this new model, but that doesn't mean that all is lost for the rest of you. Run, while you still can! Sorry to cause such a fuss. I'll shut up now. Best Regards, Will Hartung ([EMAIL PROTECTED]) -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
