untoldwind / KontrolSystem2

Autopilot scripting system for KSP2
Other
54 stars 14 forks source link

Compiler doesn't seem to like user defined types in parameter lists #91

Closed plonk-75 closed 5 months ago

plonk-75 commented 1 year ago

KS2 0.4.1 / KSP 0.1.2.0.22258

Maybe I do not fully understand the correct use of type but I get some interesting error messages. A funny one is ERROR: InvalidType - Expected parameter dt of lambda to have type myScalarType, found myScalarType.

use { Vessel } from ksp::vessel

pub type FnTypeA = fn() -> float
pub type FnTypeB = fn(float) -> float

pub sync fn getFnTypeA(vessel: Vessel, a: float, b: float) -> FnTypeA = {   // type definition works as return type
    fn() -> {
        a * b
    }
}

pub sync fn getFnTypeB(vessel: Vessel) -> FnTypeB = {  // type definition works as return type
    fn(dt: float) -> { 
        1.2345
    }
}

// compiles & works without use of types FnTypeA and FnTypeB in parameter list, 
// although called from main_flight using custom types
pub fn fn1(v: Vessel, a: float, typeAFn: fn() -> float, typeBFn: fn(float) -> float) -> bool = {
    const aRes = typeAFn()
    const bRes = typeBFn(a)
    false
}

// semantically identical to fn1 but compiler doesn't seem to like use of type definitions in parameter lists
pub fn fn2(v: Vessel, a: float, typeAFn: FnTypeA, typeBFn: FnTypeB) -> bool = { 
    const aRes = typeAFn()    // ERROR: InvalidType - Variable typeAFn with type FnTypeA cannot be called as a function
    const bRes = typeBFn(a)
    false
}

pub fn main_flight(v: Vessel) -> Unit = {
    const typeAFn = getFnTypeA(v, 1.2345, 1.2345)  // correctly returns FnTypeA
    const typeBFn = getFnTypeB(v)                  // correctly returns FnTypeB
    const fn1Res = fn1(v, 1.2345, typeAFn, typeBFn) 
    const fn2Res = fn2(v, 1.2345, typeAFn, typeBFn) // fn2 does not compile, see above
}

I tried a simple type definition as well:

pub type myScalarType = float
pub type FnTypeC = fn(myScalarType) -> myScalarType // compiles fine ...

// compiler doesn't seem to like custom types in parameter list, basic type, lambda variant
// ERROR: InvalidType - Expected parameter dt of lambda to have type myScalarType, found myScalarType
pub sync fn getFnTypeC() -> FnTypeC = { 
    fn(dt: myScalarType) -> {
        1.2345
    }
}

Is that some kind of ID10T error on my side, or a compiler bug?

plonk-75 commented 1 year ago

This also rises another question. Suppose we have a function returning a function:

pub fn iReturnAFn(a: float, b:float) -> fn(float) -> float = {
    fn(param: float) -> {
        // some magic happening here, setting variable result to a float
       result
    }
}

Is the returned function sync or async and how is it determined? Should I open a new issue for this question?

untoldwind commented 1 year ago

No that is a bug in the compiler. Will be fixed in the next release.

As for the sync/async: At the moment all lambda-expressions (like fn(param: float) -> { ... }) are sync-functions. I think it would be possible to also support async-lamdbas if there is a need for it

untoldwind commented 1 year ago

Should work in 0.4.1.3

plonk-75 commented 1 year ago

KS2 0.4.1.3 only partially fixes the issue on my side.

While now the first example compiles fine ...

pub type FnTypeA = fn() -> float
pub type FnTypeB = fn(float) -> float

pub fn fn2(v: Vessel, a: float, typeAFn: FnTypeA, typeBFn: FnTypeB) -> bool = { 
    const aRes = typeAFn()      // compiles fine now
    const bRes = typeBFn(a)     // compiles fine now
    false
}

Result: No error as expected

...problems arise when using the returned values:

pub type FnTypeA = fn() -> float
pub type FnTypeB = fn(float) -> float

pub fn fn3(v: Vessel, a: float, typeAFn: FnTypeA, typeBFn: FnTypeB) -> bool = { 
    const aRes = typeAFn()      // compiles fine now
    const bRes = typeBFn(a)     // compiles fine now
    if(aRes < bRes) return true // ERROR: IncompatibleTypes Cannot Lt a Unit with a Unit
    false
}

Result:

ERROR:IncompatibleTypes Cannot Lt a Unit with a Unit
ERROR: InvalidType Condition of if is not a boolean

I still can't get the second sample to compile, no changes in new KS2 version here

pub type myScalarType = float
pub type FnTypeC = fn(myScalarType) -> myScalarType // compiles fine ...

// ERROR: InvalidType - Expected parameter dt of lambda to have type myScalarType, found myScalarType
pub sync fn getFnTypeC() -> FnTypeC = { 
    fn(dt: myScalarType) -> {
        1.2345
    }
}

Result:

ERROR: InvalidType Expected parameter dt of lambda to have type myScalarType, found myScalarType
untoldwind commented 1 year ago

These cases should work now in 0.4.2.1

There still might be some remaining quirks with type-aliases though.

plonk-75 commented 11 months ago

Fix confirmed. Thank you very much! Regarding remaining quirks, I hope you won't mind me submitting more issues as soon as I find them.

untoldwind commented 5 months ago

Closing this for now