Global symbols from other namespaces can be imported into the current namespace with use but use does not work within classes, traits or structs, or withing functions or methods.
With the introduction of tagged union types with variants (#1132) it would be useful not to have to repeatedly write out potentially wordy qualified variant names. It would also be good not to have to repeatedly write out actual generic arguments.
Add support for use definitions in the bodies of classes, traits and structs.
Add support for use statements in statement lists in function and method bodies
Add support for use ... in expressions
These new kinds of use (but not global use) should allow generic arguments where appropriate, to support importing a particular specialization of a generic type.
[ ] use {symbol} in classy bodies
[ ] `use {alias} = {type} in classy bodies
[ ] use {symbol} statement
[ ] use {alias} = {type} statement
[ ] use {symbol} in {expression} expression
[ ] use {alias} = {type} in {expression} expression
In resolve explicit types, if the type part of use {alias} = {type} is simply a qualified identifier then it's OK for it not to resolve to a type.
union Option[T] is
SOME(value: T);
NONE;
si
class TEST[T] is
use Option[T]; // bring Option[T].SOME and Option[T].NONE into scope
use Option = Option[T]; // bring Option[T] into scope as Option
_opt: Option;
_some: SOME;
_none: NONE;
init(opt: Option, some: SOME) is
...
si
init(val: T) is
_opt = new SOME(val)
si
si
union Tree[T] is
NODE(left: Tree[T], right: Tree[T]);
LEAF(value: T);
si
create_tree[T](next_value: () -> T) is
use Tree[T].NODE;
use Tree[T].LEAF;
return new NODE(new LEAF(next_value()), new LEAF(next_value()));
si
We could treat an import of a generic type as both an import of its members and re-binding of its name to the given generic specialization:
use Option[T]
Could be taken to mean
use Option = Option[T]
use Option (i.e. import SOME and NONE)
but this would have the potentially surprising and annoying effect of hiding Option[T]
It's not immediately clear at what point in the compile process we would need to apply these kinds of use. We need to be able to resolve the referenced types, which means global symbols need to have been declared. But we also want the types to be available to member definitions, including as the types of fields and properties, as method return types and as argument types.
It could be that they can be handled in the resolve-explicit-types phase, particularly as we don't need to support forward definitions (i.e. the use of a type must precede any reference to it in subsequent definitions)
Conceptually, use could be treated as a macro that expands to the referenced type, which implies we can resolve use without adding another pass
Global use imports symbols referenced by qualified identifiers. These new kinds of use will need to import types. The syntax for types includes qualified identifiers, so it would be a non-breaking change to also support import of types from a global use. Howver, Given when the resolve-uses pass is run, it's possible this would just work.
Global symbols from other namespaces can be imported into the current namespace with
use
but use does not work within classes, traits or structs, or withing functions or methods.With the introduction of tagged union types with variants (#1132) it would be useful not to have to repeatedly write out potentially wordy qualified variant names. It would also be good not to have to repeatedly write out actual generic arguments.
Add support for
use
definitions in the bodies of classes, traits and structs. Add support foruse
statements in statement lists in function and method bodies Add support foruse
...in
expressionsThese new kinds of
use
(but not globaluse
) should allow generic arguments where appropriate, to support importing a particular specialization of a generic type.use {symbol}
in classy bodiesuse {symbol}
statementuse {alias} = {type}
statementuse {symbol} in {expression}
expressionuse {alias} = {type} in {expression}
expressionIn resolve explicit types, if the
type
part ofuse {alias} = {type}
is simply a qualified identifier then it's OK for it not to resolve to a type.We could treat an import of a generic type as both an import of its members and re-binding of its name to the given generic specialization:
Could be taken to mean
but this would have the potentially surprising and annoying effect of hiding
Option[T]
It's not immediately clear at what point in the compile process we would need to apply these kinds of
use
. We need to be able to resolve the referenced types, which means global symbols need to have been declared. But we also want the types to be available to member definitions, including as the types of fields and properties, as method return types and as argument types.It could be that they can be handled in the resolve-explicit-types phase, particularly as we don't need to support forward definitions (i.e. the
use
of a type must precede any reference to it in subsequent definitions)Conceptually,
use
could be treated as a macro that expands to the referenced type, which implies we can resolveuse
without adding another passGlobal
use
imports symbols referenced by qualified identifiers. These new kinds ofuse
will need to import types. The syntax for types includes qualified identifiers, so it would be a non-breaking change to also support import of types from a globaluse
. Howver, Given when theresolve-uses
pass is run, it's possible this would just work.