Bo Jacoby wrote:
> But perhaps the komma (,) should be komma dot (,.)
> such that y may be a list.
You know, I was fairly confident in my tacit translation's fidelity, and
applauded J's notation (again) for making it so easy.
But I didn't consider rank! Rank is so invisible and so natural it doesn't
often "stand out" for translation. Since the original
explicit verb had unbounded rank (as all explicit verbs do), and both + and *
are scalar, then the original could consume arguments
of any (conformable) rank.
I only considered my tacit translation in the context of scalar arguments*.
The cute little feature I added -- p. -- enforced
this assumption, given the dyad has left rank 1. D'oh! Of course, we could
fix it up in a snap with Et1=: Et"0 but that's
brute force, IMO. We could also fix it up with a more faithful
transliteration of the original code, e.g. with
Et2 =: ,&< ( (1 {:: [) + (0 {:: [) * 1 o. ])^:_ ]
But this is kind of a cop out, and anyway suffers from the issue that I
originally employed p. to avoid. Specifically, J verbs
can have at most 2 arguments, and if you want more you have to pack and unpack,
which is ugly and obscures the heart of the
algorithm (which is what you want to focus on). Compounding this, tacit verbs
can't have temporary (or any other) variables, so to
pass data around a tacit verb one must do un/packing in several places (as
opposed to just before you call the verb). That
secondary problem isn't so evident in this case, but it is in the general one.
Much better to let the proper rank fall out, by judicious selection of
components and careful composition. I really like how you
did this for the case where y is a list: all you had to do was add a single
dot. For the more general case of an arbitrary ranked
y (but still scalar x ) we'd have to write something like:
Et3 =: ,"0/~ (p. 1&o.)^:_ ]
But again that "0 feels a little forced. So how about:
Et4 =: 0&|:@,:~ (p. 1&o.)^:_ ]
or a little cleaner:
Et5 =: ] (p. 1&o.)^:_~ 0 |: ,:~
But now we must consider whether ,"0/~ is more immediately understandable
than 0 |: ,:~ and whether |: also feels forced,
anyway. And, should we decide these questions are "stylistic" and best
answered by context and personal preference, we must now
wrestle with the performance implications of our preferred styles:
ways=: E`Et1`Et2`Et3`Et4`Et5
ts =: 6!:2 , 7!:2@:]
R =: 3 ts&> '0.2 ' ,L:0 ways ,L:0 ' Y'[Y=:0.2*o.i.69 14 32 5
(>ways) ,. '6.2d' 8!:2 (%"1 <./) (%"1 <./) R
E 1.01 11.98
Et1 7.76 1.00
Et2 1.00 11.98
Et3 3.10 13.98
Et4 2.96 13.98
Et5 2.95 13.98
So it took an iteration to write tacit code as general as the original
(obvious) explicit code, it didn't improve performance in the
first place, and then it just led us down a path to decreased performance**.
But I still prefer tacit code.
-Dan
* I guess this is another good reason to include example inputs & outputs
when posting J puzzles.
** Well, let me down that path, anyway; I don't see others focusing so much on
tacit style as I do.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm