• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

OFFICIAL GML Updates in 2019 (Follow up AMA)

Status
Not open for further replies.

Pfap

Member
GML's library design is definitely not OK, particularly in how new features have almost always been introduced in an intentionally handicapped state.

Some examples:
  • The file sandbox that didn't allow valid external paths until 7 years down the road (i.e. sometime later this year)
  • HTTP functions that didn't support headers until 2 years down the road
  • JSON functions that didn't support nested encoding until repeated nudges from the user community (and even then it's still awkward when the top level is a list)
  • Vector and matrix functions that are awkward to use and still fail to cover many geometric use cases
If YoYo wants GML and GMS 2 to be taken seriously, they should do a 180 on its design policy. The standard library should be built complete with an assumption of skilled use, not infantilized by crippling features on purpose or forcing incomplete integrations just because "rookies could be scared of the full package".
Yea, minimum viable product is a fine line to tread. If that is what they are doing and by your examples it would appear to be so... the virtual keyboard seems to be another candidate.
https://en.wikipedia.org/wiki/Minimum_viable_product

Anyways, I think GameMaker is a good tool really quite impressive with all it has going on and with the ease a lot of features can be implemented. But, I anticipate these new features to have their issues too.
 
E

Ephemeral

Guest
SYNTAX QUESTION:
Will
Code:
array[0, 0, 0, 0, 0] = value;
be equivalent to
Code:
array[0][0][0][0][0] = value;
?
For clarity, multi-dimensional arrays are not a thing? All arrays are nested arrays, regardless of the syntax used to create them? Is that correct?
And the [0] to the right is the one inside the [0] to the left?

TERMINOLOGY QUESTION:
I'm kind of straddling the two camps, "excited for new features" and "feeling alienated". And as someone who can see both sides, I agree it is not that the new features are too advanced. It's that to describe them, SCARY NEW TERMINOLOGY WE'VE NEVER HEARD BEFORE is being bandied about like we're already supposed to know what words like "method", "class", "bound", and "constructor" mean in context, with no explanation what so ever. Personally, the part of the announcement about "binding selfs" still reads like word salad to me; I have no idea what it means.
 
Last edited by a moderator:

Lukan

Gay Wizard Freak
So, I think this was answered in the help desk topic, but I'm not positive...
GML QUESTION:
I have a several years old project that makes heavy use of Scripts, these will still work as expected with no changes?
Also, if these old scripts work as expected, will I still be able to update and make new scripts that use these new features?
 
The only thing left this year I am curious about is Sequences and what we will be able to achieve with them. Would be nice if we could use Sequences to do story cutscenes easier.
 

RanDumSocks

Member
Wow, been waiting for a few years for these features! This is the start of GML becoming a fully functional object-orientated language! Now I almost want to pause development and wait for these features because using the shortcuts I have been doing to get around them will just cause more refactoring when they do come out.
 

Coercive

Member
Any updates on any of the topics brought up here? Any decisions on calling the current objects "actors" or any of the sorts?

I totally can't wait for it to drop so we can fix this redundant change that was made with real(). Wrap it in a try..catch instead of using a JSON object.
 

gnysek

Member
I think that if they made up any decisions, we won't know until beta of GML changes, which may be sometime between end of summer and November ? I hope that there will be beta... this is too big change to just release it in Q4.
 
A

Archer6621

Guest
Amazing news, to me it makes GM quite relevant again for larger projects. Would be nice to add even more QOL features later, e.g. default values for function arguments, or maybe even something akin to Python's keyword arguments.
 

Crescent

Member
GML QUESTION: will lightweight objects have operator overloading?
GML QUESTION: will lightweight objects have inheritance?
I believe they answered these questions in the follow-up on their bugtracking site.

They're not planning to implement operator overloading, and LWOs have inheritance in that they can be defined with another LWO executed inside their body, eg:

Code:
var A = {
    foo: 0,
    bar: 1,
    func: function( ) {
        // stuff
    }
}

var B = {
    A();
}
This ties into the new() operator and constructors, since all LWOs can be executed as functions.
 

Nux

Member
Considering we can't even overload normal functions and/or scripts, I have a hunch that operator overloading is far beyond anything planned right now.

Also, I don't know why, but a lot of people seem to have the idea that lightweight objects are going to be some sort of 'lesser class,' when they are actually just going to be the objects we have right now, except without events. I think a lot of people adopted this idea just because of the way the new keyword was handled: these functions are not classes, but rather constructors for that object. You've seen these before if you've ever encountered array_create or ds_map_create, it's just a different syntax for lightweight objects, i.e. using new vec2(x, y) instead of vec2_create(x, y).

since all LWOs can be executed as functions
Lightweight objects will not be able to be executed as functions; you'll need to use a constructor to construct the instance of that object, these are functions:
Code:
function A() {
    // constructor for 'A' object
    foo = 0;
    bar = 1;
    func = function() {
        // stuff
    }
};

function B() {
    // constructor for 'B' object, inherits 'A'
    A();
};

var a = new A(); // instance of 'A'
var b = new B(); // instance of 'B,' which inherits 'A'
The reason this will work is because the new operator will create a new empty instance and automatically scope it. Imagine it like this:
Code:
// new 'A' instance
var inst = {}; // the empty instance
with (inst) {
    foo = 0;
    bar = 1;
    func = function() {
        // stuff
    }
}
 
Last edited:

Nux

Member
@GMWolf That's a good point, I could agree with that making them lesser classes. But being able to attach a function to an instance makes me think more of a struct containing closures rather than a class containing methods.

I think the use of class just makes people assume a lot more than we're getting.
 

GMWolf

aka fel666
@GMWolf That's a good point, I could agree with that making them lesser classes. But being able to attach a function to an instance makes me think more of a struct containing closures rather than a class containing methods.

I think the use of class just makes people assume a lot more than we're getting.
A struct with closures?
To me that's either a lambda, or a class :)
Its pretty much the model I have when using c++ classes... A bunch of data, and functions that can be applied to said data.
 

Fool

Member
Some observations on implementing programming languages:

If you're going toward the "Js-like" or even total scripting support with JS as the new language, don't. This is a horrible direction, and anyone thats used javascript understands why. If it goes that direction I plan on never purchasing again.

On that note: prototypes have been tried by lua, by javascript, and others. Likewise closures. Prototypes lead to problems with correctness. Likewise closures, or first class scopes, make debugging difficult because it makes flow control more dependent on runtime state, and runtime state tends to be opaque enough.

For languages that did it right, look at Wren, or a less known language, Moonscript. Classes with single inheritance plus mixins for flexibility in behavior.

I second the motion for a spread operator.

ON DATATYPES
As far as classes vs datatypes, I like julias approach to OOP, which is to have a hierarchy of datatypes, and datatype inheritance, rather than objects--while using multidispatch 'methods' instead of interfaces and all other sorts of hacks.

In this way, multidispatch, gains much of the benefits of 1. single inheritance, 2. multiple inheritance, 3. interfaces, 4. abstract base types, 5. composition, and a host of other benefits of OOP with hardly any of the downsides.

The PROBLEM with multidispatch match-on-type is that it causes it to be hard to determine when an object implements an interface or method and so it becomes easy to accidentally call types you didn't intended.

Also, thinking about state over objects is a step in the right direction, but the majority of programs already think in objects, and for the average programmer their natural mode of thinking is objects+action to mutate state. State is harder to reason about because it tends to be so mutable and dependant on run time.

A better solution is to disguise Julias type system in the language of OOP.

Datatypes becomes Classes.

Classes have methods through 'mixins' which are really just non-abstract base methods that use multidispatch, and the mixin method forms a contract that removes the risk of accidental type matching while also giving avenues for 1. self documenting code, 2. performance improvements.

ON AUTOMATIC RETURN

On systems designed to work or interoperate with C, automatic returns on the last statement could cause unexpected problems down the line in execution. Worse, for a beginner, these sorts of bugs are likely invisible, because the intent to return is assumed in languages where the last statement is ALWAYS treated as a return.

Worse still, this sort of design encourages 'pyramid coding recursion hell', where some users will first decompose their program into respective scopes, and then return and compose them..atomically as possible, meaning execution flow becomes distorted, run time state becomes dependant not on obvious plain-at-sight code, but on the run time state itself, and finally it encourages a form of thinking where programmers attempt to write code that 'just works' without thinking about how it *looks* or reads. The problem with opaque-programming is that while it may or may not be effortless, much more time is spent in reading, debugging, understanding, and maintaining code than is spent writing it--which is obviously problematic if we have a bunch of invisible returns everywhere, which requires new and even senior developers reading it down the line to stop each and every time to mentally 'insert' a return statement.
Wherever possible code should be WYSIWYG in terms of the effects per statement. Intent and the effects thereof should always be explicit per statement, not implicit, otherwise effects not intended will eventually slip in, and be missed.
It's hard to catch, and fix the effects of a statements intent where the statement is *implicit* because the effect is a *byproduct* of another statement.

ON DESTRUCTURING

Python does this as do a number of other languages, and it makes serialization/deserialization far easier.

In moonscript, the process of declaring a constructor means leads to arguments being initialized and bound automatically, so doing...

Class Foo
new(@x, @y, @z, @otherargs)


..which saves time. And unless you override those arguments, then x, y, z, and otherargs are implicitly declared and set to the value of the respective arguments that were passed in. Which is absolutely lovely.

PROPERTY ITERATORS

In kotlin theres some example code…

fun main() {
val pair = "Ferrari" to "Katrina" // 3
println(pair)

infix fun String.onto(other: String) = Pair(this, other) // 4
val myPair = "McLaren" onto "Lucas"
println(myPair)

val sophia = Person("Sophia")
val claudia = Person("Claudia")
val ron = Person("Ron")
sophia likes claudia // 5
claudia likes ron
ron likes sophia
ron likes claudia

println(sophia.likedPeople)
}

class Person(val name: String) {
val likedPeople = mutableListOf<Person>()
infix fun likes(other: Person) { likedPeople.add(other) } // 6
}


.. and I was thinking, if I wanted to list all the people Sophia likes, by name, then I'd have to do a foreach. But instead, what if I could do..


println(sophia.likedPeople.nameS)

or

println(sophia.likedPeople.name's)

or

println(sophia.likedPeople.name%s)

the idea being it looks like a string placeholder, but actually is an iterator placeholder for the given property in question.


RIPPED SHAMELESSLY FROM SWIFT

Nil-Coalescing Operator
The nil-coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.
The nil-coalescing operator is shorthand for the code below:
a != nil ? a! : b


ONE SIDED RANGES

One-Sided Ranges
The closed range operator has an alternative form for ranges that continue as far as possible in one direction—for example, a range that includes all the elements of an array from index 2 to the end of the array. In these cases, you can omit the value from one side of the range operator. This kind of range is called a one-sided range because the operator has a value on only one side.

SCOPES AND OTHER RAMBLINGS
In go, you can create and initialize a variable in one line using ":="
which works well but can cause bugs if you miss the colon (which is easy to do)

A better approach is how javascript does it, requiring the
use of 'strict' (or leaving it out) to determine if things should be declared beforehand or not.

var is a better, clearer means of doing declarations on a line anyway. It's less likely to be skipped over or missed, it's simple, and it's familiar

Finally, lexical scoping makes WAY more sense than other types of scoping. It allows you to reason about scope simply by LOOKING at the code itself.

PACKAGES

For an understanding of what not to do, an illustrative example, look no further than the mess that is python package management, or the modular mess that is javascript. Dependency management is and always will be a nightmare. Golang gets this right by including all dependencies in the build itself where possible. Go had the right idea, unlike python. Compile EVERYTHING (where possible) into the executable so the program itself carries around it's own dependencies.

Do that. Developer experience is critical, and in a few years, you'll see people leaving android for apple development in droves because of googles failure to focus on developer experience.

TUPLES

If you allow tuples to bewritten like so..

(x=0; x<=10;x++)

or

(x=0, x<=10, x++)

Then for-loops become idiomatic, as well as method and function signatures.


GENERICS AND THINGS SHAMELESSLY STOLEN FROM A LANGUAGE CALLED KIT

Assuming you implement strict typing, you're probably going to want generics or type inference.

Now, in the case of generics, the problem with them is they almost always devolve into
a bunch of T's all scattered throughout your code, depending on the language, and make
it difficult to discern what the hell is going on.

I know C# used square brackets for generic types
But they ALSO used them for directives (because generics were compile time), which is actually pretty clever, giving you the syntax for generics and directives at the same time.

An extension of all this thinking is 'traits'.

Traits, which can be compared to typeclasses, are interfaces that can be implemented on some type.

Taken from a language called Kit:
"After a trait is implemented for a certain type, values of that type can be converted to "boxed" pointers
which look the same regardless of the type's identity; this enables open polymorphism.


CONCLUSION

These are just a set of ideas worth *exploring*. Not all of them are a good fit, and some of them are taste based, but if we're fielding suggestions for improvements, we have to start somewhere.
 

fireday2

Member
1) Will be default values for function arguments?
2) Will be possibility to transit (send) variable in function by reference and by value?
3) Will be straight access to instance (like in real OOP)? I mean access witout "With" but by point
 
Last edited:
1) Will be default values for function arguments?
2) Will be possibility to transit (send) variable in function by reference and by value?
3) Will be straight access to instance (like in real OOP)? I mean access witout "With" but by point
I think some of these were already answered....
1) defaults can be used using the current system "argument_count" and "argument[x]" those will still work that way.
2) The reference/value thing I think is more a less like it is right now... Arrays/DS_* are the only ones using reference
3) The last one is a "YES" :)
 

GMWolf

aka fel666
2) The reference/value thing I think is more a less like it is right now... Arrays/DS_* are the only ones using reference
dont forget light weight objects. They could be used as a way to wrap variables in references. Probably not super efficient but might be very useful when dealing with callbacks, user data, etc.
 

fireday2

Member
I think some of these were already answered....
1) defaults can be used using the current system "argument_count" and "argument[x]" those will still work that way.
2) The reference/value thing I think is more a less like it is right now... Arrays/DS_* are the only ones using reference
3) The last one is a "YES" :)
1) you didn't understand...
Code:
"argument_count" and "argument[x]"
it's not correct solution
Default values for function arguments mean that you get possibility to skip one or more of argument!
and you don't need to invent a bicycle!
2) help: QIP Shot - Screen 011.png
check it and get prove: QIP Shot - Screen 012.png
 
Last edited:

GMWolf

aka fel666
1) you didn't understand...
Code:
"argument_count" and "argument[x]"
it's not correct solution
Default values for function arguments mean that you get possibility to skip one or more of argument!
and you don't need to invent a bicycle!
2) help: View attachment 25788
check it and get prove: View attachment 25789
Not ideal but:
Code:
var arg0 = defaultArg0;
var arg1 = defaultArg1;
var arg2 = defaultArg2;

switch(argument_count)
{
   case 3: arg2 = argument[2];
   case 2: arg1 = argument[1];
   case 1: arg0 = argument[0];
}
 

GMWolf

aka fel666
Hah. It's not ideal - it doesn't work :)
Does it not?
Does fall through not work that way anymore?
Perhaps the same idea but with a bunch of if statements then.

The bits of the docs you quoted confuse me.
You would not pass arguments in an array, you would call the function as usual.
 

FrostyCat

Member
Hah. It's not ideal - it doesn't work :)
It does work if you noticed the absence of break; statements at the end of each of the cases.

Don't believe me? See this example.
Code:
///@func foo([a, [b, [c]]]);
var arg0 = "Alice";
var arg1 = "Bob";
var arg2 = "Caitlyn";

switch(argument_count)
{
   case 3: arg2 = argument[2];
   case 2: arg1 = argument[1];
   case 1: arg0 = argument[0];
}

return arg0 + " and " + arg1 + " and " + arg2;
Code:
show_message("With no arguments: " + foo()); // Alice and Bob and Caitlyn
show_message("With 1 argument: " + foo("Apples")); // Apples and Bob and Caitlyn
show_message("With 2 arguments: " + foo("Apples", "Oranges")); // Apples and Oranges and Caitlyn
show_message("With 3 arguments: " + foo("Apples", "Oranges", "Pears")); // Apples and Oranges and Pears
2) help:
check it and get prove:
You should have used the [@ ] accessor if you wanted to modify the passed array in-place.
Code:
var m = argument0;
m[@ 1] = 99;
Arrays are still passed by reference, you just need to watch out for copy-on-write. That means knowing when to use the [@ ] accessor.
Does it not?
Does fall through not work that way anymore?
Perhaps the same idea but with a bunch of if statements then.

The bits of the docs you quoted confuse me.
You would not pass arguments in an array, you would call the function as usual.
The way you showed does work, it's probably because he misread your solution as this (which genuinely doesn't work):
Code:
var arg0 = "defaultArg0";
var arg1 = "defaultArg1";
var arg2 = "defaultArg2";

switch(argument_count)
{
   case 3: arg2 = argument[2]; break;
   case 2: arg1 = argument[1]; break;
   case 1: arg0 = argument[0]; break;
}
Given your level of experience, you should have stood your ground much firmer than you just did.
 
Last edited:

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
1) you didn't understand...
Code:
"argument_count" and "argument[x]"
it's not correct solution
Default values for function arguments mean that you get possibility to skip one or more of argument!
and you don't need to invent a bicycle!
2) help: View attachment 25788
check it and get prove: View attachment 25789
See this for how optional argument retrieval is structured and GMEdit-specific shorthand syntax if you may
https://github.com/GameMakerDiscord/GMEdit/wiki/Using-#args-magic
 

fireday2

Member
@GMWolf You are right. I did't check it. Because I don't need to execute the code to understand it. But i understood wrong by inattention (in a hurry)
Anyway - your example is a bicycle. With some restrictions (e.g. you can't skip argument in the middle)
I am very experienced in inventing bicycles. In that way i don't need examples of the invention the bicycles. I can do it by my self
And, don't forget that the invention of bicycles spend your expensive time. Besides, you can't see the default values when call the function (unless, of course, you're using another bike)
p.s. i made this question because there will be a new update with implementing functions. And it will be great to see the default values in that case

Speaking about
Code:
[@ ]
I don't know it, thx. (didn't see it in the help)
 
Last edited:
Yesterday a question popped into mind... how will JSDoc work with these new additions? I guess it won't work for anonymous functions but for global ones we will still have JSDoc, right?
my question is based on the following.. right now if I write

Code:
/// @func print_string(str)
/// @param {string} str

// Cache arguments
show_debug_message(argument0);
or

Code:
// Cache arguments
show_debug_message(argument0);

/// @func print_string(str)
/// @param {string} str
it's exactly the same thing. The IDE links the documentation to the script no matter the placement of the documentation. When we have many functions inside the same script file will the IDE be able to link the JSDocs to the function it is intended to? (supposedly the one below it?)
 
Last edited:

Yal

🐧 *penguin noises*
GMC Elder
For clarity, multi-dimensional arrays are not a thing? All arrays are nested arrays, regardless of the syntax used to create them?
Could be worth pointing out that this is exactly how multi-dimensional arrays work in C (and C++, if I recall correctly - I've been stuck doing C stuff for the last year, though). So there's a pretty big precedent.


Also, there's not all that much time left of the 2019-Q4... can we expected an early Christmas present with lots of syntactic sugar? :)
 
Could be worth pointing out that this is exactly how multi-dimensional arrays work in C (and C++, if I recall correctly - I've been stuck doing C stuff for the last year, though). So there's a pretty big precedent.
It's also how 2D arrays are handled internally in the current version of GMS2.
Code:
var i;
// 2D array syntax
i[0, 0] = 0;
i[0, 1] = 1;
i[1, 0] = 2;
i[1, 1] = 3;
show_debug_message(i);
Outputs the following:
Code:
{ { 0,1 }, { 2,3 },  }
 

GMWolf

aka fel666
Memory is always layed out linearly in a machine.
So if you want stuff to be stored contiguously, arrays of arrays are the only way to do this.

[Edit] or a 1D array with special indexing but when we look at stack allocated arrays that's the same thing.

However, if you allocate on the heap, you can have an array of pointer to arrays.
That's what arrays of arrays would be in game maker.
Which is why I recommend 1d array with special indexing. It's gonna perform somewhat better.
 
Last edited:

SoVes

Member
I'm not sure if anyone asked this already, but can functions then be passed into a script. So I can make handy stuff to speed up workflow. Like forEach in js
Code:
forEach( list, function( item, i){

});
 

Coded Games

Member
I'm not sure if anyone asked this already, but can functions then be passed into a script. So I can make handy stuff to speed up workflow. Like forEach in js
Code:
forEach( list, function( item, i){

});
I assume you would as you can already do this with scripts
 
I'm not sure if anyone asked this already, but can functions then be passed into a script. So I can make handy stuff to speed up workflow. Like forEach in js
Code:
forEach( list, function( item, i){

});
Yes that will be possible the function is created and passed as an anonymous function.
Or so they claim to be possible xD ;)
 

GMWolf

aka fel666
Yes that will be possible the function is created and passed as an anonymous function.
Or so they claim to be possible xD ;)
Are their any examples like that?
It's possible the function will first have to be assigned to a variable.
GML has always been a little weird like that, seems like expressions were never a first class citizen of the language (hence we don't yet have chained accessors, etc)
 

Yal

🐧 *penguin noises*
GMC Elder
I do this exact thing in my SoulsVania engine (to use different interpolation scripts in the skeleton animation system - limbs are angle-interpolated and offsets like "feet distance from ground" are linear-interpolated)... I just used script_execute() for it and made a script called vanillalerp that was a wrapper for lerp. Why ask for something that's currently not possible when the workaround is so simple? You can put anything in a script and there's script_execute(), you don't need anything else. Wrapping things like this is actually used quite a lot in business code since it means you're protected against future interface changes that might break anything relying on function argument order/count, you only need to update your wrapper instead of all code using it in case the builtin function ever changes.
 

Nux

Member
I don't think anybody is asking to be able to call gamemaker functions anonymously, e.g.
Code:
var f = lerp;
f(1, 2, 0.5);

The question was: do we have to do
Code:
var f = function(x) {
    show_message(x);
};
do_something(f);
or can i just do
Code:
do_something(function(x) {
    show_message(x);
});
which is very common in any language with anonymous functions.


p.s. I'm certain we will be able to do it the second way, considering the function is it's own expression in assignments. Now, whether we will be able to do
Code:
function(x) {
    show_message(x);
}("hello world");
is a different story.
 

11clock

Member
For optional parameters, the argument count thing is painful.

I would implement it how C# does it:

public void DoSomething(int optionalParameter = 0)
{
stuff
}

This means that if you don’t pass in optionalParameter, it will default to 0. C# has a lot of neat convenient features like this. Definitely a language worth looking at for inspiration.
 

Yal

🐧 *penguin noises*
GMC Elder
I was stuck a good chunk today solving a bug that turned out to be the return value defaulting to 0 in a script it turned out I hadn't actually written any code in yet (and since it took no arguments, GM didn't complain). "convenience" features like this are just silent misbehavior bugs waiting to happen, it's better if code fails fast.
 

Alice

Toolmaker of Bucuresti
Forum Staff
Moderator
I don't think anyone in their right mind would ask for a return value defaulting to 0, neither I would consider a language-defined default return a convenience feature. It seems more like a consequence of language design and implementation. If a language - like GML or JavaScript - has no return type declarations, there's no way to find out that a function is actually meant to return void, and thus some default is assumed (in JavaScript it's undefined, which seems more intuitive than 0; I guess the 0 is remnant of times when undefined wasn't a thing).

The convenience feature 11clock describes is a user-defined default argument, which is a completely different category than language-defined default return. It's opt-in and user has control over which arguments have defaults and what are the default values. So for example you could have function like this:
Code:
Button_create = function(x, y, script, text, color = c_white) {
    // insert code here
}
It would be roughly equivalent to the workaround we use now:
Code:
/// Button_create(x,y,script,text,color)
var x = argument[0];
var y = argument[1];
var script = argument[2];
var text = argument[3];
var color = argument_count > 4 ? argument[4] : c_white;
Not saying it's a feature YYG would need to implement ASAP, but it doesn't really change behaviour/compilation of existing code (variables without defaults are still treated as required) and would prove handy to those who feel confident about using defaults. If you feel user-defined defaults are too error-prone, you can just not use them (which can't be said about default 0 return value).
 
I don't think anybody is asking to be able to call gamemaker functions anonymously, e.g.
Code:
var f = lerp;
f(1, 2, 0.5);

The question was: do we have to do
Code:
var f = function(x) {
    show_message(x);
};
do_something(f);
or can i just do
Code:
do_something(function(x) {
    show_message(x);
});
which is very common in any language with anonymous functions.


p.s. I'm certain we will be able to do it the second way, considering the function is it's own expression in assignments. Now, whether we will be able to do
Code:
function(x) {
    show_message(x);
}("hello world");
is a different story.

Yes it is but if you look at the official post regarding this updates you can see that using anonymous functions will be possible.
 

Attachments

gnysek

Member
Code:
Button_create = function(x, y, script, text, color = c_white) {
   // insert code here
}
It would be roughly equivalent to the workaround we use now:
Code:
/// Button_create(x,y,script,text,color)
var x = argument[0];
var y = argument[1];
var script = argument[2];
var text = argument[3];
var color = argument_count > 4 ? argument[4] : c_white;
In GMS 2.3 it will probably be:
Code:
var button_create = function (x, y, script, text) {
    var color = argument_count > 4 ? argument[4] : c_white;
    // x, y, script, text - are already assigned to variables, and also to argument[0...3], so we don't need to assign them to "var <name>" anymore
}
Code:
// usage:
button_create(a, b, scr, "test");
button_create(a, b, scr, "test", c_red); // compiler knows, that optionally there can be 5th argument, cause you used argument[4]
button_create(a, b, scr, "test", c_yellow, 0); // error - compiler will stop, as no argument[5] is used in code, so 6th parameter cannot be used
So then passing "optional" arguments will be still possible, and all arguments (required or not) will be always in good old argument[n]. This isn't a "default value" but still it's shorter by 4 lines. All scripts might be converted to this as there will be no scripts in 2.3 anymore (but functions), so seems that argument0...argument15 will not be a built-in reserved variable anymore (but I feel that converting scripts to functions will make argument names to still be argumentX, so functions body isn't then affected at all, just wrapped around with new expression - so nothing will break).

So - if they don't allow "default" value to argument names in function definition, in GMS 2.3 it will be still much shorter to write same function.

Can't wait to test 2.3 to see if my assumptions are true :D
 
Last edited:

drandula

Member
If object "obj_1" has function "seek()", could one execute it from "obj_2" like "obj_1.seek()"? This question is about the need of executingnit as "with(obj_1) {seek()} ?
It would be nice if you could do that.

Secondary question If you can do that. If function accepts arguments, could from obj_2 say "obj_1.seek(x,y)" which would reference obj_2 x/y coordinates, but make obj_1 to execute function?

Edit. Got answer from Discord for both as yes, arguing that function can return value. So obj_2 could also use "var value = obj_1.seek(x,y);"
 
Last edited:
Status
Not open for further replies.
Top