-
Notifications
You must be signed in to change notification settings - Fork 52
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
Refactor CESK machine to track environments through new Suspended
state
#1928
Conversation
3635216
to
ed4136c
Compare
I know this is a massive refactoring---and no, there's not really any nice way to split it up into more incremental changes that I know of. This was the kind of refactoring where I started making changes and then finally got it to compile again a week later. I'm not necessarily expecting that anyone will be able to audit every line of code. What would be especially helpful is to just check out this branch and play the game for a bit, see if you can break it. I've fixed everything that I knew to check but there are bound to be some lurking bugs. |
Every time I think this is ready I find another bug... 😠 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonderful work @byorgey!
This makes possibly the most tricky part of Swarm easier to reason about. 👍
Yay for nested (type)definitions! 🥳
60fa220
to
67e1245
Compare
67e1245
to
9f4071f
Compare
e9db496
to
c903d79
Compare
3657edc
to
540fcf9
Compare
I think I have (finally!) squashed all the bugs I know about... I played through some of the early classic game (set up automated tree + bit farms, built a robot to automatically construct drill bits by fetching materials from depot robots, etc.) with no issues. Anyone else who would like to take a look at this before we merge it is most welcome! Thanks to @xsebek for the good feedback already. |
fc23cde
to
a8e263a
Compare
OK, I'm going to merge this now I think... hold onto your hats... 🎩 |
Closes #1948; see that issue for a much more in-depth discussion. Depends on merging #1928 first. A lot of this PR consists in deleting code that is either (1) ugly or (2) overly clever! 🥳 The short version is that the `Store` used to incorporate some laziness + memoization: when a cell was first allocated, it was an unevaluated thunk; it then got evaluated the first time it was referenced. However, this wasn't really needed to handle recursive definitions (which is the only thing we were using it for). Getting rid of it means we can get rid of a lot of weird ugly code needed to wrap free variables in extra calls to `force` and so on. The new and improved `Store` just stores `Value`s, period. A special `VBlackhole` value was added, to be used while evaluating a recursive `let`. Note that `VRef` is no longer really used, but I left it there for use in implementing #1660 . Once we have mutable references we can use them + delay/force to implement lazy cells.
Fixes #2007. After #1928, we handle exceptions a little differently, so it no longer works to simply set the base's CESK machine to an `Up` (exception) state no matter what. Instead we have to first check if the base is running, and if so set it to `Up` as before; if not, do nothing (except clear the REPL prompt).
The bug which necessitated the workaround was fixed in #1928.
```diff def intersperse = \n. \f2. \f1. - if (n > 0) {f1; if (n > 1) {f2} {}; intersperse (n - 1) f2 f1} {} end + if (n > 0) {f1; if (n > 1) {f2} {}; intersperse (n - 1) f2 f1} {} + end ``` * caused by #1928 where def was made more similar to let
```diff def intersperse = \n. \f2. \f1. - if (n > 0) {f1; if (n > 1) {f2} {}; intersperse (n - 1) f2 f1} {} end + if (n > 0) {f1; if (n > 1) {f2} {}; intersperse (n - 1) f2 f1} {} + end ``` You can test it with: ```sh swarm format -i data/scenarios/Challenges/_arbitrage/solution.sw ``` * caused by #1928 where def was made more similar to let
The big idea of this PR is to add a new type of CESK machine state,
Suspended
, which is a state the base robot automatically goes into after completing execution of a program entered at the REPL. It is as if the base robot is still within the local context of any definitions etc. entered previously, just printed out an "intermediate result", and is now waiting to find out what the next term to be executed will be. This allows us to treatdef
as syntax sugar forlet
and results in a much cleaner way to manage the context of definitions, which in turn allows us to remove a whole lot of special cases and fixes several annoying bugs. See #1087 for more explanation and discussion.Things that are deleted (!) by this PR:
TDef
(def
is now just syntax sugar forlet
) (Add the scope of definition to its constructor #997)VResult
(we no longer need to return anything other than plain values)FUnionEnv
,FDiscardEnv
,FLoadEnv
(we no longer need machinery to collect up definitions while evaluating terms)ProcessedTerm
(just a plainTSyntax
(i.e.Syntax' Polytype
) is now enough)Module
(it only existed to package up some contexts with typechecked terms, but we don't need them anymore)RobotContext
andtopContext
(we don't need to store those things separately any more, they are just stored in theCESK
machine where they belong)Additions/changes:
Requirement
module is split intoRequirements.Type
andRequirements.Analysis
to avoid circular module importsSuspended
state for the CESK machinedef
andtydef
are now allowed anywhere (even nested inside other definitions etc.) sincedef x = y end; z
is just syntax sugar forlet x = y in z
(see Nested definitions #349)def
, sincedef
is now a synonym forlet
, and consecutivedef
s therefore do not require abind
.Closes #1087. Fixes #681 (hence also #736, #1796). Fixes #1032. Closes #1047. Closes #997. Fixes #1900. Fixes #1466. Fixes #1424.
See also #636.