Hey Ian,
Thanks for the feedback. This is really helpful.
* Haskell vs C++
I'll think on this one. I might want to just implement this in C++ for personal
learning. I don't think there's a clearly optimal call here.
* Single vs Multi-module export.
This is really helpful. I hadn't thought deeply about cyclic messages. I'll
almost certainly build a single file export. One reason that I really like
single file per struct is that it respects how the language would build this
data. This means that for a user of the language, there's less cognitive
dissonance when using Capnp.Foo.Bar.getPerson than when using
Capnp.foo_bar_getPerson. The former fits into the model of the language uses,
the latter does not.
That said, there's a somewhat complex way that I *could* resolve this.
Arbitrarily pick one to make it polymorphic:
module A.Base
type A_Base a = A_Base a
module B
type B = B A
module A
import A.Base
import B
type A = A.Base.A_Base B
I doubt it's truly worth the complexity, but it is possible.
* Not supporting every feature/Optimize for well written schema
Very interesting point. I'm not generally good at making those sorts of
concessions, but I probably should do that more often. I'll think about where I
can relax some of the requirements to allow a better API. If you have a
suggestion on any place in the API, let me know.
* 64-bit ints/Numeric library
Yup, I’m aware. It's not particularly fun code to write (I find it boring at
least), but I think I'll have to build it either way.
* Warning for interfaces
I agree that it's probably not necessary, but given that I'll be checking
pointer type anyway, I can log this with a simple `Debug.log` statement. I just
don't feel comfortable swallowing information like that. Also, if someone
doesn't want the message, they can just not send a capability over the network.
* Traversal Limit
So I forgot to add a field to the struct data type. It was missing a
`traversalLimit` field. This field is set on a call to `Capnp.init`. Once it's
set, we keep track of the traversal depth by incrementing the
`currentTraversalDistance` field. If a call to `Capnp.get` or similar function
ever encounters a situation where `currentTraversalDistance > traversalLimit`,
we return `Err TraversalLimitExceeded`. If they succeed, the function returns
an `Ok` with the `currentTraversalDistance` updated.
One thing that isn't very clear to me is whether this is a limit per call to
`Capnp.get` or a limit per message (you can only traverse 64 Mib in depth
before you give up). I've interpreted this as the latter for this
implementation. The former is almost trivial to implement within the `get`
itself.
* Underscores in names
Sounds good. I really wish I could find a BNF notation for these things...
Thanks again for the advice. I'll probably get hacking sometimes this weekend
and see where this goes.
-- Prasanth
-----Original Message-----
From: Ian Denhardt <[email protected]>
Sent: Wednesday, May 29, 2019 1:14 PM
To: prasanth somasundar <[email protected]>
Subject: Re: [capnproto] Cap'n Proto for Elm
Neat. Some feedback:
* Re: why not the Haskell implementation, it's definitely stable enough
and complete enough to write a compiler plugin. At the serialization
layer there are only a couple things missing, and they shouldn't be a
problem for this use case. I would say don't like the stability
disclaimers in the README scare you away (note: I am the author of the
Haskell implementation).
You may even be able to cannibalize parts of the Haskell code
generator itself; especially the first bits of the translation process
would look very similar if I were writing an elm backend. Feel free to
pick my brain about it if you try to do this.
* Re: Single module vs. Splitting things up for namespacing, note that
Elm does not allow cyclic dependencies between modules, so this
probably just won't work, since you can have cycles within a single
capnp schema.
Also, from having had the same initial instinct with the Haskell
implementation (where it is possible to break cycles with .hs-boot
files), I will say that I found the massive pile of imports wasn't any
better than Long_Names_With_Underscores -- especially since you still
have to distinguish identifiers at call sites, so you don't even save
much typing outside of the imports. From an implementer's perspective
it was also much simpler to do it in one file.
I ultimately ended up going with the one-module-per-capnp-file
approach, and my usual advice re: long names is to tell people to just
not use nested namespaces in their schema file. It's always possible
to change a schema to avoid these in a wire-compatible way.
* More generally, if you try to make *every* feature of the schema
language map to Elm in an ergonomic way, you will be in for a rough
time. I suggest optimizing for "well-written" schema, and making peace
with the fact that certain constructs may generate unpleasant APIs.
This applies especially if the user can easily just avoid those
features.
* Re: built-in types, note that in addition to run-time checks, you will
also have to do some special logic for 64-bit arithmetic, since Elm
uses JavaScript's numbers internally, which are double-precision
floating point, and thus can only faithfully represent integers up to
53 bits.
* Re: interfaces, producing a warning strikes me probably unnecessary;
if the library clearly marked serialization-only, users will not
expect it to pay attention to interfaces.
* It's not entirely clear to me how you plan to implement the traversal
limit with the API you've described.
* Note that as of 0.19 Elm no longer allows single quotes in
identifiers, so you'll need to do something else for union names.
Fortunately, underscores are also illegal in capnp names, but legal in
Elm.
Hope this is helpful. I'll keep an eye on this; interested to see where it goes.
-Ian
Quoting prasanth somasundar (2019-05-29 05:00:46)
> Hey Everyone,
>
> I'm thinking about building out a Cap'n Proto implementation in Elm for
> the fun of it. Thought I'd send an email to this list as suggested and
> get some feedback on [1]the initial design which I've also linked
> below. Any thoughts, comments, or concerns are appreciated.
>
>
> --Prasanth
>
>
> Another link to the doc in case you missed it:
> https://docs.google.com/document/d/12qMVyQPOWTXviFKIpjKLXgusKZ95miuRmu9
> AxacyGOA/edit?usp=sharing
>
>
> --
> 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 [2][email protected].
> Visit this group at [3]https://groups.google.com/group/capnproto.
> To view this discussion on the web visit
> [4]https://groups.google.com/d/msgid/capnproto/BYAPR11MB259933537902814
> B8C0041F4C51F0%40BYAPR11MB2599.namprd11.prod.outlook.com.
>
> Verweise
>
> 1.
> https://docs.google.com/document/d/12qMVyQPOWTXviFKIpjKLXgusKZ95miuRmu9AxacyGOA/edit?usp=sharing
> 2. mailto:[email protected]
> 3. https://groups.google.com/group/capnproto
> 4.
> https://groups.google.com/d/msgid/capnproto/BYAPR11MB259933537902814B8
> C0041F4C51F0%40BYAPR11MB2599.namprd11.prod.outlook.com?utm_medium=emai
> l&utm_source=footer
--
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/BYAPR11MB2599AC9F88481FB7C30102E4C5180%40BYAPR11MB2599.namprd11.prod.outlook.com.