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

Proposal: export foo as Bar syntax #1075

Open
n0izn0iz opened this issue Aug 27, 2023 · 3 comments
Open

Proposal: export foo as Bar syntax #1075

n0izn0iz opened this issue Aug 27, 2023 · 3 comments
Labels
gno-proposal Gnolang change proposals

Comments

@n0izn0iz
Copy link
Contributor

n0izn0iz commented Aug 27, 2023

Problem

Currently, if we want to make a new realm that exposes a standard (for example a new grc20, grc721, or a DAO) we need to copy all public functions from the interfaces we want to support, this could be a lot of boilerplate, especially if you want your realm to support multiple interfaces

For example, for a grc20, that's this whole block:

func TotalSupply() uint64 {
	return foo.TotalSupply()
}

func BalanceOf(owner users.AddressOrName) uint64 {
	balance, err := foo.BalanceOf(owner.Resolve())
	if err != nil {
		panic(err)
	}
	return balance
}

func Allowance(owner, spender users.AddressOrName) uint64 {
	allowance, err := foo.Allowance(owner.Resolve(), spender.Resolve())
	if err != nil {
		panic(err)
	}
	return allowance
}

// setters.

func Transfer(to users.AddressOrName, amount uint64) {
	caller := std.GetOrigCaller()
	foo.Transfer(caller, to.Resolve(), amount)
}

func Approve(spender users.AddressOrName, amount uint64) {
	caller := std.GetOrigCaller()
	foo.Approve(caller, spender.Resolve(), amount)
}

func TransferFrom(from, to users.AddressOrName, amount uint64) {
	caller := std.GetOrigCaller()
	foo.TransferFrom(caller, from.Resolve(), to.Resolve(), amount)
}

Proposal

Support this syntax in realms global scope:

export foo as Bar

Where Bar is an interface and foo is an object implementing Bar
This would make all Bar methods public realm methods using foo as implementation

For example:

export foo20 as grc20.IGRC20

Would make all methods of grc20.IGRC20 public realm functions using foo20 as implementation and thus this single line could entirely replace the boilerplate we saw previously

Maybe we could also support

export foo

Where it would expose all public methods and members of foo

Questions

In the foo20 example, the grc20.IGRC20 interface return errors but the foo20 realm functions panics on those error, if we do add export, should we convert errors to panics?

Alternatives

We could use the registry pattern like in #1072 and expose the common methods on the registry realm but this would break the authority patterns using std.PrevRealm since the registry would be the previous realm

@moul
Copy link
Member

moul commented Aug 30, 2023

Thanks for your proposal. Introducing changes to the language does take time, so bear with us as we navigate this. In the meantime, considering code generation might be fruitful. We haven't fully tapped into its capabilities, and it offers promising solutions.

On a related note, enhancing our CLI to call methods directly could be beneficial. This way, we can make variables like var Foo20 accessible. Just to highlight, we can currently access methods from different contracts, but there's a challenge when connecting with gnokey. If you want a deeper understanding, you can read more in this discussion.

Additionally, integrating a language-focused feature like `exec’ is an avenue we could explore. For a detailed view, you can refer to this link.

Lastly, there's a proposition about harnessing gnoffee script for in-built code generation. You can find more information on this here.

@moul moul added the gno-proposal Gnolang change proposals label Aug 30, 2023
@moul moul mentioned this issue Sep 3, 2023
7 tasks
@piux2
Copy link
Contributor

piux2 commented Sep 6, 2023

@n0izn0iz @moul

How about embedding?

type foo struct{
AdminToken
}

We can implement foo.TotalSupply() to overwrite default implementation. This is the idiomatic way to inheriting the fields and methods of the embedded type AdminToken in go.

@moul moul added this to the 💡Someday/Maybe milestone Sep 6, 2023
@thehowl
Copy link
Member

thehowl commented Dec 4, 2023

I think this proposal addresses an issue we have with existing contracts. I'd be curious to explore first if there are any better ways to improve this without changing the language syntax. In any case, I've added it as a discussion for the team meeting. Thanks for your proposal, @n0izn0iz :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gno-proposal Gnolang change proposals
Projects
Status: 🔵 Not Needed for Launch
Status: Coffee Slot
Development

No branches or pull requests

4 participants