Solidity has struct by which arbitrary complex data structures can be created and referenced through named members. I find struct's, as a type, are particularly handy when coupled with a library through the using X for Y convention. But for some complex types names aren't necessarily needed but they can't be passed to functions and libraries (or I don't know how) without a struct wrapper....
library LibFoo {
struct MyUneccessaryStruct {
mapping (uint => mapping (uint => string)) IWishIDidnotHaveToDereferenceThisNameEveryTime
}
function libFunc(MyStruct self, uint a, uint b) internal {
return self.IWishIDidnotHaveToDereferenceThisNameEveryTime[a][b];
}
}
contract Foo {
using LibFoo for LibFoo.MyUneccessaryStruct;
LibFoo.MyUneccessaryStruct bar;
function foobar(uint a, uint b, string message) returns (string) {
bar.IWishIDidnotHaveToDereferenceThisNameEveryTime[a][b] = message;
return bar.libFunc(a,b);
}
What I would like to see is a type definition keyword (typedef) to simplify and enhance the usability of complex types in the following sense...
library LibFoo {
typedef mapping (uint => mapping (uint => string)) MyComplexType;
function libFunc(MyComplexType storage self, uint a, uint b) internal returns (string) {
return self[a][b];
}
}
contract Foo {
using LibFoo for LibFoo.MyComplexType;
LibFoo.MyComplexType bar;
function foobar(uint a, uint b, string message) returns (string) {
bar[a][b] = message;
return bar.libFunc(a,b);
}
}
Duplicate of #1013.
Not really, I'm proposing the naming of custom data types, not references/pointers/macros to instantiated variables which seems the subject of #1013
It is not really a duplicate, but there are examples of what is planned. Something like alias x = complicatedtype or using x = complicatedtype or type x = complicatedtype.
Is there still no type alias support in Solidity?
Type aliases would be useful for simpler use cases (besides complex mapping types):
Let's say I am writing an application that makes use of several different struct types, each identified by some opaque public key (maybe a hash, or even an integer ID.) This identifier type might be bytes32 in all cases.
As a result, it'd be difficult to look at the code where this ID type is used and discern what kind of record it is. If everything is bytes32, there's no semantic indication what kind of struct it refers to. Further, if a library defines methods that performs lookup by ID, users of that library are forced to do something like using Lib for bytes32, instead of something more semantic.
Additionally, in the course of development, it might become clear that bytes32 is not the correct data type to use for certain IDs, and then the developer would have to find all and only the relevant bytes32 declarations and change those.
By allowing something like type widgetId = bytes32, it'd avoid all of these problems, and I suspect not break much else in the language.
Not really, I'm proposing the naming of custom data types, not references/pointers/macros to instantiated variables which seems the subject of #1013
Actually if you look at all the comments it started out as a references, but in the comments most of the discussion was about typedefs 馃槈
Adding motivation from #7728. This issue can apply to typedeffing structs as well as other primitive types.
Add language construct for creating user-defined names for types.
Because I see somebody writing code like this:
struct AgreementParams {
uint120 ratio;
uint8 ratioType;
uint128 countdownLength;
}
...
(
uint256 ratio,
uint8 ratioType,
uint256 agreementCountdown
) = abi.decode(agreementParams, (uint256, uint8, uint256));
Add a new keyword typedef or alias to allow new scalar (not enum or struct) types.
Example:
contract ABC {
typedef uint128 TimePeriod;
struct AgreementParams {
uint120 ratio;
uint8 ratioType;
TimePeriod countdownLength;
}
}
...
(
uint256 ratio,
uint8 ratioType,
TimePeriod agreementCountdown
) = abi.decode(agreementParams, (uint256, uint8, TimePeriod));
This declaration will be visible at the contract top-level (storage declarations), functions (parameters and declarations) and inherited contracts.
This new feature will also be available for interfaces. In the generated ABI it will still use the canonical (e.g. uint) types.
This is additive, no BC issues.
Practical use case for user-defined type aliases: https://hackernoon.com/beware-the-solidity-enums-9v1qa31b2
The article presents a problem where you use enums in a contract and later you want to be able to add new values to that enum without having to recompile the contract. Currently Solidity adds runtime checks that reject values other than ones included in the enum definition which makes this impossible. We have a feature request to remove the check (#9986).
I think that this use case would be better served by being able to define a custom integer type with a set of constants (https://github.com/ethereum/solidity/issues/9986#issuecomment-708521338). Constants are already there so we're just missing the support for custom types.
Most helpful comment
Type aliases would be useful for simpler use cases (besides complex mapping types):
Let's say I am writing an application that makes use of several different
structtypes, each identified by some opaque public key (maybe a hash, or even an integer ID.) This identifier type might bebytes32in all cases.As a result, it'd be difficult to look at the code where this ID type is used and discern what kind of record it is. If everything is
bytes32, there's no semantic indication what kind ofstructit refers to. Further, if a library defines methods that performs lookup by ID, users of that library are forced to do something likeusing Lib for bytes32, instead of something more semantic.Additionally, in the course of development, it might become clear that
bytes32is not the correct data type to use for certain IDs, and then the developer would have to find all and only the relevantbytes32declarations and change those.By allowing something like
type widgetId = bytes32, it'd avoid all of these problems, and I suspect not break much else in the language.