Rob, Henry, John,
Thank you for the tips. Rob, in particular, your discussion was very
useful. Let me repeat some of it back and tell me if I have it.
First, as an old APL kinda guy (learned it as my first programming
language 40 years ago: warped me for life...) right to left evaluation
and no operator precedence is no problem for me. Some of the new verb
construction stuff is where I am still getting up to speed, and clearly
this is where some of this subtlety is still straining my little brain.
Learning J has been something like coming back home after a long time
away, and finding that the roads and major building have been improved
and somewhat changed. Nice to be home, but I don't know my way around
anymore....
Looking at how (f g h) y creates the new concept of a fork and how that
works makes perfect sense. /It appears then, that when you assign some
combination of verbs and/or nouns to a name you need to evaluate how
that combination works as an independent construction, before attempting
to understand what it will do in a specific monadic or dyadic case./ In
the specific example I gave, (1: + 2: * i.)5 seeing that the
expression in the parenthesis is a verb train which should be
interpreted as a fork (particularly after understanding that 1: and 2:
are verbs) suddenly made the result clear. What you do with five verbs
in a row is a little tricky at first, but falls into place once you see
how verbs work when strung together. What was not clear was that the
statement odds =: 1: + 2: * i. needed to be parsed and interpreted
independently before any analysis of arguments (none, one or two, and of
whatever rank). This appears to be of particular importance when
understanding a tacit verb definition. Figuring out whether the partial
expression i. was interpreted as a verb or an incomplete part of a noun
was somewhat puzzling as well.
Rob, your examples at the bottom of your post are extraordinarily clear
in explaining part of this concept and I would like to suggest that you
get them added as an essay in the standard documentation. The one other
thing I think that somebody like me could have used is some statement
somewhere that when you assign verbs in some combination to a name that
you need to evaluate that verb combination in isolation to correctly
determine the way the derived verb will behave. Or, in other (and
somewhat less precise) words, pretend there are parenthesis around it
and figure out what it does inside first.
Does any of the above make any sense?
Tom
Rob Hodgkinson wrote:
Tom, I agree the step between (f g h) y and f g h y, (where f g h are
3 verbs) can seem a little 'odd' when first encountered.
Taking John and Henry's reply a step further, hooks, forks and tacit
definition are all covered in sections in the J Primer (see Help/J
Primer or Help/Ndx, then look for these sections).
When no parens are used, an expression is evaluated according to the
rules of J (often arguably called right to left). The use of parens (
) only changes the 'order of execution'.
In the original parent language (APL) such constructs as a string of
verbs produced 'Syntax Error' as they were not supported in the
language. However J extensions enhanced the language where an
expression consists ONLY of a string of 2 or more verbs (verb train)
and no parameters (nouns in J). This was desired since what was a
syntax error previously could now be utilised to express very powerful
mathematical constructs with an even simpler notation (for example
average =: +/ % #). The extensions of verb trains go a long way
further than this and the power inherent in these constructs is not
immediately obvious when you first encounter them, and the alternate
notation appears a little confusing.
f g h y is 'usual evaluation of an expression' where the
implied order of execution is: f (g (h y)))
however ...
(f g h) y has a first expression inside the parens with no data
arguments (nouns), so J first evaluates that expression as a verb
train using the parens, as usual, to control order of execution.
A verb train as above is defined in the J Primer as a string of 2 or 3
verbs that is defined as a hook (2 verbs) or fork (3 verbs) (and these
trains can nest further):
In the J Primer, I suggest you read the section on Hooks, Forks and
Tacit Definition.
Hook: (f g) y is evaluated as y f g y
(referred to as the monadic case as there is only one noun argument y)
x (f g) y is evaluated as x f g
y (referred to as the dyadic case, as there is a left
and right noun argument, x and y)
Fork: (f g h) y is evaluated as (f y) g (h y)
(monadic case)
x (f g h) y is evaluated as (x f y) g (x h y)
(dyadic case)
The best way is to experiment using these constructs and compare
with/without the parentheses.
Here is a starter, try to experiment further:
+ % 3 NB. This evaluates as + reciprocal
3, which is just reciprocal 3
0.333333333333
(+ %) 3 NB. Evaluates as 3 + % 3 using
hook definition above
3.33333333333
- % 3
_0.333333333333
(- %) 3
2.66666666667
2 * - + 3 NB. Think of as 2 * negative 3 (+3
is just 3)
_6
2 (* - +) 3 NB. Evaluates as (2*3) - (2+3)
using fork definition above.
1
Hope this helps to get you pointed in the right direction. If still
confusing please ask.../Rob Hodgkinson
On 15/11/2008, at 10:32 AM, List wrote:
Clearly that gives the right answer but does not answer the
underlying question. I understand that this is relatively elementary,
but getting a better handle on the execution difference between 1: +
2: * i.5 and (1: + 2: * i.)5 will help those new to the concepts
understand what the heck is going on here.
Tom
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm