vyperlang / vyper

Pythonic Smart Contract Language for the EVM
https://vyperlang.org
Other
4.87k stars 796 forks source link

Style guide #905

Open fulldecent opened 6 years ago

fulldecent commented 6 years ago

Add a coding style guide to Vyper and use it consistently.

Currently examples include both camel rase (https://github.com/ethereum/vyper/blob/master/docs/structure-of-a-contract.rst storedData) and snake case (https://github.com/ethereum/vyper/blob/235e1126c292985b98988043bad79b71bb08bb7d/examples/stock/company.v.py total_shares) for the same type of thing.

I do not know which one is canonical and this is a distraction from writing code.

Work plan

Discussion

Function names, parameter names, events and public variable names are user-visible. Maybe in the future all contract calls will be hidden from the end user -- but for the foreseeable future, people will be confirming transactions on Etherscan and using MetaMask to confirm details before they click "accept".

In order to be consistent with other deployed contracts, I recommend we adopt from Solidity Style Guide anything that affects the end-user. This includes function names, parameter names, etc.

Additionally, having a style guide directly increases human readability of code which is a prime goal of the Vyper project.

fubuloubu commented 6 years ago

Solidity uses camel case and has defined several standards. The standards' function signatures would be different if using snake case, so we may have to accept that begrudgingly

maurelian commented 6 years ago

Solidity's style guide is based on PEP8, so converting the guide from Solidity to Vyper should be doable.

I do think Vyper (and future languages) are obligated to adopt camelCase for external functions, but it seems reasonable to me that private functions, and all other names can follow Python conventions.

jacqueswww commented 6 years ago

We can also consider to add some of the style rules to the compiler (e.g. all public function should be camelcase). This is a feature that I believe will make it much easier for people to adopt the style :tongue:

jacqueswww commented 6 years ago

As discussed on https://github.com/ethereum/vyper/pull/925, we will probably have to go with camelcasing all methods like solidity. The thought process goes like:

1.) Public method require it thanks to ERC's 2.) To keep method casing consistent we have to match it accross internal & public functions.

I still think we should only apply the hard camelcase check on public methods though.

fulldecent commented 6 years ago

For reference, here are the parts of the Solidity style guide that are visible outside just Solidity.

SOURCE: https://solidity.readthedocs.io/en/v0.4.24/style-guide.html


Style Guide [EXCERPTS]

Naming Conventions

Naming conventions are powerful when adopted and used broadly. The use of different conventions can convey significant meta information that would otherwise not be immediately available.

The naming recommendations given here are intended to improve the readability, and thus they are not rules, but rather guidelines to try and help convey the most information through the names of things.

Lastly, consistency within a codebase should always supercede any conventions outlined in this document.

Naming Styles

To avoid confusion, the following names will be used to refer to different naming styles.

Note

When using initialisms in CapWords, capitalize all the letters of the initialisms. Thus HTTPServerError is better than HttpServerError. When using initialisms is mixedCase, capitalize all the letters of the initialisms, except keep the first one lower case if it is the beginning of the name. Thus xmlHTTPRequest is better than XMLHTTPRequest.

Names to Avoid

Never use any of these for single letter variable names. They are often indistinguishable from the numerals one and zero.

Contract and Library Names

Contracts and libraries should be named using the CapWords style. Examples: SimpleToken, SmartBank, CertificateHashRepository, Player.

Struct Names

Structs should be named using the CapWords style. Examples: MyCoin, Position, PositionXY.

Event Names

Events should be named using the CapWords style. Examples: Deposit, Transfer, Approval, BeforeTransfer, AfterTransfer.

Function Names

Functions other than constructors should use mixedCase. Examples: getBalance, transfer, verifyOwner, addMember, changeOwner.

Function Argument Names

Function arguments should use mixedCase. Examples: initialSupply, account, recipientAddress, senderAddress, newOwner.

When writing library functions that operate on a custom struct, the struct should be the first argument and should always be named self.

Local and State Variable Names

Use mixedCase. Examples: totalSupply, remainingSupply, balancesOf, creatorAddress, isPreSale, tokenExchangeRate.

Constants

Constants should be named with all capital letters with underscores separating words. Examples: MAX_BLOCKS, TOKEN_NAME, TOKEN_TICKER, CONTRACT_VERSION.

Enums

Enums, in the style of simple type declarations, should be named using the CapWords style. Examples: TokenGroup, Frame, HashStyle, CharacterLocation.

Avoiding Naming Collisions

This convention is suggested when the desired name collides with that of a built-in or otherwise reserved name.

samajammin commented 5 years ago

Thank you all for putting thought into this!

Curious where this stands now? Function names and storage variables as camelCase make sense to me, given ERC requirements. Have we reached a consensus on function argument names and local variables? Looking through the example contracts in the Vyper docs, there seems to still be a mix of camelCase vs. snake_case for those. I also see the occasional underscore before the function argument names (e.g. _beneficiary) - any specific meaning behind the use of that?

Happy to help update the docs if/once these have been established.