leanprover-community / leanprover-community/repl
[proposal]Make request parsing more robust
Nobody has claimed this yet.
- Dominant language
- Lean
- Stars
- 228
- Forks
- 71
- Avg merge
- 15m
- Merged PRs (30d)
- 4
Description
Currently the repl is parsing request json in a try-chain, which is very prone to errors.
For example, if we declare a new request:
structure CommandParse where
env : Option Nat
cmd : String
deriving ToJson, FromJson
and add it to the end of the chain, the function parse will never return CommandParse but always Command for cases meant to be CommandParse. This is because the parsing try of Command is preceding the CommandParse.
One workaround could be changing the field name cmd, so Command fails and CommandParse get its chance. But things would get messy rapidly as more requests are added.
It is interesting that this issue can be definitely solved with the aid of dependent types. The following is a simple example.
Proposal
structure StringLit (s : String) where
val : String
h : val = s
instance {s} : ToJson (StringLit s) where
toJson _ := Json.str s
instance {s} : FromJson (StringLit s) where
fromJson? json := do
let x ← json.getStr?
if h : x = s then
return ⟨x, h⟩
else
throw s!"string literal mismatched, expected {s}, got {x}"
structure Request (type : String) where
reqType : StringLit type
structure Command extends Request "run_command", CommandOptions where
env : Option Nat
cmd : String
deriving ToJson, FromJson
#eval toJson ({ reqType := ⟨"run_command", by rfl⟩, env := none, cmd := "", infotree := none : Command})
Here we make a new type StringLit to encode a String that is always some fixed value encoded in its type.
The type Request serves as the base type of all requests.
Whenever we declare a new request R, we just declare a structure R extending Request S for some string literal S. The automatically derived ToJson R and FromJson R ensure correctness of the field reqType, which disambiguates any two requests with different reqType.
Breaking changes
This will require the clients of REPL to modify their communication code.
If the proposal is acceptable, I would like to be assigned for it.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the REPL request parsing function parse and the existing request definitions, then compare them with the proposed StringLit and Request structures. Review the client communication code affected by the breaking change; done means request variants are unambiguously parsed and clients still communicate correctly.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, cli
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100