> If you have a design approach that
simultaneously makes good use of functors,
> modules and signatures and makes OCaml's
type-to-display-selector happy, I'd be very interested in hearing
it.
Indeed, good use of functors,
modules and signatures doesn't come without type verbosity.
I have also faced it, it's a
real concern.
The Core user or library user has
to be tolerant, not every type can be called t, not every module can be
called M, modules have to include further modules, as a result type
paths become longer.
Plus functors add module
as parameters and as a result types become more
difficult to interpret.
Main part of the answer lies in accepting the cultural
shock.
More capable code libraries come with a steepier learning curve,
both as a user and as an implementer.
> To be clear, some of this
stuff can be made better by using signature functors, but that has its own
problems in terms of messiness and
> boilerplate.
Ocaml-Idaho signatures are done by composing
more elementary module types.
As a result the design is highly modular but
you end up with more boilerplate and type equalities.
However type equalities have a good reason,
they capture the context.
The context is more important than what the
actual type is.
May be the toplevel could be
more aware of opened modules then your example would be rendered as
:
# open
Option.Monad_infix;;
# Map.find m 3 >>| fun x ->
x + 1;;
- : int monad = Some
4
That would be much shorter without erasing type equalities.
- damien
PS:
As a module design example here
is an excerpt of the OCaml-Idaho UnbalancedMap
module, which has both a Mutable and a Pure version
implemented as recursive modules. On one hand it's pure boilerplate, on the
other hand it's just plain usage of ML modules.
module rec Mutable
:
functor (Ord: Interfaces.Ordered) ->
sig
include
Interfaces.MutableMap
with type key =
Ord.ordered
include
Interfaces.MutableKeySet
with type 'a
set = 'a map and type set_key = key
include
Interfaces.OrderedKeyFoldable
with type
'a foldable = 'a map and type fold_key = key
val
inserted: key -> 'a -> 'a map -> bool
val
root_inserted: key -> 'a -> 'a map -> bool
val
flatten_map: (key -> 'a -> 'a map) -> 'a map -> 'a
map
val to_pure: 'a map -> 'a
Pure(Ord).map
val to_pure_unsafe: 'a map -> 'a
Pure(Ord).map
end
=
functor (Ord:
Interfaces.Ordered) ->
struct
include BinaryTree_Keyed.Make(Ord)
module Order =
Ord
type 'a map = 'a tree
ref
type 'a foldable = 'a map and fold_key =
key
type ('a,'b) fold = (key -> 'a -> 'b ->
'b) -> 'b -> 'a map -> 'b
type 'a set = 'a
map
type set_key = key
type 'a
set_select = 'a select
...
end
and Pure
:
functor (Ord:
Interfaces.Ordered) ->
sig
include
Interfaces.PureMap
with type key =
Ord.ordered
include
Interfaces.PureKeySet
with type 'a set =
'a map and type set_key = key
include
Interfaces.OrderedKeyFoldable
with type
'a foldable = 'a map and type fold_key = key
val
root_add: key -> 'a -> 'a map -> 'a
map
val splay_add: key -> 'a -> 'a
map -> 'a map
val splay_lookup: key -> 'a map ->
'a map * 'a option
val splay_find: key ->
'a map -> 'a map * 'a
val flatten_map: (key -> 'a
-> 'a map) -> 'a map -> 'a map
val to_mutable: 'a
map -> 'a Mutable(Ord).map
val to_mutable_unsafe: 'a
map -> 'a Mutable(Ord).map
end
=
functor (Ord:
Interfaces.Ordered) ->
struct
include BinaryTree_Keyed.Make(Ord)
module Order =
Ord
type 'a map = 'a
tree
type 'a foldable = 'a map and fold_key =
key
type ('a,'b) fold = (key -> 'a -> 'b ->
'b) -> 'b -> 'a map -> 'b
type 'a set = 'a
map
type set_key = key
type 'a
set_select = 'a select
...
end
En réponse au message
de
: Yaron Minsky
du :
2009-10-09 18:52:40
À : Damien
Guichard
CC :
caml-list@yquem.inria.fr
Sujet : Re: [Caml-list]
Improving OCaml's choice of type to display
I do basically think of this as a deficiency in
the compiler as opposed to a deficiency in core (although it's hardly a major
deficiency in the compiler). Signatures, modules and functors are an
important part of the language, and if you want to use them in a significant
way, then you will end up having multiple paths to get to the same type.
OCaml's algorithm for choosing the type to display is somewhat unfortunate in
this regard.
If you have a design approach that simultaneously makes good
use of functors, modules and signatures and makes OCaml's
type-to-display-selector happy, I'd be very interested in hearing
it.
Finally, the specific point you make argues against the specific
heuristic (smallest type name) I proposed, but not against all other
heuristics. Another heuristic which I think has some potential is choosing
the type name with the smallest number of dots. (also, as a matter of
personal preference, in the case that you outline, I would prefer the answer of
"int" to "color", but that is just a coincidence, of course.)
To be
clear, some of this stuff can be made better by using signature functors, but
that has its own problems in terms of messiness and boilerplate. That
said, I have half a mind to write a syntax extension to clean that up, and
switch over to signature functors, for this and other reasons. That said,
signature functors only clean up a little bit of the problem.
y
On
Fri, Oct 9, 2009 at 10:18 AM, Damien Guichard <alphablock@orange.fr>
wrote:
Hi
Yaron,
I think you better think twice about the
problem in general (rather than the particular needs of Core) before proposing
some controversial type display improvement.
Imagine my code is:
type color = int
let black :
color = 0
Then, following your proposition, evaluating
black should give me an int rather than a color
because int is shorter and therefore nicer.
So, now, what's the point in the color
type declaration ?
There is none, type aliasing becomes useless because you can't expose it.
Call me crazy but i whish i can use more
than 3 characters as a type name.
So you want it to be displayed as
an Int.t rather than an Int.comparable ?
Then just declare it as Int.t rather
than Int.comparable, or choose another shorter name, it's not an
OCaml issue, its' a Core issue.
(obviously it would really help if no english
word would be more than 6 characters but Ocaml can't be blamed for
that)
I mean, when designing an
elaborate software library, you have to make choices, and often, no
matter how good OCaml is, some choices will be compromises. You have to
pick the lesser between several evils and live with it.
I have learned that when programming Ocaml-Idaho, suddenly module names become longer, module
types become more composited, data types become more subtle, and so on and so
on...
Blaming OCaml is a too easy path.
At one certain point you have to face
the verbosity you have created and decide whether the additionnal
expressivity worths the price.
If you think it does then it's ok, if not then
just amend, if amending doesn't help then consider refactoring.
Seek the best expressiveness/verbosity ratio
without sacrifying too much functionality.
That's your job as a library
designer.
-
damien
En réponse au message
de
: Yaron Minsky
du :
2009-10-09 11:58:11
À : Andrej
Bauer
Sujet : Re: [Caml-list] Improving
OCaml's choice of type to display
Well, if we're picking heuristics, the fewest
number of characters wouldn't be crazy either. Given the choice between
Int.t and Int.comparable (which are aliases for the same type), I'd prefer to
see Int.t.
y
On Fri, Oct 9, 2009 at 3:33 AM, Andrej Bauer
<andrej.bauer@andrej.com> wrote:
On
Fri, Oct 9, 2009 at 3:40 AM, Yaron Minsky <yminsky@gmail.com>
wrote:
> Choosing shorter names.
By which you probably mean
"the fewest number of dots (module
projections)". It might be a bit
annoying if the code that prints
doesn't know what modules are open. What
do the INRIA priests say?
Andrej
_______________________________________________
Caml-list
mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives:
http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug
reports: http://caml.inria.fr/bin/caml-bugs