System/Interpreter/Requests

From J Wiki
Jump to navigation Jump to search

Github Migration

These requests are now hosted at https://github.com/jsoftware/jsource/issues .

You should consider directing comments and additions there, rather than editing this page.

The following were already implemented, so were not moved:

  • 15 Fast Function Definition
  • 16 Execution on cells
  • 27 Fold

Outstanding requests for J interpreter extensions and enhancements. (Library extensions and enhancements are on another page.)

See also System/Interpreter/Requests/Closed, System/Interpreter/Requests/Implemented

archive




make x&(#.^:_1) invertible

Please make the monad x&(#.^:_1) (and x #.^:_1 ], x #.^:_1 [, and any other likely forms) invertible:

   #.^:_1 b. _1
#.

   (44&#.)^:_1 b. _1
44&#.

   44&(#.^:_1) b. _1
|domain error
|       44&(#.^:_1)b._1

-- Dan Bron <<DateTime(2007-03-12T17:05:34Z)>>

reinstate <;.1^:_1

I observe:

   <;.1^:_1 <;.1  '/one/two'
|nonce error
|       <;.1^:_1<;.1'/one/two'

That is, the inverse of <;.1 is momentarily undefined. I request that the previous inverse, ;, be reinstated (at least under limited circumstances).

I know the general definition of x&(<;.1)^:_1 is a tricky problem. But I am not sure that it applies to the inverse of the monad, <;.1^:_1.

Even if the monad's inverse suffers from the same complications, there are simple cases where ; would suffice, and I request that they be implemented as such. The nonce error should be retained where ; is not obviously sufficient.

An example simple case is the above: a vector of boxes where each box contains a vector (I can't think of a case where <;.1 would produce boxed scalars, but perhaps the "simple case" could be generalized to include those, too).

If this proposal is adopted, I submit the parallel proposal that [[JDic:../release/cut|special]] [[JDic:../release/cut503|code]] which supports phrases of the form: ;@:(<@:u;.1) be extended to support phrases of the form u&.>&.(<;.1).

These proposals apply to <;.2 as well as <;.1. They may also apply to the negative counterparts, <;._1 and <;._2, but that is less clear. For a fuller proposal on how to handle those inverses, see cut to fit

You may see the original request on the Forums, as well as an earlier inquiry.

-- Dan Bron <<DateTime(2007-10-30T14:32:26Z)>>

cut to fit

Similar to an old request of mine, I propose an extension to ;..

The request is for a new application of !.. Fit should apply to monads derived from the cut conjunction such that:

   u;._1!.n  ↔   u;._1 @: (n&,)
   u;._2!.n  ↔   u;._2 @: (,&n)
   u;. 1!.n  ↔   u;. 1 @: (n&,)
   u;. 2!.n  ↔   u;. 2 @: (,&n)
}}} and when  `u =: <`  then the respective inverses are:


   [: }.@:; n&,&.>
   [: }:@:; ,&n&.>
      }.@:;
      }:@:;

I'm not sure what do to for inverses of other u, as u^:_1 is probably not what's wanted. (For example, the inverse of < is > but what we want here is ; instead.)

However, that is not a large obstacle, because I think that:

   u&.>&.(<;.m!.n)
}}} will mostly cover the ground.  Given that, I believe the idiom should be given special consideration and be supported by special code.

The optimization would ideally apply for all u, but it should at least apply to all u which [[JDic:../release/cut|special]] [[JDic:../release/cut503|code]] already supports in ;@:(<@:u;.1) (viz my previous request). Special code which supports the idioms <@:u;.m and u&.>@:(<;.m) might also be considered for extension.

Motivations and disincentives for implementing this proposal are as detailed in the original Forum message:

Advantages:
  1. Concise.
  2. Solves a common problem.
    1. No worrying about losing the shard.
  3. Backwards compatible.
  4. Centralized, easily optimized. In particular, in <;._2 y,n the catenation (and attendant copying of y) need not be performed.
  5. Could easily provide for other optimizations which would support a large body of extant and likey future code. In particular, f&.>&.(<;._2!.n) could be optimized for well-behaved f (the initial definition of "well behaved" might be "doesn't change the type or shape of its argument"). For example:
   dtb&.>&.(<;._2!.LF)  NB.  dtb from lines
}}} though this is "poorly behaved" because it changes the shape of its argument.
  • In the spirit of !.
  • In the spirit of ^:_1
 Drawbacks (in addition to those associated with every backwards-compatible change to the language):
  1. <;._2 sans fit couldn't have an inverse, or, if it did, it would be inconsistent with the definition of the inverse of fitted cut (cf. previous request).
  2. Every !. reduces the consistency of J; they should be used sparingly, if at all.

-- Dan Bron <<DateTime(2007-10-30T00:19:42Z)>>

x and y in adverbs and conjunctions

   + 1 :'y' 0
|value error: y
|       y
   + 1 :'v=.y' 0
0

Could we at some point have an option to turn off the situational definition of x and y -- where x really means u and y really means v if neither u nor v are present?

-- User:Raul Miller <<DateTime(2007-11-05T22:06:46Z)>>

verb pipelines

I request an extension to the conjunction `:; I would like to use it to produce verb pipelines. That is, I would like f0`f1`:1 to be equivalent to f0@:f1 , f0`f1`f2`:1 to be equivalent to f0@:f1@:f2 and so on.

The function code 1 is arbitrary and may be anything you like. But I suggest naming the code pipe (analogous to 6, train).

You might also consider another code, similar to the above, except the connecting conjunction is @ instead (I think of f@g@h as an assembly line, but the word assemble is loaded in J, so you might consider conveyor or something else suggestive).

Here is a model of the proposed extension:

   eg =: 2 : 0  NB. Evoke Gerund
	if. n e. 1 2 do.
		m =. }: , m ,. n { a: , ;:'@:@'
		m`:6
	else.
		m`:n
	end.
)

   f0`f1 eg 1
f0@:f1

   f0`f1`f2 eg 1
f0@:f1@:f2

   f0`f1 eg 2
f0@f1

I note that that `:6 accepts verb arguments, and treats them as length-one gerunds. If you wish to make `:1 consistent with that model, substitute ({.u`]) ,. for m ,..

-- Dan Bron <<DateTime(2007-12-21T21:32:32Z)>>

    • Regarding the last point, i.e. what to do for verb arguments, other treatments are possible. Most of them will break the analogy between `:6 and `:1 , but that might be acceptable if the extension is useful enough.

One such candidate is to treat verb (train) arguments like a list of verbs; that is, treat a verb train like a gerund, and convert the train into a pipeline. Here is an extension of the model that does just that, using t2g from train to gerund:

   eg =: 2 : 0  NB. Evoke Gerund

	if. verb -: nc {.;:'u' do.
		m =. u t2g		
	end.

	if. n e. 1 2 do.
		m =. }: , m ,. n { a: , ;:'@:@'
		m`:6
	else.
		m`:n
	end.
)

   + eg
+

   (++) eg 2
+@+

   (++++) eg 2  NB.  More concise than +`+`+`+ eg 2
+@+

   (+/+/\(+/%#)----) eg 2
+/@(+/\)@(+/ % #)@-@-@-@-

   NB.!  Rightmost hooks not handled properly.
   (-(--)) eg 2
-@-@-
 I do not consider this further extension as useful or important as the original, but I thought I'd throw the idea out there.  

In fact, perhaps it would be better to separate t2g out as its own function code; since it is the "inverse" of the gerund-to-train adverb `:6, the code _6 is a mnemonic choice.

If so implemented, one could write one's own train-to-pipeline adverb as (`:_6)(`:1). Though, given that applying that adverb would take a minimum of 6 words/10 chars, the train in (train)`:_6`:1 would have to be pretty long to make it a more attractive option than writing the all the @: in the first place.

But it might have other uses.

-- Dan Bron <<DateTime(2007-12-21T21:48:12Z)>>

rank of q:^:_1

I suggest the inverse of q: be */"1 rather than */. The monad q: produces rank-1 arrays of integers, so its inverse should apply to rank-1 arrays of integers.

In my post to the fitting factors thread in the Forums, you may see a concrete example of where the new inverse would be more succinct: I had to write &.(q:"1) rather than the shorter &.q:.

Like any other change, backwards compatibility must be considered, but I don't imagine this would break much code.

-- Dan Bron <<DateTime(2008-01-08T21:48:26Z)>>


make dyad ". invertible

I request that the dyad ". (numbers) be given an inverse. I propose the inverse be ": (as it is for monadic ".). A minor improvement would be to to use a hypen rather than an underbar for the negative sign.

I can't of a way to make the x in x&". useful to the inverse. One idea is to make x&".^:_1x&":, but the problem with that approach is that for most applications, x=0, yet 0&": is not a useful format (again, for most applications).

In any case, I see no reason why +:&(0&".) should fail (and its obvious substitute, +:&.". has wrong (and dangerous) semantics.

-- Dan Bron <<DateTime(2008-02-01T23:27:07Z)>>

make tacit scalar replacement invertible

I request that the idiomatic verb =&m`(,:&n) } for scalar m and n, be invertible. The inverse is =&n`(,:&m) } .

For example:

   in  =. =&'-'`(,:&'_') }
   out =. =&'_'`(,:&'-') }

   io  =. [: ". in :. out

   +:&.io '-1 2 3'
-2 4 6
}}} could be rewritten more succinctly as:


    io =.  [: ". '-'&=`(,:&'_') }
    +:&.io '-1 2 3'
-2 4 6

This one new inverse would suffice for the majority of my use cases, but you may also consider making inverses for the verb's affilates.

That is, you could create the following mappings (or a subset thereof):

   = &m`(,:&n) } ^:_1  ↔  = &n`(,:&m) }   NB. A
   ~:&m`(n&,:) } ^:_1  ↔  ~:&n`(m&,:) }   NB. B
   m& =`(,:&n) } ^:_1  ↔  n& =`(,:&m) }   NB. C
   m&~:`(n&,:) } ^:_1  ↔  n&~:`(m&,:) }   NB. D

   = &m`(n&,:) } ^:_1  ↔  = &n`(m&,:) }   NB. E
   ~:&m`(,:&n) } ^:_1  ↔  ~:&m`(,:&m) }   NB. F
   m& =`(n&,:) } ^:_1  ↔  n& =`(m&,:) }   NB. G
   m&~:`(,:&n) } ^:_1  ↔  n&~:`(,:&m) }   NB. H

But I'm not convinced these extra inverses provide much value:

    • Mappings E-H are going to see less use (it can be useful to say "replace everything that's not a FOO with a BAR, but it's not so useful to invert that function).
    • The form m&= is redundant with =&m. It's not so hard to write the latter if you want your function invertible.
    • A similar sentiment applies to ~:&m`(n&,:) vs =&m`(,:&n) .

-- Dan Bron <<DateTime(2008-02-01T23:45:30Z)>>

special code for tacit scalar replacement

I request that the idiomatic verbs m&=`(,:&n)} and m&=`(n&,:)} for scalar m and n and e.&m`(,:&n)} and e.&m`(n&,:)} for vector m and scalar n be supported by special code.

In particular, I am thinking of the special code which underlies c}x,:y for boolean c (that is, the [[JDic:../release/iamend|special code for explicit monadic boolean amendment]]).

If my proposed inverses for scalar replacement are implemented, I submit the parrallel request that this special code support those inverses as well (which may just fall out natually, as the inverses have the same (optimizable) form).

In that previous request, I showed how the = verbs can be useful. Here is an example of the utility of the e. verbs:

   e.&WHITESPACE`(,:&' ')}  'stuff and',LF,'things',TAB,'some more'
stuff and things some more
   e.&DIGITS    `(' '&,:)} 'buy 123 of item 5'
    123         5

   ;: e.&WHITESPACE`(,:&' ')}  'stuff and',LF,'things',TAB,'some more'
+-----+---+------+----+----+
|stuff|and|things|some|more|
+-----+---+------+----+----+
   0 ". e.&DIGITS    `(' '&,:)} 'buy 123 of item 5'
123 5

-- Dan Bron <<DateTime(2008-02-02T00:29:14Z)>>

redefine u;.0 y

Currently, the definition of monad cut-0 is (1224 143 qdoj ';.'):

u;.0 y applies u to y after reversing y along each axis; it is equivalent to (0 _1 */$y) u;.0 y

I don't think this definition is very useful. I propose u;.0 y be redefined to mean "apply u along each axis of y", or, formally:

   u;.0 y  ↔  0&|:@:u^:(#@:$) y

Though backwards-incompatible, I believe the change is warranted. The question of "how do I apply a function to each axis of an array" arises perenially in the Forums. For example:

On the other hand, I do not see evidence that there is a frequent need to reverse an array along each axis. Further, code that does depend on the current definition of u;.0 y can readily be converted to use the new definition, simply by replacing u;.0 y with u |.;.0 y or (0 _1 */$y) u;.0 y or (-$y) u;.0 y; verb definitions that embed the monad u;.0 can be similarly converted by substituting @:(|.;.0) for ;.0.

As these substitutions show, the new definition is a generalization of the old, and is more in the spirit of ;. (in particular, and J in general).

-- Dan Bron <<DateTime(2008-06-20T19:24:51Z)>>

Change ;: dyad

I would like to propose two changes for the ;: dyad.

    • We should be able to represent next state and output code as a single number. Instead of 2 3 for state 2, output code 3, we should be able to use 2.3.
    • We should be able to request trace columns without having to represent all of them.

My motivation in both cases is compactness and efficiency. Of course, we have other ways of reaching these results. We could, for example, re-implement ;: in J. However, ;: is useful because of its compactness and efficiency. The benefits would be visual, as well as mechanical (especially on 64 bit systems). I have attached a proposed update to the dictionary File:Proposed-d332.htm. -- User:Raul Miller <<DateTime(2009-06-03T19:33:10Z)>>

2nd change

ew when j = _1 instead of raising error, should emit an empty box in output code 0, nothing in output code 1, (i, 0) in output codes 2 and 4.

Benefit would open up classes of FSMs where tag/bracket delimited data can be output as pre-open/inside/post-close(and pre-open next) such that all within-tag/bracket (inside) content is in boxes at odd numbered indexes. Pascal Jasmin (talk) 01:07, 12 June 2017 (UTC)

extend Cut

I'd like to propose two extensions for the Cut (;.) dyad.

  • Some partitioned algorithms require to have position of non-complete shard at the begin of array. Current u;.3 and u;._3 implementation provides that shard at the end of array only. Following is the model of extension desired ("5" is selected randomly for example only):
   (4 ,: 3) <;.5 (i. 10)
┌───┬─────┬─────┐
│0 1│2 3 4│6 7 8│
└───┴─────┴─────┘
  • Sometimes there is a need to align selected shard within frame not to the left (beginning) of the frame as currently implemented, but to the right (end), too:
   (_4 ,: 3) <;.3 (i. 10)
┌─────┬─────┬───┐
│1 2 3│5 6 7│8 9│
└─────┴─────┴───┘
   (_4 ,: 3) <;.5 (i. 10)
┌───┬─────┬─────┐
│0 1│3 4 5│7 8 9│
└───┴─────┴─────┘

-- Igor Zhuravlov <<DateTime(2009-12-26T16:55:18Z)>>

extend Evoke Gerund

I'd like to propose the extension for the Evoke Gerund (:) conjunction, described on page Extended forks. Following is example of such extension usage, e.g. for 3-fork ("9" is selected randomly for example only):

   NB. proposed evoke by extended Evoke Gerund (`:) functionality
   2 (+`%:`-`%`^`*`:9) 4
0.00379719j0.00219231

   NB. evoke using the model adverb from script supplied with page 'Extended forks'
   2 (+`%:`-`%`^`* fork3) 4
0.00379719j0.00219231

In gerund, Cap ([|) (at leftmost position in execution tree) and Self-Reference ($|) verbs support is desirable. ]

-- Igor Zhuravlov <<DateTime(2009-12-26T19:30:00Z)>>

extend fit conjunction

This would allow overtake on a boxed array to supply the fill (boxed) element suitable for further processing.

In dictionary format -

Fit(Customize)	u !. v

The case of !. with a verb right argument is defined in terms of the noun right
argument case (u !. n) as follows:

x u !. v y  <-->  x u!.(x v y) y
  u !. v y  <-->    u!.(  v y) y

and

Fit(Customize)	u !. n
This conjunction modifies certain verbs in ways prescribed in their definitions.

Case  n is not a gerund, ...(same as current definition )
Case  n is a gerund. (Compare with the gerund cases of the merge adverb } and power conjunction ^: )
x u!.(v0`v1`v2) y  <-->  (x v0 y) u!.(x v1 y)  (x v2 y)
x u!.(   v1`v2) y  <-->      x    u!.([`v1`v2)    y
  u!.(   v1`v2) y  <-->           u!.(v1 y)    (v2 y)

Because a gerund is a boxed noun there may be an issue with the second case. It may be the case that a gerund may be a valid fill (or other customisation) element so that fit evoking the gerund would not be possible.

However having a verb right argument for the fit conjunction seems possible. The verb could inspect both x and y to determine an appropriate fill element.

-- Ian Shannon <<DateTime(2010-07-28T09:36:30Z)>>

Fast Function Definition

Use (. ... ). to be recognized as m : '...' where m is chosen based on occurrence of xyuvmn

(. starts a function, and ). ends it. In a script, the function may span multiple lines. In lines entered from the keyboard (or 0!:n), the function must end on the same line it starts on.

The entire contents of the function, i. e. the words between (. and ). inclusive, are converted into a script using LF characters to end lines, and replaced with

(m : ' lines of script ') where m is chosen according to the contents of the script, using the first applicable row in the following table:

Words found in text of function Value of m
v or n 2
u or m 1
x 4
otherwise 3

In the definition of a bivalent adverb or conjunction, the sequence ::: can be used to separate the monadic and dyadic definitions.

Unresolved issues:

  • Selection of bracket characters
  • How to enter the bracket characters as Unicode, or convert to Unicode
  • What will the display of the resulting verb look like? Should all explicit entities display as if created by (. ).?
  • Note that there is no way to use (. ). to produce a noun. This is to allow verbs that don't refer to arguments

Examples:

2 1 3 2 (. 6 x} y )."0 1   i. 4 5
(. >./ 0 ". y ).;._1 (0 : 0)
0 1 2 3
4 5 6 7
)
(. if. #y do. (. (>./y) -  (<./y) ). y else. _1 end. ).&.> boxed_list

Henry Rich (talk) 14:06, 4 June 2017 (UTC) (original idea from Chris Burke)

Execution on cells

Add a primitive (or reuse an old one) to support v0`v1... cyclically applied to cells of x/y

Henry Rich (talk) 14:06, 4 June 2017 (UTC)

Semiduals

Enhance &. and &.:

u&.:(n`v) is equivalent to x v^:_1@(u v) v

u&.:(v`n) is equivalent to x v^:_1@(u~ v)~ v

and

u&.(n`v) is equivalent to x u&.:(n`v)"(n,mv) v

u&.(v`n) is equivalent to x u&.:(v`n)"(mv,n) v

Dual, but applying v only to one argument.

Example: x^y is x *&.(^.`0) y

As part of this change, u`v will be extended so that if u and v have different types, boxopen will be applied to each.

Henry Rich (talk) 14:06, 4 June 2017 (UTC)

Shutdown Callback

Certain packages such as database managers and http servers need to take certain actions such as closing files or sockets before the J system shuts down. At present the 2!:55 foreign is called directly by JQT and JConsole when the admin shuts them down via exit or the checkbox. It would be very useful for 2!:55 to execute a user defined verb prior to shutting down. That verb might simply be a well known name such as shutdown_callback_z_. When 2!:55 executes it will check for the existence of that verb and execute it. The callback is completely responsible for taking any appropriate actions. This makes testing and documentation very easy. Testing is done by writing a verb that prints "shutting down" on the screen and waits a few seconds. If that works then all is well. Documentation change is to state that prior to shutting down the interpreter will execute shutdown_callback_z_ if possible.

While I am writing this request it is due to a request in a comment in JOD by John Baker. He can give a far better explanation of its usefulness than I can.

John Robie (talk) 20:53, 11 June 2017 (UTC)

Provide a word to mean 'the currently executing explicit definition'.

This will allow recursion in anonymous explicit definitions.

Henry Rich (talk) 13:15, 12 June 2017 (UTC)

Support tail recursion

Tail recursion can be detected when

  • an explicit definition is running
  • the result of the current sentence is guaranteed to be the result of the verb
  • the sentence issues a recursion to the same explicit definition
  • all tokens have been moved from the queue to the stack in the parser
  • no names are on the stack in the parser

Henry Rich (talk) 13:15, 12 June 2017 (UTC)

Fast support for list I. list where y is in order

Perhaps using !.0 to declare that y is sorted

Henry Rich (talk) 02:04, 25 June 2017 (UTC)

Support inverse for I. y

Marshall suggests that:

the verb ((#/.~@])`(~.@])`[}) with an appropriate left argument is an left inverse to I. ignoring trailing zeros, and a right inverse to I. ignoring ordering. It counts, for each number in (i.n) where n is the length of the left argument, how many elements on the right are equal to it.

   x =. 4 7 2 4 1 7 8
   (10$0) (#/.~@])`(~.@])`[}"1 x
0 1 1 0 2 0 0 2 1 0
   I. (10$0) (#/.~@])`(~.@])`[}"1 x
1 2 4 4 7 7 8
   (/:~x) -: I. (10$0) (#/.~@])`(~.@])`[}"1 x
1

In that form, the inverse would be a dyad, which would prevent its use in duals. Perhaps a better inverse is ((#/.~)`~.`(0#~>:@(>./))}) .

Henry Rich (talk) 22:38, 27 June 2017 (UTC)

Expanded Multiple Assignment (strawman)

Let multiple assignment handle more cases: default values for missing ones; assignments at multiple levels of a boxed RH side; options for opening the box or not. Examples:

   'a [b c d]' =. 1;2 3 4
   a,b,c,d
1 2 3 4
   '<a> [b c d(99)]' =. 1;2 3
   a
+-+
|1|
+-=
   b,c,d
2 3 99

BNF description of the assignand:


 qname ::= any valid J name
           any valid J name?

 sname ::= .
           :
           qname
           qname.
           qname:
 
 name ::= sname
          sname ( default )

 default ::= any valid one-line J sentence

 item ::= < itemlistv >
          [ itemlistv ]

 items ::= name items
           item
           items itemlist

 itemlist ::= name
              items

 itemlistv ::= itemlist
               itemlist *

Multiple assignment is a sentence of the form

'itemlistv' =: value NB. or =.

If the rule for 'items' is matched, the words that match the rule are assigned from the corresponding items of the value. Any item that is enclosed in <> is assigned from the corresponding item; any other item is opened before it is assigned.

If the rule for 'items' is not matched, there must be a single name, and it is assigned with the entire value.

Multiple levels of assignment are called for by [] and <> . Each of these selects a single item of the current value and uses that item for assignments to the names within the [] or <> . Except when <> is used, one level of boxing is removed from the value before the assignment is performed.

If the rule for 'items' is matched, the number of items in the value must match the number of items specified by the pattern, except that

  • if the pattern ends with *, excess items in the value are ignored
  • if a name has an associated default value, the default sentence will be evaluated and used if the value is shorter than called for by the pattern. The default sentence is not evaluated unless its value is needed. When the default sentence is evaluated, all names assigned to its left are available to the evaluation.

If the name ends with ?, the assignment is not performed if the name is already assigned.

If the name ends with . or : (possibly preceded by ?), the ending character overrides the namespace used for the assignment: . indicates private assignment, : indicates public assignment. If the name does not end with . or : the namespace is given by the type of copula used, =. or =: .

A name consisting of the single character . or : matches an item of the value but performs no assignment.

Henry Rich (talk) 01:26, 2 July 2017 (UTC)

Support assignment in tacit expressions

Perhaps using =:: and =...

Henry Rich (talk) 23:20, 7 July 2017 (UTC)

Support prelookup of names in explicit definitions

Have a function that will scan an explicit definition and replace library names with a pointer to their definition. Could be invoked by a different left arg to :, perhaps

Henry Rich (talk) 19:31, 13 September 2017 (UTC)

Pre-parsed Parenthesized Primitives

Have a primitive that scans an explicit definition, looking for parenthesized sequences containing only primitives or pre-looked-up names. Such sequences are executed immediately and the result replaces the sequence in the explicit definition. There would need to be a user-specified limit on how big the result can be to be saved.

Henry Rich (talk) 19:47, 13 September 2017 (UTC)

Fold (strawman)

The Fold function is a generalization of u/ y and u/\ y in that it executes the verb repeatedly, first on an initial value and one item of y, and subsequently on the next item of y and the result of the previous execution. The additional features are:

  • The initial value can be specified as the x argument, rather than being the first or last item of y
  • Execution can proceed through y from head to tail or from tail to head
  • Execution can be freed from items of y altogether: the verb u is executed until it decides to quit
  • Intermediate results can be saved and assembled into an array for the final result (similar to u/\ y), or discarded to leave the result of the last execution as the final result (similar to u/ y)
  • If intermediate results are saved, only a subset of them need be saved. The verb can produce a large result, passed into the next iteration, but save only a portion of it for the final result
  • A new verb is provided to terminate the fold, either
    • at the end of the current iteration
    • immediately, using the result at the end of the previous iteration

Fold is supported by 7 new primitives, 6 for various types of iteration and 1 to support early termination. These primitives are:

Primitive Name Repeated Operation Direction First Execution when x omitted First Execution when x given Effect On Result
[x] u F.. v y Fold Single Forward (item_of_y) u (previous_result) Head To Tail (1{y) u (0{y) (0{y) u x For intermediate results, none, but (v result_from_u) is evaluated in case it executes Z: . The overall result is the result of the last execution of v that was not suppressed by an execution of 0 Z: y.
[x] u F.: v y Fold Single Reverse Tail To Head (_2{y) u (_1{y) (_1{y) u x
[x] u F. v y Fold Single [x] u (previous_result) u y x u y
[x] u F:. v y Fold Multiple Forward (item_of_y) u (previous_result) Head To Tail (1{y) u (0{y) (0{y) u x (v result_from_u) becomes an item of the growing overall result, unless suppressed by an execution of Z:
[x] u F:: v y Fold Multiple Reverse Tail To Head (_2{y) u (_1{y) (_1{y) u x
[x] u F: v y Fold Multiple [x] u (previous_result) u y x u y

In F.. F.: F:. F::, if the dyad is executed on y with no items, the result is (v x). If the monad is executed on y with no items, the result is (v u/ y). If the monad is executed on y with 1 item, the result is (v {. y).

The primitive (x Z: y) allows for early termination of any Fold, and is the only way to terminate F. and F:. The result of (x Z: y) is always $0 (an empty list). If y is 0, no action is performed. If y is 1, the action depends on x:

Executed form Effect
_2 Z: 1 Execution of the enclosing Fold terminates immediately, with the result being the result after the last execution of v. If nothing has been added to the overall result, a domain error is raised.
_1 Z: 1 Execution of the current iteration terminates immediately. The next iteration begins with the next new value of x. The value of y in the next iteration is the result of the most recent execution of u that ran to completion. Nothing is added to the overall result for the current iteration.
0 Z: 1 Execution of the enclosing Fold continues, but the result of the current execution of v is ignored. For Fold Multiple, nothing is added to the overall result. For Fold Single, the result of v does not become the final result.
1 Z: 1 Execution of the enclosing Fold continues, and stops after the next completion of v.
  • u/ y is equivalent to u F.: ] y
  • u/\. y is equivalent to u F:: ] y
  • u/\.&.|. y is equivalent to u F:. ] y


Henry Rich (talk) 21:15, 13 September 2017 (UTC)

Support conditionals that stop evaluation early

Add the control words and. and or. to allow things like

   if. a>:0 and. sentence_that_fails_if_a<0 do.

Henry Rich (talk) 12:14, 6 November 2017 (UTC)

Implement x m}:: y to amend inside boxing structure

Henry Rich (talk) 10:12, 2 March 2018 (UTC)

Change definition of negative level (strawman)

Negative level u L:(-n) will be redefined to mean "execute u within the boxed noun, on every cell that is enclosed by exactly n boxes."

Examples: u L:_1 means the same as u&.> when applied to a boxed noun.

   phi=. * -.@%@~.&.q:      NB. Euler's totient function
   ]t=. 5!:2 <'phi'
+-+-----------------------+
|*|+---------------+--+--+|
| ||+--------+-+--+|&.|q:||
| |||+--+-+-+|@|~.||  |  ||
| ||||-.|@|%|| |  ||  |  ||
| |||+--+-+-+| |  ||  |  ||
| ||+--------+-+--+|  |  ||
| |+---------------+--+--+|
+-+-----------------------+
   $L:_1 t
+-+-+
|1|3|
+-+-+
   $L:_2 t
+-+-------+
|*|+-+-+-+|
| ||3|2|2||
| |+-+-+-+|
+-+-------+
   $L:_3 t
+-+---------------+
|*|+-------+--+--+|
| ||+-+-+-+|&.|q:||
| |||3|1|2||  |  ||
| ||+-+-+-+|  |  ||
| |+-------+--+--+|
+-+---------------+

As the examples illustrate, cells whose boxing level is less than n are left unchanged.

At each level, the argument(s) are inspected to see if they are ripe for processing: far enough from the top level if the level is negative, or close enough to the bottom level is level is nonnegative. If all argument(s) are ripe, the verb is executed on it(them) and the y argument is replaced with the result of the execution.

If an argument is not ripe, there are several cases:

  • if an argument is not ripe, contains no boxes, and its required level is negative, execution along that branch terminates, because the argument will never become ripe along the branch. If the argument is y, the current value of the argument remains unchanged (as in the example above); if the argument is x, the cell is deleted from the result.
  • otherwise, if all arguments are not ripe, each argument-atom is opened and processing continues on each argument-atom contents. If the arguments have different shapes, atoms are repeated as if this open-and-recur step were executed with rank 0. During the recursion, the test for ripeness of a negative-level argument uses the depth of the cell in the original argument.
  • otherwise, exactly one argument must be unripe. The atoms of the unripe argument are opened and processed, with the ripe argument (whose required level must be nonnegative) being unchanged and repeated in its entirety for each opened atom of the unripe argument.


Henry Rich (talk) 20:56, 22 July 2018 (UTC)

Data teleport

A simple way to overcome trains dataflow restrictions would be a primitive to establish a data pipe ("teleport") between arbitrary code points. It is described on page Data teleport.

Igor Zhuravlov (talk) 02:47, 3 September 2019 (UTC)

I think pronouns (aka 'variables') satisfy this description? --Raul Miller (talk) 14:59, 4 September 2019 (UTC)

Improve Format 8!:n

1. The dyad Numbers (".) understands Inf and NaN:

   11 ". '42 4.2 4e2 _4E-2 INF +inf -Inf NAN +NaN -NaN NULL nil'
42 4.2 400 _0.04 _ _ __ _. _. _. 11 11

but it's close inversion via Format (8!:n) is impossible:

   (8!:0) 42 4.2 _4e_2 _ __ _.
+--+---+-----+-+--+--+
|42|4.2|-0.04|_|__|_.|
+--+---+-----+-+--+--+
   'd<nan>' (8!:0) 42 4.2 _4e_2 _ __ _.
+-----+----+-----+---+---+---+
|42.00|4.20|-0.04|nan|nan|nan|
+-----+----+-----+---+---+---+

Is it possible to extend it to get:

   SOMETHING (8!:0) 42 4.2 _4e_2 _ __ _.
+-----+----+-----+---+----+---+
|42.00|4.20|-0.04|inf|-inf|nan|
+-----+----+-----+---+----+---+

2. The Format (":) supports any precision:

   (":!.18) 1p1
3.14159265358979312
   0j17 ": 1p1
3.14159265358979312

This allows to export all significant digits. But the number of decimal places in the companion dyad Format (8!:n) is limited to at most 9:

   (8!:0) 1p1
+-----------+
|3.141592654|
+-----------+
   '9' (8!:0) 1p1
+-----------+
|3.141592654|
+-----------+
   '10' (8!:0) 1p1
|domain error
|   '10'    (8!:0)3.14159

Is it possible to increase this limit to at least 17 for 64-bit platforms, and to at least 9 for 32-bit platforms?

Igor Zhuravlov (talk) 07:29, 23 June 2021 (UTC)