> 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
