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

feat: Introspection, a Metaprogramming alternative to reflection #971

Open
peter7891 opened this issue Jul 13, 2023 · 2 comments
Open

feat: Introspection, a Metaprogramming alternative to reflection #971

peter7891 opened this issue Jul 13, 2023 · 2 comments
Assignees
Labels
gno-proposal Gnolang change proposals

Comments

@peter7891
Copy link
Contributor

peter7891 commented Jul 13, 2023

Description

Introspection gives us the ability to inspect types, just like reflection but since it is done at compile time, it is completely type safe.
This is a proposal for a Gno add-on transpiler that would compile an extended version of Gno into regular Gno that the VM can execute.
Here is a small example of what we can do with introspection.
Formatting in Go is done by using runtime reflection to get the type information and the analysis on the actual format are done at runtime.

Zig, Dlang, Jai and C++ have similar features.

Conditional compilation

comptime blocks make restrictions that all expressions inside are required to operate on values known at compile time.
verb comes from format in the actual code that is left out. This means that format must be a value that is known at compile time. What this code will end up doing is, it will run the switch at compile time and based on weather the verb is 'T' or 'p' that code will end up being compiled in the actual function. The code from the other cases will be discarded.
That gives the ability to be dynamic but generate concrete types that can be analysed by the VM and give us more type safety.

func print(format string, vars...anytype) {
        ........... some code

     	comptime {
	    switch verb {
	case 'T':
		p.fmt.fmtS(@TypeOf(arg).String())
	case 'p':
		p.fmtPointer(@ValueOf(arg), 'p')
	    }	
	}	  
}

If verb is T and the type is int the actual code in the Gno file would be compiled as

func print(format string, vars...anytype) {
        ........... some code

		p.fmt.fmtS(int.String())}

Running code during compilation

The @ symbol tells the compiler to run this function during compilation and produce the result.

n := @fibonacci(10)

The code that will actually end up in your Gno file will be

n := 55
@moul
Copy link
Member

moul commented Jul 13, 2023

Related with #774 (JIT with LLVM)
Related with gnolang/hackerspace#15 (Golang working group / Gnolang 1.x)
Related with #972

@peter7891
Copy link
Contributor Author

This is obviously not a full spec of the proposed feature.
One of the implementation details is that we need to do monomorphization of the functions that have compile time expressions. When the AST is analysed, for every type/value that the function is called with, we need to generate a different print function, as in the example.

The following invokations will result in having to generate 2 different print functions

func foo() {
   print("%T", 1)
}

func foo() {
   print("%p",  SomePointer)
}

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
Development

No branches or pull requests

2 participants