Guides/Language Bindings
If you want to call the other language from J, your best bet is probably to make a shared library (*.so or *.dll) and just call the DLL from J.
This page is about embedding J in another language.
Example Language Bindings
- gdscript (godot 4 game engine): https://github.com/tangentstorm/jlang-rs-gd (uses jlang-rs and rust bindings gdextension)
- haskell: https://github.com/vmchale/j-hs
- pascal: https://github.com/tangentstorm/jlang-pascal
- python: Addons/api/python3
- rust: https://github.com/tangentstorm/jlang-rs
How to make a language binding (Writing a J Frontend)
The basic idea is essentially the same as making a J front end, wrapping j.dll.
The interface is defined in jsrc/jlib.h
bare minimum
At a minimum, you need to wrap the following functions:
CDPROC JS _stdcall JInit(void); /* init instance */ CDPROC int _stdcall JDo(JS jt,C*); /* run sentence */ CDPROC int _stdcall JFree(JS jt); /* free instance */
With these, you can make J do things, but you can't yet observe the state of the system.
fetching and setting variables by name from J
Once you can run J sentences, you can ask for the value of a variable using either JGetA
or JGetM
.
JGetA
gives you a (copy?) of the data as a J array, whereas JGetM
gives you a direct reference to the data in memory. (?? I think. Someone please fact check this!)
CDPROC A _stdcall JGetA(JS jt,I n,C* name); /* get 3!:1 from name */ CDPROC int _stdcall JGetM(JS jt, C* name, I* jtype, I* jrank, I* jshape, I* jdata);
You can set variables either by calling JDo
and performing a normal assignment, or using JSetM
:
CDPROC int _stdcall JSetM(JS jt, C* name, I* jtype, I* jrank, I* jshape, I* jdata);
JInit
creates a new J session. JDo
executes a J string, and JFree
closes the session when you're done.
Adding I/O
If you want to expose interaction with the J session -- for example, if you want to see the results printed after running a line with JDo
-- then you need to pass in some callbacks:
CDPROC void _stdcall JSM(JS jt, void**callbacks); /* set callbacks */
The signatures for the callbacks are:
void _stdcall Joutput(JS jt, int type, C* s); int _stdcall Jwd(JS jt, int x, A parg, A* pres, C* loc); C* _stdcall Jinput(JS jt, C*);
jt
is the session token you got from JInit
. C*
indicates a C string, and A
indicates a J array.
Implementing JWd (11!:x)
NOTE: you do not actually need to implement this, but it is a simple way to expose functions from your frontend language to J.
This is a callback for the J Window driver, a predecessor to JQt. The QT IDE is split into an executable and a shared object (jQt.dll on windows), so J can interact with Qt just by calling into the DLL directly. (This is set up in the ide_qt git repo.)
If you don't want to split parts of your application out into a DLL, you can use JWd. (JAndroid still does this, for example.)
The basic idea is that you call (11!:x) y
from the J side, where x
is a number that represents the host function you want to call, and y
is some rank-1 array with the arguments.
You can use whatever numbering system you like, but if you are interested in implementing your own wd
or gl2
backend, you might want to mirror the scheme here:
https://www.jsoftware.com/docs/help602/user/win_driver_cmd_ref_overview.htm
understanding the A struct
The basic structure is documented here: https://www.jsoftware.com/ioj/iojNoun.htm
field | purpose |
---|---|
k | "offset of ravel with respect to byte 0 of the array" |
f | a flag of some sort (not sure what this is for) |
m | "maximum number of bytes in ravel" |
t | the type number (see datatype verb in J)
|
c | the reference count (at least for JWd, this will have a weird high bit set, and you can just ignore the whole field) |
n | the length of the data |
r | rank + some other information in the high bits. (just look at the lowest 7 or 8 bits to get the rank) |
s | a pointer to the shape |
v... | the ravel (unshaped data of length n) |
see also
- jsrc/jfex.c is an example frontend written in C
- Interfaces/JFEX is some commentary on the jfex.c example.
- 11!:n/JWd thread on the jprogramming forum