functoria icon indicating copy to clipboard operation
functoria copied to clipboard

Make typ abstract

Open yallop opened this issue 10 years ago • 3 comments

Overall, I think the Functoria API looks very good: clean, well-designed and well-documented. For the moment, I have just one request: I'd prefer to see typ as an abstract type (and perhaps one or two other things made more abstract). At the moment typ is exposed like this

type _ typ =
  | Type    : 'a -> 'a typ
  | Function: 'b typ * 'c typ -> ('b -> 'c) typ

and typically used like this:

type io_page = IO_PAGE
let io_page = Type IO_PAGE

The current approach has two drawbacks:

  • First, there's no constraint on the argument to Type.
    As a result, it's possible to inadvertently pass the wrong thing -- e.g. to use the same argument twice. In fact, it seems like the argument isn't actually used, so removing it from the interface would make the interface more coherent.
  • Second, since the concrete type is exposed, it's going to be hard to change things later in a backwards-compatible way.
    It's conceivable that a Type may one day carry more information, but it's going to be hard to attach more information without changing the current interface.

There are already typ and @-> functions in the interface that correspond to the two constructors, so it's already more or less possible to hide the type definition. However, typ suffers from the first drawback above: you can pass anything at all to it. It'd be useful to have the interface guarantee that each type is distinct from all others, with an interface like this:

module type TYPE = sig
  type t
  val t : t typ
end
val typ : (module TYPE)

which could be used like this:

module Io_page = (val typ)
let io_page = Io_page.t  (* optional; could just use Io_page.t directly *)

This approach addresses both problems: first, it guarantees that the generated types are distinct; second, since the details of the type are hidden it's possible to add more to the type later without breaking backwards compatibility.

yallop avatar Nov 03 '15 15:11 yallop

How do you implement the ip/udp interface with the v4/v6 parameter when typ is not covariant and you don't use the constructor directly. This is why it's exposed, to be able to have fully polymorphic parameter while the type is not covariant.

I agree with you. My initial idea was to hide it.

Drup avatar Nov 03 '15 15:11 Drup

@yallop Do you have an idea for the issue I mentioned ?

Drup avatar Nov 21 '15 17:11 Drup

I think it's possible to attack this by making some changes to ip and udp to make that particular problem go away. If that's the only blocker, it might be possible to then make typ abstract, as I think we haven't added anything else that needs it to be exposed.

yomimono avatar Nov 05 '16 01:11 yomimono