On Mon, Aug 27, 2018 at 9:16 PM, Ian Denhardt <[email protected]> wrote:
> Quoting Kenton Varda (2018-08-27 20:41:57) > > Nice! Let me know when you want this added to the "other languages" > > page. > > Go right ahead. > Done (with the 0.7 release). > > How does zero-copy work out in Haskell? It seems like you can't really > > do zero-copy writes in a purely-functional way, right? > > The low-level mechanisms in the library aren't ultimately that different > than in most implementations. It's possible to get locally-mutable state > in Haskell without breaking the global invariants via a trick with the > type system that basically emulates Rust's lifetimes -- so the mutable > variables can't be used outside of a certain scope. Naively this > involves a single copy on the way out for the data you want to keep, but > e.g. the vector library provides a create[1] function, which lets you > write code like (to paraphrase & reformat the example on that page): > > immutableResult = create $ do > vec <- new 2 > write vec 0 'a' > write vec 1 'b' > return vec > > So you return a mutable value, which becomes unavailable when you leave > the scope, and you get an immutable one back. > > Internally, create calls unsafeFreeze to cast from mutable -> immutable, > but > provides an API that can't directly be used in ways that violate > referential transparency. > Oh neat, I didn't know this existed. > > --- > > The harder questions were all around how to package stuff up in a way > that was actually comfortable to use; there are worse things than writing > Haskell like it's C, but I wanted to come up with something a little > higher level for common cases. > > Right now there's a split high-level/low-level set of interfaces where the > high level ones basically ignore all of the novel properties of the wire > format, parse the thing up front, and expose an idiomatic Haskell data > type. This is not unlike the Go implementation's "pogs" package, except > that there's support in the code generator. > This makes a lot of sense. I still plan to add "POCS" support to the C++ implementation at some point. > I have some ideas on other spots in the design space that get you a > larger share of the benefits of the wire format without much compromise > of programmer convenience, but they're not implemented yet. My main > interest is really in RPC, which is a much less weird fit for the > language anyway. > > Ironically, *read* support was the harder direction to design for, > because of the need to track the traversal limit and deal with errors > in the midst of traversing the data. The current design again just > has a split, where you can either parse the whole thing up front > and forget about it, or write very imperative-looking code with > explicit error checks everywhere. > Interesting. I would think that for validation errors, at least, you could return `error` and let that bubble up as needed. But the traversal limit is indeed rather inherently imperative. I wonder if there's some other strategy for detecting aliasing that would be more friendly to a purely-functional approach. > > I have some ideas for how to provide most of the convenience of > the high-level API while still being able to do random access/only > access part of the message, and the API surface for them is pretty > tiny, so they should slot in nicely, but it hasn't happened yet. > > [1]: https://hackage.haskell.org/package/vector-0.12.0.1/docs/ > Data-Vector.html#v:create > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. Visit this group at https://groups.google.com/group/capnproto.
