-------- Original Message --------
Subject: Case statements, decision trees, and good OO design Date: Mon, 30 Oct 2000 23:26:46 -0500 From: Jan Theodore Galkowski <[hidden email]> Organization: ::dark side of the moon:: CC: [hidden email] Newsgroups: Dolphin.smalltalk One of the principles of classical OO design and programming is that one should shun case structures like case statements, decision trees, and comparable switches. The rationale is that, if used, these tend to couple individual components strongly to the domain the set of objects is supposed to solve. Thus, if that domain is to be extended, and such extended switches are used, many classes will be affected by the change, something which is clearly undesirable. This is discussed at length by Meyer in his _Object_ _Oriented_ _Software_ _Construction_ ("OOSC-2", ISBN 0136291554). The recommended alternative is to give each distinguishing object a method with a standard name and then implement that method with function specific to the object to which it is attached. Thus, instead of, say, creating a case structure which elects various arms depending upon the value of a character code, the idea would be to provide a method called, say, doWhatYouNeedToDo (but obviously more pertinent to the application) for each of the character code instances that are to be "decoded" and define the thing that needs to be done in the doWhatYouNeedToDo for that instance. Thus, one extends the function of the application in a uniform way, namely, by adding methods to objects. So, I've got this same situation and am wondering if there is a standard Dolphin class library way of handling it. I'd like to be able to take a character and send it the "asSymbol" method and exploit attaching of specific methods to these instances. I suppose I could use a dictionary to collect these, filing away code in the dictionary under the appropriate symbolic key. Does anyone have suggestions on this point? Thanks. --jtg -- ----------------------------------------------------------------------- Jan Theodore Galkowski ºoº [hidden email] algebraist.com/ wikiweb.com/ intercot.com/ [hidden email] *********************************************************************** "Smalltalk? Yes, it's really that slick." *********************************************************************** Want to know more? Check out whysmalltalk.com/, object-arts.com/ ----------------------------------------------------------------------- |
Subject:
[Fwd: Re: Case statements, decision trees, and good OO design] Date: Tue, 31 Oct 2000 13:46:09 -0500 From: Jan Theodore Galkowski <[hidden email]> Organization: Cornell University (CIT ASDT) Newsgroups: comp.lang.smalltalk.dolphin -------- Original Message -------- Subject: Re: Case statements, decision trees, and good OO design Date: Tue, 31 Oct 2000 09:29:17 -0500 From: Jan Theodore Galkowski <[hidden email]> Organization: ::dark side of the moon:: Newsgroups: Dolphin.smalltalk References: <[hidden email]> As a followup, a way of doing what I describe I want to below is to define an additional series of class methods for the class Character in the manner of defining the constants lf, nl, etc. Do this for each character in what would be the case switch. Do this instead of applying "asSymbol" to the character. Then, on the fly, associate each of the doWhatYouNeedToDo methods with the individual constant instances just defined. Thoughts? --jt Jan Theodore Galkowski wrote: > > One of the principles of classical OO design and programming is that > one should shun case structures like case statements, decision trees, > and comparable switches. The rationale is that, if used, these tend > to couple individual components strongly to the domain the set of > objects is supposed to solve. Thus, if that domain is to be extended, > and such extended switches are used, many classes will be affected > by the change, something which is clearly undesirable. > > This is discussed at length by Meyer in his _Object_ _Oriented_ > _Software_ _Construction_ ("OOSC-2", ISBN 0136291554). > > The recommended alternative is to give each distinguishing object > a method with a standard name and then implement that method with > function specific to the object to which it is attached. Thus, > instead of, say, creating a case structure which elects various > arms depending upon the value of a character code, the idea > would be to provide a method called, say, doWhatYouNeedToDo (but > obviously more pertinent to the application) for each of the > character code instances that are to be "decoded" and define > the thing that needs to be done in the doWhatYouNeedToDo for > that instance. Thus, one extends the function of the application > in a uniform way, namely, by adding methods to objects. > > So, I've got this same situation and am wondering if there is a > standard Dolphin class library way of handling it. I'd like to > be able to take a character and send it the "asSymbol" method and > exploit attaching of specific methods to these instances. I suppose > I could use a dictionary to collect these, filing away code in > the dictionary under the appropriate symbolic key. > > Does anyone have suggestions on this point? > > Thanks. > > --jtg > > -- > ----------------------------------------------------------------------- > Jan Theodore Galkowski ºoº [hidden email] > algebraist.com/ wikiweb.com/ intercot.com/ [hidden email] > *********************************************************************** > "Smalltalk? Yes, it's really that slick." > *********************************************************************** > Want to know more? Check out whysmalltalk.com/, object-arts.com/ > ----------------------------------------------------------------------- -- ----------------------------------------------------------------------- Jan Theodore Galkowski ºoº [hidden email] algebraist.com/ wikiweb.com/ intercot.com/ [hidden email] *********************************************************************** "Smalltalk? Yes, it's really that slick." *********************************************************************** Want to know more? Check out whysmalltalk.com/, object-arts.com/ ----------------------------------------------------------------------- |
JT,
I might not be understanding this right, but it seems as though you'd be muddying up class Character by adding symbols that seem to be application specific. A variant on this is to define another class, e.g., MyChar, but I'm not sure what you'd gain over the implementation you've already pointed to, namely using a Dictionary consisting of pairs of character codes and method names (or code blocks). I assume you're starting from something like: MyModel>>myMethod "Assume that code already contains a Character." code = $A ifTrue: [do stuff with $A]. " ... other codes" code = $K ifTrue: [do other stuff with $K] So instead of this list of ifTrues, you create a method for each code, e.g., doStuffA yadayadaA doStuffB yadayadayadaB then you can dynamically create the message, i.e., myMethod self perform: ('doStuff', code asString) asSymbol This will not work, however, if the method name you build is not a valid Smalltalk name. For exmaple, if code = $%, this won't work since you can't have a method named #doStuff%. The Dictionary approach gets around this and also keeps myMethod short. MyModel class>>initialize MyCharMap := IdentityDictionary new at: $A put: #doStuffA; at: $K put: #doStuffK; at: $% put: #doStuffPerCent; yourself MyModel>>myMethod self perform: (MyCharMap at: code) -- Louis |
In reply to this post by Jan Theodore Galkowski
I have developed a class that is more flexible than Case/Switch called
If. The way to use it is as follows: If begin elseIf [bool expr] do: [code]; elseIf [bool expr] do: [code]; .. .. elseIf [boolean expression] do: [code]; elseDo: [bool expr] Example: x:=3. If begin elseIf: [x = 2] do: [ res := 1. ]; elseIf: [x = 1] do: [ res := 2. ]; elseIf: [x = 3] do: [ res := 3. ]; elseDo: [ res := 4. ]. Transcript cr; show: res printString. I guess you can use the same concept and make a Case class. The key to this class is an instance variable called logicState. Once an elseIf expression is true then the rest of the elseIfs/elseDo do nothing . Currently the result of the If is not defined. E.g. whichIf := If begin elseIf: [x = 2] do: [res := 1. Transcript cr; show: res printString]; elseDo: [res := 2. Transcript cr; show: res printString]; will not work. Regards, Costas Menico Following is the code I Filed Out for the "If" class. To try it you should File In. ======================================= "Filed out from Dolphin Smalltalk 99 release 3.0"! Object subclass: #If instanceVariableNames: 'logicState' classVariableNames: '' poolDictionaries: ''! If class instanceVariableNames: ''! If comment: ''! If guid: (GUID fromString: '{15E71380-AF8A-11D4-86D8-853A44732C79}')! !If categoriesForClass!Unclassified! ! !If methodsFor! elseDo: aBlock self logicState ifTrue: [^self]. logicState := true. aBlock value ! elseIf: aBooleanExpr do: aBlock self logicState ifTrue: [^self]. ^aBooleanExpr value ifTrue: [logicState:= true. aBlock value]. ! logicState ^logicState! logicState: aBoolean logicState:=aBoolean. ^self.! ! !If categoriesFor: #elseDo:!*-unclassified!public! ! !If categoriesFor: #elseIf:do:!*-unclassified!public! ! !If categoriesFor: #logicState!*-unclassified!private! ! !If categoriesFor: #logicState:!*-unclassified!private! ! !If class methodsFor! begin ^super new logicState: false. ! ! !If class categoriesFor: #begin!*-unclassified!public! ! |
"Costas Menico" <[hidden email]> wrote in message
news:[hidden email]... > I have developed a class that is more flexible than Case/Switch called > If. The way to use it is as follows: ...snip... For further reference and ideas, here is the Switch class from QKS-Smalltalk/SmallScript -- you're free to use it. It inherits from <IndexedSlotCollection>, but (depending on dialect) you'll probably want to make it a subclass of something like <OrderedCollection> which supports ordered #add: value operations. (Switch new) case: ... do: [ ]; case: [...] do: [ ]; default: [ ... ]; on: switchValue. Or duplicating the previous posters if/else example: res := (Switch new) case: 2 do: [1]; case: 1 do: [2]; case: 3 do: [3]; default: [4]; on: x. Switch class source follows: (No compiler changes are required but a compiler can easily optimize this form) --------------------------- Inherited methods required are: #add:, #at: External messages used are: #class, #==, #=, #~=, #+ #to:by:do:, #ifTrue:ifFalse:, #value: NOTE: QKS Smalltalk allows blocks (and methods) to be valued with more or less arguments that they were declared with. So, you may want to replace references to #value: for the <caseValuable,defaultHandlerValuable> with #value. --------------------------- <!--BEGIN Switch--> <class name ='Switch; {BCF183CE-331B-445E-8721-BDB448B456D9}; {917D20F6-6BAC-4B14-BDE8-BD71222E18E2}' extends ='IndexedSlotCollection; {42524DCD-19C0-4106-8347-D547F3F4CC4A}' inst-vars ='defaultHandler' authors ="David Simmons" version ="1.0.0" > <!--Switch--><?method [ default: defaultHandlerValuable "This registers a default statement to be executed when no other on: value matches a statement." defaultHandler := defaultHandlerValuable. ]?> <!--Switch--><?method [ case: caseValuable do: handlerValuable "This registers a statement to be evaluated and then compared to the passed value: parameter." self add: caseValuable; add: handlerValuable. ]?> <!--Switch--><?method [ exactlyOn: switchValue "This causes the array of conditions to be tested in the defined order. The first condition to evaluate to true has its do: block evaluated and the result is returned. Test uses #==." 1 to: self size by: 2 do: [:i||case| ((case := self at: i) class == Block) ifTrue: [ ((case value: switchValue) == switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ] ifFalse: [ (case == switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ]. ]. defaultHandler ? [^nil]. ^defaultHandler value: switchValue ]?> <!--Switch--><?method [ equivalentlyOn: switchValue "This causes the array of conditions to be tested in the defined order. The first condition to evaluate to true has its do: block evaluated and the result is returned. Test uses #~=." 1 to: self size by: 2 do: [:i||case| ((case := self at: i) class == Block) ifTrue: [ ((case value: switchValue) ~= switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ] ifFalse: [ (case ~= switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ]. ]. defaultHandler ? [^nil]. ^defaultHandler value: switchValue ]?> <!--Switch--><?method [ on: switchValue "This causes the array of conditions to be tested in the defined order. The first condition to evaluate to true has its do: block evaluated and the result is returned. Test uses #=." 1 to: self size by: 2 do: [:i||case| ((case := self at: i) class == Block) ifTrue: [ ((case value: switchValue) = switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ] ifFalse: [ (case = switchValue) ifTrue: [ "Invoke the <handler>" ^(self at: i+1) value: switchValue ]. ]. ]. defaultHandler ? [^nil]. ^defaultHandler value: switchValue ]?> <!--Switch--><?method [ value: switchValue "This causes the array of conditions to be tested in the defined order. The first condition to evaluate to true has its do: block evaluated and the result is returned. Test uses #=." ^self on: switchValue ]?> </class> <!--END Switch;{BCF183CE-331B-445E-8721-BDB448B456D9}--> -- Dave Simmons [www.qks.com / www.smallscript.com] "Effectively solving a problem begins with how you express it." |
"Taylor Corey" <[hidden email]> wrote in message
news:C_ZL5.5131$[hidden email]... > Ummmmmm, I think Kent Beck had a pattern called 'Death to case statements'. > IMHO, switch statements are not very good OO practice. > > --tc > Aside from the fact that Kent's ideas or words are not gospel... There are a lot of design and implementation problems and performance related issues that are either ignored or possibly not understood in making such a sweeping thesis as 'Death to case statements'. It is worth noting that Kent's focus is with using OO languages for creating Business objects and systems. I would suggest that it does not, in general, address all the issues or cases for software development across the entire spectrum. -- Dave Simmons [www.qks.com / www.smallscript.com] "Effectively solving a problem begins with how you express it." Here are snippets from posts I made on a CLS thread earlier this year. Thread title was: "Re: Major differences between Smalltalk and Java" ************************************ ************************************ > "Wayne Johnston" <[hidden email] <mailto:[hidden email]>> wrote in message > <news:[hidden email]>... > > Ian Upright wrote: > > > > > > "James A. Robertson" <[hidden email] <mailto:[hidden email]>> wrote: > > > >If you feel the need for a case > > > >statement, it's easy enough to do with a Dictionary. > > > > > Yes, you can use this trick, but many times I don't want the extra > > > overhead of creating a dictionary object and filling up the dictionary > > > with the blocks, evertime the method is invoked. > > > > What kind of alternative do you suggest? I can't think of an alternative > > where you don't have to pass in all the blocks anyway, something which I'm > > guessing that you would still resist for performance reasons. > > > > What's your extension, James? > > -- > > Wayne Johnston > > I'm not James but I thought you'd find it useful to know that QKS Smalltalk > has had a standardized inlineable switch form since 1991. I believe The QKS > dialect was the first to define switches and it is my understanding that, > like a variety of other new QKS Smalltalk constructs, this switch > implementation was also adopted by both Dolphin and Squeak. > > Like cascadable exception guards, the entire expression "(Switch new) and > its cascaded messages" are always inlineable (and it should be easy for a > smalltalk compiler to inline them via its parse-tree) for hi-performance > execution. As with most optimizations for Smalltalk, we designed this > construct (and a portable <Switch> class) to both compile and execute > without requiring compiler inline support (it's just a whole lot faster > more efficient to have the compiler inline support). > > (Switch new) > case: "value or Block" do: [...]; > ... > default: [...]; > on: value. "#= equality matching of cases" > > (Switch new) > case: "value or Block" do: [...]; > ... > default: [...]; > exactlyOn: value. "#== identity matching of cases" > > (Switch new) > case: "value or Block" do: [...]; > ... > default: [...]; > equivOn: value. "#~= equivalence matching of cases" > " or #equivalentlyOn:" > > If the case expression is a block, then it is injected with the switch > argument as in: > case: [:switchArg| ...] do: [...] > > The block is then evaluated and the result of the block valuation is > as the case value for "...on:" testing. > ---------------------------------- > ---------------------------------- > SIDEBAR: Transforming and maintaining code (and subsequent updates) from one > language or associated style to a Smalltalk usage can be problematic. > > In that scenario, it is useful to have constructs to capture and preserve > the original code's intent... > > I.e., It is also the case that switch statements have the value that they > provide a locality of reference for the human programmer to understand the > conditional flow of execution. > > Switches can outperform message sends and have the ability to efficiently > combine cases without messaging at all. They should not be used for > patterns of behavioral dispatching but may be quite appropriate for > maintaining the simplicity (for purposes of understanding) of a specific > algorithm (while possibly gaining (as opposed to losing) performance > benefits). > > In general, it is important to distinguish control flow design based on > behavior from that based on value. I.e., it is bad form to write > control-flow code based on something responding to some suite of behavior; > it is appropriate to write control-flow-code based on specific values of one > or more types. > > NOTE: The following snippets are written in SmallScript which has an XML > source form; within method source the SmallScript annotation operator > '<...>' is used. SmallScript is a new language that fully incorporates and > extends the QKS' Smalltalk-2000 dialect. > > "" Bad form -- it is based on behavioral/type intent > "" Use polymorphism instead > if (t class == XX) > ... > else if (t class == Y) > ... > > "" Appropriate and more efficient than messaging > "" since messaging will not discriminate a 'foo' > "" value from a 'bar' value unless they are of > "" different types (and even if they were, the > "" intent was to distinguish the 'foo' value from > "" the 'bar' value not their behavior types. > if (t = foo) > ... > else if (t = bar) > ... > > "" Or a SmallScript switch form > switch (obj) > [ > case foo: "" Case 'foo' will do both > action1... "" action1 and action2 > case bar: > action2... > break. > case [... abc ...]: "" a completely dynamic-case > action3... > break. > ]. > > Similarly, if/unless/assert can provide similar value. > -- > if (cond) "" #ifEquivTrue: > expr > else if "or 'unless'" (...) > -- > unless (cond) "" #ifEquivFalse: > expr > else if "or 'unless'" (...) > -- > assert (cond) "" if assert-level-enabled on thread > expr "" and (cond) ifEquivTrue: > else ... > -- > assert:level (cond) > expr > ... > -- > ============================== > > -- Dave S. [www.qks.com] ************************************ ************************************ > > Similarly, chains of if-then-elseif-then-else or > > switch statements generally indicate that someone hasn't thought very > > carefully, as these constructs are usually what polymorphism is for. > > > > --- > > Doug Palmer "I've got that certain nothing, > > <mailto:[hidden email]> No one can do without." > > <http://www.charvolantSPAMUNOT.org/~doug> > > This is only makes sense if everything is already an object and if all > "data" has a behavioral representation. This is a limited and perhaps > impossible way to view the world. > > Ask yourself: > > Is "1" a different class from "2"? > Is "'asString'" as different class from "'new'". > > Obviously, the word "class" itself tells us there is a "grouping" and we > know that implies similar characteristics ("behavior" in OO-terms and > structure in procedural-terms). However, the members of the group are > "values" that share the same "behavior". > > So, obviously we need some way to express distinctions between the values > and sometimes to "marshal" values between one behavioral group and > The need for this and the solutions to addressing that need have nothing to > do with "behavior" and thus nothing to do with OO concepts as you're trying > to express them. > > Control flow is about the expression of decision making. Not all decisions > are of a "behavioral" form -- this is the flaw in "pure" OO thinking as it > leaves no room for all the rest. > > if (aString = 'abc') > ...body... > else if (aString = 'def') > else if (aString = 'xyz') > > if (interest > 0.05 and: [cost < 50]) > else if (interest > 0.08 and: [cost > 200 and: [balance < 4000]]) > ... > > What is behavioral about the preceding types of constructs? These > while not from any real code, are not atypical of what one encounters in > general programming problems. This kind of expression of relationships > between values (or sets of values) is one of the basic elements that forms > the basis for functional languages. And it is the basic kind of problem from > which procedural languages evolved. > > The above two examples take a form that provides "locality of reference" for > a human reader. Which means that one can go to one location to understand > the decision process. Whether they are an appropriate use of control-flow or > a misuse in view of behavioral constructs depends on what the various > control flow body statements contain -- one would assume they would be short > and succinct often translating the value operation into some behavioral > construct. > > Given one is working in a language that has OO facilities, syntactic > constructs can be easily misused, just like OO semantics can be easily > misused for things like value operations. One can take an otherwise concise > and clear set of value relationships and completely obscure and obfuscate > them with extra effort to "objectify" the implementation of the problem > solution. This is not a black and white issue. It often has to do with the > granularity/scale of the problem and as a problem evolves it may well need > to be "refactored" to express the solution using more or less of the "pure" > object facilities available. > ************************************ ************************************ > From a design point of view the question of using some form of "if" > conditionals versus a dispatched behavior mechanism cannot be determined > without understanding more about the problem itself. > > Under what situation is this better (before answering look at the more > reasonable approach next): > --------------------------------------------------------- > | dispatchTable | > (dispatchTable := Dictionary new) > at: 'abc' put: #someSelectorA:with:; > at: 'def' put: #someSelectorB; > at: 'xyz' put: #someSelectorC:. > selector := dispatchTable at: aString ifAbsent: [...]. > (expr) perform: selector withArguments: ("what goes here?") > > The above approach introduces many questions and does nothing to clarify > intent, improve readability, consistency, maintainability. > > Or (one possibly reasonable solution for a complex case): > > Noting that in the "simple localized case" even this is slower, more > to code and potentially understand, and requires more complex logic for the > programmer because now there are two methods and one of them requires some > initialize lifecycle design (why do this unless the problems > scope/complexity makes it appropriate?) > --------------------------------------------------------- > SomeClass metaclass>>initialize > (dispatchTable := Dictionary new) > ... > SomeClass>>aMethodSelector... > selector := dispatchTable at: aString ifAbsent: [...]. > (expr) > perform: selector > withArguments: ("what goes here? -- could use blocks") > --------------------------------------------------------- > > As my original comments stated, the decision about when to choose one or > another form of decision making algorithm depends on the problem and its > level of complexity: > > I.E., Once Again: > Given one is working in a language that has OO facilities, syntactic > constructs can be easily misused, just like OO semantics can be easily > misused for things like value operations. One can take an otherwise > and clear set of value relationships and completely obscure and obfuscate > them with extra effort to "objectify" the implementation of the problem > solution. This is not a black and white issue. It often has to do with the > granularity/scale of the problem and as a problem evolves it may well need > to be "refactored" to express the solution using more or less of the "pure" > object facilities available. > |
re: 'I would suggest that it does not, in general, address all the
issues or cases for software development across the entire spectrum.' Of course it doesn't. I worked in an engineering environment writing software for an intelligent gripper (for a robot) that had to process real time data. The project manager made most of the decisions about what language to use (which was Pascal), environment, etc. After the system was implemented, it was found to be too slow. The PM had us go thru the code and short circuit loops by doing a break as soon as possible, use case statements, etc. The code improved by only a few milliseconds. What I am saying is, I find it to believe that an ST switch statement makes the difference between an acceptable software solution and an unacceptable one. However, good OO practice is sacrificed by using them, IMHO. --tc Sent via Deja.com http://www.deja.com/ Before you buy. |
Simple fact is that every version of Smalltalk is littered with the
equivalent of case statements. All you need to do is look for a nested if statement and you have a pretty good chance of replacing it with a case statement and making more readable and probably faster. Chris Lopeman Object Link Inc. [hidden email] wrote: > re: 'I would suggest that it does not, in general, address all the > issues or cases for software development across the entire spectrum.' > > Of course it doesn't. > > I worked in an engineering environment writing software for an > intelligent gripper (for a robot) that had to process real time data. > The project manager made most of the decisions about what language to > use (which was Pascal), environment, etc. After the system was > implemented, it was found to be too slow. The PM had us go thru the > code and short circuit loops by doing a break as soon as possible, use > case statements, etc. The code improved by only a few milliseconds. > > What I am saying is, I find it to believe that an ST switch statement > makes the difference between an acceptable software solution and an > unacceptable one. However, good OO practice is sacrificed by using > them, IMHO. > > --tc > > Sent via Deja.com http://www.deja.com/ > Before you buy. |
Chris Lopeman <[hidden email]> wrote in message
news:[hidden email]... > Simple fact is that every version of Smalltalk is littered with the > equivalent of case statements. All you need to do is look for a nested if > statement and you have a pretty good chance of replacing it with a case > statement and making more readable and probably faster. > Right. Or. . . I have a parent object aggregating a collection of children stored by keys, i.e., using a Dictionary. Very common pattern, is it not :-? Now I need to send a message to one of the children based on matching a key. So, its match the key, find the value and send a message to it. Uh, that's a case statement. |
No matter how bad it is, people make their own case/if elseif
classes. But the bigger problem is that there is no standardized class that we all can adhere to. And thats the shame of it. Costas Menico "Richard MacDonald" <[hidden email]> wrote: >Chris Lopeman <[hidden email]> wrote in message >news:[hidden email]... >> Simple fact is that every version of Smalltalk is littered with the >> equivalent of case statements. All you need to do is look for a nested if >> statement and you have a pretty good chance of replacing it with a case >> statement and making more readable and probably faster. >> >Right. Or. . . >I have a parent object aggregating a collection of children stored >by keys, i.e., using a Dictionary. Very common pattern, is it not :-? >Now I need to send a message to one of the children based on >matching a key. >So, its match the key, find the value and send a message to it. >Uh, that's a case statement. > > |
In reply to this post by lopemanc
What your saying is there is bad code in any language. I don't
disagree with you. --tc In article <[hidden email]>, Chris Lopeman <[hidden email]> wrote: > Simple fact is that every version of Smalltalk is littered with the > equivalent of case statements. All you need to do is look for a nested if > statement and you have a pretty good chance of replacing it with a case > statement and making more readable and probably faster. > > Chris Lopeman > Object Link Inc. > > [hidden email] wrote: > > > re: 'I would suggest that it does not, in general, address all the > > issues or cases for software development across the entire spectrum.' > > > > Of course it doesn't. > > > > I worked in an engineering environment writing software for an > > intelligent gripper (for a robot) that had to process real time data. > > The project manager made most of the decisions about what language to > > use (which was Pascal), environment, etc. After the system was > > implemented, it was found to be too slow. The PM had us go thru the > > code and short circuit loops by doing a break as soon as possible, use > > case statements, etc. The code improved by only a few milliseconds. > > > > What I am saying is, I find it to believe that an ST switch statement > > makes the difference between an acceptable software solution and an > > unacceptable one. However, good OO practice is sacrificed by using > > them, IMHO. > > > > --tc > > > > Sent via Deja.com http://www.deja.com/ > > Before you buy. > > Sent via Deja.com http://www.deja.com/ Before you buy. |
No, that is not what I am saying. What I am saying is that since most of us
admired Smalltalk (The base system) even to the point of basing our careers on it, and it has many occurrences of the type of statement, then that type of statement cant be all that bad. To add to this, I have seen far too many object oriented systems that have created far too many objects to do the job. Making them nearly impossible to understand, and delegate responsibility so much that nothing ever actually gets done. I will not create a new class or classes to do the job of a flag. Nor will I do it to do the job of a nested if statement that is used by one place; and would have each new class with a single method used to handle what the case statement can do. Chris Lopeman Object Link Inc. [hidden email] wrote: > What your saying is there is bad code in any language. I don't > disagree with you. > > --tc > > In article <[hidden email]>, > Chris Lopeman <[hidden email]> wrote: > > Simple fact is that every version of Smalltalk is littered with the > > equivalent of case statements. All you need to do is look for a > nested if > > statement and you have a pretty good chance of replacing it with a > case > > statement and making more readable and probably faster. > > > > Chris Lopeman > > Object Link Inc. > > > > [hidden email] wrote: > > > > > re: 'I would suggest that it does not, in general, address all the > > > issues or cases for software development across the entire > spectrum.' > > > > > > Of course it doesn't. > > > > > > I worked in an engineering environment writing software for an > > > intelligent gripper (for a robot) that had to process real time > data. > > > The project manager made most of the decisions about what language > to > > > use (which was Pascal), environment, etc. After the system was > > > implemented, it was found to be too slow. The PM had us go thru the > > > code and short circuit loops by doing a break as soon as possible, > use > > > case statements, etc. The code improved by only a few milliseconds. > > > > > > What I am saying is, I find it to believe that an ST switch > statement > > > makes the difference between an acceptable software solution and an > > > unacceptable one. However, good OO practice is sacrificed by using > > > them, IMHO. > > > > > > --tc > > > > > > Sent via Deja.com http://www.deja.com/ > > > Before you buy. > > > > > > Sent via Deja.com http://www.deja.com/ > Before you buy. |
In article <[hidden email]>,
Chris Lopeman <[hidden email]> wrote: >No, that is not what I am saying. What I am saying is that since most >of us admired Smalltalk (The base system) even to the point of basing >our careers on it, Okay that is pretty clear . . . >and it has many occurrences of the type of statement, Okay. >then that type of statement cant be all that bad. Now I am having trouble relating the pieces of the sentence. I've known people that have based their careers on Smalltalk and have written terrible code. I don't see how one relates to the other tho. Should someone strive to become better at their chosen career? My answer would be yes but not everyone agrees with that and 'strive to be better' has different meanings to different people. The result can be bad code. Also, sometimes a project has time and budget constraints and the code suffers. >To add to this, I have seen far too many object oriented systems that >have created far too many objects to do the job. You've seen bad code, so have I. >Making them nearly impossible to understand, and delegate >responsibility so much that nothing ever actually gets done. Yes, we've both seen bad code. >I will not create a new class or classes to do the job of a flag. Nor >will I do it to do the job of a nested if statement that is used by >one place; and would have each new class with a single method used >to handle what the case statement can do. And that is your decision to make. I don't think we are going to be able to enumerate all the cases and how to handle them in a forum message. >Chris Lopeman >Object Link Inc. --tc Sent via Deja.com http://www.deja.com/ Before you buy. |
In reply to this post by lopemanc
Chris Lopeman <[hidden email]> wrote in message
news:[hidden email]... > No, that is not what I am saying. What I am saying is that since most of us > admired Smalltalk (The base system) even to the point of basing our careers > on it, and it has many occurrences of the type of statement, then that type > of statement cant be all that bad. > I believe we should minimize case statements and use polymorphism wherever possible, but: (1) too much of a good thing makes code hard to read, as stated by Chris (2) there is a point where it "bottoms out" and if-then-else is required, i.e,. case is *required*. I think :-) We had a discussion about this perhaps a year ago and I'm sure we determined case statements were necessary at some point. Unfortunately, I'm drawing a blank on the definitive argument. Perhaps its was just that eliminating them would require doing self-brain-surgery on the base classes, such as Number. Interesting subject: Are case statements necessary for even a pure OO language? |
Case statements are quite useful when parsing external information,
i.e. data from other software or external files. However, for code that is completely under control of a smalltalk developer, and information that is completely internal, I don't know of any reason to use a case statement. -- Terry =========================================================== Terry Raymond Smalltalk Professional Debug Package Crafted Smalltalk *Breakpoints* and *Watchpoints* for 19 Tilley Ave. VW and ENVY/Developer Newport, RI 02840 (401) 846-6573 [hidden email] http://www.craftedsmalltalk.com =========================================================== "Richard MacDonald" <[hidden email]> wrote in message news:kYnM5.15194 > We had a discussion about this perhaps a year ago and I'm sure we determined > case statements were necessary at some point. Unfortunately, I'm drawing a > blank on the definitive argument. Perhaps its was just that eliminating them > would require doing self-brain-surgery on the base classes, such as Number. > > Interesting subject: Are case statements necessary for even a pure OO > language? > > |
In article <8tt3ii$[hidden email]>,
"Terry Raymond" <[hidden email]> wrote: > Case statements are quite useful when parsing external information, > i.e. data from other software or external files. However, for code > that is completely under control of a smalltalk developer, and information > that is completely internal, I don't know of any reason to use a case > statement. In my experience both of the above statements are correct. The only time I've "really needed" a case statement, and devolved to writing a bunch of 'if' statements, was when trying to make decisions about the proper classes to create based on values returned from system calls. Other than that, my desire for a case statement has always turned out to be my brain being lazy, recalling years of using case statements in other languages, and not wanting to think about how to use objects to solve the problem at hand. Interestingly, even in the cases where I've used a case statement to handle those nasty values returned by the operating system, in the end I've gotten better performance out of a more object-oriented solution. If anyone wants specifics I'll be happy to discuss it. -- Bob Jarvis Compuware @ Timken Sent via Deja.com http://www.deja.com/ Before you buy. |
Free forum by Nabble | Edit this page |