Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classes #6

Open
jchitel opened this issue Nov 9, 2017 · 0 comments
Open

Classes #6

jchitel opened this issue Nov 9, 2017 · 0 comments

Comments

@jchitel
Copy link
Owner

jchitel commented Nov 9, 2017

Classes

Dependencies: Interfaces, Overloads, Extensions, Assignables

Description

Ren classes will be inspired by C# and TypeScript classes. They are declarable wherever types can be declared, and used wherever types are used.

Constructors

Classes can contain one or more constructors, which are functions that receive parameters and an implicit this variable, and must return an instance of the class (it can be different from this).

Class members

  • Classes can contain fields, which mirror the syntax of struct type fields, and can also contain an initializer.
  • They can contain methods, with the syntax <type> <name>(<...params>) => <body>. This will need ambiguity resolution logic with fields.
  • Classes can contain properties, with the syntax <type> <name> { get => <body> set => <body with value> }. Either get or set are optional.
    • Shorthand properties are of the form <type> <name> { get set } where set is optional, in which case an initializer is required: <type> <name> { get } = <value> or in the constructor(s).

Inheritance

Classes can inherit from other classes using the extends keyword, and implement interfaces using the implements keyword. Classes labelled sealed cannot be overridden.

Access modifiers

  • Any member of a class can be private, meaning that it is only accessible from inside the class. Class members are private by default.
  • Any member of a class can be protected, meaning that it is only accessible from the class and subclasses.
  • Any member of a class can be public, meaning that it is accessible anywhere the class is imported.

Abstract classes/members

Methods and properties can be abstract, in which case the class must be abstract. Abstract members may omit bodies, but any non-abstract child class must implement them. For abstract members with bodies, child classes can implement them using the super keyword.

Virtual members

Methods and properties can be virtual, allowing subclasses to override them. Any class wishing to override a member must use the override keyword. Methods and properties not labelled virtual cannot be overridden. (We may use a new keyword like C# to explicitly hide members)

Static stuff

Static members are not a thing in this language because there are far simpler alternatives.

Assignability with classes

  • Any value is assignable to a class type if its type is the class or one of the classes child types.
  • Because of this, it is possible for the runtime type of an instance to be more specific than its compile time type.
  • This is contrary to primitive values, which will be coerced to the compile time type.
  • The is operator and getType() method are required to inspect the runtime type of an instance.
  • An important thing that differentiates classes from other types is that classes are not structural types. Assignability is determined nominally, and the structure does not matter.
    • An interesting thing here is that class instances are assignable to struct types if the fields match, but not the other way around.

Using classes

  • Classes are instantiated using the new keyword followed by the class name and a set of arguments that match one of the constructors.
  • This is an expression that returns an instance of the class corresponding to the chosen constructor.
  • Methods and properties can access class members using the special this value, which always points to the current instance of the class.
  • If this is omitted, class members are last in the precedence order for resolving ambiguities, thus the order is:
    • scope variables (recursively upwards to the top scope of the function)
    • module-scoped names
    • class members
  • super is a special form of this that allows access to ancestors' members.
  • super() in a constructor allows parent constructors to be called. super must be called at some point during any child constructor.

New syntactic features:

New Tokens:

CLASS ::= class
SUPER ::= super
EXTENDS ::= extends
IMPLEMENTS ::= implements
CONSTRUCTOR ::= constructor
GET ::= get
SET ::= set
SEALED ::= sealed
PRIVATE ::= private
PROTECTED ::= protected
PUBLIC ::= public
ABSTRACT ::= abstract
VIRTUAL ::= virtual
OVERRIDE ::= override
IS ::= is
NEW ::= new
VALUE ::= value

New NonTerminals:

ClassDeclaration ::= (ABSTRACT | SEALED)? CLASS IDENT TypeParameterList? (EXTENDS Type)? (IMPLEMENTS (Type (COMMA Type)*))? LBRACE ClassMember* RBRACE
AnonClassDeclaration ::= (ABSTRACT | SEALED)? CLASS TypeParameterList? (EXTENDS Type)? (IMPLEMENTS (Type (COMMA Type)*))? LBRACE ClassMember* RBRACE
ClassMember ::= ClassConstructor | ClassField | ClassMethod | ClassProperty
ClassConstructor ::= CONSTRUCTOR ParamList FAT_ARROW (Expression | Statement)
ClassField ::= (PUBLIC | PROTECTED | PRIVATE)? Type IDENT (EQUALS Expression)?
ClassMethod ::= (PUBLIC | PROTECTED | PRIVATE)? (ABSTRACT | VIRTUAL | OVERRIDE | SEALED)? Type IDENT TypeParamList? ParamList FAT_ARROW (Expression | Statement)
ClassProperty ::= (PUBLIC | PROTECTED | PRIVATE)? (ABSTRACT | VIRTUAL | OVERRIDE | SEALED)? Type IDENT (PropertyBody | ShorthandPropertyBody)
PropertyBody ::= LBRACE Getter? Setter? RBRACE
Getter ::= GET FAT_ARROW (Expression | Statement)
Setter ::= SET FAT_ARROW (Expression | Statement)
ShorthandPropertyBody ::= LBRACE GET? SET? RBRACE (EQUALS Expression)?

Extended NonTerminals:

Declaration ::= ... | ClassDeclaration
AnonDeclaration ::= ... | AnonClassDeclaration
Expression ::= NewObject
             | SuperCall
             | SuperMethodCall
             | VALUE
             | IsOperation
NewObject ::= NEW IDENT TypeArgList? LPAREN (Expression (COMMA Expression)*)? RPAREN
SuperCall ::= SUPER LPAREN (Expression (COMMA Expression)*)? RPAREN
SuperMethodCall ::= SUPER DOT IDENT TypeArgList? LPAREN (Expression (COMMA Expression)*)? RPAREN
IsOperation ::= Expression IS Type

New semantic features:

  • Classes add a whole mess of crap.
  • New class and object types
    • Class is the type of a class declaration
    • Object is the type of an instantiated object of a class
  • Class declarations need to be type checked for:
    • Generics
    • Inheritance (including circular inheritance checks)
    • Interface implementation
    • Constructor validity (ensuring super is called and an instance is returned)
      • Default constructor (in the absence of a constructor, a default one is implied)
    • Fields (no duplicate names)
      • Shadowing is ok
    • Methods (inheritance modifiers need to be checked against the class modifiers and the super class methods)
      • Proper variance rules need to apply
    • Properties (same checks as methods, including variance)
  • New object expressions need to check against constructors, resolve to object type
  • Super calls are only valid in constructors
  • Super method calls are only valid in class members, must be checked against parents
  • Object types are assignable to their corresponding class or the class's parents
  • 'is' operator will be complicated
    • For one, logic needs to be added to check assignability
    • This will also affect typechecking so that expressions will take on more restricted types in branches when 'is' is used

Transformation:

  • Will require object instantiation instruction
  • Classes effectively translate to the same kind of structure as structs
  • Constructors and properties translate to whatever methods translate to
@jchitel jchitel self-assigned this Nov 9, 2017
@jchitel jchitel added this to To Do in Ren v0.1 via automation Nov 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Ren v0.1
  
To Do
Development

No branches or pull requests

1 participant