I thought more about this and I realize that the whole idea of having object-oriented methods on any primitive is wrong. If I see x.foo() I have no idea where foo() comes from. The current idea of forcing require() calls to make clear where everything comes from is lost for something like s.upper() . If I eliminate object-oriented primitive methods, then seeing x.foo() immediately tells me that x is a table and foo is a method in that table. The only exception is when I call java() but this doesn't apply to casual Luan programmers.
This is another example of removing a feature from Luan to improve it. The object-oriented string methods are magic that are confusing and aren't needed. Using a local variable for these functions is both clearer and faster to execute.
In this case, the above Number methods become:
local Number = require "luan:Number"
local long = Number.long
local double = Number.double
local number_type = Number.number_type
local a = long(10)
local b = 3
local c = double(b)
number_type(c) == "double" or error "not double"