Skip to content
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

Lift lambdas #44

Merged
merged 40 commits into from
Dec 8, 2021
Merged

Lift lambdas #44

merged 40 commits into from
Dec 8, 2021

Conversation

hmontero1205
Copy link
Contributor

Opening a draft to get some feedback in. Need advice on how to type lifted lambdas and general monadic programming critiques :)

Closes #32

Copy link
Contributor

@j-hui j-hui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Hans! This is great start. Wrote some style suggestions (:

src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
@hmontero1205 hmontero1205 marked this pull request as ready for review November 26, 2021 07:22
@hmontero1205
Copy link
Contributor Author

@XijiaoLi I ran into a very interesting issue while I was trying to make my code pass the regression tests. Consider main routine of doubleblink.ssl:

main(led : &Int) -> () =
  par ((slow: &Int -> ()) (led: &Int): ())
         ((fast: &Int -> ()) (led: &Int): ())

While the type annotation says main returns a unit type, I don't think that's technically true right? Because the type of the body is ((), ()). In my code, I have to expand chained lambdas and then collect them which requires me to reconstruct the lambda chain (and therefore type annotate each lambda). I was originally ignoring the original type annotation on the overall function because I assumed it'd be exactly the same as the type annotations in the body after type inference. However, I was wrong because I was failing the regression tests. My code, upon reconstructing the main function, incorrectly(?) annotated it as `(&Int) -> ((), ()) which makes codegen fail since we don't have tuples yet.

Is the behavior I encountered expected? Does your type inference unify(?) ((), ()) and ()?

@XijiaoLi
Copy link
Contributor

XijiaoLi commented Nov 26, 2021

@XijiaoLi I ran into a very interesting issue while I was trying to make my code pass the regression tests. Consider main routine of doubleblink.ssl:

main(led : &Int) -> () =
  par ((slow: &Int -> ()) (led: &Int): ())
         ((fast: &Int -> ()) (led: &Int): ())

While the type annotation says main returns a unit type, I don't think that's technically true right? Because the type of the body is ((), ()). In my code, I have to expand chained lambdas and then collect them which requires me to reconstruct the lambda chain (and therefore type annotate each lambda). I was originally ignoring the original type annotation on the overall function because I assumed it'd be exactly the same as the type annotations in the body after type inference. However, I was wrong because I was failing the regression tests. My code, upon reconstructing the main function, incorrectly(?) annotated it as `(&Int) -> ((), ()) which makes codegen fail since we don't have tuples yet.

Is the behavior I encountered expected? Does your type inference unify(?) ((), ()) and ()?

It should be ((), ()). I think it was a mistake that was made in the first version of doubleblink.ssl and we just haven't changed it. My type inference should infer the type of par as Tuple [t] Builtin type (e.g., ((), ()) in this case). However, I believe that the current Codegen does not support Tuple type yet based on Codegen.hs#L164.

src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
Copy link
Contributor

@j-hui j-hui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hmontero1205 ! This is awesome work.

This looks good overall. I left a bunch of suggestions inline, mostly places where you could have used existing helpers.

I'm requesting changes because this is still missing Haddock comments, and a test suite demonstrating correctness. For the test suite, add a new test suite named ir-to-ir where we can write tests that assert the correctness of source-to-source transformations.

src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
src/IR/LambdaLift.hs Show resolved Hide resolved
src/IR/LambdaLift.hs Outdated Show resolved Hide resolved
@hmontero1205
Copy link
Contributor Author

It should be ((), ()). I think it was a mistake that was made in the first version of doubleblink.ssl and we just haven't changed it. My type inference should infer the type of par as Tuple [t] Builtin type (e.g., ((), ()) in this case). However, I believe that the current Codegen does not support Tuple type yet based on Codegen.hs#L164.

@XijiaoLi I'm confused then -- does your type inference logic compare main's annotated return type of () to ((), ())?

I'm still not sure which type annotation I should be following when I am reconstructing lambdas -- the type annotation on the lambda itself or the type annotation on the lambda bodies. To reiterate, I was doing the latter but I'm not sure if I am supposed to be doing the former or if it really shouldn't matter to this compiler pass? @j-hui any thoughts?

@j-hui
Copy link
Contributor

j-hui commented Nov 26, 2021 via email

@XijiaoLi
Copy link
Contributor

@XijiaoLi I'm confused then -- does your type inference logic compare main's annotated return type of () to ((), ())?

I'm still not sure which type annotation I should be following when I am reconstructing lambdas -- the type annotation on the lambda itself or the type annotation on the lambda bodies. To reiterate, I was doing the latter but I'm not sure if I am supposed to be doing the former or if it really shouldn't matter to this compiler pass? @j-hui any thoughts?

I mean, the current type annotation for main's return type is wrong - it should be ((), ()) since the type of par should be a tuple. The type annotation on the lambda bodies should always be the same as the type annotation on the lambda's return type. We should really fix this regression test.

@j-hui
Copy link
Contributor

j-hui commented Nov 26, 2021 via email

Copy link
Contributor Author

@hmontero1205 hmontero1205 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@j-hui check this out, now with tests and documentation 😳

Copy link
Contributor

@j-hui j-hui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall! I'm going to stamp this for now, but there still are a few things to follow up on, for which I left comments inline.

Also, could we add a more deeply nested example? Something like:

f x y =
  let z = 4
  let g a =
    let h b = a + b + x
    h z
  g y

app/Main.hs Outdated Show resolved Hide resolved
src/IR/IR.hs Outdated Show resolved Hide resolved
test/ir-to-ir/Tests/LiftProgramLambdasSpec.hs Show resolved Hide resolved
test/ir-to-ir/Tests/LiftProgramLambdasSpec.hs Show resolved Hide resolved
src/IR/IR.hs Outdated Show resolved Hide resolved
@hmontero1205 hmontero1205 merged commit e88ed8b into main Dec 8, 2021
@hmontero1205 hmontero1205 deleted the hans-lambda-lift branch December 8, 2021 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lambda-lifting
3 participants