Currying a function across more than two lets gives the wrong result.
let f1 = func a b c -> a + b + c
let f2 = func a b -> f1 a b
let f3 = func a -> f2 a
from t | derive {
y = (((f3 100) 20) 3),
z = ((f2 100 20) 3),
}
I thought y and z should be equivalent but they aren't.
SELECT
*,
100 + 20 + 20 AS y,
100 + 20 + 3 AS z
FROM t
y's c is 20 (the value of b) instead of 3.
The weird thing is it works for the 4th param.
let f1 = func a b c d -> a + b + c + d
let f2 = func a b -> f1 a b
let f3 = func a -> f2 a
from t | derive {
y = (((f3 100) 20) 3 4),
z = ((f2 100 20) 3 4),
}
SELECT
*,
100 + 20 + 20 + 4 AS y,
100 + 20 + 3 + 4 AS z
FROM t
Looking at
|
let param_name = format!("_partial_{i}"); |
.
A function returning a partially-applied func seems to wrap it with a wrapper func and pass the remaining params through as
_partial_i. Somehow f3's wrapper ends up shadowing f2's wrapper.
Guessing d is fine because d gets stored as _partial_1 while c is _partial_0, so d doesn't collide with f3's own _partial_0 from its partial application, but c does.
Currying a function across more than two
lets gives the wrong result.I thought
yandzshould be equivalent but they aren't.y'scis20(the value ofb) instead of3.The weird thing is it works for the 4th param.
Looking at
prql/prqlc/prqlc/src/semantic/resolver/functions.rs
Line 129 in 4a9b9b6
A function returning a partially-applied func seems to wrap it with a wrapper func and pass the remaining params through as
_partial_i. Somehow f3's wrapper ends up shadowing f2's wrapper.Guessing
dis fine becausedgets stored as_partial_1whilecis_partial_0, soddoesn't collide with f3's own_partial_0from its partial application, butcdoes.