blob: 67228e18c7ea40b96b1263af8a7ac0749c355c7e (
plain) (
blame)
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
|
This file contains various notes about the Oryx language and language
design more generally that I have compiled over my time developing the
Oryx ecosystem. These are mostly just for myself to remember in the
future, as well as the potential interest of others.
1. Unified logical- and bitwise operators is a potentially bad idea.
After a few attempts at unifying these seemingly similar operators
(‘|’ and ‘||’, ‘&’ and ‘&&’, etc.) I have concluded that it makes
little sense.
The first argument is that when you see ‘a & b’ you assume that both
sides of the argument are being evaluated while you assume
short-circuiting in ‘a && b’.
Another issue I came to realize is one that occurs when you consider
the fact that bitwise-NOT is merely the unary version of bitwise-XOR¹
(similar to how you have both a unary- and binary-minus). This means
that a NOT and an XOR would look like ‘~a’ and ‘a ~ b’ respectively.
This is fine until you merge bitwise- and logical-NOT. All of a
sudden you get ambiguity when you see ‘a ~= b’. Is this a compound
assignment that expands to ‘a = a ~ b’, or is it a logical not-equals
operation between ‘a’ and ‘b’?
¹ This is an observation made by both Go and Odin. Odin does use ‘~’
for both operations. Go on the otherhand retains ‘^’ for XOR and ‘~’
for bitwise-negation, but it does have an AND-NOT operator
represented by ‘&^’, the operators for AND and… XOR. Likewise
LLVM IR does not even include an operator to perform a bitwise
negation, instead requiring the user to express it as the XOR of your
to-be-negated oprand and 1.
2. Prefixless functions à la Jai are not a good idea. Take the simple
example of ‘f :: (a: int) (int, int)’. What is ‘f’? It seem to be a
function that takes an integer and returns two integers, but this
could actually also be a function that takes an integer and returns a
new function that accepts 2 integers and returns nothing. With a
function prefix this ambiguity is solved:
f :: func (a: int) (int, int);
f :: func (a: int) func (int, int);
Additionally this allows for consistent syntax between functions and
macros:
addf :: func (a, b: int) int { return a + b; }
addm :: macro (a, b: int) int { return a + b; }
|