solidity icon indicating copy to clipboard operation
solidity copied to clipboard

Introduce a type definition keyword

Open o0ragman0o opened this issue 8 years ago • 8 comments

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

o0ragman0o avatar Sep 15 '16 06:09 o0ragman0o

Duplicate of #1013.

axic avatar Sep 15 '16 09:09 axic

Not really, I'm proposing the naming of custom data types, not references/pointers/macros to instantiated variables which seems the subject of #1013

o0ragman0o avatar Sep 15 '16 13:09 o0ragman0o

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.

chriseth avatar Sep 15 '16 15:09 chriseth

Is there still no type alias support in Solidity?

adrianmcli avatar Nov 15 '17 19:11 adrianmcli

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.

gnidan avatar Apr 24 '18 15:04 gnidan

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 😉

axic avatar Apr 26 '18 14:04 axic

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.

fulldecent avatar Nov 18 '19 23:11 fulldecent

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.

cameel avatar Oct 14 '20 16:10 cameel

Any update on this? Having a simple alias to reduce typing would be nice. No fancy side effects, just a "dumb" type alias.

KholdStare avatar Nov 01 '22 15:11 KholdStare

We do have user-defined value types these days, if you want a full type abstraction instead of a mere alias (even though only for value types so far). We may (or may not) still additionally introduce type aliases in the future, if only for providing backwards compatibility aliases for new generic builtin type definitions, but we do not plan on spending resources on this in the near future and before making progress with generics in the language in the first place.

ekpyron avatar Nov 01 '22 16:11 ekpyron

Not sure why I am being "thumbs down"ed

contract SomeContract {
    struct ComplexParams {
        //...
    }

    function func(ComplexParams params) internal {
        //...
    }
}

contract SomeContractFactory {
    using ComplexParams = SomeContract.ComplexParams; // introduce shorthand
    using SomeContract.ComplexParams; // or bring into scope

    function func() internal {
        ComplexParams memory params = ComplexParams(/* ... */);
        // without the aliases have to type SomeContract.ComplexParams everywhere
    }
}

We use user-defined value types for "Strong typing", and it's very useful, thank you. However, for a simple alias, it's overkill to wrap and unwrap. The usecase is entirely different to user-defined value types. Aliases help ergonomics, and keeping things scoped appropriately. Without aliases people may get tempted to pull out inner struct definitions and end up with something like this to save on typing:

struct ComplexParams {
    //...
}

contract SomeContract {
    function func(ComplexParams params) internal {
        //...
    }
}

contract SomeContractFactory {
    function func() internal {
        ComplexParams memory params = ComplexParams(/* ... */);
    }
}

KholdStare avatar Nov 01 '22 16:11 KholdStare

This issue has been marked as stale due to inactivity for the last 90 days. It will be automatically closed in 7 days.

github-actions[bot] avatar Feb 12 '23 12:02 github-actions[bot]

Unmarking this from being stale - this is roadmap relevent, since we'll need type aliases eventually if only for restoring backwards compatible aliases for generic "user"-defined versions of the currently builtin types (i.e. type_synonym uint256 = uint<256>; to get the idea, even though the ultimate syntax will differ).

ekpyron avatar Feb 13 '23 20:02 ekpyron

Plus one for allowing something like using SomeLibrary.StructDefinedTherein; to reduce verbosity when referencing that struct type!

aathan avatar Mar 31 '23 19:03 aathan