[Move 2024] Method Syntax #14063
Labels
design
devx
move
Type: Major Feature
Major new functionality or integration, which has a significant impact on the network
Method syntax is a syntactic transformation that allows for functions to be called “on” a value rather than directly from a module. The goal of this change is to greatly improve the ease of programming in Move.
For example
let c2: Coin<SUI> = c.withdraw(10);
which would expand to
let c2: Coin<SUI> = sui::coin::withdraw(&mut c, 10);
A new syntax,
use fun
, will be introduced for adding eitherpublic
or internal method aliases. This feature can be used for creating an alias to “rename” a method. Or it can be used to create a local method alias outside of the associated types defining module.See the main issue for more on Move 2024 changes
Design
When calling
e.g(arg_0, ..., arg_n)
, the compiler will statically resolveg
depending on the type ofe
. The compiler will keep a method alias table (dependent on aliases defined in that scope) to resolve these functions. The compiler will then automatically borrowe
depending on the signature of the function.So assuming
e: X
and there is an alias to resolvee.g
toa::m::f
where the first argument tof
is&mut X
, the compiler will resolvee.g(arg_0, ..., arg_n)
toa::m::f(&mut e, arg_0, ..., arg_n)
The auto-borrowing and signature aspect of the expansion should be more apparent with examples. But before looking at examples, let’s look at this “method alias” system a bit more:
use fun a::m::f as X.g;
creates a method alias local to the scope (much like normaluse
aliases).use fun
aspublic
, e.g.public use fun a::m::f as X.g;
. But! Only the module that definesX
can declare apublic use fun
. More on this below.public use fun
for any function declaration for its types when the type is the first argument in the function.a::m
that defines a typeX
, the functionfun foo(x: &X) { ... }
gets an implicit aliaspublic use fun foo as X.foo;
. This is done regardless of the visibility offoo
so that these aliases are discoverable in all cases, which is particularly helpful forpublic(package)
functions.However, the function
fun bar(flag: bool, x: &X) { ... }
would not get an implicit alias sinceX
is not the first argument (and one is not created forbool
sincebool
is not defined in that module).use
aliases for functions also create an implicituse fun
when the functions first argument is a type declared in that module, e.g.use a::m::f as g
also creates ause fun a::m::f as X.g
assuminga::m::X
is the first argument off
(either by reference or by value)use a::m::f as g
as affecting the implicitpublic use fun a::m::f as X.g
from the modulea::m
The goals around this aliasing system is to give power and flexibility to programmers, particularly when migrating old code that might not have been written with method syntax in mind. But above all we want this feature to feel explicit and predictable. A way to think about this is that any additions to a package’s dependencies will not affect existing method calls. This is achieved by always relying on local
use fun
s oruse
aliases, and falling back to the defining module when none are present; the local aliases take precedence which ensures additions in dependencies do not change how method calls in existing packages resolve.Examples
Automatic Borrowing
Public Use Fun
Use Fun
Some Uses Create Implicit Use Funs
The text was updated successfully, but these errors were encountered: