Hi all!

I did not write the post because I want information about the J interpreter but to describe why *. can not be used as an if structure. I welcome comments about what is wrong with the text, but what I mainly expect is that responders look at the meaning of my post and the question we discuss and continues with this discussion.

Cheers,
Erling Hellenäs

Den 2017-11-07 kl. 13:58, skrev Raul Miller:
(quoted thoughts itemized and numbered here so I can respond to them
individually)

EH 1> The verbs are passed only noun arguments. There is no functional
left argument to *. which the verb could omit to execute.

As a simplifying assumption, this has been true, largely because of
the parsing rules. That said, Jose has illustrated some cases where
it's possible to circumvent this.

EH 2> The parser curries the program. The interpreter does not see any
brackets which it could omit executing.

I would not make a distinction between the parser and the interpreter.
Currying is also a term which may or may not apply to otherwise
similar trains handled by the parser.

EH 3> The parser works from left to right, the interpreter from right
to left. The parse result is list of pointers to nouns and verbs that
is interpreted/executed from right to left.

The lexer works from left to right. The parser works from right to
left as documented here:
http://www.jsoftware.com/help/dictionary/dicte.htm

While you can identify list structures in a variety of things
generated by the parsers (arrays, for example, can be said to have
list structures), using the terminology that way is more shoehorning
the J design into a terminology framework oriented around other
languages.

EH 4> The parser reads the statement until the first bracket start,
the bracket contents are then parsed and interpreted/executed, the
resulting noun is packed for later interpretation. All brackets are
handled this way recursively until the end of the statement. Then the
statement is interpreted/executed.

Sort of, but no:

Yes, content of parenthesis gets evaluated before its immediate
context can finish being evaluated, but parsing is interpretation /
execution. When parsing has completed on a sentence, that sentence has
a single result which may be a noun (array), verb, adverb or
conjunction.

That said, when a derived verb (or adverb or conjunction) executes, it
may not need further use of the parser (if it does, that's where the
recursion would come in - other than that, the parser is not recursive
- instead it is iterative with an explicit stack data structure).

EH 5> The difference in the tacit case is that the execution is
delayed. The bracket contents are packed in a composition, a new verb,
a "single verb", which is executed by the nearest explicit parent
statement. The pointer to this new verb is included in the list to be
parsed, instead of it's noun result.

Sort of - see above.

EH 6> *. in J is a scalar verb. All it receives is its scalar
arguments. It could in theory omit executing the And if the right
argument is zero, however, you would need an if statement and a
comparison to do that and doing the And immediately is cheaper.

I am not sure what you mean by "scalar". If you mean "rank zero", you
are correct.

I am also not sure what you mean by "receive" - there are at least two
potentially relevant "receive" concepts here - the rank 0 concept
(handling the individual numbers) and the rank wrapper concept
(handling the array structures).

That said, trying to break the rank mechanism to borrow "short
circuit" evaluation from other languages would... break the rank
mechanism.

EH 7> Then there is a "hidden" rank-like program handling all scalar
verbs. This program takes noun arguments and references to the scalar
verb. What it executes is the C/C++ code corresponding to the scalar
verb. The scalar verb does not actually exist as an entity. There are
several corresponding entities - C/C++ programs. One for each type
combination. This "hidden" rank-like program is highly optimized and
it is very important to keep special cases out of it.

Assuming I understand what you mean by "scalar verb", the scalar verbs
actually do exist as entities, internal to the interpreter - these are
used to implement the visible behavior of the system.

Specifically, for *. the interpreter defines four "scalar verb"
functions which are used in its implementation. You can see their
declarations here:

https://github.com/openj/core/blob/master/ve.c#L132

You can see the  definition of the APFX macro (which provides the bulk
of the function body) here:
https://github.com/openj/core/blob/master/va.h#L154

I could go on, but hopefully this is enough to show you this aspect of
the implementation.

I hope this helps. (But I am not sure it will help enough - I know I
have repeated some of these concepts many times already - in
particular the parsing process - so maybe there is something wrong
with how I try to express these concepts?)

To see the execution steps performed by the parser, I recommend using
J's trace facility.

For example, please try this:

    require'trace'
    trace'(2*3)+5'
    trace'2*3+5'

Each block displayed will contain up to five newline separated items:

(*) a separator line identifying the relevant rule from the parsing
and execution appendix of the dictionary --
http://www.jsoftware.com/help/dictionary/dicte.htm

(*) two or three lines identifying the relevant parsing entities
(nouns, verbs, adverbs, conjunctions or punctuation) being evaluated
in this parsing step. These correspond to the bolded items from the
table of that appendix.

(*) the result of that evaulation

If parsing completes successfully there will be a
============================== line followed by the final result
(which will be the same as the result of the final evaluation).

Again... I hope this helps.

Thanks,


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

Reply via email to