Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!amdcad!ames!think!bloom-beacon!gatech!mcnc!decvax!cca!g-rh From: g-rh@cca.CCA.COM (Richard Harter) Newsgroups: comp.software-eng Subject: Re: examples complexity measure usage Message-ID: <23080@cca.CCA.COM> Date: 9 Jan 88 07:09:54 GMT References: <398e2f3e.fed5@apollo.uucp> Reply-To: g-rh@CCA.CCA.COM.UUCP (Richard Harter) Organization: Computer Corp. of America, Cambridge, MA Lines: 101 Summary: Discussion of example 1 In article <398e2f3e.fed5@apollo.uucp> marc@apollo.uucp (Marc Gibian) writes: >As promised, here are some examples of decreasing the quality of code >while reducing the complexity measure value... > >original fragment: > > if (a == value1) then > y = target1; > else if (b == value2) then > y = target2; > else if (c == value3) then > y = target3; > else if (d == value4) then > y = target4; > else if (e == value5) then > y = target5; > else if (f == value6) then > y = target6; > end if; > >transformed fragment: > > new_func((a == value1), target1); > new_func((b == value2), target2); > new_func((c == value3), target3); > new_func((d == value4), target4); > new_func((e == value5), target5); > new_func((f == value6), target6); > >with new_func defined as: > >new_func(relation_value, target) >{ > if (relation_value) then > y = target; > end if; >} I would agree that the altered code is less desirable than the original code -- indeed the altered code is not correct in that it is not equivalent to the original code! The altered code goes through all tests whereas the original code stops testing when a match is found. The fundamental problem with the complexity measure in this case is, I believe, twofold: (a) that the language being used lacks the construct being used, and (b) the complexity measure is incorrectly calculated. The language doesn't really capture the parallelism of the construct. The desired construct, in pseudocode, runs something like this: define value list A = {a,b,c,d,e,f} define desired value list B corresponding to A = {value1,value2,value3,value4,value5,value6} define target list C corresponding to A = {target1,target2,target3,target4,target5,target6} loop through list A if item from A equals coresponding desired item from B then set y to target in C corresponding to item from A and exit from loop If the lists are short one prefers to embed them implicitly in the code; if they are long one prefers to be put them in tables. However this solution is not available if the types in the the value list are not all the same. If we borrow the naked select statement from PL/I the code would look like this select { a==value1: y = target1; break; b==value2: y = target2; break; ...... f==value6: y = target6; break; } Whether each case should count as an increment in complexity depends on the cases. In this instance the cases are parallel -- I would feel that the appropriate measure of complexity is the logarithm of the number of cases. If, however, the cases are not parallel, then I would feel that the compexity goes up linearly with the number of case. [I am not prepared to defend this position.] In any case what we see here is a complex structure that uses code repetition rather than data repetition. Neither the language being used, nor the complexity measure being used provide means for dealing with the higher level construct. Each, in its own way, deals with the higher level construct only in terms of lower level constructs. I would agree that the complexity measure being used does not adequately measure the complexity of the code -- I would argue that the fault lies in the lack of adequate means for heirarchical composition of structure in the language and a corresponding lack of measurement in the complexity measurement tool. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.