-
Notifications
You must be signed in to change notification settings - Fork 0
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
#36 add interpreters to free #53
base: master
Are you sure you want to change the base?
Conversation
Can't output a Free program for unwrapped, eager operations; fixed.
Got the basic pattern down, and a pattern for algebras like the various BufferIOs which use inheritance to share declarations of common blocks of operations.
Demonstrates completion of the fbound operation pattern. Also demonstrates how a leaf FreeIO interpreter gets built.
Found that *BufferIO in general weren't inheriting from *BufferReadIO and they really should have been. This was letting Free*BufferIO not implement *BufferReadIO, which is bad. Fixing the *BufferIO algebras required refactoring ByteReadBufferFs and FreeByteReadBufferIO to be extended by FreeByteBufferIO.
Working on something else for a while, so here's the status:
The interesting puzzle of the moment is Lift, Term, and how to handle operations that take a polymorphic aligned interpreter as input. It highlights just how little I've thought through interpretation of Free programs into tagless interpreters. Exactly how state can be threaded through be the Free interpreter is unclear. |
The polymophic buffer work makes FreeBufferIO significantly more complex. This commit gets the project compiling by starting a bit of the fix up and commenting out the rest of the FreeBufferIO file. Sebsequent commits will work towards making FreeBufferIO, Lift, and Term play together with the alignment type. Should be an adventure.
In the branch I'd put bounds on the alignment type parameter, forcing it to be the Module. In the case of ByteBuffer it's the whole Buffer system Module. For the others it's their type specific Module. The bound allows the algebra definitions in the IO traits to return full leaf types. The trouble is it really complicated the Lift/Term declarations as the bounds had to be recreated to ensure soundness. That was gonna be UGLY and the pay off was exposing leaf types from interpreters which probably isn't even a good idea. In this commit we allow the alignment parameter to be unrestrained. This prevents type projection into the Module to define f-bound return types from operations that accept and return interpreter instances. That's fine as we have the algebra trait types, with their alignment parameters. In this commit all the f-bound operations are modified to use the abstract algebra trait type and the alignment type. This still uses the alignment type to prevent a FreeByteBufferIO interpreter from being passed into the JVM interpreter's .read method for instance. It just doesn't give up the actual runtime type of the returned interpreter, which is probably better anyway.
When I tried to carry unrestricted alignment types to the FileIO and FSIO interfaces I ran into the wall because those interfaces relied on the alignment type being bound to a Module type to align the multiple algebras it depends on. I then realized that we don't need really fine grained alignment, we just need to ensure that Free interpreters are passed Free interpreters and Java backed interpreters are passed Java backed interpreters. There won't be 6 competing and incompatible Java backed interpreters, ever. So instead of silently using the JVMBufferIOModule type to align Buffers (and then being out of luck when we get to FileIO/FSIO) I created a new single purpose JVMA type in the root of the Java API package. Any interpreter which implements a wrapped Java library's algebra by deferring directly to the Java implementation can be tagged with this dedicated alignment type.
So I've solved the problem with polymorphic aligned interpreters as arguments and results from algebra operations. It took refactoring the whole code base to use unrestricted alignment types and pretty much gutted the Module system. There are two big bang commits with this work. They were the only two intermediate "compiles and runs" points in the whole job. There's a bunch of clean up left; heck I've not even closely read the diffs from the second commit. My plan is to do a detailed review now that it's committed and go back to working incrementally while cleaning up whatever dreck I find. |
FSPathLogic took a heavy reworking to take the IO[_[_], _] shape. I removed the operation to create a Path from a String because that was the only one that really needed FSPathLogic to wrap a FileSystem object. Right now the examples are cheesed together using the IsoImmutableUnsafe instance for FSPath, which doesn't create FSPath.P instances with correct D domain labling types. The better way to create FSPath.P instances is to use the (not yet created) FileSystem algebra. That's for the future though. Other than that this commit is a ton of nuking Modules as alignment types and adding JVMA and FreeA. And gutting Modules. I'm glad I never cleaned up the Modules. I suspect they'll mostly go away with the new alignment types approach.
The fun thing here is adding TermP1 (Term/Polymorphic/Order 1) to put select (instead of selectA) into the F1 term trait for non algebra/polymorphic result types within an algebra that ALSO has algebra/polymorphic types. Nice to reduce a bit of boilerplate.
Eliminated a few more spurious A's
Why'd I stop? ByteBufferIO.putBuffer(ByteBufferReadIO) pretty much breaks what we're doing. Term is configured to be polymorphic in the target interpreter's alignment parameter, which is fine. Trouble is putBuffer, and many other operations in the FileIO algebras that require input parameters that are aligned interpreters. Free requires the inputs be stored which happens BEFORE the polymorphic call to Term.select. I'm not sure what I'm going to do.
Addressing issue #36 to bootstrap all existing algebras with case class hierarchies to represent existing operations and then to add tagless interpreters which create Free programs via a new Embed typeclass (which stands in for Inject from specific FP libraries).