Closed qwertie closed 4 years ago
I'm now thinking it would be best if the syntax of 'apostropheOperators
was a sequence of IdStartChar
instead of a normal identifier, i.e. digits and apostrophes would not be allowed in the operator name after the initial apostrophe. A couple of reasons for this restriction:
'sin'abs x
would be okay and 'foo7
would mean 'foo 7
.x = 'Hello' + x
has incorrect syntax and that if it were changed to x = "Hello" + x
it would have correct syntax.Also, rather than Unit
, perhaps Type
is a better name? A unit is a kind of type, but perhaps in some languages it might be attractive to express other kinds of types with the backquoted notation. Is
also seems attractively generic... I imagine a language where you could specify 'dependent type' relationships:
.constraint positive: value > 0;
(x`positive`, y Is int >= 0);
I like this enough to use it in the initial commit today, but there's a problem: CodeSymbols.Is
is already defined and represents lowercase 'is
. So instead I'll use all-uppercase IS
and define CodeSymbols.IS = (Symbol)"'IS"
.
Also, I forgot in Rationale 1 that Unit
would be immiscible with + - * /
. I guess I'll solve this by removing the immiscibility on uppercase word operators. Immiscibility is good to avoid confusion... right up until there's a reason to allow mixing.
Right now I have two uses of uppercase word operators in mind (Mod
/Remainder
and Unit
/IS
), and for both of them it is mostly OK to have the current precedence which is between * /
and + -
. It would be slightly better for Mod
if its precedence was exactly equal to %
but given that I have no idea what else people might use uppercase ops for, I'll just leave the precedence alone.
Added backquoted and single-quoted unary operators for v28.0, where A`B`
means A IS B
.
I think it's important to be able to express that expressions have units, so I've spent some time thinking about a notation for expressing them. For a long while I was thinking about using the single quote to begin one:
The problem is that both numbers and identifiers can already contain apostrophes, so this notation requires either (1) a space before the apostrophe or (2) disallowing apostrophes in numbers and identifiers. I really like the Haskell-like apostrophe notation
table'
instead oftable2
, so I wanted to avoid option 2. Besides which, there is often a need for a space after the "operator" if punctuation is included in the operator as shown here. Eventually I realized I could use backquoted strings to denote units:This happens to be the same notation I used for units in my unit inference engine for Boo back in 2006. I guess this possibility slipped my mind because it also conflicts with the current grammar, in which
m/s
is considered to be a type marker on the number. However, this is easily solved by requiring numeric literals with unusual type markers to be printed in string form (`_m/s`"7"
).Proposal A
7x
remains legal but7`x`
will no longer be equivalent.'suf
like all other suffix operators. Thusx`++`
is equivalent tox++
, which is equivalent to'suf++
(x).The rationale for the last part is that LES should avoid prescribing specific features (like unit support) for programming languages and, since the syntax is operator-like, it makes sense to encode it as a suffix operator in the Loyc tree.
Discussion
I'm not entirely happy with proposal A by itself. The problem is that there is no elegantly-symmetric way to write prefix operators. LES3 doesn't support arbitrary prefix operators right now (it only supports punctuation-based operators). I'm thinking of allowing them in the form of a single-quoted name, e.g.
but of course, this is not symmetrical - the syntax is different from suffix operators. On the other hand, this notation has the advantage that the name stored in the Loyc tree literally matches the code as written. So, while not perfect, the idea of having prefix and suffix operators that have a rather different syntax is not without advantages.
A more ambitious possibility is to include both
'apostropeOperators
and`backquoted operators`
in the language. In this case I'm inclined to treat backquoted suffix operators as having a different meaning than apostrophe-based suffix operators. For example, what if7`m/s`
was shorthand for7 unit `m/s`
(which in turn is shorthand for`'unit`(7, `m/s`)
)? Although I just said that LES should avoid prescribing specific features, I do believe that unit inference is so useful that it will be widely be supported in programming languages someday.I like this idea, so along with this proposal I will make a second one:
Proposal B
'id
whereid
is a normal identifier (not backquoted)'id expr
, whereexpr
is a subexpression, is a call to'id
with one argument (expr
)expr 'id
, whereexpr
is a subexpression, is a call to'sufid
with one argument (expr
). Note: the example from above,speed 'm/s
, means(speed 'm)/s
in this proposal!-
,++
and*
.++
and--
.foo/*comment*/'op
should also parse fine.)262'144
is fine but262'144'
will be illegal.expr `unitId`
will be shorthand forexpr Unit `unitId`
, except that the precedence will be different.Why
expr Unit `unitId`
?Rationale 1: I chose
Unit
instead ofunit
to change the precedence to be above+
. This allows users to write an expression likeflag && baseSpeed + dDist/dTime Unit `m/s` < max
with a useful structureflag && baseSpeed + (dDist/dTime Unit `m/s`) < max
. In contrast,(flag && baseSpeed + dDist/dTime) unit (`m/s` < max)
would be useless. Rationale 2: A complex unit may not be defined explicitly (as an identifier) in a given language (e.g. perhapsm
ands
are defined but notm/s
), so it is tempting to defineexpr `unitId`
asexpr Unit "unitId"
, which is probably a more appropriate definition in many languages. However it is important to make LES easy to learn, and it is easier to learnexpr `unitId` ≡ `expr Unit `unitId`
thanexpr `unitId` ≡ `expr Unit "unitId"`
.