Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: "std" package naming #1475

Open
leohhhn opened this issue Dec 20, 2023 · 11 comments
Open

Discussion: "std" package naming #1475

leohhhn opened this issue Dec 20, 2023 · 11 comments
Assignees
Labels
🌟 must have 🌟 Mandatory work needed to complete a project

Comments

@leohhhn
Copy link
Contributor

leohhhn commented Dec 20, 2023

Opening the discussion on the naming of the "std" package within Gno.

While writing the docs, I came across an issue on how to differentiate the Standard libraries (ie. "encode/binary", "strings", "testing" etc), and the "std" package itself, which contains blockchain-specific types and functionalities, like std.Address, std.GetBanker(), std.GetOrigCaller() etc.

Have we considered renaming this package to avoid confusion? Some of the ideas are as follows:

  • "os" - since os isn't used (ie. no access to the OS functionality like in Go, only to VM context), and std gives information about the chain/vm state, this could make sense,
  • "chain" - makes sense to have chain-related things called by chain.GetHeight(), chain.GetBanker(), etc,
  • or simply have them imported by default, ie you can call GetBanker() without the . notation.

What do you guys think?

@moul @thehowl @zivkovicmilos

@leohhhn leohhhn changed the title Discussion: "std" package naming Discussion: "std" package naming Dec 20, 2023
@waymobetta
Copy link
Contributor

waymobetta commented Dec 20, 2023

I'm with the opinion to avoid overwriting any existing Go stdlib package names to avoid confusing: those who often switch between the languages, the searchability within the codebase (as os is used internally), as well as misc. auto-import tools.

I don't think renaming this library is necessary but I'm curious to hear what others think; or we can determine as a collective rather how to refer to the current std package, as we have been discussing.

@moul
Copy link
Member

moul commented Dec 20, 2023

I have experienced similar feelings on multiple occasions.

Here are my current ideas, listed randomly:

  • Keep the name as std.
  • Change the name to os to align with Golang's package. However, this would result in significant API differences. For a blockchain-less version of gnovm, such as for CLI scripting, we could enable the actual os.
  • Rename it to gno since it is specific to running on a gnovm blockchain. We can imagine a blockchain-less version of a gnovm-powered server with a completely different std package.
  • Move it to a userland package like gno.land/p/std to only have shared std libraries with Go. This would be facilitated by merging the native binding PR (feat(gnovm): improved native bindings #859), but it might create more ambiguity.

@leohhhn
Copy link
Contributor Author

leohhhn commented Dec 20, 2023

@moul

With 1. we will need workarounds in order to discuss/document the std package (not that big of a deal, but still), so essentially I am for modifying the name.

I believe 2. is a totally valid concern. I think "gno" is quite intuitive and unique enough to not get confused with anything.

Are there any technical challenges in regarding to doing this kind of renaming?

@moul
Copy link
Member

moul commented Dec 20, 2023

I can't see any significant technical challenges. It's primarily a challenge related to language design and concerns about adoption and documentation.

Remember that it will be the most widely used import. It's kind of similar with choosing the right keyword, like "return," "panic," "switch," or "for,". It should be something memorable, similar to the well-known if err != nil, which is strongly associated with go.

@deelawn
Copy link
Contributor

deelawn commented Dec 20, 2023

I like the name std and not renaming it to os or something else that overloads an existing go standard library package name. In my opinion, std is the perfect name to avoid naming conflicts with go standard library packages because go does not allow packages to be named std. If we want to apply more meaningful names to groups of functionality within std, then I'd suggest grouping them into subpackages.

I think it is better to keep it out of the normal "userland" package space because of the native bindings that it is built on. I think it makes sense in general for ONLY standard library packages to be able to define native bindings. And in fact, now that the native bindings PR has been merged, it ensures that they are only supported in standard library packages.

So TLDR; I don't support renaming this package but am fine with reorganizing into subpackages.

EDIT: see the strikethrough above; I thought I encountered this the other day but I was wrong

@thehowl
Copy link
Member

thehowl commented Dec 21, 2023

I largely second others in thinking that putting std functionality in os is a tough fit. I think time.Now() returning the block time is a good exception, because as long as we explain the differences, everything else in time still works the same (though, even then, a good consideration might be to rename Now() to something more descriptive like BlockTime(), but I digress).

I don't like std as a name because I think it is too generic and would like for it to be broken down. os is largely not a good fit and a misnomer (you are not accessing the OS, and calling Gno.land an "OS" is a stretch of imagination). But I think runtime, in this regard, is a much better fit. Go's runtime package already exposes many meta-runtime features that make sense within Go programs, so I think in this case we can have the runtime package with a different API.

I propose the following (sorry, I detoured on a redesign of all of the function names, hope you'll forgive me):

  • Package runtime/chain OR just chain (or variants blockchain, bc), containing:
    • types Address, AddressList
    • DerivePkgAddr (better name: AddressFromPkgPath?)
    • EncodeBech32/DecodeBech32
    • type Banker
    • type Coin, Coins
    • type Realm
    • type RawAddress (better: either remove, or make functions like EncodeBech32/DecodeBech32 use it
  • Package runtime, containing:
    • GetCallerAt (better: CallerAt)
    • GetOrigCaller (better: OriginCaller)
    • GetOrigPkgAddr (better: axe this in favour of OriginPkgPath + chain.AddressFromPkgPath)
    • GetBanker (better: NewBanker) + BankerType
    • GetOrigSend (better: OriginSend)
    • CurrentRealm, PrevRealm
    • CurrentRealmPath (better: axe in favour of CurrentRealm.Path)
    • GetChainID (better: ChainID)
    • GetHeight (better: Height, BlockHeight)
    • AssertOriginCall / IsOriginCall

In other words, I like to have a package chain which defines key blockchain-specific types (and utility functions for them), and have a runtime package that accesses the "meta-gnovm" features.

In a kind of way, this is similar to package io (define types, interfaces and useful helper functions) and package os (access the filesystem, often through io types).

@thehowl
Copy link
Member

thehowl commented Dec 21, 2023

Also, one more thought.

I'd reserve gno to be used as a keyword, just-in-case. (And thus not use it as an identifier anywhere)

Maybe the way we implement goroutines is different enough that a better fit is to change the keyword entirely to gno :)

@ilgooz
Copy link
Contributor

ilgooz commented Dec 21, 2023

os/gno or syscall/gno?

Similar to syscall/js

@leohhhn
Copy link
Contributor Author

leohhhn commented Dec 21, 2023

Let this comment be a poll:

Idea 1: as per @thehowl's comment, split std into chain & runtime. Vote with 🚀

Idea 2: simply rename std to gno. Vote with 🎉

Idea 3: keep std as is. Vote with ❤️

In addition, I think that no matter the case, we should decouple classic std functions from functions used for test context editing (ie std.TestSetOrigCaller), and do some name refactoring to make function names more clear from the get-go.

@thehowl thehowl self-assigned this Apr 17, 2024
@thehowl thehowl added this to the 🏗4️⃣ test4.gno.land milestone Apr 17, 2024
thehowl added a commit that referenced this issue Jun 19, 2024
Merge order:

1. #1700 
2. #1702
3. #1695 (this one!) -- review earlier ones first, if they're still
open!

This PR modifies the Gno transpiler (fka precompiler) to use Gno's
standard libraries rather than Go's when performing transpilation. This
creates the necessity to transpile Gno standard libraries, and as such
support their native bindings. And it removes the necessity for a
package like `stdshim`, and a mechanism like `stdlibWhitelist`.

- Fixes #668. Fixes #1865.
- Resolves #892.
- Part of #814. 
- Makes #1475 / #1576 possible without using hacks like `stdshim`.

cc/ @leohhhn @tbruyelle, as this relates to your work

## Why?

- This PR enables us to perform Go type-checking across the board, and
not use Go's standard libraries in transpiled code. This enables us to
_properly support our own standard libraries_, such as `std` but any
others we might want or need.
- It also paves the way further to go full circle, and have Gno code be
transpiled to Go, and then have "compilable" gno code

## Summary of changes

- The transpiler has been thoroughly refactored.
- The biggest change is described above: instead of maintaing the import
paths like `"strconv"` and `"math"` the same (so using Gno's stdlibs in
Gno, and Go's in Go), the import paths for standard libraries is now
also updated to point to the Gno standard libraries.
- Native functions are handled by removing their definitions when
transpiling, and changing their call expressions where appropriate. This
links the transpiled code directly to their native counterparts.
  - This removes the necessity for `stdlibWhitelist`. 
- As a consequence, `stdshim` is no longer needed and has been removed.
- Test files are still not "strictly checked": they may reference
stdlibs with no matching source, and will not be tested when running
with `--gobuild`. This is because packages like `fmt` have no
representation in Gno code; they only exist as injections in
`tests/imports.go`. I'll fix this eventually :)
- The CLI (`gno transpile`) has been changed to reflect the above
changes.
- Flag `--skip-fmt` has been removed (the result of transpile is always
formatted, anyway), and `--gofmt-binary` too, obviously. `gno transpile`
does not perform validation, but will gladly provide helpful validation
with the `--gobuild` flag.
- There is another PR that adds type checking in `gno lint`, without
needing to run through the transpilation step first:
#1730
- It now works by default by looking at "packages" rather than
individual files. This is necessary so that when performing `transpile`
on the `examples` directory, we can skip those where the gno.mod marks
the module as draft. These modules make use of packages like "fmt",
which because they don't have an underlying gno/go source, cannot be
transpiled.
- Running with `-gobuild` now handles more errors correctly; ie., all
errors not previously captured by the `errorRe` which only matches those
pertaining to a specific file/line.
  - `gnoFilesFromArgs` was unused and as such deleted
- `gnomod`'s behaviour was slightly changed.
- I am of the opinion that `gno mod download` should not precompile what
it downloads; _especially_ to gather the dependencies it has. I've
changed it so that it does a `OnlyImports` parse of the file it
downloads to fetch additional dependencies

Misc:

- `Makefile` now contains a recipe to calculate the coverage for
`gnovm/cmd/gno`, and also view it via the HTML interface. This is needed
as it has a few extra steps (which @gfanton already previously added in
the CI).
- Realms r/demo/art/gnoface and r/x/manfred_outfmt have been marked as
draft, as they depend on packages which are not actually present in the
Gno standard libraries.
  - The transpiler now ignores draft packages by default.
- `ReadMemPackage` now also considers Go files. This is meant to have
on-chain the code for standard libraries like `std` which have native
bindings. We still exclude Go code if it's not in a standard library.
- `//go:build` constraints have been removed from standard libraries, as
go files can only have one and we already add our own when transpiling

## Further improvements

after this PR

- Scope understanding in `transpiler` (so call expressions are not
incorrectly rewritten)
- Correctly transpile gno.mod

---------

Co-authored-by: Antonio Navarro Perez <antnavper@gmail.com>
Co-authored-by: Miloš Živković <milos.zivkovic@tendermint.com>
@grepsuzette
Copy link
Contributor

grepsuzette commented Jul 12, 2024

I simply advocate renaming std to gno package.

I do agree splitting packages makes sense as possible solution1, however people are not only going to program exclusively in gno in the future.

Beginners (in gno) and nobody else are the ones who will become long-term users, and for that conversion rate to be maximized I think they need a simple language.

import "gno" is extremely simple, it's as simple and automatic no-brainer as import "std" today. From there, people get autocompletion upon typing gno.|. It doesn't get more simple for beginners.

About reserving gno as a future keyword

The fact go func(){ .. }() exists does not force us to reserve gno func() { .. }().
If we need something special (don't deny, it's a possibility), we can always work a longer name like gnoroutine.

We should choose the most impactful

gno as a keyword is never going to be as impactful as gno as a package.

There not enough material to split?

If I understand correctly, runtime would get just 3 functions: DerivePkgAddr, EncodeBech32, DecodeBech32.

Imagine you go camping with 2 backpacks.
Whenever you need anything, you need to think in which bagpack something is.

Not only that, but you need to remember the bagpack names too.

One bagpack called gno, and you can autocomplete upon it:

gno.GetBanker()
gno.DerivePkgAddr()

Where's the harm in being simple?

Footnotes

  1. I also like runtime and chain TBH, but they lack the instant, quick reflex quality of "std" or "gno".

gfanton pushed a commit to gfanton/gno that referenced this issue Jul 23, 2024
Merge order:

1. gnolang#1700 
2. gnolang#1702
3. gnolang#1695 (this one!) -- review earlier ones first, if they're still
open!

This PR modifies the Gno transpiler (fka precompiler) to use Gno's
standard libraries rather than Go's when performing transpilation. This
creates the necessity to transpile Gno standard libraries, and as such
support their native bindings. And it removes the necessity for a
package like `stdshim`, and a mechanism like `stdlibWhitelist`.

- Fixes gnolang#668. Fixes gnolang#1865.
- Resolves gnolang#892.
- Part of gnolang#814. 
- Makes gnolang#1475 / gnolang#1576 possible without using hacks like `stdshim`.

cc/ @leohhhn @tbruyelle, as this relates to your work

## Why?

- This PR enables us to perform Go type-checking across the board, and
not use Go's standard libraries in transpiled code. This enables us to
_properly support our own standard libraries_, such as `std` but any
others we might want or need.
- It also paves the way further to go full circle, and have Gno code be
transpiled to Go, and then have "compilable" gno code

## Summary of changes

- The transpiler has been thoroughly refactored.
- The biggest change is described above: instead of maintaing the import
paths like `"strconv"` and `"math"` the same (so using Gno's stdlibs in
Gno, and Go's in Go), the import paths for standard libraries is now
also updated to point to the Gno standard libraries.
- Native functions are handled by removing their definitions when
transpiling, and changing their call expressions where appropriate. This
links the transpiled code directly to their native counterparts.
  - This removes the necessity for `stdlibWhitelist`. 
- As a consequence, `stdshim` is no longer needed and has been removed.
- Test files are still not "strictly checked": they may reference
stdlibs with no matching source, and will not be tested when running
with `--gobuild`. This is because packages like `fmt` have no
representation in Gno code; they only exist as injections in
`tests/imports.go`. I'll fix this eventually :)
- The CLI (`gno transpile`) has been changed to reflect the above
changes.
- Flag `--skip-fmt` has been removed (the result of transpile is always
formatted, anyway), and `--gofmt-binary` too, obviously. `gno transpile`
does not perform validation, but will gladly provide helpful validation
with the `--gobuild` flag.
- There is another PR that adds type checking in `gno lint`, without
needing to run through the transpilation step first:
gnolang#1730
- It now works by default by looking at "packages" rather than
individual files. This is necessary so that when performing `transpile`
on the `examples` directory, we can skip those where the gno.mod marks
the module as draft. These modules make use of packages like "fmt",
which because they don't have an underlying gno/go source, cannot be
transpiled.
- Running with `-gobuild` now handles more errors correctly; ie., all
errors not previously captured by the `errorRe` which only matches those
pertaining to a specific file/line.
  - `gnoFilesFromArgs` was unused and as such deleted
- `gnomod`'s behaviour was slightly changed.
- I am of the opinion that `gno mod download` should not precompile what
it downloads; _especially_ to gather the dependencies it has. I've
changed it so that it does a `OnlyImports` parse of the file it
downloads to fetch additional dependencies

Misc:

- `Makefile` now contains a recipe to calculate the coverage for
`gnovm/cmd/gno`, and also view it via the HTML interface. This is needed
as it has a few extra steps (which @gfanton already previously added in
the CI).
- Realms r/demo/art/gnoface and r/x/manfred_outfmt have been marked as
draft, as they depend on packages which are not actually present in the
Gno standard libraries.
  - The transpiler now ignores draft packages by default.
- `ReadMemPackage` now also considers Go files. This is meant to have
on-chain the code for standard libraries like `std` which have native
bindings. We still exclude Go code if it's not in a standard library.
- `//go:build` constraints have been removed from standard libraries, as
go files can only have one and we already add our own when transpiling

## Further improvements

after this PR

- Scope understanding in `transpiler` (so call expressions are not
incorrectly rewritten)
- Correctly transpile gno.mod

---------

Co-authored-by: Antonio Navarro Perez <antnavper@gmail.com>
Co-authored-by: Miloš Živković <milos.zivkovic@tendermint.com>
@zivkovicmilos zivkovicmilos added the 🌟 must have 🌟 Mandatory work needed to complete a project label Sep 12, 2024
@thehowl
Copy link
Member

thehowl commented Sep 20, 2024

I simply advocate renaming std to gno package.

I appreciate the "natural feeling" given by typing out gno.Address, however I do think we should use the term "gno", including in our standard libraries, to refer to the programming language rather than the chain.

This is similar to what happens in go; where the go/* packages are those concerning the Go programming language (ie. parsing, AST, type checker...).

I do agree splitting packages makes sense as possible solution1, however people are not only going to program exclusively in gno in the future.

What?

People aren't going to programming exclusively for gno.land in the future. But this is a change that concerns primarily the standard libraries, which are likely to be brought over into other gno.land ecosystems. This actually strengthens my argument; that chain translates better when using gno elsewhere than having a gno package.

Beginners (in gno) and nobody else are the ones who will become long-term users, and for that conversion rate to be maximized I think they need a simple language.

import "gno" is extremely simple, it's as simple and automatic no-brainer as import "std" today. From there, people get autocompletion upon typing gno.|. It doesn't get more simple for beginners.

good rhetoric ;)

i don't think we'll necessarily end up using it as a keyword; it's a backward-incompatible change with go, i'd much rather use go.

but from principles, i disagree that gno is a better way to namespace types like Address, Coins and Banker. They relate to the blockchain it's referencing, not the programming language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌟 must have 🌟 Mandatory work needed to complete a project
Development

No branches or pull requests

9 participants