From: topmind on

Robert Martin wrote:
> On 2007-01-25 22:53:48 -0600, "topmind" <topmind(a)technologist.com> said:
>
> >
> > Robert Martin wrote:
> >> On 2007-01-24 01:35:40 -0600, frebe73(a)gmail.com said:
> >
> >> Consider this:
> >>
> >> Select employee_number from employee where date_of_birth < 1952 and sex
> >> = F and employment_type = EXEMPT OR emloyment_type = SPECIAL and salary
> >> > 90000;
> >>
> >> I'd like to hide this behind:
> >>
> >> find_all_employees_eligible_for_early_retirement();
> >>
> >> Firstly, it makes the program easier to understand.
> >
> > Do you think that those who disagree WANT hard-to-understand programs?
>
> No. What does that have to do with my statement?


You are implying that we don't know the difference between "easy to
understand" and "hard to understand", and that is why we don't wrap
more. I know pretty well after all these years what trips me up and
what doesn't. What I cannot do is heavily extrapolate that to everybody
else because brains are too different.


> > Perhaps SQL trips you up,
>
> No.
>
> > but you have to be
> > careful which psychology of yours you extrapolate to other human
> > beings.
>
> You are completely missing the point. The Select statment above is
> loaded with detail. (DOB, salary, emloyee type etc). The function
> simply named the policy. Hiding that detail behind the policy name is
> a good, and very old, engineering discipline.

Not every damned detail under the sun. This sounds similar to a debate
that raged on C2 a few years ago:

http://c2.com/cgi/wiki?HeadlinesTechnique

http://c2.com/cgi/wiki?LongFunctionsDiscussion


> >> Secondly, it
> >> isolates the policy from the implementation. I can change the
> >> implementaiton of the SQL statement without affecting the functions
> >> that call find_all_employees...
> >
> > But you fail to consider simplicity. If such a statement is only used
> > *once*, then wrapping it in a function/method creates more code and
> > more red tape. That creates confusion and slower productivity in
> > itself. It is not a free lunch.
>
> 1. That's a big if.
> 2. Putting a select statement into a function requires a negligible
> amount of code that has a one-time negligible cost.

It adds code, interface maitaining layers, and fill up the "function
space".

> 3. Giving the select statement a name reduces confusion and increases
> productivity every time the statement is read.

Not specific enough. Too much clutter slows me down, and superfulous
chunk-a-tizing creates clutter.

>
> > I agree that if it is used several times, then it makes sense to put it
> > into a shared function. But you seem to want to wrap ever last one.
>
> In general I do. For any number of different reasons.
>
> 1. It's clearer.

By what metric? You again seem to be extrapolating your personal
preferences to others.

> 2. It's easier to test since I can replace the function implementations
> with canned data.

I see no reason to test at such a small level. Testing an SQL statement
outside of the context of the app is of marginal use anyhow. Do you
wrap every math formula and reg-ex also?

// RCM lampoon code
....
x = addThreeNumbers(a, b, c);
....
function addThreeNumbers(a, b, c) {
return(a + b + c);
}


> 3. I can deploy the business rules that call the functions separately
> from the SQL that implements the functions. (This is a big deal for
> most medium to large systems, and even has significant impact on
> smaller systems)

Please clarify.

>
>
> --
> Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com

-T-

From: Robert Martin on
On 2007-01-26 18:12:29 -0600, "topmind" <topmind(a)technologist.com> said:

> You are implying that we don't know the difference between "easy to
> understand" and "hard to understand", and that is why we don't wrap
> more. I know pretty well after all these years what trips me up and
> what doesn't. What I cannot do is heavily extrapolate that to everybody
> else because brains are too different.

Consider this:

Select employee_number from employee where date_of_birth < 1952 and sex
= F and employment_type = EXEMPT OR emloyment_type = SPECIAL and salary
> 90000;

I'd like to hide this behind:

find_all_employees_eligible_for_early_retirement();

It seems to me that the first exposes implementation and the second
exposes intent. Generally, when programs expose intent, they are
easier to understand.


--
Robert C. Martin (Uncle Bob)��| email: unclebob(a)objectmentor.com
Object Mentor Inc.� � � � � ��| blog:��www.butunclebob.com
The Agile Transition Experts��| web:���www.objectmentor.com
800-338-6716� � � � � � � � ��|



From: topmind on

Robert Martin wrote:
> On 2007-01-26 18:12:29 -0600, "topmind" <topmind(a)technologist.com> said:
>
> > You are implying that we don't know the difference between "easy to
> > understand" and "hard to understand", and that is why we don't wrap
> > more. I know pretty well after all these years what trips me up and
> > what doesn't. What I cannot do is heavily extrapolate that to everybody
> > else because brains are too different.
>
> Consider this:
>
> Select employee_number from employee where date_of_birth < 1952 and sex
> = F and employment_type = EXEMPT OR emloyment_type = SPECIAL and salary
> [greater than] 90000;

[greater than symbols throw off indenter so I replaced it.]

>
> I'd like to hide this behind:
>
> find_all_employees_eligible_for_early_retirement();
>
> It seems to me that the first exposes implementation and the second
> exposes intent. Generally, when programs expose intent, they are
> easier to understand.

Do this:

// find employees elegible for ealy retirement
rs = query(std, "SELECT emp_no FROM employees WHERE...");

It is unnecessary to create a function/method JUST to name something.
And if there are parameters (usually the case), then there is the
extra effort of maintaining the interface parameters.

Further, it clogs up the function space with names like:

find_all_good_ employees_eligible_for_early_retirement();
find_all_bad_ employees_eligible_for_early_retirement();
find_all_employees_eligible_for_raises();
find_all_employees_who_didnt_pay_their_parking_permit();
find_all_employees_who_dont_have_parking_permits();
find_employees_who_lost_a_pink_sweater_last_friday();
find_employees_who_think_oop_is_the_pits();

The big-picture functions get lost in the dandruff of SQL wrapping.
Large function spaces decrease the speed of me finding functions and
groking the app. I know that is a fact for me. It is a truism for me.
If you have a magic memory or are a speed-reader, congratulations for
being a superior being. But I am not a speed reader such that your
assumptions about what throws you off do not necessarily apply to me.
I KNOW WHAT SLOWS ME DOWN better than anybody because I am stuck with
my body and my brain (for good or bad) and have been for many many
decades.

You wouldn't do this I assume:

x = sumFourNumbers(a,b,c,d);
....
function sumFourNumbers(a,b,c,d) {
return(a + b + c + d);
}

If you *wouldn't* do it for math, then why would you do it for
queries? When such functions/methods are single-use, you are crossing
the line between hiding implimentation and making an e-beurocracy out
of code. K.I.S.S. is an important factor in easy maintanence.


> --
> Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com

-T-

From: Robert Martin on
On 2007-01-29 17:35:39 -0600, "topmind" <topmind(a)technologist.com> said:

>
> Robert Martin wrote:
>> On 2007-01-26 18:12:29 -0600, "topmind" <topmind(a)technologist.com> said:
>>
>>> You are implying that we don't know the difference between "easy to
>>> understand" and "hard to understand", and that is why we don't wrap
>>> more. I know pretty well after all these years what trips me up and
>>> what doesn't. What I cannot do is heavily extrapolate that to everybody
>>> else because brains are too different.
>>
>> Consider this:
>>
>> Select employee_number from employee where date_of_birth < 1952 and sex
>> = F and employment_type = EXEMPT OR emloyment_type = SPECIAL and salary
>> [greater than] 90000;
>
> [greater than symbols throw off indenter so I replaced it.]
>
>>
>> I'd like to hide this behind:
>>
>> find_all_employees_eligible_for_early_retirement();
>>
>> It seems to me that the first exposes implementation and the second
>> exposes intent. Generally, when programs expose intent, they are
>> easier to understand.
>
> Do this:
>
> // find employees elegible for ealy retirement
> rs = query(std, "SELECT emp_no FROM employees WHERE...");

Why? All that does is add detail to what would otherwise be a nice
clear program. Why would you prefer:

// DO A
akwlke;rlkj;wlekmrw;lekjrwe
welrkjwe;lkrjw;lekjrw;lkejr
lwje;lkrjw;eiruw;elkrnw;leknrp;owie
we;lkrjw;eoijrw;lekr
wekljrwpeoijrw[oeirjw;elkrnj
l;wker;owijer;lkwejmrpoijw

// DO B
w;lekjr;wlkmnef[owiejf;lwkejnf
welkjwe;lrkjw;elkrjw;eiorjw;elrknjwer
welkjrwo;eklrjw;elirjWer;lkwjer;lkj
wejklrw;eijo
wer;lkjwe;riljwe
we;lrkjweporiwerpoiu

to just:

DO_A();
DO_B();

Oh, and then there's the problem of comments that don't actually
describe what's going on because they don't get maintained. Yes, I
know we shouldn't do that, but...
>
> It is unnecessary to create a function/method JUST to name something.

It may not be necessary, but it is remarkably beneficial.

> And if there are parameters (usually the case), then there is the extra
> effort of maintaining the interface parameters.

Again, we like to make sure the parameters have meaning, so that the
code reads well.
>
> Further, it clogs up the function space with names like:
>
> find_all_good_ employees_eligible_for_early_retirement();
> find_all_bad_ employees_eligible_for_early_retirement();
> find_all_employees_eligible_for_raises();
> find_all_employees_who_didnt_pay_their_parking_permit();
> find_all_employees_who_dont_have_parking_permits();
> find_employees_who_lost_a_pink_sweater_last_friday();
> find_employees_who_think_oop_is_the_pits();

So what? The functions space is big.

> The big-picture functions get lost in the dandruff of SQL wrapping.

That's just silly. Lesser theorems do not get lost in the dandruff of
larger theorems. Go back to geometry and prove that the sum of angles
in a triangle is 180 using nothing but postulates and no sub theorems.

> Large function spaces decrease the speed of me finding functions and
> groking the app.

Quite to the contrary.

> I know that is a fact for me. It is a truism for me. If you have a
> magic memory or are a speed-reader, congratulations for being a
> superior being.

I have an IDE.

> But I am not a speed reader such that your assumptions about what
> throws you off do not necessarily apply to me. I KNOW WHAT SLOWS ME
> DOWN better than anybody because I am stuck with my body and my brain
> (for good or bad) and have been for many many decades.

I don't doubt that you do. However, you tend to make assumptions for
everyone. e.g. OOP_IS_MAD.

> You wouldn't do this I assume:
>
> x = sumFourNumbers(a,b,c,d);
> ...
> function sumFourNumbers(a,b,c,d) {
> return(a + b + c + d);
> }

No, but I would very likely do this:

function computeInitialRentPayment(securityDeposit, monthlyRate) {
return securityDeposit + monthlyRate;
}

>
> If you *wouldn't* do it for math, then why would you do it for queries?

Because queries have an intent that is not communicated by their syntax.

> When such functions/methods are single-use, you are crossing the line
> between hiding implimentation and making an e-beurocracy out of code.
> K.I.S.S. is an important factor in easy maintanence.

K.I.S.S. does not mean: "hide intent".


--
Robert C. Martin (Uncle Bob)��| email: unclebob(a)objectmentor.com
Object Mentor Inc.� � � � � ��| blog:��www.butunclebob.com
The Agile Transition Experts��| web:���www.objectmentor.com
800-338-6716� � � � � � � � ��|



From: topmind on

Robert Martin wrote:
> On 2007-01-29 17:35:39 -0600, "topmind" <topmind(a)technologist.com> said:
>
> >
> > Robert Martin wrote:
> >> On 2007-01-26 18:12:29 -0600, "topmind" <topmind(a)technologist.com> said:
> >>
> >>> You are implying that we don't know the difference between "easy to
> >>> understand" and "hard to understand", and that is why we don't wrap
> >>> more. I know pretty well after all these years what trips me up and
> >>> what doesn't. What I cannot do is heavily extrapolate that to everybody
> >>> else because brains are too different.
> >>
> >> Consider this:
> >>
> >> Select employee_number from employee where date_of_birth < 1952 and sex
> >> = F and employment_type = EXEMPT OR emloyment_type = SPECIAL and salary
> >> [greater than] 90000;
> >
> > [greater than symbols throw off indenter so I replaced it.]
> >
> >>
> >> I'd like to hide this behind:
> >>
> >> find_all_employees_eligible_for_early_retirement();
> >>
> >> It seems to me that the first exposes implementation and the second
> >> exposes intent. Generally, when programs expose intent, they are
> >> easier to understand.
> >
> > Do this:
> >
> > // find employees elegible for ealy retirement
> > rs = query(std, "SELECT emp_no FROM employees WHERE...");
>
> Why? All that does is add detail to what would otherwise be a nice
> clear program. Why would you prefer:
>
> // DO A
> akwlke;rlkj;wlekmrw;lekjrwe
> welrkjwe;lkrjw;lekjrw;lkejr
> lwje;lkrjw;eiruw;elkrnw;leknrp;owie
> we;lkrjw;eoijrw;lekr
> wekljrwpeoijrw[oeirjw;elkrnj
> l;wker;owijer;lkwejmrpoijw
>
> // DO B
> w;lekjr;wlkmnef[owiejf;lwkejnf
> welkjwe;lrkjw;elkrjw;eiorjw;elrknjwer
> welkjrwo;eklrjw;elirjWer;lkwjer;lkj
> wejklrw;eijo
> wer;lkjwe;riljwe
> we;lrkjweporiwerpoiu
>
> to just:
>
> DO_A();
> DO_B();
>

Often I do. It reduces "jumping around" to inspect details, and
reduces the maintenence of interfaces/parameters. I've tried to get
out of the business of telling people what their eyes and brains
*should* like. I've found out the hard way that people think
differently. Some have fast eyes and slow brains, and visa versa, and
compensate in different ways. I don't insist that my pet tools are
objectively better, but rather now try to focus on why they fit my
mental work processes (personal psychology). There are times where I
think my pet tech objectively favors the change pattern frequencies I
observe, but we disagree on these frequencies also. One can show that
something is better for given change frequencies, but the actual
values of such frequencies are merely anecdotal at this stage.

Note that I prefer dashes for larger blocks:

// ------ Do B

w;lekjr;wlkmnef[owiejf;lwkejnf
welkjwe;lrkjw;elkrjw;eiorjw;elrknjwer
welkjrwo;eklrjw;elirjWer;lkwjer;lkj
wejklrw;eijo

// ------- Do C

w;lekjr;wlkmnef[owiejf;lwkejnf
welkjwe;lrkjw;elkrjw;eiorjw;elrknjwer
wsdfsf...


> Oh, and then there's the problem of comments that don't actually
> describe what's going on because they don't get maintained. Yes, I
> know we shouldn't do that, but...

Same applies to function/method names. A program can still work even
though the function/method name has grown obsolete. Thus, there is no
immediate incentive to fix it, just like comments.

> >
> > It is unnecessary to create a function/method JUST to name something.
>
> It may not be necessary, but it is remarkably beneficial.

I disagree in many cases.

>
> > And if there are parameters (usually the case), then there is the extra
> > effort of maintaining the interface parameters.
>
> Again, we like to make sure the parameters have meaning, so that the
> code reads well.

Often they just feed something with a name into something else with a
similar name. Wasting code going in and out and in and out and up and
down. Mamma's got a squeaze-box...

> >
> > Further, it clogs up the function space with names like:
> >
> > find_all_good_ employees_eligible_for_early_retirement();
> > find_all_bad_ employees_eligible_for_early_retirement();
> > find_all_employees_eligible_for_raises();
> > find_all_employees_who_didnt_pay_their_parking_permit();
> > find_all_employees_who_dont_have_parking_permits();
> > find_employees_who_lost_a_pink_sweater_last_friday();
> > find_employees_who_think_oop_is_the_pits();
>
> So what? The functions space is big.

But human brains and eyes have limits. It is the people who we are
catering to here, not so much the machines.

>
> > The big-picture functions get lost in the dandruff of SQL wrapping.
>
> That's just silly. Lesser theorems do not get lost in the dandruff of
> larger theorems. Go back to geometry and prove that the sum of angles
> in a triangle is 180 using nothing but postulates and no sub theorems.

Sub-theorems are fine. Sub-Sub-Sub-Theorems are overkill in my
opinion.

>
> > Large function spaces decrease the speed of me finding functions and
> > groking the app.
>
> Quite to the contrary.

Please re-read this. I don't think you realized what you just objected
to.

>
> > I know that is a fact for me. It is a truism for me. If you have a
> > magic memory or are a speed-reader, congratulations for being a
> > superior being.
>
> I have an IDE.

Still it produces more candidate matches to visually sift thru. Plus,
if you print out code for paper-based inspection, one may not have an
IDE. Further, one can tune an IDE to work around many of the problems
you claim exist in p/r code.

>
> > But I am not a speed reader such that your assumptions about what
> > throws you off do not necessarily apply to me. I KNOW WHAT SLOWS ME
> > DOWN better than anybody because I am stuck with my body and my brain
> > (for good or bad) and have been for many many decades.
>
> I don't doubt that you do. However, you tend to make assumptions for
> everyone. e.g. OOP_IS_MAD.

"Mad" is not necessarily a technical term. See above regarding my anti-
OO rants. Your book is written as if your design decisions are a
mathematical truism, not a subjective preference. I object to the
industry implication that OO is a slam-dunk sureshot. If it is a
subjective personal proference, they should clearly tell the readers.

>
> > You wouldn't do this I assume:
> >
> > x = sumFourNumbers(a,b,c,d);
> > ...
> > function sumFourNumbers(a,b,c,d) {
> > return(a + b + c + d);
> > }
>
> No, but I would very likely do this:
>
> function computeInitialRentPayment(securityDeposit, monthlyRate) {
> return securityDeposit + monthlyRate;
> }

You're kidding, right?

I think our differences are far beyond OO versus p/r.

>
> >
> > If you *wouldn't* do it for math, then why would you do it for queries?
>
> Because queries have an intent that is not communicated by their syntax.

That is why we have comments. Plus, often there is only one SQL
statement per task such that the task name describes what it does.

>
> > When such functions/methods are single-use, you are crossing the line
> > between hiding implimentation and making an e-beurocracy out of code.
> > K.I.S.S. is an important factor in easy maintanence.
>
> K.I.S.S. does not mean: "hide intent".

It does not mean wrap every piece of dust either.

>
>
> --
> Robert C. Martin (Uncle Bob) | email: unclebob(a)objectmentor.com
> Object Mentor Inc. | blog: www.butunclebob.com
> The Agile Transition Experts | web: www.objectmentor.com
> 800-338-6716 |

-T-