it's a system to connect gno and go code together, used for packages like fmt, but it has some problems and is not inspectable using static analysis
i often expressed in issue comments and conversations that i don't really like what i call "gonative". with that word, i generally refer to the entirety of the code in gnovm/pkg/gnolang/gonative.go, but also to the other large part of the codebase that handles the special cases of NativeType and NativeValue. there's been some efforts to improve it lately, and i've been reviewing and merging them provided that they 1. improve some existing flows 2. don't involve too much hassle in reviewing or further maintenance.
but, partly related to the native bindings effort, there's an issue to get these removed. to get some context, let's explore the two mechanisms whereby you can execute go code inside of gno:
DefineNative. this is the underlying function used both for uverse functions, "package injections" and native bindings.append, len, cap, and so on. it directly calls DefineNative.DefineNative, which are generated by connecting a gno declaration with a go definition. here's an example of the generated code. this is how most native functions work now, like sha256.Sum256, or std.AssertOriginCaller().Go2GnoValue, and Gno2GoValue. these are, in fact, from gonative; but they can eventually be removed with a better effort on code-generation, which would remove reflect from the equation here. (check this other blog post out for more code-generation in service of removing reflection.)NativeValue. this method allows to bind a go value directly to an equivalent gno symbol. these, at the time of writing, only exist when using the "testing context"; ie. gno run and gno test (but not on-chain). here's a list of current functions using it. the most useful function which uses NativeValue is fmt.Printf.there are essentially two problems with NativeValue/NativeType:
this is a problem that native bindings was attempting to solve as well: long ago, native functions were all defined in a big "native injector". the consequence was that none of the functions natively defined were "visible" from static analysis tools, like gno doc.
aside from gno doc, tools like gnopls cannot currently "see" these functions, without adding them as exceptions within the code itself. native bindings solved this by adopting the same approach used in go for functions that are defined using assembly: body-less declarations. if you inspect the sync/atomic package, as an example, you'll see that most functions are simply without a function body, because their source is in assembly.
similarly, in gno, native functions are now declared like this; to allow anyone who inspects the source to easily see the matching native go code.
reflect limitations and risksreflect, you cannot create new named typesthis last one is particularly annoying, and is a known "gotcha" when testing; as it's common to be using unexported fields, but when you throw them into a fmt.Printf, the gnovm just panics. the "simple" solution is to use println instead, which, as a native machine function, has no problem with unexported fields. but it's still annoying.
in the short term, we're shrinking the amount of gonative code and removing its usage from the gnovm. by the mainnet launch, which is on the horizon, we should have all of its related code removed.
os package, i expect there to be a testing-only shim that provides an interface to stdin / stdout.fmt and encoding/json package, i expect us to develop an mvp formatter and encoder which can be adequately be used in testing, likely in a restricted subset than their go counterparts, but which work directly on the internal TypedValue rather than trying to convert them to reflect values first.internal/os_test may simply be moved to be another variable which can be manipulated by the testing.Context struct, as part of the std re-organizationmath/big can probably be removed for the time being, awaiting a full implementation in gno.there is nothing more satisfying than deleting code :)