Which Types Should We Support?
In jytpe.h there are a list of supported types:
#define B01 ((I)1L<<B01X) /* B boolean */
#define LIT ((I)1L<<LITX) /* C literal (character) */
#define INT ((I)1L<<INTX) /* I integer */
#define FL ((I)1L<<FLX) /* D double (IEEE floating point) */
#define CMPX ((I)1L<<CMPXX) /* Z complex */
#define BOX ((I)1L<<BOXX) /* A boxed */
#define XNUM ((I)1L<<XNUMX) /* X extended precision integer */
#define RAT ((I)1L<<RATX) /* Q rational number */
#define BIT ((I)1L<<BITX) /* BT bit boolean */
#define SB01 ((I)1L<<SB01X) /* P sparse boolean */
#define SLIT ((I)1L<<SLITX) /* P sparse literal (character) */
#define SINT ((I)1L<<SINTX) /* P sparse integer */
#define SFL ((I)1L<<SFLX) /* P sparse floating point */
#define SCMPX ((I)1L<<SCMPXX) /* P sparse complex */
#define SBOX ((I)1L<<SBOXX) /* P sparse boxed */
#define SBT ((I)1L<<SBTX) /* SB symbol */
#define C2T ((I)1L<<C2TX) /* C2 unicode (2-byte characters) */
#define C4T ((I)1L<<C4TX) /* C4 unicode (4-byte characters) */
#define XD ((I)1L<<XDX) // DX extended floating point used to represent intolerant compare in jtiosc
#define XZ ((I)1L<<XZX) /* ZX extended complex */
My feeling is that we should remove some of these types. I think the first 6 should be kept. But then (the question is) should we remove any of the following:
- [ ] Rational number
- [ ] Bit boolean
- [ ] Sparse *
- [ ] Unicode
- [ ] Extended *
I will do some investigation into this, we should be intentional about how we remove these and associated code blocks.
https://godbolt.org/z/Krcvaf
I'm a little confused as to what I is defined as. Because there are several typedefs for I in the same file.
I was wanting to see what the compiler thinks these are but I didn't define I.
typedef struct {A a,t;}TA;
typedef A (*AF)();
typedef UI (*UF)();
typedef I (*VF)(); // action verb for atomic dyad
typedef I (*VA1F)(); // action verb for atomic monad
typedef void (*VARPSF)(); // action verb for atomic reduce/prefix/suffix routine
typedef B (*CMP)(); /* comparison function in sort */
typedef A X;
typedef struct {X n,d;} Q;
typedef struct {D re,im;} Z;
typedef union {D d;UINT i[2];UI ui;} DI;
typedef I SI;
Though since they are macros I guess it doesn't matter what I is as it'll be set when they are used.
Yea i had thought I was usually int64_t but this is a bit perplexing
I didn't find any other typedef for I, other than typedef long long I; (one was ifdef paired with typedef long I; in jfex.h, but it's not used AFAIK)
From the list, none of the occurences of I define it as a name, but refer to the previous typedef:
/* define name `SI` to be the type `I` */
typedef I SI;
/* define name `VF` to be the type `I (*)()`, i.e. function (pointer) with return type `I` (and may take any arguments) */
typedef I (*VF)();
/* same as above, but the defined name is `VA1F` */
typedef I (*VA1F)();
The c typedef syntax can be a bit confusing at times, especially with function pointer types (not to mention arrays). The different order with c++'s using new_name = existing_type; doesn't help either.
Ah oops. Sorry I was reading it backwards. Thanks for clearing that up. 👍
- J engine implements rational numbers by representing big numbers as a list of 10000-based decimal numbers (rather than 2-based). It's easy to debug, terrible for performance. A GMP addon is enough to the job.
- MPFR can serve the need of extended floating points.
- I prefer to keep all 3 Unicode types.
- J's sparse arrays are just COOs. They can be more useful if more effect being put into it.
Just for peoples reference:
- COO = Coordinate List
- MPFR = Multiple Precision Floating Point Reliable library
- GMP = GNU Multiple Precision
So sounds like we could if we wanted remote:
- extended types
- sparse types
@zhihaoy from reviewing the code, rational seems extremely coupled with extended integer. We would probably have to remove both. Is my impression correct?
@zhihaoy from reviewing the code, rational seems extremely coupled with extended integer. We would probably have to remove both. Is my impression correct?
I think yes. A rational is a pair of extended integers. Similar to Python's Fraction, except that the extended integers are not 2-based. Rational numbers in J are somewhat interesting as well. They do not round-trip back to the float-point numbers that they are extending, although J people have good reasons not to.
I personally feel that things like these are better served using some external types, like NumPy's array of objects.
Yea the one tricky part of removing fractional and extended will be modifying the promotion. It is easy enough to identify types with "??x" but "int * int = ??x" will take more time.