• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Discussion The duck operator

GMWolf

aka fel666
With a new version of GML around the corner with support of functions, methods, etc, I think it would be a great time to actually make use of GM's dynamic typing and turn it into a duck typing powerhouse!

wlt8alg.png Duck typing suggestion

The duck type operator would allow use to easily query if an object/lwo has a given variable.
This would have the advantage of being easier to type, read, and offer early hashing performance improvements over current string based solutions.
I suggest the use of '?' as an operator.
Code:
a?foo // evaluates to true if 'a' contains variable 'foo'

if ( a?foo ) {
    var n = a.foo;
}
The double duck operator ?? Would allow us to test and evaluate all in one swoop using ternary like syntax
Code:
a??foo : b; //evaluates to a.foo if a contains foo. B otherwise.

var b = a??bar() : undefined; //evaluates a.bar if a has bar. Undefined otherwise.

//As a shortcut you could leave out the ' : undefined' part when you don't care about the return result. Returns undefined by default

a??bar();

This will allow us to write some really neat duck typed code.
For instance, on collision with a trigger object:
Code:
other??onCollision();
If the object we collided with has an onCollision method, we can run it. Otherwise it doesn't do anything.

Another example is to use the duck operator to find out the type of a lwo:
Code:
if (o?sprite && o?position)
{
  //This is a thing we can render!
}
This way we don't need to rely on messy inheritance, but can directly test if an LWO can be used in some way simply by looking at which variables it has defined.
If it has a sprite and a position, we can draw it.
If it has health, we can damage it.
Etc.

The introduction of these new operators will not introduce any fundamentally new functionality we could not do without, but it would help shape the way we write GML.
And I believe that healthy use of duck typing is the right way to go for GM.

What are your thoughts? Have a missed something? Do you have anything you would like to add to this suggestion?
Should YYG implement this for the next GML update?
 
Last edited:

Tthecreator

Your Creator!
This reminds me of Kotlin's safe call operator: https://kotlinlang.org/docs/reference/null-safety.html#safe-calls
The operator is actually quite useful and widely used. I've worked with ti and I like it so I approve of this suggestion.
The other !! (not null assertion) operator (which checks if a value is not null and throws an error if is), wouldn't be that much needed as the safe call operator since most gm functions already check this, and game maker throws errors itself. The upside to implementing a not null assertion operator is to be able to find false value higher up in the call stack, not until we get to a gm function. This makes debugging easier.
 

curato

Member
I am not sure Yoyo is going to allow any kind of type checking that doesn't comply with community standards :p. All joking aside, I am all for stronger typing. Also, I would like to be able to strongly type all my variables instead of leaving them as variants.
 

GMWolf

aka fel666
I think ActionScript-style `<field name> in <object>` would be more appropriate for GML and slightly more flexible. I commonly implement a variation of it in scripting systems that I write for games
View attachment 26116
Yeah that may be more appropriate as it does mean less chance of it being ambiguity with the ternary operator.

Though what about the ?? Operator. I'm quite fond of reducing the number one line if statement bodies...
 
Last edited:

Juju

Member
variable_instance_exists() can be used for traditional objects; gone are the days when that function is disgustingly slow. Given that the implementation of LWOs is strongly related to traditional objects, we live in hope that an equivalent will exist for LWOs too.
 

GMWolf

aka fel666
variable_instance_exists()
Yeah but it's blaaaa to write!
Also because it take a dynamic string the value variable name be hashed or otherwise processed at compile time. (Which I hope GM normally does for variable names since it would be a huge speed up)
 

Cpaz

Member
Yeah but it's blaaaa to write!
Also because it take a dynamic string the value variable name be hashed or otherwise processed at compile time. (Which I hope GM normally does for variable names since it would be a huge speed up)
This is basically why the ternary operator exists, and I'm all for it.
 

GMWolf

aka fel666
Perhaps a simpler, but just as effective suggestion would to just have the following:

Code:
var a = foo?bar; //evaluates to foo.bar if too contains bar, undefined otherwise
This still allows is to easily test if instances have variables
Code:
if (!is_undefined(obj?bill))
{
   //Could be a platypus
}
However we can no longer distinguish between not having a variable and having a variable be undefined.
Though I believe that shouldn't be a problem in a codebase using duck typing. !as having an undefined member and not having a member is equivalent)
 

Yal

🐧 *penguin noises*
GMC Elder
However we can no longer distinguish between not having a variable and having a variable be undefined.
A major goal with my parenting structures (in code) is to achieve this, so I don't see why it'd be a problem :p

(It's better to have a known 'fail' value set ASAP so you only need to check one "has invalid value" case instead of two everywhere, and if you ever need to reinitialize (or de-initialize) you can set the variable to that value, while there's no way to remove a variable's existence once you get it once)
 
Top