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.

Reply via email to