ballerina-spec
ballerina-spec copied to clipboard
Specify which keywords are reserved in which contexts
The spec doesn't get into the details of what keywords are reserved in what contexts.
We have a lot of keywords and they shouldn't be reserved everywhere.
@hasithaa Please describe what the current implementation does
Currently, the following keywords are allowed in function/method calls.
- foreach
- map
- start
- continue
- __init
Ref: https://github.com/ballerina-platform/ballerina-lang/blob/master/compiler/ballerina-lang/src/main/resources/grammar/BallerinaParser.g4#L923
We have built-in type names which are keywords such as int, string, boolean, float, decimal, XML, and json etc. One use case is Using them in an expression context
Usecase:
var x = int;
var y = 'int; // Workaround
As far as I can see, there is no need to treat things like int
and string
as a reserved word. It can just be an identifier that is predefined as a type name in every module's main symbol space.
A second category is built-in type-names that can be followed by type parameters in angle brackets. I think we may be able to deal with them by adding a more general type-descriptor production:
parameterized-type-descriptor = type-reference "<" type-descriptor ("," type-descriptor)* ">"
and then restricting type-reference to refer to specific built-in types. @SupunS Will this work?
A third category is things like object
and record
which have specific syntax following them. These need to be reserved words.
That is doable.
But I have some concerns over, whether it is useful to make those built-in type-names non-keywords:
- Since they are already defined in the main symbol space, no one can use them in-place of identifiers.
- By making them not keywords, we effectively make the parser unaware of those 'special' identifiers. So if someone actually used it, say, as a function name in a function definition, we cannot fail early (at parser level). Have to go all the way up to semantic analyser phase.
- If we allow shadowing symbols, that would be a problem. - but i'm not sure whether we do this for type-desc symbols.
What if we keep those as keywords, but allow them in expression context only (other than in type-desc contexts), rather than universally allowing them?
One thing I find absolutely ghastly is having to quote prefixes that are keywords e.g. 'xml:Element
. At the moment we have
module-prefix := identifier
Can we fix this problem by simply changing this to:
module-prefix := identifier | predeclared-prefix
predeclared-prefix :=
boolean
| decimal
| error
(etc for all predeclared prefixes that are keywords)
?
Split off https://github.com/ballerina-platform/ballerina-spec/issues/34#issuecomment-732518850 into a separate issue #659. The rest we will address later.
C# has concept of contextual keywords https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/contextual-keywords
https://github.com/dotnet/csharplang/blob/main/spec/lexical-structure.md#keywords
List of all Ballerina keywords: https://github.com/ballerina-platform/ballerina-lang/blob/master/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/internal/parser/LexerTerminals.java
C++ context-sensitive keywords https://bulldozer00.blog/2014/04/17/context-sensitive-keywords/
Can we special case join
, map
and start
as method-name?
We decided to move this to 2022R1 except possibly for the special case in #958.
As per the current spec,
public function main() {
string s1 = string:'join("/", "a", "b", "c"); // does not work without quote
string s2 = "/".join("a", "b", "c"); // does work without quote
}
I suspect there are cases when we can allow keywords after colon in a qualified identifier, but this is complicated by the fact the colon is also used in conditional expressions.
parameter
, field
, and source
are keywords only in https://ballerina.io/spec/lang/master/#annot-attach-points. We can relax in other places. @jclark @hasithaa WDYT?