There were many adverb and conjunction producing trains during a period
which Henry has referred as the Golden Age. Some were available as
early
as 1993 [0] and several more afterward [1]. A few of those adverb
producing trains (all of them bidents) survived [2] (using nv to denote
noun or verb),
"
x (a1 a2) is x a1 a2
x (c nv) is x c nv
x (nv c) is nv c x
"
but none of the conjunction producing trains did. Nevertheless, I
learned
to appreciate very much two of them (a trident and a bident),
together with
the survivors, many years after they were decommissioned,
"
x (a1 c2 a3) y is (x a1) c2 (y a3)
...
x (c a) y is (x c y) a
"
I hope mentioning old versions of J does not provoke a wild-goose
chase ;)
Remarkably, the adverb producing train survivors are sufficient to
allow
for complete adverbial programming in the following sense: if the
desired
entity (a noun, verb, adverb or conjunction), to be produced, can be
computed from the adverb's argument then there is a (pure) tacit adverb
able to do so (even compliantly; that is, the hard way, without
using any
black magic).
How come? There are several ways to show how this can be done; the J
sentences further down define a (Curried) adverb hg which can define an
arbitrary adverb t as follows,
t=. v hg
hg acts on a (presumably pure tacit) workhorse verb v and produces the
required adverb (t). The workhorse verb acts on the atomic
representation
of t's argument and should produce the atomic representation (or
similar)
of the desired entity; finally, hg evokes (`:6) it. Since (at
least, in
principle) one can go back and forth between the atomic
representations and
the entities they represent, tacit adverbial programming is reduced to
tacit verbal programming and the latter is Turing complete [3, 4].
The adverb hg can be defined as follows (no agendas are used, which
some
members might find too cryptic), beware of line-wrapping,
9!:14''
j805/j64/windows/release/commercial/www.jsoftware.com/2016-12-11T08:02:16
o=. @:
ar=. 5!:1@:<
(a0=. `'') (a1=. (@:[) ((<'&')`) (`:6)) (a2=. (`(<(":0);_)) (`:6))
((`'')(((@:[)(&`))(`:6)))((`_)(`:6))
av=. ((ar'a0')`) (`(ar'a1')) (`(ar'a2') ) (`:6)
NB. Adverbing a monadic verb (adv)
assert 1 4 9 -: 1 2 3 *: av
aw=. < o ((0;1;0)&{::) NB. Fetching the atomic representation
a3=. (@: (aw f.)) ('av'f.)
a4=. "_
a5=. `:6
a6=. ((( ar'a4') ; ] ; ( ar'a3')"_) ('av'f.)) (`:6)
hg=. `((ar'a6')`(ar'a5')) (`:6)
assert 1 4 9 -: 1 2 3 ((<'*:') ; ]) hg
erase'a0 a1 a2 a3 a4 a5 a6 ar av aw'
1 1 1 1 1 1 1 1 1 1
The adverb hg is tacit and it is fixed. Once it is defined one does
not
have to know or remember how it works to use it (that was the main
point
for defining it in the first place).
The verb an is convenient to use together with hg for development
(because
it neutralizes the hg ending adverb evoke (`:6))
an=. <@:((,'0') (,&<) ]) NB. Atomizing words (monadic verb)
For example, assume one wants an adverb t to act on a gerund,
representing
two verbs (say, u and v) u`v, and produce the verb v@u; thus one
needs a
workhorse verb to produce,
v@:u an hg
┌──────────┐
│┌──┬─────┐│
││@:│┌─┬─┐││
││ ││v│u│││
││ │└─┴─┘││
│└──┴─────┘│
└──────────┘
acting on,
(u`v) an hg
┌─────────┐
│┌─┬─────┐│
││0│┌─┬─┐││
││ ││u│v│││
││ │└─┴─┘││
│└─┴─────┘│
└─────────┘
Therefore, given that,
(u`v) an o (< o ((('@:') ; < o |.)) o (('';1)&{::)) hg
┌──────────┐
│┌──┬─────┐│
││@:│┌─┬─┐││
││ ││v│u│││
││ │└─┴─┘││
│└──┴─────┘│
└──────────┘
the adverb t can be defined as,
t=. < o ((('@:') ; < o |.)) o (('';1)&{::) hg
(u`v)t
v@:u
Let us entertain a more general version of t taking a gerund
representing a
(variable) number of verbs, the atomic representation of a sample
argument
u0`u1`u2`u3`u4 (extra parentheses used again for clarity) is,
(u0`u1`u2`u3`u4) an hg
┌────────────────────┐
│┌─┬────────────────┐│
││0│┌──┬──┬──┬──┬──┐││
││ ││u0│u1│u2│u3│u4│││
││ │└──┴──┴──┴──┴──┘││
│└─┴────────────────┘│
└────────────────────┘
and the atomic representation of the product u0@:u1@:u2@:u3@:u4 is,
(u0@:u1@:u2@:u3@:u4) an hg
┌──────────────────────────────────────────┐
│┌──┬─────────────────────────────────────┐│
││@:│┌────────────────────────────────┬──┐││
││ ││┌──┬───────────────────────────┐│u4│││
││ │││@:│┌──────────────────────┬──┐││ │││
││ │││ ││┌──┬─────────────────┐│u3│││ │││
││ │││ │││@:│┌────────────┬──┐││ │││ │││
││ │││ │││ ││┌──┬───────┐│u2│││ │││ │││
││ │││ │││ │││@:│┌──┬──┐││ │││ │││ │││
││ │││ │││ │││ ││u0│u1│││ │││ │││ │││
││ │││ │││ │││ │└──┴──┘││ │││ │││ │││
││ │││ │││ ││└──┴───────┘│ │││ │││ │││
││ │││ │││ │└────────────┴──┘││ │││ │││
││ │││ ││└──┴─────────────────┘│ │││ │││
││ │││ │└──────────────────────┴──┘││ │││
││ ││└──┴───────────────────────────┘│ │││
││ │└────────────────────────────────┴──┘││
│└──┴─────────────────────────────────────┘│
└──────────────────────────────────────────┘
Now, that seems to be messy but it does not have to be (hint:
producing the
atomic representation is not necessary, as long as the entity can be
evoked
correctly). A solution of this type is shown near the end of this
post.
While currently, tacit adverbial programming is complete, tacit
conjunctional programming is, alas, virtually zip. Nevertheless, let us
have a thought experiment: what would happen if the two conjunction
producing trains I mentioned above had survived? Would conjunctional
programming be complete in the same sense in which tacit adverbial
programming is? The answer is yes.
How come? Because then tacit conjunctional programming could be
reduced to
tacit adverbial programming. Assume, for example, that a
conjunction acts
on a noun and a verb, say 1 2 3 4 and +/, then
1 2 3 4 ((an f.hg) (` (an o ((('';1)&{::))hg))(an f.hg)) (+/)
┌───────────┬───────┐
│┌─┬───────┐│┌─┬───┐│
││0│1 2 3 4│││/│┌─┐││
│└─┴───────┘││ ││+│││
│ ││ │└─┘││
│ │└─┴───┘│
└───────────┴───────┘
Therefore, one can replace the verb an by a workhorse verb v acting
on the
above gerund to produce whatever is desired, for example, if one
wants the
right-hand verb argument to act on the left-hand side argument we could
simply define the conjunction as follows,
t=. ((an f.hg) (` (|. o ((('';1)&{::))hg)) (an f.hg))
1 2 3 4 t (+/)
10
'boxed' t <
┌─────┐
│boxed│
└─────┘
type't'
┌───────────┐
│conjunction│
└───────────┘
In general, an arbitrary conjunction could be defined as,
t=. (an f.hg) (` (v o ((('';1)&{::))hg)) (an f.hg)
where v is the workhorse verb. For the common case where the two
arguments
are verbs,
t=. ` (v o ((('';1)&{::))hg)
would be sufficient.
The 1993 version J is unable to successfully define hg because,
although
evoke (`:6) supported gerunds representing lists of verbs, it did
not have
the extended functionality for hg to be able to work; that was added
later. I am not sure if the late versions of the interpreters of the
Golden Age can reproduce all the above.
However, the above is not quite a pure thought experiment. It
reflects a
Jx session (Jx is a fork of J that provides some extensions [5]).
(Jx does
not require the conjunction producing trains to make tacit
conjunctional
programming complete because it provides an alternative way to produce
arbitrary conjunctions; there are there because they are useful and I
personally consider any tiny performance penalty, due to restoring a
trident entry in the parse table, as a well-deserved tribute to them.)
Could they find their way back to official interpreters? I do not
think
so. Yet, complete conjunctional tacit programming could be provided
without
having to restore any trident (apart from the fork trident which is
special). How come? I could give an outline on how this could be
implemented but this post is already way too long and I wonder how many
members could still be reading it at this point.
However, before I forget, just in case someone wants to see it...
The more general adverb t can be obtained easily: since,
(u0`u1`u2`u3`u4) an o (([ , (<'@:') , ])/o |. o (('';1)&{::))hg
┌──┬──┬──┬──┬──┬──┬──┬──┬──┐
│u4│@:│u3│@:│u2│@:│u1│@:│u0│
└──┴──┴──┴──┴──┴──┴──┴──┴──┘
then t can be defined as,
t=. ([ , (<'@:') , ])/o |. o (('';1)&{::)hg
u0`u1`u2`u3`u4`u5`u6 t
u6@:u5@:u4@:u3@:u2@:u1@:u0
*:`(+/)`-`j.`(^ %:)t 1 2 3
2.40034j16.7123
PS. My plans for sending a version of this post during the weekend were
crushed because I was too busy (oversleeping, watching dance
performances,
eating out, swimming, watching boxing, football, etc. :)
References
[0] [Jprogramming] Tacit Expressions with Explicit J Syntax roger
stokes
http://www.jsoftware.com/pipermail/programming/2017-September/048917.html
[1] [Jprogramming] Jx 1.1 Release neitzel
http://www.jsoftware.com/pipermail/programming/2017-October/049177.html
[2] [Jprogramming] Jx 1.1 Release neitzel
http://www.jsoftware.com/pipermail/programming/2017-October/049179.html
[3] Universal Turing machine (J)
https://rosettacode.org/wiki/Universal_Turing_machine#J
[4] Jforum: A Tacit Implementation of a Turing Machine
http://www.jsoftware.com/pipermail/general/1999-December/002736.html
[5] [Jprogramming] Jx 1.1 Release Jose Mario Quintana
http://www.jsoftware.com/pipermail/programming/2017-September/048957.html
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm