Paper talk: # Elaborator Reflection: Extending Idris in Idris By Edwin Brady and David Christiansen @cyberglot | November, 2021 --- In summary: - It introduces the `Elab` monad, that provides an interface to the *primitive* tactic language in Idris, plus `%runElab` which is a handler of sorts for the monad. ![](https://hackmd.io/_uploads/HkxDKQOwK.png) --- - Most (all?) Idris's higher-level features are implemented in terms of the `Elab` monad: + typeclasses + implicit arguments + type-driven disambiguation of names + local definitions + monomorphisation + (potentially others not mentioned by name) --- - More powerful tactics à la Coq can be derived from `Elab`, eg `crush` ```haskell mush : Elab () mush = do attack x <- gensym "x" intro x try intros induction (Var x) `andThen` auto solve ``` --- # Important details - Idris's TT, the tactics language and the proof state together form the development calculus, TT$$_{dev}$$ (implemented in Haskell for Idris1, implemented in Idris1 for Idris2) --- - The proof state is **not** implemented as a state effect, but rather as binders within the code that behaves similarly to `let` bindings: + `? x : t` for hole binding + `? x ~~ t : t` for guess binding - Quasi-quotation is included in TT$_{dev}$ + quoted code has type `Raw`, ie non-typecked terms + unquoted code has type `TT`, ie well typed, de Bruijn indexed terms --- - Tactics: + gensym : (hint : String) -> Elab TTName + focus : (h : TTName) -> Elab () + unfocused : (h : TTName) -> Elab () + fill : (e : Raw) -> Elab () + solve : Elab () + claim : (n : TTName) -> (t : Raw) -> Elab () + apply : (op : Raw) -> (argSpec : List Bool) -> Elab (List TTName) --- - Tactics (cont.): + compute : Elab () + rewriteWith : (rule : Raw) -> Elab () + intro : (n : TTName) -> Elab () + forall : (n : TTName) -> (t : Raw) -> Elab () + patbind : (v : TTName) -> Elab () + letbind : (n : TTName) -> (v : Raw) -> (t : Raw) -> Elab () + attack : Elab () --- - Tactics (cont.): + getEnv : Elab (List (TTName, Binder TT)) + lookupTy : (n : TTName) -> Elab (List (TTName, NameType, TT)) + lookupDatatype : (n : TTName) -> Elab (List Datatype) + lookupFunDefn : (n : TTName) -> Elab (List (FunDefn TT)) + lookupArgs : (n : TTName) -> Elab (List (TTName, List FunArg, Raw)) --- - Tactics (cont.): + normalise : (env : List (TTName, Binder TT)) -> (tm : TT) -> Elab TT + declareType : TyDecl -> Elab () + defineFunction : FunDefn Raw -> Elab () + declareDatatype : TyDecl -> Elab () + defineDatatype : DataDefn -> Elab () + metavar : TTName -> Elab () + search' : Int -> List TTName -> Elab () --- - Tactics (cont.): + debug : Elab a + debugMessage : List ErrorReportPart -> Elab a + runElab : Raw -> Elab () -> Elab (TT, TT) - Requires TypeProviders for more complex elaborations, such as records --- # Problems - Staging becomes a nightmare: + they don't specify how it is handled + they suggest looking at Racket's approach to staging - Coq-style tactics are also a nightmare - Reliance on Type Providers
{"metaMigratedAt":"2023-06-16T14:12:11.077Z","metaMigratedFrom":"YAML","title":"Elaborator Reflection -- Extending Idris in Idris","breaks":true,"description":"View the slide with \"Slide Mode\".","contributors":"[{\"id\":\"1d1a8ea4-4e48-4c7d-a006-405df381bd63\",\"add\":3387,\"del\":2384}]"}
    362 views