Syntax for types and declarations ================================= Shortened type definitions? --------------------------- Replace the "type I = ..." syntax with the following? Type definitions: class I { ... } record I { ... } enum I { ... } error I { ... } # Should it be possible to define function types? # Or should function types always go into records? # Or should there a separate keyword for function types? # - functype? callback? ...? callback Compare(T a, T b) -> ComparisonResult functype Compare(T a, T b) -> ComparisonResult Declarations of private types class I record I enum I error I Disadvantages: - Does not allow definitions of integer types - It is not obvious to the user that non-class types can have methods and "constructors"/typescopes - Type declarations can be confused with global variables. Order of declaration -------------------- Switch to "right-to-left" declarations: int[5] ref arr <-- reference to array of length 5 of int Should generics syntax be switched around also? Map m Types vs other identifiers -------------------------- A distinction between names of types and variables/constants/fields/funcs is important for two reasons: 1. Syntax highlighting can color types in a different colors (this makes declarations stand out more) 2. Types can start with an identifier, so no "ref" or "data" keyword is needed in declarations. Declarations start with uppercase, and expressions with lowercase. Uppercase, _Uppercase = type lowercase, _lowercase = variable/constant/field/func _1 = forbidden Avoiding the "ref" keyword -------------------------- Functions: - Remove the "ref" keyword completely. It doesn't make sense to distinguish between "ref" and "non-ref" funcs, and function references might be implemented as something that is not a pointer, or a different kind of pointer than a normal data pointer. Objects: - Objects with identity should always be passed by reference, so the "ref" keyword is redundant. Records, enums and elementary types: - These may be passed by value, so there could more than one "instance" of what appears to be the same instance. So pointers don't work well here. Also, small records, enums and numbers may have sub-byte sizes/boundaries, so pointers won't work anyway. Strings: - Single characters are special (encoded in the pointer), so pointers don't work here either. Arrays: - Arrays should work like records. Qualifiers when parameter needs to be passed by reference --------------------------------------------------------- "var", "threaded", "aliased" could be used for those purposes. There is no point in explicitly passing a non-aliased constant parameter by reference. The compiler can decide automatically when to pass by reference or by value. Qualifiers in classes/records/arrays ------------------------------------ In classes and records, it is necessary to specify whether the item should be inlined or not, when it is a structure or array. type A = object { #class A { B inplace x # type structure must be known (i.e. cannot be private in place of declaration of A) B ref y int[] ref a int[3] inplace b # arrays can only be inplace-allocated if they have a compile-time constant size inplace B[3] inplace c # array is inplace allocated, and so are the elements } New "out" qualfier for parameters --------------------------------- Unlike "writeonly", this MUST be initialized in all code paths (except on error). Qualifiers on variables/parameters ---------------------------------- It can be desirable to have modifiable references also. That could be written like this: func do_stuff(int out result) { File? var f = find_file("a.txt") if f == none { f = find_file("b.txt") result = 2 } else { result = 1 } } Qualifiers on arrays -------------------- There are several things that can be controlled by qualfiers: - the field (if the array is in a struct) - the array size - the array "slots" - the array "element contents" Field: int[] ref a <-- Reference to an array int[] var ref a <-- Modifiable reference to an array Array size: int[var] ref a Array "slots": Buffer var[] ref a <-- "Buffer" objects can be exchanged in list, but not modified themselves Array "element contents": var Buffer[] ref a <-- "Buffer" objects themselves can be modified, but not exchanged in list. Error enums ----------- Like enums, but can be used as follows: type FileError = error { #error FileError { not_found permission_denied } func .open(string filename) -> File or FileError ...in impl file: func work() { File f1 = .open("1.txt") or FileError e1 { ...handle error... } File f2 = .open("2.txt") or goto fail ... return fail: # XXX how to get the error code? ...handle error... }