Game Maker Suggestions
#981
Posted 24 January 2012 - 03:25 PM
Now I know that is a bit woolly but it is buried within the language definition and due to the nature of GML it is problematic - currently the parser enforces that the && || ^^ MUST have boolean arguments (the left and right of the operator) this stops the type propagation which is what you are desiring - in the long term for type safety I think this is a good idea (though I would like to hear the arguments for and against).
Russell
#982
Posted 24 January 2012 - 03:51 PM
I do wonder how possible it would be to enforce == without confusing people though (or if it would even be beneficial).
#983
Posted 24 January 2012 - 04:08 PM
Trust me when I say that the Delphi parser it is complicated to do the propagation - for HTML5 and Studio it is a bit easier and I will investigate how to propagate the type correctly from left and right arguments of || && and ^^ - the problem is when you have 2 types that are not the same (say <int> && <boolean>) then the propagation rules have to make sense and be easily understood - some of C's more basic problems originally stemmed from arbitrary and ill understood edge case rules for things like this...
I will need to sit down and think about them when finalising GM9's GML
Russell
#984
Posted 24 January 2012 - 05:57 PM
I don't understand that second one at all...why would some_call() necessarily be stored in foo? With an && operator, both must be true to evaluate to true, so why is some_call() stored instead of some_check?Can I make a request for short-circuiting behavior? Scripting languages often allow logical operators to evaluate not to true/false, but to whichever object decided their truth/falsehood, which is then treated equivalently by e.g. if statements. This allows for things like default values with ||, or similar checks to the "b != 0" example in more contexts.
For example, to give argument3 a default value, since 0 (or null, that would be nicer) is treated as false, you could sayarg3 = argument3 || my_defaultYou could also do something like this, using &&, saving the result of some_call in foo:foo = some_check && some_call()This even allows for implementing ?: yourself, although it's not very readable:a = cond && yes || no
-IMP
#985
Posted 24 January 2012 - 11:26 PM
@rkway: I was thinking it would be pretty simple for && and || just to evaluate to the operand that decided their result, the way e.g. Lua, Python, JavaScript, Ruby, Lisp... do. There's no need to bring in C-like type coercion, and since GML is dynamically typed the result doesn't need to be coerced either.
Edited by Rusky, 24 January 2012 - 11:29 PM.
#986
Posted 25 January 2012 - 12:06 PM
So.. the TYPE of returned value may differ depending on the first operand?If some_check evaluates to false, foo gets some_check. If some_check evaluates to true, foo gets some_call(). It doesn't matter what some_call() evaluates to at that point because if it evaluates to true, it will evaluate to true again; if it evaluates to false, it will evaluate to false again.
@rkway: I was thinking it would be pretty simple for && and || just to evaluate to the operand that decided their result, the way e.g. Lua, Python, JavaScript, Ruby, Lisp... do. There's no need to bring in C-like type coercion, and since GML is dynamically typed the result doesn't need to be coerced either.
#987
Posted 25 January 2012 - 02:35 PM
#988
Posted 25 January 2012 - 05:01 PM
I've never been a fan of dynamic typing. Weak typing is nice, however when a variable changes it's type of their life I frown upon that heavily. Just a trivial example of a "bug":I don't see how that's a problem, especially with dynamic typing. The value will behave exactly the same when used in a boolean context with or without this behavior, and instead of throwing out information it just keeps it around to enable some useful idioms.
var i, s; i = 10; s = random(1000) < 1 && "hello world"; s += i;That's a 1 in 1000 chance the program will crash.
#989
Posted 25 January 2012 - 06:56 PM
Well then, you make sure your code is better written than that, don't you?Just a trivial example of a "bug":
I don't see how that's a problem, especially with dynamic typing. The value will behave exactly the same when used in a boolean context with or without this behavior, and instead of throwing out information it just keeps it around to enable some useful idioms.
#990
Posted 25 January 2012 - 11:37 PM
You can crash a program the same way with or without this feature, and this feature can exist with or without dynamic typing. It's a completely separate issue.I've never been a fan of dynamic typing. Weak typing is nice, however when a variable changes it's type of their life I frown upon that heavily. Just a trivial example of a "bug":
var i, s; i = 10; s = random(1000) < 1 && "hello world"; s += i;That's a 1 in 1000 chance the program will crash.
#991
Posted 26 January 2012 - 12:04 AM
Well the problem is how the error may be reported.You can crash a program the same way with or without this feature, and this feature can exist with or without dynamic typing. It's a completely separate issue.I've never been a fan of dynamic typing. Weak typing is nice, however when a variable changes it's type of their life I frown upon that heavily. Just a trivial example of a "bug":
var i, s; i = 10; s = random(1000) < 1 && "hello world"; s += i;That's a 1 in 1000 chance the program will crash.
With such a feature, the crash occurs at the "s += i" - line 4. Yet the actual bug is in the s = random(1000) < 1 && "hello world"; - line 3. Here the lines are directly below each other, but with these features you'll always have subtle cases where things may crash, making it much more difficult to track the bug down to the correct line.
When to operands of the && operator are forced to be "convertable to boolean", the above example would crash at line 3.
Well sure it's not deal breaking, but I'm not really seeing any advantage of such syntax? Especially if a ternary operator is added I don't see any use to this - well only thing would be if the left side operator is an expression with a side effect...
#992
Posted 26 January 2012 - 12:59 AM
var i, s; if (random(1000) < 1) s = true else s = "hello world" s += iThere are plenty of much more realistic situations where the cause of the bug is not on the reported line; just because you can write a sample with that problem that just happens to use a feature doesn't mean the feature is in any way to blame. In fact, you can't even really blame it fully on dynamic typing, as the same thing can happen in statically typed languages.
On the other hand, I have already given several examples where value propagation is more concise:
foo = argument0 || default_value // default values when an argument is null bar = do_something() || handle_error() // also when some operation fails if (baz != 0 && some_condition(qux / baz)) // checking before performing an operation that can errorThere are more that may or may not apply depending on other changes, such as checking if an array index exists before using it, etc.
Edited by Rusky, 26 January 2012 - 01:01 AM.
#993
Posted 26 January 2012 - 06:48 AM
It would also be nice if ds_lists were implemented as doubly linked lists internally instead of normal arrays (i.e. vectors). Index-based functionality would still be supported, for the new programmers, but it could also support iterators which are much more efficient.
I created my own version of doubly-linked lists not too long ago, using constant-sized ds_lists to represent list nodes. They were much more efficient than ds_lists in everything except adding to the end, which I eventually realized is because if GM's arrays are vectors, they double in size whenever they reach the end, whereas my methods require new allocation for each new node. Still, everything else was orders better, so...I think it should be implemented "correctly" (i.e. in a more standard, generally more efficient way).
Many people use lists as pointers to arrays (random access). Perhaps it would be better to change the implementation, but to add a set of ds_vector functions (or a class, if classes are added).
Some of the current data structures should have their current implementation overhauled. For example, I have written GML that replicates the ENTIRE set of ds_priority functions, and runs 10x faster on average than the built-in functions (~31000 elements). The DLL averages 120x faster on the same data set (includes the time required to determine whether input/output is string or real) (Mine: log n) (Built-in: n). If used properly, the DLL is faster than built-in for 32 or more elements.
GM seems to use the most naive method for managing priority queues (An unordered list, with finding/deleting max/min handled using a picking algorithm)
A better solution would be to use a min heap (or max heap, if people check the max more often than the min). The finding of the other one (min or max) can still be done using picking algorithms, but problems arise when changing or deleting random elements.
Best solution: Min-max heap. This is what I did. O(1) for finding min/max, O(log n) for adding/deleting. Care must be taken when editing/deleting a random element, but if its position is known, it can be done in O(log n)
#994
Posted 29 January 2012 - 06:39 AM
#995
Posted 29 January 2012 - 07:02 AM
Edited by Big J, 29 January 2012 - 07:03 AM.
#996
Posted 05 February 2012 - 04:09 PM
#997
Posted 05 February 2012 - 04:37 PM
Edited by Rusky, 05 February 2012 - 04:37 PM.
#998
Posted 08 February 2012 - 10:58 PM
Sorry, but who exactly were you replying to?That's already planned, and available in GM:HTML5.
#999
Posted 12 February 2012 - 08:13 AM
For example, say I have an Object1 instance that has a script which will return true/false depending upon some condition which must be checked real-time. Right now, in order to do a conditional based upon that value from outside the scope of Object1, I have to take a rather verbose approach:
var temp;
with(Object1) temp = script_name();
if(temp){....}
The need for useless intermediate values and verbose code can be done away with by combining the if & with statements into one:
if_with(Object1,script_name()) {...}
of course, if_with is not exhaustive and could be improved with a return_with statement. For instance, say I needed to do a conditional using values from scripts using variables from different instances? I could make a bunch of temporary variables to store the values or I could have the much nicer return_with approach:
if(local_script() && return_with(instance1,another_script())) {...}
Still better yet, I would love to see a "->" operator, like in c++, which would essentially serve as a quick with statement. It would set the scope to the variable indicated on the left for the variable/script indicated on the right. Like so:
somevariable = someinstance->evaluate_script(); someinstance->do_function();
This would be an incredible improvement to the language for those of us who know how to program outside of GML.
#1000
Posted 12 February 2012 - 06:08 PM
Alternatively, just add an additional argument to any scripts that require taking in local variables...This would be an incredible improvement to the language for those of us who know how to program outside of GML.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users



This topic is locked






