> Still, once you can do that, you can start optimizing, such as inferring that something is an integer and using ordinary Go arithmetic types.
I was hoping for something more aggressive even, like compiling Python classes to Go structs so long as the program doesn't need the dynamic behavior. Alternatively, Grumpy could support declaring native Go types via some sort of pragma or a new `struct` keyword or some such, which would be treated like a normal Go object (rather than defining your Go objects in a separate Go package).
I'd expect to see that in time. If you analyze the whole program to find all the fields of an object and verify the absence of code which dynamically adds a field, you can then make it a struct of "CObject" like entries. Then, try type inference on the fields. Some will clearly be integers, booleans, floats, or strings. Those can be represented with type-specific representations.
If you can identify the built-in types, that's most of the potential win; you get to do hardware arithmetic. If you represent integers as 64 bits and check for overflow, you probably don't need bignum promotion outside of crypto code.
Are Go's integers unbounded? If not, proving the value never exceeds the range to silent convert essentially a BigInteger into an int might be hard.
Go tends to use machine sizes like C, but this implementation appears to properly handle it. The following Python code has identical output for me under Python and grumpy:
two_32 = 4294967296
print(two_32 * two_32)
print(type(two_32 * two_32))
And I tested some other things I won't burden HN with, but promotion is implemented, yes.
All that stuff with "switch" seems to be to handle Python exceptions in a language that doesn't have exceptions. Maybe later, analysis can tell that some function can't raise an exception, and translated calls for such functions can be simpler.