vyper icon indicating copy to clipboard operation
vyper copied to clipboard

Variables cannot be declared both `immutable` and `public`

Open jakerockland opened this issue 2 years ago โ€ข 6 comments

Version Information

  • vyper Version (output of vyper --version): 0.3.3.
  • OS: osx
  • Python Version (output of python --version): Python 3.8.2

What's your issue about?

I'm not sure if this is WAI or something that is a bug, but when trying to do something like genArt721CoreAddress public(immutable(address)), I am hitting a comilation error:

UnknownType: No builtin or user-defined type named 'immutable'. 
  contract "contracts/minter-suite/minter_set_price_v1.vy", line 31:29 
       30 # Core contract address this minter interacts with
  ---> 31 genArt721CoreAddress: public(immutable(address))
  -------------------------------------^
       32

Is it possible to declare a variable that is both immutable and public?

jakerockland avatar Jun 09 '22 17:06 jakerockland

not at this time, you have to write the getter manually.

leaving this open since it seems like something one would generally want to have. the only issue is that, with the function call syntax for these modifiers, we would not only need to be able to parse public(immutable(foo)) but also immutable(public(foo)) (and also decide if the latter is legal - my gut says we should not allow it actually).

charles-cooper avatar Jun 09 '22 22:06 charles-cooper

not at this time, you have to write the getter manually.

leaving this open since it seems like something one would generally want to have. the only issue is that, with the function call syntax for these modifiers, we would not only need to be able to parse public(immutable(foo)) but also immutable(public(foo)) (and also decide if the latter is legal - my gut says we should not allow it actually).

Roger that :) SGTM. Will take that approach for now of manual getter; though definitely agree that this feature would be nice to have in the future (would also similarly love to be able to do something like minterType: public(constant(String[48])) = "MinterSetPriceV1" in the future, though currently working around with this approach which is fine just less idiomatic/readable:

MINTER_TYPE: constant(String[48]) = "MinterSetPriceV1"
minterType: public(String[48])

jakerockland avatar Jun 09 '22 23:06 jakerockland

Also, unrelated, long-time-no-chat @charles-cooper ๐Ÿ‘‹ ๐Ÿ˜„ ๐Ÿ™

jakerockland avatar Jun 09 '22 23:06 jakerockland

I think we may actually take this approach for now for the public + constant use-case:

_minterType: constant(String[48]) = "MinterSetPriceV1"
@external
@view
def minterType() -> address:
    """
    @notice a separate explicit getter declaration is currently needed per https://github.com/vyperlang/vyper/issues/2903
    """
    return _minterType

As I find this slightly more readable personally stylistically.

Any reason that is immediately evident from your perspective @charles-cooper that there would be a strong reason to use the above instead though (copied here again for readability in comparing) other than for purely stylistic reasons?

MINTER_TYPE: constant(String[48]) = "MinterSetPriceV1"
minterType: public(String[48])

jakerockland avatar Jun 09 '22 23:06 jakerockland

stylistically i would have all constants be all caps -- MINTER_TYPE: constant(String[48]) = "MinterSetPriceV1"

i think auto-generated getters are generally A Good Thing, since they remove another avenue for the programmer shooting themselves in the foot. we just haven't implemented them for constants and immutables. but it's stylistic, getters are also relatively easy to implement manually so i don't see an issue with doing that.

(btw - there is a codegen optimization which gets triggered when the length of a string is <= 32, so if it's allowed you may want to declare MINTER_TYPE as having type String[32]).

charles-cooper avatar Jun 10 '22 00:06 charles-cooper

stylistically i would have all constants be all caps -- MINTER_TYPE: constant(String[48]) = "MinterSetPriceV1"

i think auto-generated getters are generally A Good Thing, since they remove another avenue for the programmer shooting themselves in the foot. we just haven't implemented them for constants and immutables. but it's stylistic, getters are also relatively easy to implement manually so i don't see an issue with doing that.

Yeah this rationale all makes sense, we'll go with the later of the two options then instead then for now :)

(btw - there is a codegen optimization which gets triggered when the length of a string is <= 32, so if it's allowed you may want to declare MINTER_TYPE as having type String[32]).

Huzzah!! Thank you very much for calling that outโ€“we can work within 32, so will adjust accordingly.

jakerockland avatar Jun 10 '22 00:06 jakerockland

I believe this was fixed in #3024

charles-cooper avatar Jan 03 '23 21:01 charles-cooper

I believe this was fixed in #3024

Ah nice!! Good to know โ€“ย thanks @charles-cooper ๐Ÿ˜„ ๐Ÿ’œ

cc @ryley-o

jakerockland avatar Jan 03 '23 22:01 jakerockland