On 6/30/07, Tracy Harms <[EMAIL PROTECTED]> wrote:
Recently I enjoyed producing the sequence of
triangular numbers through the following code:
+/\}.i.>:
I imagine you did something like
+/\}.i.>: 3
I sort-of understand why the conjunctions are required
when defining verbs, but not required when entering
literal command-line entries.
Conjunctions are not required in either of these cases, though
of course they can be used.
Please help me understand why triangularNumber does
what it does. Thank you.
I think you are trying to understand the topic describe in
the J dictionary under "Parsing and Execution".
First off, let's consider +/\}.i.>:3 so we can draw contrasts.
The first thing J does when evaluating this is break it apart into
words.
;:'+/\}.i.>: 3'
+-+-+-+--+--+--+-+
|+|/|\|}.|i.|>:|3|
+-+-+-+--+--+--+-+
And, then it works from right to left, shifting each word onto a stack,
and then inspecting the top four words on that stack. When those
top four words fit a certain pattern, it evaluates them using the
corresponding parsing rule, and updates the stack accordingly.
These parsing rules are documented at
http://www.jsoftware.com/help/dictionary/dicte.htm
Anyways, back to your example:
words stack action
+ / \ }. i. >: 2 shift word to stack
+ / \ }. i. >: 2 shift word to stack
+ / \ }. i. >: 2 shift word to stack
+ / \ }. i. >: 2 shift word to stack
+ / \ }. i. >: 2 1 Monad
Note: }. i. >: 3 matched the pattern EDGE+AVN VERB VERB NOUN
In this case, }. is a verb which matches the AVN part of EDGE+AVN
(since AVN denotes ADV+VERB+NOUN).
Note also that the 1 Monad action processes the rightmost verb and
the noun to its right, replacing both of them with the result of
that verb acting on that noun.
+ / \ }. i. 3 shift word to stack
+ / \ }. i. 3 1 Monad
+ / \ }. 0 1 2 shift word to stack
Note that 0 1 2 is a single word from J's point of view.
+ / \ }. 0 1 2 shift word to stack
+ / \ }. 0 1 2 shift word to stack
EDGE + / \ }. 0 1 2 3 Adverb
Here, J combines + and \ to produce the verb we will be using
for summation. I'm going to represent this as +/
Even though +/ is technically two words, I will use the convention
that without spaces between them I am talking about the verb they
represent rather than the simple meaning of the underlying words.
EDGE +/ \ }. 0 1 2 3 Adverb
Same issue again with +/ and \
EDGE +/\ }. 0 1 2 1 Monad
EDGE +/\ 1 2 0 Monad
EDGE 1 3 DONE
Note: J's execution is done when you have exactly two elements
on the stack and one of them is EDGE (indicating there's no
more words available). If there's more than two words on the
stack and there's no rules that apply, to reduce the stack,
that's a syntax error.
Now, what happens if you try and extract the +/\}.i. part
of that sentence?
words stack action
t =: + / \ }. i. >: shift word to stack
t =: + / \ }. i. >: shift word to stack
t =: + / \ }. i. >: shift word to stack
t =: + / \ }. i. >: shift word to stack
t =: + / \ }. i. >: 5 trident
Notice that we're using completely different parsing rules.
As it happens, 5 Trident forms a fork. If this rule were
defined differently you might get the behavior you expect,
but it's not. (Also, if this rule were defined differently,
we'd have to introduce a new mechanism into the language
to form forks).
You use the rules described on the next page in the dictionary
when evaluating forks (http://www.jsoftware.com/help/dictionary/dictf.htm)
For example:
(}. i. >:) 2
(}. 2) i. (>: 2)
'' i. 3
0
Obviously this is not getting you where you intended.
If you continue evaluating the above phrase, you'll find that the
verb +/\ gets formed (as before), but it will be combined with
this fork in a hook. But since that's off topic for what you are
trying to do, I'll not go into details.
So... what can you do about this?
One approach, which you stumbled across, is to prevent the 5 Trident
rule from getting used at all. If you put conjunctions between
each of those verbs, you'll never have a train of unadorned verbs.
Another approach would be to give the parser a hint about your
intentions.
words stack action
t =: [: + / \ [: }. [: i. >: shift word to stack
t =: [: + / \ [: }. [: i. >: shift
t =: [: + / \ [: }. [: i. >: shift
t =: [: + / \ [: }. [: i. >: shift
t =: [: + / \ [: }. [: i. >: 5 Trident
Here,, the 5 Trident rule is going to combine [: i. >:
[: is documented at http://www.jsoftware.com/help/dictionary/d502.htm
but, basically, the 5 Trident rule recognizes that cap and
knows that you want to be using i. as a monad rather than as a dyad.
The derived verb [: i. >: has essentially the same behavior as
i. @: >: but it's spelled differently.
If we keep going, we'll wind up using the 5 Trident rule again
(along with the 3 Adverb rule to form +/\). The final definition
of t will wind up being equivalent to ([: +/\ ([: }. ([: i. (>:))))
Does this answer your question, or would you like me to go into
more detail in some area?
If you understand what I've written here, and the pages I've
referred to, you should be able to figure out why
t=: [: +/\ 1 + i.
will do what you intended. The parsing rules which will be applied are
(in order):
5 Trident
3 Adverb
3 Adverb
5 Trident
7 Is
Let me know if this does not make sense.
Thanks,
--
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm