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.

Reply via email to