Geoff Canyon <[EMAIL PROTECTED]> wrote:
> I'm trying to write a monadic function that will take a number,  
> create a list of that number times 1..6, with each number's  
> characters sorted, and return whether they are all the same. So f 17  
> would look at the list 17 34 15 68 58 012 and return 0. Here's my  
> closest attempt so far:
>
> =/ /:~ each ": each <"0 (>:i.6)*]
>
> <"0 (>:i.6)*26 returns
>
> +--+--+--+---+---+---+
> |26|52|78|104|130|156|
> +--+--+--+---+---+---+
>
> But
>
> f=:<"0 (>:i.6)*]
>     f 26
> 0 1 1 1 1 1
>
> That looks to me like < is being treated dyadically, and returning  
> false, true, true, etc. What do I need to do to force it to box instead?

You have fallen into a common J pitfall.

In trains of odd length (for example, (a b c d e f g)),  the verbs are
arranged as a series of forks (in this case, (a b (c d (e f g))).
The odd-numbered terms (a, c, e, g) operate on the given parameter,
while the even-numbered terms (b, d, f) operate on the results of those verbs.

However, if a train has an even length, the leftmost verb create a hook
(a b c d e f) becomes (a (b c (d e f)).
which can sometimes be useful, but more often than not is the result of an
error.

A hook (a b) is equivalent to the fork ([ a [EMAIL PROTECTED])

If you want to use a monadic verb within a fork, or train of forks,
rather than using a hook, you should use a capped fork ([: a b)

   f=:[: <"0 (>:i.6)*]
   f 26
+--+--+--+---+---+---+
|26|52|78|104|130|156|
+--+--+--+---+---+---+

You can also use a@:b which is equivalent (or [EMAIL PROTECTED] if b is known 
to have infinite rank):
   f=:<"0@:((>:i.6)*])
although in this particular case, use of the capped fork is probably better,
since it avoids a klunky set of parentheses, and as the two are equivalent,
which to use is often a matter of style.

In monadic trains, you can slso replace forks of the form (constant dyad ])
with the bond (constant&dyad) which can sometimes clarify matters,
although in this particular case, it doesn't really buy you anything.

>=/ /:~ each ": each NB. seems to work, but is there a better way than  
>two eaches?
>
> Finally, putting it all together:
>
> f=: =/ /:~ each ": each <"0 (>:i.6)*]
>     f 4
> |domain error: f
> |       f 4

Since this train contains a lot of monadic verbs, it needs a lot of capped 
forks:
   f=: [: =/ [: /:~ each [: ": each [: <"0 (>:i.6)*]
   f 4
0

(which is equivalent to Roger's use of conjunctions):
  f=: =/ @: (/:~ each) @: (": each) @: (<"0) @: ((>:i.6)*])

> 1. So what _does_ =/ mean?

The result has a technically-defined meaning, but it is generally not
useful for anything except booleans.

In mots cases, it will complare the leftmost two items
and produce a boolean result. It will then compare this boolean with
the previous value (which will likely be 0 if that value is of
some other type than boolean.)

In general, f/ produces less than useful results if f's output
type is different than it input types. This can be doubly true if
the parameters themselves have different types and/or shapes.
(+/ */ +./ ,/ ,&.</ etc. are useful; =/ e./ i./ ":/ generally aren't)

Sometimes such verbs can be useful with parameters of restricive domains.
Since verbs like = ~: < <: > >: return booleans, =/ ~:/ etc. are useful on
boolean lists (for example, = is equivalent to exclusive-nor, ~: is
equivalent to exlcusive-or).
Since i. and i: return indices and { uses them,
{/ and i./ and i:/ could be useful on permutations.

There are three special cases that apply to all lists:
f/ a list of length 2 just applies f between the two items. This works for all 
verbs.
f/ a list of length 1 just returns that item, and the verb f is not actually 
used at all
f/ a list of length 0 returns the identity for f (only a few verbs have 
identities).

> 2. If it doesn't mean anything, is it possible for me (any user) to  
> define =/=:1&=#]  ? (apparently not)

Primitives cannot be assigned nor reassigned

> 3. Is there a way to compose my two lines above into a single command?

> 4. To avoid all the @: above, should I be looking for ways to turn it  
> into forks and/or hooks?

See above.

> I have to add: my brain hurts! (in a good way)

Yes, J has a habit of doing that. It seems to activate different
parts of the brain than procedural languages. This is one reason I love it :)

-- Mark D. Niemiec <[EMAIL PROTECTED]>

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

Reply via email to