Pascal wrote:
> The mistake I make regularly is forgetting that conjunctions are not greedy
> to the right.
Perhaps it will make it easier to remember if you consider it as a
universal rule, rather than some kind of exception for conjunctions: J's
grammar would break down if any part of speech were greedy to the right
(that's what I was trying to express in the recent thread on copulas [1]).
Only punctuation (things that, by definition, can't contribute to the
_semantics_ of a sentence, only its syntax and flow) can be greedy to the
right. In fact, one might argue, this is the primary characteristic of
punctuation:
NB. Comments are the best! Once started, nothing to the right can stop
them, except a new line!
'everything to the right of this quote is captured in the literal, until
I hit another quote or a newline and then SYNTAX ERROR
(the whole purpose of parens is to elevate precedence for everything
rightwards until )
3 : 'label_line0. the only way label_line1. to include multiple lines
label_line2. on a single line is label_line3. punctuation.'
name =: hi, I can be anything at all, and I'll stay to the right of the
copula (including other copulas)
In the examples above, the punctation marks are, in order: NB., ', (),
control words, and copulae. Which is also their order of precedence (I
think). And, at a meta-level, if you view a J program as a sequence of
physical bytes, rather than a logical collection of lines, you could
include newline itself as highest among the punctuation marks (i.e. as a
character that influences the flow of a program). But anyway, whether you
include newline or not, and whether I got the relative precedences right,
you'll note than all of the punctuation marks -- any one of them -- has
precedence over the parts of speech proper (i.e. nouns, verbs, adverbs,
and conjunctions, i.e. executable parts of the language, i.e. things that
can be assigned to names). They must, or they couldn't do their jobs.*
If this universal-rule approach doesn't make "conjunctions are NOT greedy
to the right [nor is anything else] " easier to remember, maybe you could
try internalizing J's grammar directly, from DoJ §II.E [2]. Right at the
top of that page is a summary of J's grammar, presented as an enumerated
list in plain English. You'll see the second item calls out explicitly:
Adverbs and conjunctions are executed before verbs; the phrase ,"2-a
is equivalent to (,"2)-a , not to ,"(2-a) .
Unfortunately, to really understand the rules, reading the (necessarily
ambiguous) English summary isn't enough. For example, the sentence
directly following that one says:
Moreover, the left argument of an adverb or conjunction is the entire
verb phrase that precedes it.
Which might lead one to believe that in *: % +/ the / would gobble up the
(*: % +), because it is indeed a verb phrase, and does indeed precede the
/ . Yet, as we know, the / can only see the immediately preceding + , and
no further. This has tripped up many people, many times, over the years.
Try searching for [entire verb phrase that precedes] in the Forum archives.
Bottom line: to really get a grasp of J's parsing rules, you have to
internalize the table at the bottom of §II.E and the auxillary definition
of trains in §II.F [3], or you have to just spend enough time conversing
(arguing) with the interpreter to develop an intuition.
-Dan
[1] [Jprogramming] copula
http://www.jsoftware.com/pipermail/programming/2014-June/037704.html
[2] Dictionary §II.E, Parsing and Execution:
http://www.jsoftware.com/help/dictionary/dicte.htm
[3] Dictionary §II.F, Trains (i.e. the interpretations of parsing rules 5
[Fork] and 6 [Bident] in the preceding table):
http://www.jsoftware.com/help/dictionary/dicte.htm
* Contributing to this situation is the fact that J (in pursuit of being
expressive and succinct) is an infix language, and does make the
distinction between "left" and "right" (which it takes advantage of to
compress more information into less space). Contrast this with the simple
S-expression syntax popular in the Lisp world, where there's no such thing
as precedence _at all_, leading to its characteristic power to quote and
manipulate programs directly as data.
This is similar to J's decision to eliminate precedence among the members
of any given nameclass (so that, e.g. the verbs + and * have the same
precedence, unlike in PEMDAS and most programming languages). Except that
Lisp went one step further, and eliminated the precedence among
nameclasses. In fact, my understanding is that Lisp (and derived
languages) have no nameclasses at all, and that in place of what we would
call adverbs or conjunctions (and APL would call operators and other
languages might call metafunctions), Lisp has only plain functions, which
can be trivially passed other functions as parameters, due to the postfix
nature of S-expressions (because everything following the name of a
function is by definition its inputs, and so passing in a function is
simply a matter of writing it as you normally would, and then prefixing it
with a single quote, which has the effect of quoting /everything to the
right/, i.e. the very definition of the function).
(Of (course (the (drawback of (Lisp's (elegant syntax) is its (horrible
syntax) ) ) ) ) :). **
** polish reverse notation using altogether parentheses eliminate
the-other-way entirely go and you-could of-course
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm