codereport / jsource

J Language Source Code. Livestream links ⬇️
https://www.youtube.com/playlist?list=PLVFrD1dmDdvfVhYLU_iKkV67X9XqCJLWe
Other
38 stars 18 forks source link

Which Types Should We Support? #105

Open codereport opened 3 years ago

codereport commented 3 years ago

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:

I will do some investigation into this, we should be intentional about how we remove these and associated code blocks.

Sebanisu commented 3 years ago

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.

codereport commented 3 years ago

Yea i had thought I was usually int64_t but this is a bit perplexing

juntuu commented 3 years ago

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.

Sebanisu commented 3 years ago

Ah oops. Sorry I was reading it backwards. Thanks for clearing that up. 👍

zhihaoy commented 3 years ago
  1. 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.
  2. MPFR can serve the need of extended floating points.
  3. I prefer to keep all 3 Unicode types.
  4. J's sparse arrays are just COOs. They can be more useful if more effect being put into it.
codereport commented 3 years ago

Just for peoples reference:

So sounds like we could if we wanted remote:

@zhihaoy from reviewing the code, rational seems extremely coupled with extended integer. We would probably have to remove both. Is my impression correct?

zhihaoy commented 3 years ago

@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.

codereport commented 3 years ago

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.