-
Notifications
You must be signed in to change notification settings - Fork 373
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: extending const behavior #919
Comments
I'm sort of against on significantly changing the behaviour of the language from Go without good reason or to enable a specific functionality which makes sense in our context. But in any case, let me try to tackle why I don't think this is a good idea. Aside from numeric, boolean, and string data types, in Gno we currently have slices, structs, maps, pointers, arrays, interfaces, function values. Let's run through each one of them: SlicesSlices have the semantic in Go where, in essence, the underlying array is always heap allocated and modifiable. package main
const a = []byte{1, 2, 3, 4, 5, 6, 7, 8}
func main() {
b := a[:4] // allowed operation
toOnes(a) // preprocess-time panic: cannot modify constant underlying array of a
toOnes(b) // preprocess-time panic: cannot modify constant underlying array of b
}
func toOnes(s []byte) {
for i := range s {
s[i] = 1
}
} So in other words, what is written out as a Note, on top of everything, that aside perhaps some preprocess-time optimizations that could be added when referencing the slice, this does not necessarily add performance improvements; the array still needs to be "heap-allocated", and I can see little optimizations in the above example, or any examples off top of my head, where computations would be reduced. PointersPlease no. I think I elaborated enough in the slice example why I think having pointers where the underlying data is immutable is a bad feature. StructsI would not necessarily take too much issue with this, were it not for the fact that the structs we could specify as constants probably couldn't have in the type any of the data types we don't support for constant values. MapsSame problem as slices. Operations like assignment of a key would have to runtime or preprocess-time panic. Would imply adding concept of im/mutability of variables. InterfacesNo point having them as constants if you ask me. ArraysProbably the only ones that make some degree of sense. The only additional things we would need to add, compared to the disallowed operations of a constant string, are slicing I still see little advantage than what we could do with simple static analysis, optimizing an array-typed variable to be implicitly a constant. Function valuesA constant function value is just a function definition, and would only be useful for aliasing. I think this is already a clear and preprocessor-optimizable pattern for function aliases:
Previous language design discussions, and conclusionLooking up on google golang/go#6386 provides the following useful commentary, which I tend to agree on:
Russ Cox: Evaluation of read-only slices, found through golang/go#20443. Extra: on errorsAs far as I know, in Go there is one big case of exported variables which really should be constants to avoid a ""malicious"" package being able to modify the values: errors. It is not uncommon in Go to have variables such as I think in Go this is less of an issue than the commenter writes; not reading through a dependency's source code before using its code is a bad practice IMO, and if you allow code like that to enter your project that's on you. Of course, this is different for Gno, where we have realms. It might be the case that the better pattern for implementing errors in Gno might have to be this -- and as a consequence replace most global variable declarations also in the stdlibs to be constants: type Error string
func (e Error) Error() string {
return string(e)
}
const ErrVerification = Error("crypto/rsa: verification error") Although I think this warrants a separate issue. Extra: using a function's output as a constantIf the function is pure (ie. no dependency on global variables), this can be determined by the preprocessor, and the instances where its called "pre-compiled". Similarly, if it's used in an unexported global variable or a local variable which is never changed, its value can in turn be changed by the processor to be a constant value. So, pointless to me. |
Related with gnolang/hackerspace#15 |
Description
Right now, we have constants implemented as described by the Go language spec.
I think, it would be a worthwhile discussion on whether we should extend that functionality.
For example, adding constant data structures, arrays, slices etc.
Additional questions on this might be if the const behavior should propagate to members and
if we should allow function results to be assignable to constants and how that would look like.
Why
I think, it would be of significant benefit of users, as they won't need to create special functions as in Go
to simulate this behavior. Also, it would catch bugs when there is mutation.
The text was updated successfully, but these errors were encountered: