From J Wiki
Jump to: navigation, search

The j901 beta cycle started in Oct 2018 and was first made available in April 2019.

For installation, see Installation/Beta.

Changes to the J engine

J901 beta-? (unreleased work in progress)

  • Bugs fixed from previous beta:
    • 13!:19 (cut stack) did not always stop after cutting back
    • 13!:5 (run next) sometimes exited the running definition prematurely
  • 256-bit instructions used for more arithmetic primitives on floating-point lists (dyads >. <., monad | +/ <./ >./)
  • If x f y uses 256-bit instructions when y has rank 1, so do f/ y, f/\ y, and f/\. y when y has rank > 1
  • 256-bit instructions used in floating-point x +/@:*"1 y (the recommended form for dot products of lists)
  • stack error is detected better, allowing deeper recursion and eliminating stack-related segfaults

J901 beta-f (the current beta)

Incompatible change: m!:n generates an immediate domain error if the combination is not supported (previously it generated an equivalent of [:, without error)

  • Bugs fixed from previous beta:
    • In debug, assert. failures did not show up on the debug stack
    • dbr 1 executed during loading a script was ignored
    • assigning 13!:19 (cut stack) to a name caused a hang
    • anonymous verbs always executed with debug turned off
    • Performance Monitor failed with an assertion error
    • break.bat file didn't create interrupt
  • 256-bit instructions used for floating-point arithmetic primitives (dyads + - * % p., monad %:)
  • Inplacing is now supported for boolean arguments of arithmetic dyads even if rank is specified

J901 beta-e

  • Bugs fixed from previous beta:
    • In debug, the display showed the line executed before a stop rather than the line about to be executed
    • Run after stop skipped a line
  • New feature: virtual extended nouns. If a noun that is not referred to more than once is extended by appending items to the end, the extended value and the original value share the same data without copying
    • This speeds up the form (x { name,default) where values of _1 or #name in x select from the default. The default is appended as a virtual extension without copying all the values in name.
  • Multiple accumulators used for +/\ y and +/\. y when y is a float list, 2x faster
  • New foreign x 3!:9 y to get internal information about noun y

J901 beta-c

What Do I Need To Do?


Incompatible change: x m} y changed when m is numeric with rank>1. The language is going to be modified to use this case to specify scatter-modify, which previously required boxing each row of m. Until the new interpretation is available, the case will create nonce error. To remove the error, use (<"0 m)} instead of m} . If x is an atom you can work around with (, m)} .

Incompatible change: 18!:4 changed. Users should be using this under its system name cocurrent or coclass; those uses are unchanged. If you misguidedly use 18!:4 directly, you will see that its side effects have changed: previously it altered the current locale in the name calling the name that uses 18!:4 only if there was no subsequent named execution in the name executing 18!:4; now it always causes the caller to continue on in the locale in effect when the called name exits.

Coding guideline: cocurrent and coclass should be used only in scripts to set the locale for lines executed from the script, and avoided inside of verbs in favor of using locatives. Indirect locatives (like a__b) have less overhead. Using cocurrent or coclass adds a small overhead to the execution of all named verbs until the function that called the deprecated name returns.

Parser refinement: For parsing purposes, the execution of a verb is assumed to produce a noun, and the execution of a fork is assumed to produce a verb.

Parser specification change: If the right-to-left processing of the words of a sentence encounters a sequence that must inevitably lead to a syntax error, it is undefined whether or not the rest of the sentence will be parsed and executed. Examples of such sequences include & =. and ('a' 5)

Change in behavior of nonexistent numbered locales: attempting to access a nonexistent numbered locale now produces locale error rather than creating the locale.

New Features

  • [x] 128!:6 y - Add keccak, MD4, MD5. see latest Dictionary for documentation on support for Secure Hash Algorithms


  • Quicker way to specify numbered locales: numbered locales can be referred to by indirect locatives that are an integer atom or a boxed integer atom (rather than a boxed string). Such locatives can be processed quicker because they do not have to be validated and converted to a number. If you have (obj =: conew parameters) you can replace that with (obj =: 0&".@> conew parameters) and get a performance improvement every time you use (name__obj).
  • Domain of x u;.0 y expanded: the selected subarray may start on any valid atom of its axis, or on the atom one position before or after the axis. In all cases the length will be limited to the largest valid value for the starting position (which will be 0 for positions starting outside the array)
  • New parameter types in calls to DLL (cd or 15!:0):
    • b unsigned byte integer (1 byte)
    • z J float complex (8 byte - 2 f values) (pointer only, not as result or scalar)
  • The support code that prepares for execution of verbs/adverbs/conjunctions has been restructured for speed
    • Parsing recoded, including matching of the parsing table, which is now very fast
    • Named execution recoded, reducing overhead
    • Name re-lookup avoided on names that are repeatedly executed (for example name"0)
    • Explicit-definition startup recoded, giving ~15% improvement on definitions whose sentences are quick
  • Odometer function (#: i.@:(*/)) y recoded, 2-3x faster
  • Partitioning modifiers, and some verbs, modified to use stack space rather than heap space for most cases
  • u^:v faster when v returns atomic value 0 or 1
  • x -: y faster on boxed arrays, especially when corresponding boxes refer to the same memory areas
  • the dispensation on virtual arrays, which allows them to be boxed without being realized only when they are to be immediately opened, is detected in more cases. For example in (x (f g&.> <;.1) y) the result of <;.1 may contain virtual arrays because they will be immediately opened.
  • Lookups for numbered locales much faster
  • When security level is set, 1!:43 and 1!:44 are not allowed, and 2!:55 is allowed.
  • Multiple assignment 'name1 name2...' =. value1;value2... now preprocesses the names during function definition, making execution much faster
  • Name processing polished to reduce space used and overhead in deleting a namespace
  • All loops that copy shapes or check for agreement reworked to avoid mispredicted branches when array rank <3
  • Deal (x ? y) changed, 5x faster
  • Roll on shape (x ?@$ y) changed, 2x faster for nonzero y

  • Special code for x (comparison L.) y when comparison is one of < <: > >:; stops scanning y as soon as possible. This means that the best way to see if y is boxed is 0&(>: L.) y
  • Special code for some common idioms:
    • Rank of a noun:  #@$ y    #@:$ y    ([: # $) y
    • Number of atoms in a noun:  #@, y    #@:, y    ([: # ,) y    */@$ y    */@:$ y    ([: */ $) y
    • Is noun empty?  (0 e. $) y
    • Is noun nonempty?  *@#@, y
    • Does noun have items?  *@# y
  • Startup of atomic dyads recoded yet again, this time with emphasis on hiding load latency and eliminating unpredicted branches. Startup time is now approximately the amount of time needed to add 10 pairs of integers (was 20).
  • Amend in place polished
    • Audit indexes faster: 2x improvement on list list} list
    • Does not build addressing cells for each atom, and thus many times faster when the cells selected by m are larger than atoms
  • Scatter-read (x (<"1@[ { ]) y) reworked. Faster when there is a negative index; otherwise just a bit faster, more so for small arguments
  • Multiple accumulators used where multi-cycle instructions created a carried dependency, giving speedups:
    • x +/@:*"1 y and x +/ . *"1 y on floating-point lists: 2x
    • +/ y on floating-point lists: 4x
    • <./ y and >./ y on integer and floating-point lists: 2x
    • (+/ % #) y on integer and floating-point lists: 2x
    • (i. <./) y, (i. >./) y, (i: <./) y, and (i: >./) y: 3x
  • Inplacing allowed in f/\ y and f/\. y for certain f
    • for <. and >., on integer/floating arguments
    • for * and +, on floating arguments
  • New sort algorithm added
    • Faster on float lists less than 50,000 long; 2x faster on lists shorter than 6000
    • A smidgen faster on integer lists less than 40 long
  • x # y recoded for boolean x. Faster, the more so as items of y are short, or x contains zeros. About 5x faster if y is integer or float and x is half zero.
  • I. y recoded for boolean y. 5x faster when y is half zero.
    • special code for x I.@:comparison y removed as it is no longer faster
  • Code for x +/@:comparison y polished, 2x faster on integer/boolean lists when the results of the comparison are coin-flips.
  • Code for x u;.1 y etc. recoded for boolean and ASCII x, 1.5x faster on fast verbs u
  • Code for comparisons improved:
    • x = y on integers brought up to the speed of the other integer comparisons, 5x faster
    • Intolerant comparison treated as a special case, 2x faster on random floats
    • x = y and x ~: y on one-byte characters recoded, 2x faster
  • x # y inplaceable when x is boolean; if inplaced, avoids copying unmoved leading cells
  • Comparison combinations (such as i.&1@:>) treat intolerant comparison as a special case
  • Several atomic monads recoded for integer and float cases
    • <. y and >. y inplaceable for integer and float; float recoded, 5x faster
    • * y inplaceable for integer and float; integer recoded; float recoded, 2x faster
    • | y inplaceable for integer and float; integer recoded; float recoded, 1.5x faster
    • %: y inplaceable for float

Changes to the base system

Changes to the Qt IDE