I was reading http://eli.thegreenplace.net/2007/06/21/sicp-section-11/
and writing J versions of the exercises.  When I got to 1.7 I wrote this:


sqrt_iter=: dyad define
  improved_guess=. x improve y
  if. x close_enough improved_guess do.
    improved_guess
  else.
    improved_guess sqrt_iter y
  end.
)

improve=: [ average %~
average=: + % 2:
close_enough=: 1 = 0.999 1.001 I. %
square=: *~
mysqrt=: 1&sqrt_iter

Now, mysqrt is a faithful reimplementation of
the version Eli posted.  But I try to avoid
recursion in J, especially for simple expressions,
because it is so slow.

So, I rewrote the core of the above to
use iteration instead of recursion:

sqrt_iter=: dyad define
  whilst. -. x close_enough guess do.
    guess=. x
    x=. guess improve y
  end.
)

This is better, though perhaps my names
are not the best.  But it's still slower and
bulkier than it really needs to be.  All we
really need for this exercise is:

mysqrt=: improve~^:_ 1:

Notice, by the way, that the testing function
'close_enough' has vanished.  Instead we keep
going until the result stops changing.

Of course, if we fix that definition and look
at it, it's still a bit more complicated than
it needs to be, because of the whole
"swapping arguments left and right" thing:

   mysqrt f.
(([ (+ % 2:) %~)~^:_) 1:

Also, J already has -: which gives us
half of a number.

So we could write this more directly as:

mysqrt=: (] -:@+ %)^:_ 1:

And note, by the way, that this definition
works on arrays:

   mysqrt 2 3 4
1.41421 1.73205 2

And that's about as simple as you can get, I imagine,
unless you are willing to use J's built-in square root
function:

   %:

And, of course, the built in will be a lot faster...

I suppose a key issue here is "what are we  trying to
teach".  But I am not at all sure that teaching about
recursion has more value than teaching about mechanisms
like ^:

-- 
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to