aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/usability_comparisons.txt
blob: 5b1f142547e15a991718a4bb1b57cca2df8792fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

Comparisons of different syntaxes w.r.t. usability
==================================================

Integer types
-------------

    int   vs.   int
    byte        byte    # common case
    int8        int<-127..128>
    int16       int<-32768..32768>  # maybe a bit too long?
    int32       int<0..9>   # custom range with constant bounds
    int64       int<0..len> # custom range with a (immutable) variable
    wuint       uint<.., .wrapping>  # allows specifying an overflow mode,
                                     # e.g.:
                                     # .bounds_checked(the default),
                                     # .wrapping, .saturating, invalidating


How about having both?


Regarding arithmetic with wrap-around:

    # Alternative 1: (LRL style, i.e. SLULs predecessor)
    # + most concise
    # - might be confusing if wuint is used in a function param!
    #   (on the other hand, it can also make expressions very concise)
    wuint x = (a + 1) shr 1
    uint y = ((a + 1) as wuint) shr 1
    # Alternative 1b:
    int<0.. .uintmax, .wrapping> x = (a + 1) shr 1
    uint y = ((a + 1) as int<0.. .uintmax, .wrapping>) shr 1
    # Alternative 1c:
    uint<.., .wrapping> x = (a + 1) shr 1
    uint y = ((a + 1) as uint<.., .wrapping>) shr 1
    # Alternative 2: "wrap" pseudo-function
    # + can be extended with "saturate" etc.
    uint x = wrap((a + 1) shr 1)
    uint y = wrap(a + 1) shr 1
    # Alternative 3:
    wrapping {
        uint x = (a + 1) shr 1
        uint a1 = a + 1
    }
    uint y = a1 shr 1
    # Alternative 4: special operations (what other languages seems to be using)
    # * should shr and shl trap or discard bits on overflow?
    uint x = (a %+ 1) %shr 1
    uint y = (a %+ 1) shr 1

Regarding non-power-of-two integer bit-sizes (e.g. int24):
* Some languages like Zig have them.
* But how should it work w.r.t. alignment?
    - uint16 typically has an alignment of 16 bits.
    - what alignment would uint15 have?
    - what alignment would uint17 have?
* I think it is better to have a dedicated bitfield type instead.

Regarding signed/unsigned types:
* Java only has signed types. But there are some problems:
    - For bytes, it requires a lot of casts.
    - For integers larger than 2^63 it is necessary to use BigIntegers.
* Slul's predecessor LRL had "eint" which has the common subset of
  values in int and uint. I.e. the range is 0..SIGNED_INT_MAX.
    - e = "either" (can be either signed or unsigned, i.e. common subset)
    - Can be useful for ambiguous expressions, e.g. 127 can be an eint8.
    - Could be useful for lengths (e.g. "esize" = 0..2^63).