- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
There is no God!
Admin
First posters should be taken out and shot.
So are "Enterprise Rules Engines" basically just reinventing Prolog?
Admin
It is too late on a friday to try and make sense of this crap.
I'm going home...
Admin
No wonder microsoft won't release their source code
Admin
EreRuleAtom[] versus EreRuleAtam ... oy vey.
For bonus points, write a program that auto-translates C# code to ERE-populating code.
Admin
The real WTF is that the forum software says '1 Replies'
Haven't they heard of:
caption = (replies = = 1 ? "Reply" : "Replies");
Admin
And I was going to add to that, "those who do not understand Prolog will reinvent it, poorly."
Person(P)
UnderstandsProlog(P, false) :- and(WillReinventProlog(P), WillDoItBadly(P))
See? Much clearer.
Admin
They should have used XML. See how much simpler it would have been and you wouldn't need to re-compile the code when you change something:
<ruleset>
<EreRule>
<param>OrderRule.CanCancelOrder</param>
<!-- Order Can Be Canceled When -->
<EreRuleAtomGroup>
<!-- Status Is OK -->
<EreRuleAtomGroup>
<!-- ( order.OrderStatus != OrderStatus.Approved -->
<EreRuleAtomGroup>
<EreRuleAtom>
<EreRuleAtam>
<param>order.OrderStatus</param>
<param>Operands.IsNotEqualTo</param>
<param>OrderStatus.Approved</param>
</EreRuleAtam>
</EreRuleAtom>
</EreRuleAtomGroup>
...
<!-- && order.OrderStatus != OrderStatus.Canceled -->
<EreRuleAtomGroup>
<param>EreRuleAtomGroupType.And</param>
<EreRuleAtom>
<EreRuleAtam>
<param>order.OrderStatus</param>
<param>Operands.IsNotEqualTo</param>
<param>OrderStatus.Approved</param>
</EreRuleAtam>
</EreRuleAtom>
</EreRuleAtomGroup>
</EreRuleAtomGroup>
<!-- User Is Authorized -->
<EreRuleAtomGroup>
<!-- || ( IsAuthorizedForOperation (
currentUser,
Operations.LateStatusCancel ) )
-->
<EreRuleAtomGroup>
<param>EreRuleAtomGroupType.Or</param>
<EreRuleAtom>
<EreRuleAtam>
<param>IsAuthorizedForOperation(
currentUser,
Operations.LateStatusCancel)</param>
<param>Operands.IsEqualTo</param>
<param>true</param>
</EreRuleAtam>
</EreRuleAtom>
</EreRuleAtomGroup>
</EreRuleAtomGroup>
</EreRuleAtomGroup>
</EreRule>
</ruleset>
Admin
I was thinking of ML, but I think Prolog is actually better.
Admin
There's a name for this: Second System Syndrome.
For those who haven't heard of it, I offer this:
http://en.wikipedia.org/wiki/Second_system_syndrome
Funny how creating a pseudo-language to "save" coding effort always seems to end up creating more work than it saves.
Admin
I like how the comment contains actual working code that pretty much does the same thing (but in a way that can be read and comprehended) in order to explain what the Enterprise Rules Engine is actually doing (which is obfuscated and enterprisey).
Admin
<FONT face="Courier New" size=1>[I]</FONT>
<FONT face="Courier New" size=1>EnterpriseReply enterpriseReply = EnterpriseReply.Load(Reply.NumberOfReplies); // 0 to infinity and beyond! Negative? Never!!</FONT>
<FONT face="Courier New" size=1>try {
if (EnterpriseReply.ObjectNotInitializedProperly) { // huh?
enterpriseReply.Result = 'file not found';
</FONT><FONT face="Courier New" size=1> }
else {
</FONT><FONT face="Courier New" size=1>if (e<FONT face="Courier New" size=1>nterpriseReply.NumberOfReplies==EnterpriseReply.OneReplyOnly)</FONT>) // 1
{</FONT><FONT>
<FONT face="Courier New" size=1> enterpriseReply.Result</FONT></FONT><FONT face="Courier New" size=1> = EnterpriseReply.MultipleReplies; // "Replies"
</FONT><FONT face="Courier New" size=1> }
</FONT><FONT face="Courier New" size=1> else {
</FONT><FONT face="Courier New"><FONT size=1><FONT> enterpriseReply.Result = EnterpriseReply.SingleReply; // "Reply"
</FONT><FONT> }
}
}
catch { // me if u can }
finally { E</FONT></FONT></FONT><FONT face="Courier New" size=1>nterpriseReply.Unload(enterpriseReply); }</FONT>
<FONT face="Courier New" size=1>return ('moose');</FONT>
<FONT face="Courier New" size=1>[<:o)] It's a *good* friday after all!</FONT>
Admin
.NET 3.0 will certainly include exec method to execute code written inside XML strings
Admin
They need to scrap all of the code and just compile the comments to make a program that is more readable and maintainable.
Admin
ERE: because what we had EREnow was better.
Wow! This must be the latest thing! Just look at all those "new"s.
Good comments! I can read the comments and understand what is supposed to be done. Too bad that is not true of the code^Wdatabase contents.
Sincerely,
Gene Wirchenko
Admin
I'd like to say I've never worked in a place where something like that was tried.
'Nuff said.
Still, I've always thought a decent way to get around this would be to write the mainstream code in something like C#, and then make callouts to something like JavaScript (or any interpreted language) for certain kinds of rules, which could be replaced as needed without requiring compilation (except in extreme cases).
It worked quite well for a food kiosk I did in which I had to map a single store PLU code for "sauce" into the correct image for a "what condiments do you want?" page. The script mapped sandwich PLUs to appropriate sauce pseudo-PLUs, and returned the correct image index for the sandwich (so your Big M@c showed special sauce, and your Filet-o-F1sh showed tartar sauce, even though the lazy-ass store managers would code the same PLU for both into the point-of-sale system). When a new sandwich came along, I just rewrote the script and propped it to the kiosks, without having to restart anything.
In an enterprise environment, the script would just get JIT'd into place the first time, and remain resident thereafter, without the performance hit.
Admin
It just occurred to me that this might explain .Net.
You can leave off "pseudo-" and still have a correct statement.
Sincerely,
Gene Wirchenko
Admin
So... is this like Old English for-
??
Also, is the last one really supposed to be spelled "Atam" ?
Admin
Whoops -- obfuscation typo! Fixed it.
Admin
I don't see a huge problem with the underlying concept, the ability to modify the business rules of something without recompiling, perhaps without shutting the program down. I'd lean towards using IronPython for the 'rules engine'. Native code for infrastructure, IP for scripting. Of course, I'd rather do Python for everything and use C# if I really needed speed. Guess that's why I'm not enterprise.
PS: Your design mode forum posting system is my daily wtf.
Admin
Obviously you still understood that there was one reply even though the plural was used. Why add extra complexity to the software for no benefit?
For some programs, choosing between singular/plural nouns automatically can actually be detrimental because it makes the output harder to be parsed by other programs.
Admin
_ And I was going to add to that, "those who do not understand Prolog will reinvent it, poorly." _ _ Person(P) _ UnderstandsProlog(P, false) :- and(WillReinventProlog(P), WillDoItBadly(P)) _ _ See? Much clearer.
I was thinking of ML, but I think Prolog is actually better.
I was thinking Lisp myself.
Attention CommunityServer: Get out of my community. You're obviously bigoted against Opera browser.
Admin
1) Why should I have to do error recovery just to read a message?
2) If the output is wrong/sloppy, what else might be wrong/sloppy?
OK, fess up, folks! Who uses a program to read this forum for them? "Once upon a time, a ..."
Sincerely,
Gene WirchenkoAdmin
Guess you weren't a computer science / English literature double major. It is true the English language isn't very efficient. I definitely recommend inventing a new language .. we'll call it English Sharp, without pluralilty and conjugation. While we're at it we can stop using this primitive base 10 crap, with factors of 2 and 5 and move on to the more efficient world of base 12 with factors of 2,3 and 4. The combined paper savings of calculating 1/3 = 4 rather than 1/3 - 3.3333 will save at least 10% of our national forests.
Admin
I'm sure there is a database back end for this app .... so I have to ask: would it be too simple and obvious to put a "IsCancellable" bit column in the OrderStatus table?
Probably.
Admin
I'd better go home ... 1/3 = .3333_
Admin
Yep - I was just thinking that. Basically, they should've written the rules using some terse-but-readable representation like that and coded a parser to read in the rules. (But then it wouldn't be on The Daily WTF...)
Admin
Choosing singular/plural nouns makes users less inclined to think that the program was written by retarded people. Besides, it's not like it's hard to do.
I use this handy Java code in programs where I do this often:
/**
* Returns pluralized item.
* pluralize(1, "fung", "us", "i"); returns "1 fungus", whereas
* pluralize(5, "fung", "us", "i"); returns "5 fungi"
*/
public static String pluralize(int count, String item, String singularSuf, String pluralSuf) {
return Integer.toString(count) + " " + item + ((count == 1) ? singularSuf : pluralSuf);
}
/**
* Pluralizes a term that you only need to add an "s" to.
*/
public static String pluralize(int count, String item) {
return pluralize(count, item, "", "s");
}
And I also have my much simpler PHP version that will work with integers or floating-point numbers, and doesn't require overloading:
function pluralize($count, $item, $singular_suf='', $plural_suf='s') {
return "$count $item" . ($count == 1 ? $singular_suf : $plural_suf);
}
It would be trivial to internationalize this as well (well, at least to a language that uses a suffix.. there probably are languages that don't do pluralization that way.. but I've never had to code to support one so I don't know).
Admin
Gah - was playing with the test forum (which doesn't need me to pretend to be using IE anymore) and forgot to change my Konqueror settings back, hence the mangled post.
Admin
Admin
IsCancellable would be a calculated field from Order Status which is a WTF in live a database
Admin
It wouldn't. There are much more complex plural forms in other languages. See http://translate.sourceforge.net/wiki/l10n/pluralforms for details.
Admin
It wouldn't. There are much more complex plural forms in other languages. See http://translate.sourceforge.net/wiki/l10n/pluralforms for details.
Admin
Absolutely right on on this, unless one cares about proper language usage in a UI. Since real men don't use UIs, we definitely should never develop them properly.
Of course. And since this forum software output is clearly meant to be parsed by another program, rather than displayed, you are right again.
What do you do, code screen scrapers for a living??
Admin
The pseudo-language is so complex, that the interpreter is likely to have a bug. A rule change will likely require a redeployment anyway.
Worse, the author must be some kind of masochist. Database-driven rules can be useful as they can be edited by a depertment manager or business analyst who cares about the application. This pseudo-language is so complex that another programmer would struggle to edit it. The original programmer would have to do it. For ever.
Admin
Apparently, the difficulties can be considerable: http://search.cpan.org/dist/Locale-Maketext/lib/Locale/Maketext/TPJ13.pod
Sincerely,
Gene Wirchenko
Admin
I'd like to see that in Intercal language :)
Admin
I think we have the first "WTF comment of the day!" award. Congratulations!
IsCancellable is an *attribute* of an Order Status. If you have a table defining your order statuses (hopefully, if you are using foreign keys and all of them other fancy database features) then that is where it belongs. Not in your code, not in an XML file, not anywhere else.
see:
http://weblogs.sqlteam.com/jeffs/archive/2006/02/10/9002.aspx
where I present an ingenious new idea of actually storing data in your *tables* as opposed to embedding it in your code.
Admin
<FONT face=Georgia>And Joel couldn't breathe, eat, walk, or have an erection without SnagIt. That's how important it is. [<:o)]</FONT>
<FONT face=Georgia>>BiggBru</FONT>
Admin
Careful soon he'll be as big as Jared from Subway ...
Admin
Please tell me how to make the twitching stop. I've heard rumors of goggles. Will they help?
Admin
Admin
I would prefer to see this information in a view -- I like the distinction of physical and virtual tables (views). I haven't been convinced that mixing the two help maintainability.
In any case, I'm not sure I'd put this in a view myself, as the last predicate on the rule is based on the user's context.
Admin
I said "some programs", not THIS program. For being so obsessive about language use, you sure are terrible at reading.
Admin
Please look up Java's ChoiceFormat and MessageFormat classes. You won't need your function.
Admin
The goggle are a no-op and do nothing.
Sincerely,
Gene Wirchenko
Admin
In base-12, 1/3 would be 0.4.
Not to mention that 1/5 = 0.24312431_
We should use base-60, or base-420
Admin
Some people have mentioned as an alternative calling out to a scripting language, and using that to implement the rules. Another alternative is to use a language where symbolic processing of this sort does not actually suck. Lisp is a prime example, but Haskell, ML and Prolog are also good choices.
Admin
Actually, the more I look at this, the more I get the impression that we're just looking at an unfinished system. That is, I think the people who implemented the classes that are being assembled also meant to have some other piece of code parsing a human-friendly representation, and spitting out the abstract syntax trees that the code shown is constructing by hand.
Admin
Quote [Opera style]:
IsCancellable is an attribute of an Order Status. If you have a table defining your order statuses (hopefully, if you are using foreign keys and all of them other fancy database features) then that is where it belongs. Not in your code, not in an XML file, not anywhere else.
Um, wrong. If you store isCancellable as a column then it will need to be updated any time any of the fields it depends on are modified. This means any rearrangement of the DB, any rollback-type stuff, and just plain any operation affecting this order will also need to run the logic of updating the IsCancellable field. Thats just asking for a bug.
IsCancellable is a calculated attribute. It should not be stored as a constant value. It should be added to a view via a stored procedure, or remain in the logic of the program. It IS application logic, afterall. Noone should be browsing the database and saying "well, I think this one should be cancellable, so I'll set that to true".