Does anyone have a good idea of how to clean this code up. Currently I have 3 values that all depend on the same conditional:
actuallyFlap = !prev.lastFlap && flap && flapAllowed
yVel =
if actuallyFlap then
jumpSpeed
else
prev.player.yVel + gravity
nextAnim =
if actuallyFlap then
anim = prev.rocciFlapAnim
{ anim & index: 0, state: RunOnce }
else
updateAnimation prev.frameCount prev.rocciFlapAnim
flapSoundTask =
if actuallyFlap then
W4.tone {
startFreq: 700,
endFreq: 870,
channel: Pulse1 Quarter,
attackTime: 10,
sustainTime: 0,
decayTime: 3,
releaseTime: 5,
volume: 10,
peakVolume: 20,
}
else
Task.ok {}
I originally had it all in one conditional returning a tuple, but I don't think that reads well:
(yVel, nextAnim, soundTask) =
if !prev.lastFlap && flap && flapAllowed then
anim = prev.rocciFlapAnim
(
jumpSpeed,
{ anim & index: 0, state: RunOnce },
W4.tone {
startFreq: 700,
endFreq: 870,
channel: Pulse1 Quarter,
attackTime: 10,
sustainTime: 0,
decayTime: 3,
releaseTime: 5,
volume: 10,
peakVolume: 20,
},
)
else
(
prev.player.yVel + gravity,
updateAnimation prev.frameCount prev.rocciFlapAnim,
Task.ok {},
)
How about a record instead of a tuple? I have often done this in Elm.
{ yVel, nextAnim, soundTask } =
if !prev.lastFlap && flap && flapAllowed then
anim = prev.rocciFlapAnim
{
yVel : jumpSpeed,
nextAnim : { anim & index: 0, state: RunOnce },
soundTask : W4.tone {
startFreq: 700,
endFreq: 870,
channel: Pulse1 Quarter,
attackTime: 10,
sustainTime: 0,
decayTime: 3,
releaseTime: 5,
volume: 10,
peakVolume: 20,
},
}
else
{
yVel : prev.player.yVel + gravity,
nextAnim : updateAnimation prev.frameCount prev.rocciFlapAnim,
soundTask : Task.ok {},
}
This way, you get to "label" each expression. And it doesn't count as shadowing because field names don't clash with variable names. And yet the record destructuring syntax makes them the same names. :thumbs_up:
That works better than I would expect
Last updated: Jul 06 2025 at 12:14 UTC