> I must say I like your approach very much, however in some cases having 21
methods allows the user to write the code in a more declarative fashion  for
example "subscribe sock ..." vs "setsockopt sock subscribe ..." or "has_more
sock" vs "getsockopt sock rcvmore".]

I think the key insight here is that the client may always reconfigure the
functions to his or her preference by simple declarations such as:

let subscribe sock = setsockopt sock subscribe.

However, the reverse is not as simple.  My principle was to introduce as few
alterations to the original API as possible.

> Well using Uint keeps the user from passing negative arguments plus respects
the type of the original options so I thought it was necessary. Why do you
think it is unnecessary?

Ocaml's implementation of the Int64 type explicitly allocates 64 bits, so
that an Int64 can denote any unsigned integer value and more.  Testing for
negative integers is accomplished via the set_uint64 function, which will
raise an exception for negative integer values.

> Besides the previous diferences there is another one between the two bindings:
ocaml-zmq uses phantom types to prevent the user from calling subscribe,
unsubscribe and create devices with the wrong kind of socket, while Caravan
just allows that to happen.

Caravan uses phantom types to represent sockets, contexts, and generic
socket options.  I think you are here only describing the socket option type
so I will address that.  The phantom socket option is a pair of getter and
setter functions, whose polymorphic types are matched with the polymorphic
type of the declared socket option.  Thus, an int socket_option has a getter
that returns an int and a setter that takes an int.  The getsockopt and
setsockopt essentially project the first or second of the pair to utilize
the appropriate function.  This is all black-boxed behind the phantom type,
and no client can declare new socket options.

This allows a dispatch pattern, wherein I can carefully use the unsafe
external declarations for C's getsockopt and setsockopt.  In the case of
such methods that do not have a getter or a setter, I simply dispatch to a
function which raises an exception if anybody should try such a thing.  It
had actually not occurred to me to protect the user from exceptions which
ZMQ already accounts for, but if I had such an intention, I could dispatch
any such getter or setter function to an appropriate check-function.  This
is done, for instance, if someone tries to getsockopt a subscribe or
unsubscribe.  They are dispatched to a function which immediately raises an
exception.


I went through many iterations of the language interface for getsockopt and
setsockopt; work which shed light upon some of the practical short-comings
of the strict type system.  This interface, I feel, is the best possible
design for OCaml and the ZMQ API, and may even set a good example for other
functional implementations.  Issues raised by Guillaume show that my system
programming is shaky at best, and will require revision in the Git if it is
to mature into a serious project.  I would ask whether I should fork
OCaml-ZMQ to fix the API, or if OCaml-ZMQ should fork Caravan to fix the
system.

In answer, I would argue that Caravan is more tightly coupled to the ZMQ
API, and that system revisions are largely a matter of small rewrites inside
the C stubs.  On the other hand, OCaml-ZMQ would have to integrate the
entire exception mechanism, and would not achieve the granularity of the
Caravan error descriptions without refactoring the multiple getsockopt and
setsockopt functions.  Further, refactoring the language interface for
OCaml-ZMQ is non-trivial and compromises a great deal of code in the
project.  Returning the project to a stable build could take up a great deal
of developer time, and is unpleasant at best.  Finally, decoupling OCaml-ZMQ
from the UInt libraries is time consuming, but utterly necessary for the
health of the project.

I hope you trust that I gave this problem a good deal of thought before
proceeding to rebuild this library from scratch.  If it had been more
efficient to revise the OCaml-ZMQ code, then I would have saved myself the
trouble of all this investigation.  I hope all interested parties will weigh
in on this.

-- 
Brian Ledger
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to