Skip to content

Commit 2df5549

Browse files
authored
Merge pull request #755 from google-research/load-bearing-monads-2
Remove Immut constraint, leaning on the monads for safety instead
2 parents 81db9ac + 943e6a1 commit 2df5549

20 files changed

+1021
-1323
lines changed

src/dex.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ runMode evalMode preludeFile opts = do
5858
env <- cachedWithSnapshot "prelude" key do
5959
hPutStrLn stderr "Compiling the prelude. This may take some time."
6060
execInterblockM opts initTopState $ evalPrelude preludeFile
61+
env <- cachedWithSnapshot "prelude" key do
62+
hPutStrLn stderr "Compiling the prelude. This may take some time."
63+
execInterblockM opts initTopState $ evalPrelude preludeFile
6164
case evalMode of
6265
ReplMode prompt -> do
6366
let filenameAndDexCompletions = completeQuotedWord (Just '\\') "\"'" listFiles dexCompletions

src/lib/Algebra.hs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,25 +191,22 @@ clamp p = cpoly [(1, cmono [Clamp p] (mono []))]
191191
type CPolySubstVal = SubstVal AtomNameC (MaybeE ClampPolynomial)
192192

193193
blockAsCPoly :: (EnvExtender m, EnvReader m) => Block n -> m n (Maybe (ClampPolynomial n))
194-
blockAsCPoly (Block _ decls' result') = fromMaybeE <$> liftImmut do
195-
Distinct <- getDistinct
196-
scope <- getScope
197-
case refreshAbs scope $ Abs decls' result' of
198-
DistinctAbs decls'' result'' ->
199-
fmap toMaybeE $ runMaybeT1 $ runSubstReaderT idSubst $ go decls'' result''
194+
blockAsCPoly (Block _ decls' result') =
195+
runMaybeT1 $ runSubstReaderT idSubst $ go $ Abs decls' result'
200196
where
201-
go :: (EnvExtender2 m, EnvReader2 m, SubstReader CPolySubstVal m, Alternative2 m, Distinct l)
202-
=> Nest Decl o l -> Expr l -> m o o (ClampPolynomial o)
203-
go decls result = case decls of
204-
Nest decl@(Let b (DeclBinding _ _ expr)) rest -> do
197+
go :: (EnvExtender2 m, EnvReader2 m, SubstReader CPolySubstVal m, Alternative2 m)
198+
=> Abs (Nest Decl) Expr o -> m o o (ClampPolynomial o)
199+
go (Abs decls result) = case decls of
200+
Empty -> exprAsCPoly result
201+
Nest decl@(Let _ (DeclBinding _ _ expr)) restDecls -> do
202+
let rest = Abs restDecls result
205203
cp <- toMaybeE <$> optional (exprAsCPoly expr)
206-
withSubscopeDistinct rest $ do
207-
extendSubst (b@>SubstVal cp) $ do
208-
cpresult <- extendEnv (toEnvFrag decl) $ go rest result
209-
case hoist decl cpresult of
204+
refreshAbs (Abs decl rest) \(Let b _) rest' -> do
205+
extendSubst (b@>SubstVal (sink cp)) $ do
206+
cpresult <- go rest'
207+
case hoist b cpresult of
210208
HoistSuccess ans -> return ans
211209
HoistFailure _ -> empty
212-
Empty -> exprAsCPoly result
213210

214211
exprAsCPoly :: (EnvReader2 m, SubstReader CPolySubstVal m, Alternative2 m) => Expr o -> m o o (ClampPolynomial o)
215212
exprAsCPoly e = case e of

src/lib/Builder.hs

Lines changed: 62 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module Builder (
1919
emit, emitOp, emitUnOp,
2020
buildPureLam, BuilderT (..), Builder (..), ScopableBuilder (..),
2121
Builder2, BuilderM, ScopableBuilder2,
22-
runBuilderT, buildBlock, app, add, mul, sub, neg, div',
22+
liftBuilderT, buildBlock, app, add, mul, sub, neg, div',
2323
iadd, imul, isub, idiv, ilt, ieq, irem,
2424
fpow, flog, fLitLike, buildPureNaryLam,
2525
emitMethodType, emitSuperclass,
@@ -43,7 +43,7 @@ module Builder (
4343
TopEnvFrag (..),
4444
inlineLastDecl, fabricateEmitsEvidence, fabricateEmitsEvidenceM,
4545
singletonBinderNest, varsAsBinderNest, typesAsBinderNest,
46-
runBuilderM, liftBuilder, liftEmitBuilder, makeBlock,
46+
liftBuilder, liftEmitBuilder, makeBlock,
4747
indexToInt, indexSetSize, intToIndex,
4848
getIxImpl, IxImpl (..),
4949
litValToPointerlessAtom, emitPtrLit,
@@ -89,9 +89,9 @@ class (EnvReader m, EnvExtender m, Fallible1 m)
8989

9090
class Builder m => ScopableBuilder (m::MonadKind1) where
9191
buildScoped
92-
:: (SinkableE e, Immut n)
92+
:: SinkableE e
9393
=> (forall l. (Emits l, DExt n l) => m l (e l))
94-
-> m n (DistinctAbs (Nest Decl) e n)
94+
-> m n (Abs (Nest Decl) e n)
9595

9696
type Builder2 (m :: MonadKind2) = forall i. Builder (m i)
9797
type ScopableBuilder2 (m :: MonadKind2) = forall i. ScopableBuilder (m i)
@@ -136,12 +136,11 @@ class (EnvReader m, MonadFail1 m)
136136
-- implemented more efficiently by avoiding a double substitution
137137
-- XXX: emitBinding/emitEnv don't extend the synthesis candidates
138138
emitBinding :: Mut n => Color c => NameHint -> Binding c n -> m n (Name c n)
139-
emitEnv :: (Mut n, SinkableE e, SubstE Name e)
140-
=> Abs TopEnvFrag e n -> m n (e n)
139+
emitEnv :: (Mut n, SinkableE e, SubstE Name e) => Abs TopEnvFrag e n -> m n (e n)
141140
emitNamelessEnv :: TopEnvFrag n n -> m n ()
142-
localTopBuilder :: (Immut n, SinkableE e)
141+
localTopBuilder :: SinkableE e
143142
=> (forall l. (Mut l, DExt n l) => m l (e l))
144-
-> m n (DistinctAbs TopEnvFrag e n)
143+
-> m n (Abs TopEnvFrag e n)
145144

146145
emitSourceMap :: TopBuilder m => SourceMap n -> m n ()
147146
emitSourceMap sm = emitNamelessEnv $ TopEnvFrag emptyOutFrag mempty sm mempty mempty
@@ -160,23 +159,20 @@ emitImpFunBinding hint f = emitBinding hint $ ImpFunBinding f
160159
extendCache :: TopBuilder m => Cache n -> m n ()
161160
extendCache cache = emitNamelessEnv $ TopEnvFrag emptyOutFrag mempty mempty cache mempty
162161

163-
getCacheM :: EnvReader m => m n (Cache n)
164-
getCacheM = liftImmut $ getCache <$> getEnv
165-
166162
extendImpCache :: TopBuilder m => AtomName n -> ImpFunName n -> m n ()
167163
extendImpCache fSimp fImp = extendCache $ Cache mempty (eMapSingleton fSimp fImp) mempty
168164

169165
queryImpCache :: EnvReader m => AtomName n -> m n (Maybe (ImpFunName n))
170166
queryImpCache v = do
171-
cache <- impCache <$> getCacheM
167+
cache <- withEnv (impCache . getCache)
172168
return $ lookupEMap cache v
173169

174170
extendObjCache :: (Mut n, TopBuilder m) => ImpFunName n -> CFun n -> m n ()
175171
extendObjCache fImp cfun = extendCache $ Cache mempty mempty (eMapSingleton fImp cfun)
176172

177173
queryObjCache :: EnvReader m => ImpFunName n -> m n (Maybe (CFun n))
178174
queryObjCache v = do
179-
cache <- objCache <$> getCacheM
175+
cache <- withEnv (objCache . getCache)
180176
return $ lookupEMap cache v
181177

182178
newtype TopBuilderT (m::MonadKind) (n::S) (a:: *) =
@@ -185,20 +181,20 @@ newtype TopBuilderT (m::MonadKind) (n::S) (a:: *) =
185181
, CtxReader, ScopeReader, MonadTrans1, MonadReader r, MonadIO)
186182

187183
instance Fallible m => EnvReader (TopBuilderT m) where
188-
getEnv = TopBuilderT $ getOutMapInplaceT
184+
unsafeGetEnv = TopBuilderT $ getOutMapInplaceT
189185

190186
instance Fallible m => TopBuilder (TopBuilderT m) where
191-
emitBinding hint binding = TopBuilderT $
192-
emitInplaceT hint binding \b binding' -> do
193-
let envFrag = toEnvFrag (b:>binding')
187+
emitBinding hint binding = do
188+
Abs b v <- newNameM hint
189+
let ab = Abs (b:>binding) v
190+
ab' <- liftEnvReaderM $ refreshAbs ab \b' v' -> do
191+
let envFrag = toEnvFrag b'
194192
let scs = bindingsFragToSynthCandidates envFrag
195-
TopEnvFrag envFrag scs mempty mempty mempty
193+
let topFrag = TopEnvFrag envFrag scs mempty mempty mempty
194+
return $ Abs topFrag v'
195+
TopBuilderT $ extendInplaceT ab'
196196

197-
emitEnv ab = TopBuilderT do
198-
extendInplaceT do
199-
scope <- getScope
200-
ab' <- sinkM ab
201-
return $ refreshAbs scope ab'
197+
emitEnv ab = TopBuilderT $ extendInplaceT ab
202198

203199
emitNamelessEnv bs = TopBuilderT $ extendTrivialInplaceT bs
204200

@@ -220,7 +216,6 @@ runTopBuilderT
220216
-> TopBuilderT m n a
221217
-> m a
222218
runTopBuilderT bindings cont = do
223-
Immut <- return $ toImmutEvidence bindings
224219
liftM snd $ runInplaceT bindings $ runTopBuilderT' $ cont
225220

226221
type TopBuilder2 (m :: MonadKind2) = forall i. TopBuilder (m i)
@@ -240,34 +235,25 @@ newtype BuilderT (m::MonadKind) (n::S) (a:: *) =
240235

241236
type BuilderM = BuilderT HardFailM
242237

243-
runBuilderT
244-
:: (Fallible m, Distinct n)
245-
=> Env n
246-
-> BuilderT m n a
247-
-> m a
248-
runBuilderT bindings cont = do
249-
Immut <- return $ toImmutEvidence bindings
250-
(Empty, result) <- runInplaceT bindings $ runBuilderT' cont
251-
return result
252-
253-
runBuilderM :: Distinct n => Env n -> BuilderM n a -> a
254-
runBuilderM bindings m = runHardFail $ runBuilderT bindings m
255-
256-
liftBuilder
257-
:: (EnvReader m, SinkableE e)
258-
=> (forall l. (Immut l, DExt n l) => BuilderM l (e l))
259-
-> m n (e n)
260-
liftBuilder cont = liftImmut do
261-
DB bindings <- getDB
262-
return $ runBuilderM bindings $ cont
238+
liftBuilderT :: (Fallible m, EnvReader m') => BuilderT m n a -> m' n (m a)
239+
liftBuilderT cont = do
240+
env <- unsafeGetEnv
241+
Distinct <- getDistinct
242+
return do
243+
(Empty, result) <- runInplaceT env $ runBuilderT' cont
244+
return result
245+
246+
liftBuilder :: EnvReader m => BuilderM n a -> m n a
247+
liftBuilder cont = liftM runHardFail $ liftBuilderT cont
263248

264249
-- XXX: this uses unsafe functions in its implementations. It should be safe to
265250
-- use, but be careful changing it.
266251
liftEmitBuilder :: (Builder m, SinkableE e, SubstE Name e)
267252
=> BuilderM n (e n) -> m n (e n)
268-
liftEmitBuilder cont = liftImmut do
269-
DB bindings <- getDB
270-
let (result, decls) = runHardFail $ unsafeRunInplaceT (runBuilderT' cont) bindings
253+
liftEmitBuilder cont = do
254+
env <- unsafeGetEnv
255+
Distinct <- getDistinct
256+
let (result, decls) = runHardFail $ unsafeRunInplaceT (runBuilderT' cont) env
271257
Emits <- fabricateEmitsEvidenceM
272258
emitDecls (unsafeCoerceB decls) result
273259

@@ -282,17 +268,15 @@ instance Fallible m => ScopableBuilder (BuilderT m) where
282268
instance Fallible m => Builder (BuilderT m) where
283269
emitDecl hint ann expr = do
284270
ty <- getType expr
285-
BuilderT $ emitInplaceT hint (DeclBinding ann ty expr) \b rhs ->
286-
Nest (Let b rhs) Empty
271+
Abs b v <- newNameM hint
272+
let decl = Let b $ DeclBinding ann ty expr
273+
BuilderT $ extendInplaceT $ Abs (Nest decl Empty) v
287274

288275
instance Fallible m => EnvReader (BuilderT m) where
289-
getEnv = BuilderT $ getOutMapInplaceT
276+
unsafeGetEnv = BuilderT $ getOutMapInplaceT
290277

291278
instance Fallible m => EnvExtender (BuilderT m) where
292-
extendEnv frag cont = BuilderT $
293-
extendInplaceTLocal (\bindings -> extendOutMap bindings frag) $
294-
withExtEvidence (toExtEvidence frag) $
295-
runBuilderT' cont
279+
refreshAbs ab cont = BuilderT $ refreshAbs ab \b e -> runBuilderT' $ cont b e
296280

297281
instance (SinkableV v, ScopableBuilder m) => ScopableBuilder (SubstReaderT v m i) where
298282
buildScoped cont = SubstReaderT $ ReaderT \env ->
@@ -322,6 +306,12 @@ instance (SinkableE e, Builder m) => Builder (ReaderT1 e m) where
322306
emitDecl hint ann expr =
323307
ReaderT1 $ lift $ emitDecl hint ann expr
324308

309+
instance (SinkableE e, HoistableState e m, Builder m) => Builder (StateT1 e m) where
310+
emitDecl hint ann expr = lift11 $ emitDecl hint ann expr
311+
312+
instance Builder m => Builder (MaybeT1 m) where
313+
emitDecl hint ann expr = lift11 $ emitDecl hint ann expr
314+
325315
-- === Emits predicate ===
326316

327317
-- We use the `Emits` predicate on scope parameters to indicate that we may emit
@@ -353,8 +343,8 @@ buildBlock
353343
:: ScopableBuilder m
354344
=> (forall l. (Emits l, DExt n l) => m l (Atom l))
355345
-> m n (Block n)
356-
buildBlock cont = liftImmut do
357-
DistinctAbs decls results <- buildScoped do
346+
buildBlock cont = do
347+
Abs decls results <- buildScoped do
358348
result <- cont
359349
ty <- cheapNormalize =<< getType result
360350
return $ result `PairE` ty
@@ -419,10 +409,10 @@ buildNullaryPi effs cont =
419409
buildLamGeneral
420410
:: ScopableBuilder m
421411
=> NameHint -> Arrow -> Type n
422-
-> (forall l. (Immut l, DExt n l) => AtomName l -> m l (EffectRow l))
412+
-> (forall l. DExt n l => AtomName l -> m l (EffectRow l))
423413
-> (forall l. (Emits l, DExt n l) => AtomName l -> m l (Atom l))
424414
-> m n (Atom n)
425-
buildLamGeneral hint arr ty fEff fBody = liftImmut do
415+
buildLamGeneral hint arr ty fEff fBody = do
426416
withFreshBinder hint (LamBinding arr ty) \b -> do
427417
let v = binderName b
428418
effs <- fEff v
@@ -451,7 +441,7 @@ buildPi :: (Fallible1 m, Builder m)
451441
=> NameHint -> Arrow -> Type n
452442
-> (forall l. DExt n l => AtomName l -> m l (EffectRow l, Type l))
453443
-> m n (PiType n)
454-
buildPi hint arr ty body = liftImmut do
444+
buildPi hint arr ty body = do
455445
withFreshPiBinder hint (PiBinding arr ty) \b -> do
456446
(effs, resultTy) <- body $ binderName b
457447
return $ PiType b effs resultTy
@@ -485,9 +475,9 @@ buildAbs
485475
, SinkableE e, Color c, ToBinding binding c)
486476
=> NameHint
487477
-> binding n
488-
-> (forall l. (Immut l, DExt n l) => Name c l -> m l (e l))
478+
-> (forall l. DExt n l => Name c l -> m l (e l))
489479
-> m n (Abs (BinderP c binding) e n)
490-
buildAbs hint binding cont = liftImmut do
480+
buildAbs hint binding cont = do
491481
withFreshBinder hint binding \b -> do
492482
body <- cont $ binderName b
493483
return $ Abs (b:>binding) body
@@ -504,9 +494,9 @@ varsAsBinderNest (v:vs) = do
504494
return $ EmptyAbs (Nest (b:>ty) bs)
505495

506496
typesAsBinderNest :: EnvReader m => [Type n] -> m n (EmptyAbs (Nest Binder) n)
507-
typesAsBinderNest types = liftImmut $ liftEnvReaderM $ go types
497+
typesAsBinderNest types = liftEnvReaderM $ go types
508498
where
509-
go :: forall n. Immut n => [Type n] -> EnvReaderM n (EmptyAbs (Nest Binder) n)
499+
go :: forall n. [Type n] -> EnvReaderM n (EmptyAbs (Nest Binder) n)
510500
go tys = case tys of
511501
[] -> return $ Abs Empty UnitE
512502
ty:rest -> withFreshBinder NoHint ty \b -> do
@@ -522,12 +512,11 @@ singletonBinderNest hint ty = do
522512
buildNaryAbs
523513
:: (ScopableBuilder m, SinkableE e, SubstE Name e, SubstE AtomSubstVal e, HoistableE e)
524514
=> EmptyAbs (Nest Binder) n
525-
-> (forall l. (Immut l, Distinct l, DExt n l) => [AtomName l] -> m l (e l))
515+
-> (forall l. DExt n l => [AtomName l] -> m l (e l))
526516
-> m n (Abs (Nest Binder) e n)
527-
buildNaryAbs (EmptyAbs Empty) body =
528-
liftImmut do
529-
Distinct <- getDistinct
530-
Abs Empty <$> body []
517+
buildNaryAbs (EmptyAbs Empty) body = do
518+
Distinct <- getDistinct
519+
Abs Empty <$> body []
531520
buildNaryAbs (EmptyAbs (Nest (b:>ty) bs)) body = do
532521
Abs b' (Abs bs' body') <-
533522
buildAbs (getNameHint b) ty \v -> do
@@ -614,7 +603,7 @@ buildUnaryAtomAlt ty body = do
614603
buildNewtype :: ScopableBuilder m
615604
=> SourceName
616605
-> EmptyAbs (Nest Binder) n
617-
-> (forall l. (Immut l, DExt n l) => [AtomName l] -> m l (Type l))
606+
-> (forall l. DExt n l => [AtomName l] -> m l (Type l))
618607
-> m n (DataDef n)
619608
buildNewtype name paramBs body = do
620609
Abs paramBs' argBs <- buildNaryAbs paramBs \params -> do
@@ -1152,12 +1141,11 @@ reduceE monoid xs = liftEmitBuilder do
11521141
emitOp $ PrimEffect (sink $ Var ref) $ MExtend (fmap sink monoid) x
11531142

11541143
andMonoid :: EnvReader m => m n (BaseMonoid n)
1155-
andMonoid = do
1156-
combiner <- liftBuilder $
1144+
andMonoid = liftM (BaseMonoid TrueAtom) do
1145+
liftBuilder $
11571146
buildLam "_" PlainArrow BoolTy Pure \x ->
11581147
buildLam "_" PlainArrow BoolTy Pure \y -> do
11591148
emitOp $ ScalarBinOp BAnd (sink $ Var x) (Var y)
1160-
return $ BaseMonoid TrueAtom combiner
11611149

11621150
-- (a-> {|eff} b) -> n=>a -> {|eff} (n=>b)
11631151
mapE :: (Emits n, ScopableBuilder m)
@@ -1251,14 +1239,14 @@ telescopicCapture bs e = do
12511239
vs <- localVarsAndTypeVars bs e
12521240
vTys <- mapM (getType . Var) vs
12531241
let (vsSorted, tys) = unzip $ toposortAnnVars $ zip vs vTys
1254-
ty <- liftImmut $ liftEnvReaderM $ buildTelescopeTy vs tys
1242+
ty <- liftEnvReaderM $ buildTelescopeTy vs tys
12551243
result <- buildTelescopeVal (map Var vsSorted) ty
12561244
let ty' = ignoreHoistFailure $ hoist bs ty
12571245
let ab = ignoreHoistFailure $ hoist bs $ abstractFreeVarsNoAnn vsSorted e
12581246
return (result, ty', ab)
12591247

12601248
-- XXX: assumes arguments are toposorted
1261-
buildTelescopeTy :: (EnvReader m, EnvExtender m, Immut n)
1249+
buildTelescopeTy :: (EnvReader m, EnvExtender m)
12621250
=> [AtomName n] -> [Type n] -> m n (Type n)
12631251
buildTelescopeTy [] [] = return UnitTy
12641252
buildTelescopeTy (v:vs) (ty:tys) = do

0 commit comments

Comments
 (0)