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

Support where expressions in Gibbon #209

Open
vidsinghal opened this issue May 20, 2023 · 3 comments
Open

Support where expressions in Gibbon #209

vidsinghal opened this issue May 20, 2023 · 3 comments

Comments

@vidsinghal
Copy link
Collaborator

Making an issue from discussion with @ckoparkar in the onboarding session.
Gibbon doesn't support where expressions currently.
Neither does it have a Where expression in L0-L4.

To get around this we can parse where expressions in the HaskellFront end, then write a L0 -> L0 compiler pass to transform a where expression to its equivalent Let expression which is supported in the language.

This is a good compiler pass to write for anyone who wants to get familiar with Gibbon internals.

f :: Int -> Int 
f a = y 
     where 
         x =  a * a
         y = x + 1  

equivalent let expression.

f' :: Int -> Int 
f' a = let 
           x = a * a 
           y = x + 1
         in y
@ulysses4ever
Copy link
Collaborator

ulysses4ever commented Dec 20, 2023

Good first issue, indeed. Note, however, that in Haskell there are subtle differences between let and where, as discussed on the Haskell wiki: https://wiki.haskell.org/Let_vs._Where

For example, this is not easy to encode with let:

f x
  | cond1 x   = a
  | cond2 x   = g a
  | otherwise = f (h x a)
  where
    a = w x

But Gibbon doesn't seem to allow guards in function definitions. So, maybe the proposed desugaring into let's is viable.

@ulysses4ever
Copy link
Collaborator

Currently, the parser seems to simply be throwing away the wheres :-)

-- tmp.gibbon.hs
f x = y
  where
    y = x+1

gibbon_main = f 1
$g --run ./tmp.gibbon.hs -v4
 ! Responding to env Var: GIBBON_DEBUG=4
 ! We set DEBUG based on command-line verbose arg: 4
 [compiler] pipeline starting, parsed program: 
================================================================================
Prog {ddefs = [],
      fundefs = [(f,
                  FunDef {funName = "f",
                          funArgs = [x],
                          funTy = ForAll [] (ArrowTy [MetaTv $0] (MetaTv $1)),
                          funBody = VarE "y",
                          funMeta = FunMeta {funRec = NotRec,
                                             funInline = NoInline,
                                             funCanTriggerGC = False}})],
      mainExp = Just (AppE "f" [] [LitE 1], MetaTv $2)}

 [compiler] Running pass, freshen
Pass output:
================================================================================
{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False}}
f :: forall. ($0 -> $1)
f x_3 =
    y

gibbon_main :: $2
gibbon_main = (f [] 1)

 [compiler] Running pass, typecheck
gibbon: L0.Typecheck: 
    Unbound variable y in Var "f"
CallStack (from HasCallStack):
  error, called at src/Gibbon/L0/Typecheck.hs:83:18 in gibbon-0.3-inplace:Gibbon.L0.Typecheck

@ulysses4ever
Copy link
Collaborator

The AST for where is currently being discarded at

FunBind _ [Match _ fname pats (UnGuardedRhs _ bod) _where] -> do
Should be easy to fix it, but I was contemplating on how much work would #132 take (it'd require to re-do this transformation on another AST, ghc-lib-parser's one instead of haskell-src-ext's one).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants