Refactoring REXX - Temporarily Inlined Functions

Автор: Martin Packer

Дата: 16.07.2013

Источник: IBM developerWorks

You could consider this another in the Small Programming Enhancement (SPE) :-) series. You’ll probably also notice I’ve been doing quite a lot of REXX programming recently. Anyway, here’s a tip for refactoring code I like.

Suppose you have a line of code:

norm_squared=(i-j)*(i-j)

that you want to turn into a function.

No biggie:

norm2: procedure
parse arg x,y

return (x-y)*(x-y)

and call it with:

norm_squared=norm2(i,j)

But what about the process of developing that function? Most naturally you might scroll to the bottom of the member you’re editing and add the function there. But that’s a pain as your iterative development would require you to scroll down to where it’s defined at the bottom and up to where it’s called. Many times over.

Try the following, though:

/* REXX */

do i=1 to 10
  do j=1 to 10
    say i j norm2(i,j)

/* do never */
if 0 then do

norm2: procedure
parse arg x,y

return (x-y)*(x-y)

/* end do never */
end

  say "After procedure definition"
  end
end
exit

It works just fine: The “if 0” condition is never met: It’s effectively a “do never” and you have to have it or else the REXX interpreter will crash into the function definition. (You can’t use a SIGNAL instruction if this is inside a loop or function definition for this purpose as it throws away the context. Early attempts did do this but it immediately failed once I tried it inside a loop: You learn and move on.)

What this enables you to do is to develop the function “inline” and then you can move it later - to another candidate invocation or indeed to the end of the member (or even to a separate member).

It saves a lot of scrolling about and encourages refactoring into separate routines. It’s not the same as an anonymous function but it’s heading in that direction, in terms of utility.

In that vein you might choose not to move the function away from “in line” - particularly if its use is “one time”. If you don’t you could consider an unmnemonic function name, such as “F12345” - which I wouldn’t normally recommend. But sometimes it’s really hard to come up with a meaningful function name. :-)