Dr. Mark Tarver wrote:
> But it seems from what Jacob is writing
> that it is not so easy as I thought for whatever reason.
The easy parts were quite easy, thanks to the hard work put in by you,
Robert, and the maintainers of open source .NET. Most of it comes down
to me being slow and unfamiliar with F# and Shen. But I figure I'll
lay out the timeline of my changes so I don't forget.
Six-ish years ago I got an inkling to play with Shen on .NET. This was
around the time that .NET Core was new, and ShenSharp supported
Framework and therefore only Windows (at least I remember it
misbehaving on Mono). I wanted it on Linux, and I wanted it on .NET
Core. I tried to figure out the upgrade, but misunderstood both the
tooling and ShenSharp's architecture. Robert helped me out but my
attempt was ultimately unsuccessful.
In the interim, Robert refactored the codebase to mostly work with
.NET Core. Meanwhile, the distinction between .NET Core and Framework
went away, and it became simpler to target all of .NET at once. At the
same time, F# became more tightly integrated with the new .NET
tooling; It had always been developed more openly than C#, so the
opening of C# let the projects gradually merge.
Last November, I took another look at the project and decided to take
a crack with the new tooling. The work I ended up doing mostly had
nothing to do with Shen, just with getting the project to build in a
Linux container. The commits from that period resolve a few bugs in
how we emit code, because ShenSharp originally built a DLL out of
translated KL in-memory for the runtime to use. This feature caused
all kinds of versioning grief and was ultimately removed from F#'s
compiler library, so I created a step similar to one in ShenScript
which saves the code to a file which can be included in a normal build
of the rest of the project. But the bulk of them have to do with
upgrading our use of F#'s compiler API, FSharp.Compiler.Service. That
library releases new versions as new versions of the language are
released, and there are sometimes breaking changes (there was a major
namespace overhaul and pieces of syntax accumulate new fields in them
for metadata; If ML-style types are familiar to you, it's no surprise
that this forces you to change two source locations for each such
addition). .NET library authors have the bad habit of relying on your
IDE's auto-complete instead of writing comprehensive changelogs, which
I find annoying and slowing. I finally got the REPL booting, but
something was broken and I got garbled output, so I shelved the
project for a while.
Last week I decided to fix that small issue and see how hard porting
to S series would be. The issue of newlines turned out to be another
tiny bug in the F# emitter, and the number of errors importing the S
series files was tractable. I had to update some F# calls of Shen
functions to match renames: add-macro became record-macro with a
slightly different signature and the test suite no longer needed to
load README.shen and then another file. I added the stub functions for
I/O: ShenSharp remains purely byte-oriented.
Those changes were (and the other ones are) small, but now I had to
figure out why Shen was breaking. I was slow because I find ML-style
languages hard to debug sometimes, and these bugs required unwinding
both Shen code and the execution tree of the ShenSharp interpreter. I
also misunderstood the nature of the GitHub sources as detailed in my
earlier messages to the group. ShenSharp's custom builtins were not
recognized by Shen's (fn) since ShenSharp does not update the property
vector: I was able to solve that using a leftover step that sets up
function arities and types after the kernel loads. There was a simple
bug in the interpreter's evaluator which meant that let did not work
at all inside lambdas or freezes: This is easy to miss because
functions get walked differently and I'm not sure if the issue existed
when evaluating pre-S-series Shen, it's not directly exercised by the
test suite; The fix was easy once I found it buried in Prolog
evaluation. And finally I realized that (type) was having its right
side walked, leading to function-not-found errors: That was buried in
YACC code.