-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
Move Edition 2024: New Language Features! #14062
Comments
Each major feature will get its own issue as we progress, but in the meantime, don't hesitate to ask if you have any questions! |
Thank you for the report. I am of the opinion that these changes will be an improvement to Move. I have a couple of questions:
|
@rockbmb, great questions, thanks!
These changes will not be merged back into https://github.com/move-language/move/ (except perhaps into our own branch over there, still TBD). As far as compatibility goes, Sui has had its own development stream of Move for some time now, as do all other deployments. I do not know of any deployment of Move currently tracking
Is this planned, or will the Move Prover remain dormant for now? |
@tnowacki thanks for the reply, Todd! I did not know that Sui has had its own stream of Move; I've found it at Regarding the prover, it is good to hear that the team would like to at least maintain the tool so that specifications that already work can continue to do so 👍 |
Would it be possible to add the option to make global constants and arbitrary struct fields public by default? |
I wanted to note that we have decided to sunset support for the prover. |
Do you have a link to those issues? |
Here's a GH query to this repository's issues that shows them: |
This would be nice. Two other ideas:
|
We will be allowing constants to be used by other constants, but only within a given module right now. After that, we are looking at enabling it within a package. Long term, we are torn about outside of a package given the potential uncertain expectations around package upgrades and constants. |
Great, an improvement is always an improvement.
Even better!
That's understandable - in fact, I was only implicitly considering the first two cases, as the third is, as you say, trickier and perhaps not worth the potential headaches. |
@tnowacki I'm currently trying out Move's
Question: can I use |
No use of edition will affect upgrades. Some tangential things to keep in mind though:
|
@tnowacki I understand, now - thank you for the reply, Todd. |
Hey @tnowacki :) Love the concept of enums and for our project it would make things so much simpler. 2 questions accordingly: Would you advise us to do our architecture with enums considering our mainnet launch? A bit scared of the required byte code changes? |
I'm not sure I would be able to make that call for you, sorry.
Our current plan is to have them in devnet by the end of May. |
This year, we plan to fully release a set of new features to the language. Many of these changes are enhancements to the source language (that is they will affect the compiler without requiring any changes to the binary representation that is published on chain).
Primarily, the goal of these changes is to make Move easier to write, and hopefully easier to read. Secondarily, we will make a few breaking changes to the source language to better position the language for the future.
Do not worry though, existing code will continue to compile! So these new features and the breaking changes will be opt-in. Any existing code will continue to compile. This also means that you will be able to write your packages with the new features, even if your dependencies do not.
These features will be developed and rolled-out over the coming months (and some have already landed!).
To try these features out and provide feedback, you can specify
edition = "2024.alpha"
under the[package]
section in yourMove.toml
WARNING! Features released under
alpha
will be unstable! Each time you update the compiler, any code inedition = "2024.alpha"
might fail to compile, even though it previously did. We definitely want folks to try out the features here! But with the unstable nature of the code, it should not be used in scenarios where you will need to have a persistent source file; for example, you should not use this edition if you want your package to work with source verification (that is if you want to be able to match your source code with some published bytecode package)Once features have stabilized a bit, and all breaking changes have been added, we will release a release candidate edition, i.e.
edition = "2024.rc"
. Unlikealpha
, code written in this edition should not break when you update your compiler. While that is our goal, keep in mind it still is arc
and things might break depending on bug fixes or changes related to feedback. In short,rc
will be more stable but be wary that there might be some breakages.Sometime later in the year, we will finalize the edition and
edition = "2024"
will become the default for all new Move packages! At that point, any further changes or breakages will come in a future edition.Outlined below are the planned features and changes. If you have suggestions or feedback (either for the outlined features or for new features entirely), please let us know!
Major Features
Method Syntax
Method syntax is a syntactic transformation that allows for functions to be called “on” a value rather than directly from a module.
For example
let c2: Coin<SUI> = c.withdraw(10);
which would expand to
let c2: Coin<SUI> = sui::coin::withdraw(&mut c, 10);
There will also be additional syntax for adding new methods, without having to declare a new function, using the new
use fun
alias declaration. See the issue for more details.Index Syntax
Building on Method syntax, we will add syntax for index accesses depending on the type of access. Tentatively:
&x[i]
expands tox.borrow(i)
&mut x[i]
expands tox.borrow_mut(i)
x[i]
expands to*x.borrow(i)
x[i] = v
expands tox.assign(i, v)
Macro Functions
Higher-order functions (such as map, filter, fold, for_each, etc) are useful in many languages for concisely transforming collections. Move does not have lambdas (or closures or function pointers), which makes defining these sorts of operations impossible.
Macro functions will allow for Move to mimic these sort of operations, without supporting the behavior at runtime. The body of the macro mimicking the "higher-order function" will get inlined at each call site. And the call site can provide a "lambda" that will be substituted in as the macro is expanded. For example
let v2 = v.map!(|x| x + 1);
or
v.for_each!(|x| foo(x));
The "lambdas" additionally will support control flow through
break
andreturn
.Enums
Enumerations allow you to define a single type that may hold multiple different shapes of data. Unlike
struct
s which always have the same fields,enum
s can have different fields depending on the variant of theenum
. For example,enum Option<T> { None, Some(T) }
the variantNone
has no fields and the variantSome
has a single field of typeT
.Move will allow destructuring enums using
match
expressions. Some examples of enums in Move are the following:Move is adding support for basic high-level enums that have similar visibility rules to structs in Move today; the enumeration type is publicly visible, just like
struct
types, but the variants of the enumeration are not public, much like fields. But, we have plans to add public variants in the future. Similarly, enumerations cannot be recursive at release, but we have plans on supporting this in the future.Smaller Improvements
public(package)
public(package)
visibility. #13408Since
friend
declarations can only be made within the same package, it feels a bit strange to require explicitfriend
declarations.public(package)
will replacepublic(friend)
, and the compiler will do the rest, eliminating the need for explicitfriend
declarations.Positional fields
For simple wrappers, it can be annoying to have to declare field names. Positional fields can make this a bit less tiresome, e.g.
struct Wrapper(u64)
Postfix
has
ability declarationsWith positional fields, it is a bit awkward to read
has
declarations in the middle of a declaration. As an alternative,has
can now be written after the fields. For example, both will be valid:struct Wrapper1 has copy, drop, store (u64)
struct Wrapper2(u64) has copy, drop, store;
Type inference holes
_
on type annotationsWith type directed programming, often you need to annotate a variable declaration or provide type arguments. But, sometimes you really only need to annotate on specific type, but the other types can be inferred.
_
will be added to allow that type to still be inferred, even when other parts of the type are annotated. For exampledynamic_field::borrow_mut<address, Coin<SUI>>(&mut id, owner)
could be rewritten as
dynamic_field::borrow_mut<_, Coin<SUI>>(&mut id, owner)
where the
_
would be inferred asaddress
break
with valueWhile Move is an expression based language, it is cumbersome to extract values from a
loop
concisely. In the 2024 edition,break
will be able now take a value. This should help code be more concise and less nested. For example:can be rewritten as
Named blocks with enhanced control flow operations
Move 2024 supports naming
loop
,while
, and normal blocks, allowing for more-complex controlflow.
Previous code with nested
while
loops (such as this simplified excerpt from deepbook) would need toset a flag to break both loops:
Now we can directly name the outer loop and break it all at once:
This will immediately break to the outer loop, allowing us more-precise control flow when we'd like
to escape from loops.
This feature also works with normal loop forms, including breaks with values:
In this toy example,
y
will take on the value10
because the firstbreak
will break the'outer
loop with that value.Finally, this feature can be apply to normal blocks in Move, but instead utilizes the
return
keyword. This can be useful when sequencing a block of code that may need early returns with values.
While we do not expect programmers to use named blocks with return in everyday cases, we anticipate
that they will ease the development and usage of macros significantly.
Breaking Changes
public struct
While
struct
declarations in Move can currently only be “public”, they do not currently require the visibility modifier when declared. To make room for a future where struct types have visibility other than “public”, we will be requiringpublic
on allstruct
declarations in the 2024 edition.let mut
Today, all local variables in Move can be assigned
x = e
and mutably borrowed&mut x
. While Move has been influenced by Rust greatly (especially in regard to references and the borrow checker), we did not see the need to require variables to be annotated asmut
before being modified or mutably borrowed; our reasoning being that you could always look locally to check for assignments or mutable borrows.In the 2024 edition however, the new “method syntax” feature will automatically borrow locals when some circumstances. For example,
c.withdraw(10)
might expand tocoin::withdraw(&mut c, 10)
. The point being thatc
is being mutably borrowed implicitly, so you can no longer check locally for modifications to local variables when reading Move code.To improve readability and understandability in the presence of method calls (and any other potential language features down the line), we will be requiring
mut
annotations to be added to all local variables if they are assigned or mutably borrowed.New Keywords
Move 2024 will add new keywords that were previously accepted as identifiers. The list of new keywords is:
mut
enum
type
match
To help with any migrations of existing fields, functions, or local variables with these names, new syntax has been added that lets you use a keyword as an identifier, for example
let `type` = 0; `type` + 1
In short, any keyword can be used as an identifier by escaping it in backticks,
`
.Namespace Revisions
In legacy Move, addresses, modules, module identifiers, and locals all live in separate namespaces.
This allows for users to write rather confusing code, such as:
While nobody would write this specific program, there are some cases on-chain where we have found
name collisions. Move 2024 combines address, module, and non-function module member namespaces (leaving locals and functions to
their own namespace). The code above will now produce the following error:
This is because the
a
name for our module shadows thea
address alias.Similarly, use statements that both define names will now produce errors. For example, the following
use statement
use a::a::{Self, a};
will produce an error:This namespace evolution is toward making it easier to work with enums and enum variants, but we
also hope that it will improve code clarity and help programmers avoid ambiguity.
Other Move Changes
While not related directly to compiler editions, we do have other new features coming to Move!
The final version of these features will not be gated by any edition, and will be available across all editions. (Though as they are developed, some of them might be gated by editions until everything is finalized)
Major Features
Auto Formatter
A long requested feature has been an auto-formatter for Move. We are still in the early stages of planning and starting this work, but it is in the works.
Linting Framework
Still in the early days, but we are working on the a linting framework for Move. Most of the lints today are geared towards best practices in Sui, but we will add other lints over time.
If you have feedback for lints or have suggestions for future lints, please open an issue!
Smaller Improvements
The compiler now allows warnings to be suppressed with the
#[allow(<warning name>)]
annotation. Warnings should also note how to suppress the given warning. All warnings can be suppressed with#[allow(all)]
[move-compiler][sui-mode] Add init and one-time witness rules #13335
[move-compiler][sui-mode] Added struct declaration, private generics, and global storage checks #13482
The compiler will now give specific diagnostics for rules present in Sui. Previously, these messages were only present at the bytecode level. This should make these problems easier to diagnose and fix. They can be enabled by setting the flavor to
flavor = "sui"
in theMove.toml
, or by using thesui move
CLI.The compiler has greatly improved its code generation for the layout of blocks. This should result in some small reductions in gas costs.
The compiler has improved readability of named addresses in error messages, expanding to their numerical value only in cases of ambiguity
The compiler will now warn on unnecessary usages of mutable references
&mut
. This can be suppressed for parameters with a leading_
.The text was updated successfully, but these errors were encountered: