On Wed, May 29, 2019 at 8:38 PM Ian Denhardt <i...@zenhack.net> wrote:

> The biggest one is nested namespaces, per discussion.


If it's any consolation, even though C++ has nested namespaces, the code
doesn't end up any less verbose. When you're using the declarations from a
capnp file in C++ code, you either need to write out the declaration's full
path wherever it is used, or you need to declare a shorter alias and use
that. That is to say, I don't think there's much practical difference
between "Foo::Bar::Baz" vs. "Foo_Bar_Baz" or "Foo'Bar'Baz" -- in fact, the
latter two are technically shorter.

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.
>

Actual line of code from Cloudflare Workers:

    case PipelineDef::Stage::Worker::Global::Value::JSON:

So again, I'm not sure this is a problem specific to certain languages. :)


> 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.
>

Hmm. It's unfortunate that this means that if someone adds a non-union
field to a struct that previously contained only a union, Haskell code
using the protocol will break and probably need major rewrites.

But I do see why you'd want to use the language's built-in variant types if
at all possible.

FWIW I feel this is a fundamental flaw in variant types as seen in most
functional languages: if you ever discover there's some field that is
needed by *all* the variants, you can't add it without completely changing
the type and updating every use site.

More generally, I feel like Haskell made many design choices that make code
concise and beautiful but difficult to change and evolve. :/


> 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.


FWIW C++ does this too. The type name is formed by capitalizing the first
letter of the field name.


> I intentionally decided to just not support custom default values for
> pointer fields;


I admit that, in practice, I've never had a serious need for default values
for pointer fields. They probably were not worth the implementation
complexity.

And, admittedly, I knew that they were unlikely to be used much when I
designed the language.

My main motivation was just that it feels inconsistent to allow defaults
only for primitives but not for pointers. And default values for primitives
are used all the time.

But perhaps I should have been more practical here.


> 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.
>

Looking forward to more feedback.

-Kenton

-- 
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 capnproto+unsubscr...@googlegroups.com.
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/CAJouXQ%3DZ4Nm-buWs4RUq%3DN0rFOgZe9tjowiihz7j6iXvpNeH%2BQ%40mail.gmail.com.

Reply via email to