pmgl / microstudio

Free, open source game engine online
MIT License
921 stars 103 forks source link

Function Arguments default to "number" type #132

Open BlueRaccoon opened 2 years ago

BlueRaccoon commented 2 years ago
test = function(a,b)
  return a.type + " " + b.type
end

When typed into console:

>> test()
"number number"
>> test(1)
"number number"
>> test(1,2)
"number number"
>> test('a')
"string number"

All variables default to 0, but variable.type==0 adds the ability to check if variables are unused or undeclared

I had hoped to use this to check for missing arguments, or write functions with 'optional' arguments (such as a function that can accept a 'Vector2' object or separate 'X,Y' arguments)

pmgl commented 2 years ago

Yes this is something that should be fixed, currently an omitted argument translates to 0 with type "number", should be 0 with type 0 instead, as you say. I will be working on a fix.

Skaruts commented 2 years ago

On a related note, Number.parse() could have a similar behavior, such that you could test result.type == 0 in case the string couldn't be converted to a number.

pmgl commented 1 year ago

Default argument values have been improved in the commit below (default argument is now only used when the arg was actually omitted in the function call ; previously was also activated when passing 0) ; also this commit introduced the arguments list which you can access in the function and use to check for omitted arguments.

Commit: https://github.com/pmgl/microstudio/commit/e0bbe4ed209482c215e7f74d35a461aea771889f

You may now write your test function like this:

test = function(a,b)
  return arguments[0].type + " " + arguments[1].type
end

Or another possibility to check for omitted arguments:

omitted = object end

test = function(a=omitted,b=omitted)
  if b == omitted then print("b was omitted") end
  if a == omitted then print("a was omitted") end
end
Skaruts commented 1 year ago

@pmgl, to be honest, the way I see it,... this all seems to me like just ways of having a nil type in microscript after all... except more laborious, more error-prone and more cluttering than usual, and quite beginner-unfriendly.

From a user perspective, it would be much safer and more comfortable to just be able to ask if a == nil or if not a, and having the details of that being handled by microscript under the hood, in whatever way it must. (And by that I mean nil would actually be a read-only value pre-defined by microscript as a 0 of type 0 or something.)

I'm just saying.

(Having nil defined as an object works fine, but makes nil evaluate to true.)

pmgl commented 1 year ago

Good point ; I am reopening the issue. I am not in favor of introducing a nil value, however I think the testing of the argument types should be made easier, as in if not a.type then print("no value was provided for a") end. That wasn't done because... it is a bit difficult with the current implementation of microScript ; but certainly not impossible.

Skaruts commented 1 year ago

Well,... what I was really trying to say is that I think you already have a nil value in microscript... except it's more complicated to work with than usual.

From my perspective, as a user, all those type 0 checks are no different from any regular nil checks. They serve exactly the same purpose. Except they require more typing and more brain effort. And more learning. The value with type 0 is effectively a nil value. Except it's also less flexible than usual, because you can't assign a value with type 0 to a variable. In other words, you can't make a variable nil. (At least not yet.)

It really seems to me that you're trying to avoid having what you already have.

To be clear, I'm not saying you should replace all that with a nil value. I'm not suggesting features, I'm just letting out my thoughts.

But I am wondering if it wouldn't be possible to make all that work as if there was a nil value, where a user could just simply do ìf not a or if a == nil, and microscript, under the hood, would automatically check for the 0 type, and the user wouldn't have to care about those details.

Skaruts commented 1 year ago

By the way, I just noticed that arguments default to number type when they're not omitted but should still be taken as undefined or nil. An example is when an non-existent object field is passed to the function. (I was trying to do this to simplify a whole bunch of complex validity checks):

omitted = object end

init = function()
  data = object end  

  print("data.foo.type == 0: " + (data.foo.type == 0))   //-- true
  print("\n")

  check_field(data.foo, data.foo)
end

check_field = function(arg0, arg1=omitted)
  print("arguments[0].type == 0: " + (arguments[0].type == 0))  //-- false
  print("arg1 == omitted: " + (arg1 == omitted))                //-- false

  print("\n")

  print("arg0.type: " + arg0.type)                              //-- number
  print("arguments[0].type: " + (arguments[0].type))            //-- number
  print("arg1.type: " + arg1.type)                              //-- number
end