Thanks! I wrote some comments inline below.

On Wed, May 29, 2019 at 11:38 PM Ian Denhardt <[email protected]> wrote:

> Quoting David Renshaw (2019-05-29 21:33:03)
>
> >    This has piqued my interest. Which parts of the schema language don't
> >    map well to Haskell/Elm?
>
> The biggest one is nested namespaces, per discussion. Neither language
> has intra-module namespaces, so you either end up doing a bunch of
> complex logic to split stuff across multiple modules and still break
> dependency cycles (in Haskell; per my earlier message, in Elm you're
> just SOL, since mutually recursive modules are just not supported, full
> stop), or you deal with long_names_with_underscores (Haskell actually
> uses the single quote as a namespace separator).  This is a problem
> for the Go implementation as well; some of the stuff from sandstorm's
> web-session.capnp spits out identifiers that are pushing 100 characters.
> (I actually bumped into @glycerine at a meetup just the other day; we
> talked about this among other things).
>

That's unfortunate.


>
> The fact that union field names are scoped to the struct is a bit
> awkward, since union tag names are scoped at the module level in
> most ML-family languages. More makeshift namespacing.
>

Sounds like this is awkward mainly because of the previous problem, i.e.
Haskell lacks
nested namespaces. With nested namespaces, you would define your union
datatype
within the namespace of the enclosing struct, and the tag names would have
exactly
the right namespace.


>
> The lack of a clean separation between unions and structs introduces a
> bit of an impedance mismatch as well; if you do things naively you end
> up with an awkward situation where *every* sum type is wrapped in a
> struct, which is a bit odd since they are used so liberally (and are
> normally so lightweight) in these languages. The Haskell implementation
> specifically looks for structs which are one big anonymous union so it
> can omit the wrapper.
>
> If you have an anonymous union you also need to invent a name for the
> field, since you can't actually have "anonymous" fields in records.
>

`which` is the usual name for such a field, as in:
https://github.com/capnproto/capnproto/blob/0f368d5781872ffc3e63db54b0ac4a138b0e0a05/c%2B%2B/src/capnp/encoding-test.c%2B%2B#L121


>
> For Haskell, there's no way to talk about a record type without giving
> it a name, so every group needs an auxiliary type defined. There's not
> really anything clearly nicer to do than just name it <Type>'<field> or
> such, which makes the long name problem worse. Along similar lines, in
> Haskell you end up having to define auxiliary types for parameter and
> return types, and without more of a hint the end up being things like
> <Type>'<method>'params and <Type>'<method>'results -- a mouthful even
> for short type names. I've taken to just always manually giving my
> parameter and return arguments names to avoid this kind of compiler
> output; the schema is much more verbose, but the call site is much
> nicer. None of this section applies to Elm since you can just have
> anonymous record types.
>

Again, sounds like this is awkward mainly as a consequence of Haskell's
lack of nested namespaces.


>
> I intentionally decided to just not support custom default values for
> pointer fields; it gets really awkward because messages can be mutable
> or immutable, and you end up needing different implementation strategies
> for each type; for immutable messages you can't do what most
> implementations do (copy the value in place on first access),


Copying into an immutable message would mean mutating it,
so I agree that's not a good way to go.


> but you
> could "follow" the pointer into some constant defined in the generated
> code without a copy. But that gets weird because there are functions to
> access the underlying message/segment, so you could run into situations
> where you've jumped to a whole other message silently.


Are there reasons that client code needs to use these functions? If not,
is there a way for you to hide them or mark them as internal-use-only?


> With mutable
> messages you can do the normal thing, but writing code that's generic
> over both of these gets really weird. At some point I ended up checking
> the schema that ship with capnproto, and with sandstorm, and discovered
> that, in >9000 lines of schema source, the feature was used exactly
> twice, both to set the default value of a text parameter to the empty
> string. So I just said "screw it, this is a waste of time." The plugin
> just prints a warning to stderr and ignores the custom default.
>

For what it's worth, I actually had someone request this feature last
month: https://github.com/capnproto/capnproto-rust/issues/127
I'm not sure what their use case is, though.


>
> I actually have a much longer critique that I think would be worth
> writing, including some things that aren't a problem for Haskell
> specifically, but cause problems for other languages -- and I am being
> bothered to go help with dinner, so I'll leave it at this for now.
>

I'd be eager to read the longer critique!


>
> -Ian
>
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/155918727572.10312.15632533580192568031%40localhost.localdomain
> .
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CABR6rW9oqepgz%2BvauR5vAAaqWce1NJQws9bqaS8y5iGDTFOc5g%40mail.gmail.com.

Reply via email to