ItsDeltin / Overwatch-Script-To-Workshop

Converts scripts to Overwatch workshops.
208 stars 26 forks source link

Better syntax for inline lambdas #332

Open ItsDeltin opened 3 years ago

ItsDeltin commented 3 years ago

My proposed syntax for inline lambdas would be: const (parameterTypes) => returnType Ex:

(const Number => String)           action1 = num   => "The value equals " + num;
(const () => void)                 action2 = ()    => {};
(const (Number, Number) => Number) action3 = (a,b) => a^b;

An issue that may arise from this is when the lambda is usage in reevaluation. Currently OSTW does not have a way to determine if an expression will generate actions in the semantics stage.

void MakeEffect((const Vector => Vector) evaluate)
{
    CreateEffect(Position: evaluate(host.Position));
}

rule: "Make Effects"
{
    // OK: Returned expression in lambda is inlined.
    MakeEffect(pos => pos + up * 3);

    // Not OK: Only 'pos + up * rnd' is reevaluated, creating a new random number is ignored.
    MakeEffect(pos => {
        Number rnd = RandomReal(0, 3);
        return pos + up * rnd;
    });
}

If a way to check if actions will be generated is implemented, then adding an alternative syntax may be a good idea:

// Portable, assignable to variables.
(Number => String) action1;
// Inline constant
(const Number => String) action2;
// Inline constant macro
(macro Number => String) action3;
Protowalker commented 3 years ago

It should be simple enough to give each node an associated property WillGenerateActions and then recursively check all of its child nodes; I can look into this later and see if it's viable

ItsDeltin commented 3 years ago

The const () => void syntax was added in v2.0.