Solidity: Introduce a type definition keyword

Created on 15 Sep 2016  路  8Comments  路  Source: ethereum/solidity

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);
    }
}
feature language design

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 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.

All 8 comments

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.


Abstract

Add language construct for creating user-defined names for types.

Motivation

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));

Specification

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.

Backwards Compatibility

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

VoR0220 picture VoR0220  路  4Comments

AnthonyAkentiev picture AnthonyAkentiev  路  3Comments

chriseth picture chriseth  路  4Comments

kkagill picture kkagill  路  4Comments

Dohtar1337 picture Dohtar1337  路  4Comments