-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function Syntax RFC #263
Comments
TODO: make it compatible with #45 |
What about calling function reference stored in variable (like passing callback function via parameter, or functions stored in array)? |
What about functions that can take/return multiple types of variables? |
How condition result will be handled? Your earlier idea with |
union types are out of scope for this RFC. There should be a separate function for each combination of types |
any idea for complete syntax? |
Though case. For sure condition result can not be on the right side of the return keyword. It leads to idea having it on the left: |
this syntax is complicated and confusing. I think the last case should be handled outside of the function, or the boolean value should be returned as a regular value. A function should have the condition result set to true at the start of the function. It would allow to use empty functions or functions without ifs in conditions.
If the function wants to explicitly change the condition result to false, we can use Then you are allowed to use regular tricks with conditional opcodes to alter the condition result:
so to summarize: If you return any value, it is always a success. Condition result is true (unless altered by the last conditional opcode) We can use
|
Um I really don't like fact that Inexplicit carrying on condition state of last executed opcode also seems not right. Instead of easy functionality we get hidden convoluted logic without clear rules enforcement. Function returns true by default, but seemingly not related change will make behave it differently. Maybe instead of return we should only allow return_true and return_false as function ending keywords? |
If function returns one bool param, it suits the proposed logic.
|
Currently there is no such thing as bool type. Will it be reserved for condition result only? It might be good idea do declare if function sets condition state or else it will be true by default. Then condition result is just one of the args in return call statement. `func test() : (int, string, float) test() // allowed, discard return if test() // allowed, check first return <> 0 if (0@, 1@, 2@) = test() // allowed, first as condition result if (0@, 1@) = test() // error, not all return values used if (_, 0@, _) = test() // allowed, first returned value as condition (as usual). Store just second argument` Idea to consider is to allow '_' in return calls like I see one problem with |
Not sure we need to overengineer it. Many functions are just calculations and they don't need to work with condition at all. As you mentioned, there is no bool type which is correct. It means you can't store a result of a bool function into a variable. It only works as a condition.
|
Then it simply just returns single argument (for example float). If used in condition statement then in typical fashion return[0] is tested for <> 0. Introducing Boolean type will make everyone question why it is not possible to use it for var declarations or as input argument type. Some corner cases: Over engineering is when you have multiple rules to describe simple thing. I propose single rule: condition result of function call is |
My idea was to use |
how do you express this with opcodes? |
What do you mean with opcodes?
|
Mentioned Maybe it should be keyword 'null' instead. Now it makes more sense to call function with null as some params. |
Rewrite this example using opcodes only please. As if you just decompiled the script. |
|
Imagine there is a script:
Today, it shows the message "No", because the condition result was modified by a conditional opcode 059A (which is expected and fits the language). 0AB2 does not modify the result. With your proposal the behavior changes and it will now display "Yes". Can you address these two concerns in your script (both high-level and low-level)? |
|
It was fixed for a scenario with multiple conditions. A single condition (see my example) has been used for years. |
Yep, legacy behaviour of 0AB2 is untouchable then. |
UPDATE 11/13/2023Make two separate opcodes to allow for true/false return without arguments. CLEO_RETURN_FALSE - 0 params, exits current function, ignores all caller's variables, sets the cond result to false retf // CLEO_RETURN_FALSE My proposal is to add a new cleo_return. We can certainly use
Examples
Before writing the result, scmFunc->Return(thread);
-if (nRetParams) SetScriptParams(thread, nRetParams);
+if (nRetParams && (*thread->GetBytePointer())) SetScriptParams(thread, nRetParams); it solves the case when
Then we can use the following syntax with this proposal:
|
My idea is, that a function either returns something and the condition result is true, or returns nothing and the condition result is false. There is no case, when you need to return something and set the condition to false. |
Sounds reasonable. |
You are trying to bend the language to be corresponding to other languages, but in only introduces ambiguity and makes understanding concept of Placing
Functions like
appears to be interchangeable, but are totally different at call site. I think We had series of talks about that topic already and finally settled on having mandatory first arg as return result. As you said in most functions condition result is not important so it is bit inconvenient to have to type it every time. Maybe better solution would be replace |
you can only use
|
Ok, then I don't like the idea of automatic condition result deduction:
C/Java languages also do not allow you to exit from function expecting return argument with naked Maybe mixing bool with args should be a thing. If it is important to you that function sets condition result then make it obligatory like:
so then there is no way you can forget it when calling return (this again creates discrepancy between declaration/call args format) |
no, see above
not possible, see above
any function already may modify condition result, as 2003 (function's end) sets the flag to
for
correct. but this is also true with any other types, as today compiler does not validate them.
it's already counter-intuitive. function returning int should return 0 or 1.
no, see above
this is possible, but you can also return wrong values, or mix up the order (y x z), etc.
with single (naked) return you just need to learn once, that it is always "exit with nothing" and it's never a success. |
Keyword in that whole list was |
You keep thinking of bool as another form of integer value, but in fact nothing in runtime supports it. bool here is an indicator of success/failure and only have meaning within IF..THEN check. You can't store result of conditional opcode anywhere except for explicit
but then result is an think of |
I know the concept of condition result very well. Problem is that anyone who has any programming experience will think about it exactly like that. You keep explaining the bool is meant to represent condition result, then why not name it "condition result". Problem with it is there is no straight analogy to other languages, so it would be better to not introduce confusion by calling it the same way as base type available in most languages. |
:bool type was a getaway from no-type functions:
I can't think of a better name other than :bool that is not completely out of the place. Ideas? |
It seems like |
back to the roots
|
|
How about naked return then? |
I don't see any issue with naked return (or rather any return) setting condition result. Even now, if you "forget" to return values from a function you hit 2003 that sets the result to false and skips the variables. Also there are many opcodes that set condition flag without you knowing it. e.g. from SA SCM
Condition result should only be considered in context of current IF statement. Then you should carefully review what opcodes and functions you put in there. I also don't see any problem with naked return not modifying output variables. I think returning default or garbage values are equally bad. When you call a function that may fail, you always have to inspect the returned value:
even if any function must return some value, garbage or not, calling code still have to check the result. In this case, why bother returning garbage zeros or -1, if you discard those values anyway. What I think a real flaw in the current implementation is that there is no indication of a fact the function MAY fail. Looking at the function declaration:
how do you know, whether it always returns a valid handle, or may return nothing (or 0, or -1)? Without looking at the function's code you wouldn't know. In this sense, a naked return and return -1 are equally bad. |
to address the last issue, in addition to
an ☝️ assumes
|
Woah returning only few of the args? I do not think I ever had need for something like that. This is getting over complicated now. |
Yes, all or nothing. I crossed out the other part, that suggested that only some params can be returned. |
so, |
logical doesn't return any values, only sets the condition flag. returning a value AND setting result to false is not supported with |
I thought it will be able to mix logical and args. Ok then. |
Proposal updated |
How about allowing using logical and return values in function declaration, like: Logical keyword would be allowed only as first argument (but technically it wouldn't be problem to make it any). |
future extension: variable arguments
|
Nice, but how to know provided args count inside the function? |
up to you. |
Hm information like this can possibly be accessed in future via VirtualVariables feature. |
future extension: any type
|
RFC Update:
|
So for logical functions without return the last set condition result will be passed through? Seems like feature. |
released in 4.0.0 |
Goal
Considerations for function syntax
Pascal-style:
#### C-style:* consistent with inline var declarationPascal-style is more consistent with the rest of the language.
Rules
Function must be declared before first usageFunction are available anywhere within current scope. Functions defined inside other functions are available anywhere in that function bodyFunction body starts with the "function" keyword followed by the function signature.
Function name
prefixed with @is a valid labelThe signature includes input parameters (if any) and their types, comma-separated.
Input parameters, when present, must be enclosed in "()". For zero-input functions "()" is optional
Input parameters are followed by a return type if the function returns anything
Multiple return types are comma-separated,
and parenthesized.Return type(s) can be prefixed with the
optional
keyword. Function with an optional result may return nothing.Function body ends with the
end
keyword.return
keyword immediately exits the function and returns control to the calling code. See Return Semanticsreturn
to bail out immediately while returning nothinglogical
return type. This result can only be validated in IF..THEN and can not be stored in a variable. Logical function returns true or false.Function can return one or more values using the following syntax:return <condition flag> <value1> <value2> ....
return
keyword in functions should not be confused withreturn
keyword in gosubs. Function's return is always followed by some values, ortrue
, orfalse
using CLEO5's CLEO_RETURN_WITHend
keywords serves as an implicitreturn
with the default values matching the function signatureusing RETURN (CLEO5 is required)using CLEO_RETURNreturn false
is a special case that can be used in any function. It sets the condition result to false and exits the function ignoring all output variablesreturn true
is a special case that can be used in function with no return type. It sets the condition result to true.Examples
Declaration
CLEO_RETURN_FAIL
RETURN
CLEO_RETURN 0
if there no an explicitcleo_return_*
on the preceding lineExamples of logical/optional return types
Calling functions
Grammar
The text was updated successfully, but these errors were encountered: