caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Stdlib regularity
@ 1999-10-06 13:25 Ohad Rodeh
  1999-10-06 16:18 ` Markus Mottl
                   ` (3 more replies)
  0 siblings, 4 replies; 43+ messages in thread
From: Ohad Rodeh @ 1999-10-06 13:25 UTC (permalink / raw)
  To: caml-list

Caml list,
  I have used OCaml extensively in the past few years, and I've had
some misgivings about the CAML standard library argument ordering. It
is a little bit confusing and not standard. For example:

	  val Queue.add: 'a -> 'a t -> unit 
	  val Hashtbl.add: ('a,'b) t -> 'a -> 'b -> unit

My general suggestion is to always make the first argument the <'a t>
type and the second the <'a> type. The only exception to this rule
should be functionals, for example, in Queue:

	 val iter: ('a -> unit) -> 'a t -> unit

I've summed up the proposed changes in an order of importance, please
remember that this is suggestion based on my personal taste alone. 

The changes I'm most interested are:
Module Queue: 
  switch:   val add: 'a -> 'a t -> unit 
  to:       val add: 'a t -> 'a -> unit 

Module Stack: 
  switch: val push: 'a -> 'a t -> unit
  to:     val push: 'a t -> 'a -> unit

Module Stream: 
  switch: npeek : int -> 'a t -> 'a list;;
  to:     npeek : 'a t -> int -> 'a list;;

This make the data-structure modules (Hashtbl,Queue,Stack,Stream) behave 
the same. 

If this is possible, I'd like this to apply to the Map and Set
modules. For module Map, this is the current signature:

module type OrderedType =
  sig
    type t
    val compare: t -> t -> int
  end

module type S = 
  sig
    type key

    type 'a t

    val empty: 'a t

    val add: key -> 'a -> 'a t -> 'a t

    val find: key -> 'a t -> 'a

    val remove: key -> 'a t -> 'a t

    val mem:  key -> 'a t -> bool

    val iter: (key -> 'a -> unit) -> 'a t -> unit

    val map: ('a -> 'b) -> 'a t -> 'b t

    val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b

   end

  end
module Make(Ord: OrderedType): (S with type key = Ord.t)


I'd rather make it: 

module type S = 
  sig
    type key

    type 'a t

    val empty: 'a t

    val add: 'a t -> key -> 'a -> 'a t

    val find: 'a t -> key -> 'a

    val remove: 'a t -> key -> 'a t

    val mem:  'a t -> key -> bool

    val iter: (key -> 'a -> unit) -> 'a t -> unit

    val map: ('a -> 'b) -> 'a t -> 'b t

    val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b

   end




For module Set, this is the current signature:


module type OrderedType =
  sig
    type t
    val compare: t -> t -> int
  end

module type S =
  sig
    type elt

    type t

    val empty: t

    val is_empty: t -> bool

    val mem: elt -> t -> bool

    val add: elt -> t -> t

    val singleton: elt -> t

    val remove: elt -> t -> t

    val union: t -> t -> t
    val inter: t -> t -> t
    val diff: t -> t -> t

    val compare: t -> t -> int

    val equal: t -> t -> bool

    val subset: t -> t -> bool

    val iter: (elt -> unit) -> t -> unit

    val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a

    val cardinal: t -> int

    val elements: t -> elt list

    val min_elt: t -> elt

    val max_elt: t -> elt

    val choose: t -> elt

  end
module Make(Ord: OrderedType): (S with type elt = Ord.t)


Id rather switch S to: 
module type S =
  sig
    type elt

    type t

    val empty: t

    val is_empty: t -> bool

    val mem: t -> elt -> bool

    val add: t -> elt -> t

    val singleton: elt -> t

    val remove: t -> elt -> t

    val union: t -> t -> t
    val inter: t -> t -> t
    val diff: t -> t -> t

    val compare: t -> t -> int

    val equal: t -> t -> bool

    val subset: t -> t -> bool

    val iter: (elt -> unit) -> t -> unit

    val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a

    val cardinal: t -> int

    val elements: t -> elt list

    val min_elt: t -> elt

    val max_elt: t -> elt

    val choose: t -> elt

  end


Module List has some of the same functions (mem,remove), so my
suggestion is: 

switch: 
	val mem : 'a -> 'a list -> bool
	val memq : 'a -> 'a list -> bool
to:
	val mem : 'a list -> 'a -> bool
	val memq : 'a list -> 'a -> bool


switch: 
	val assoc : 'a -> ('a * 'b) list -> 'b
	val assq : 'a -> ('a * 'b) list -> 'b
	val mem_assoc : 'a -> ('a * 'b) list -> bool
	val mem_assq : 'a -> ('a * 'b) list -> bool
	val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list
	val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list

to: 
        val assoc : ('a * 'b) list -> 'a -> 'b
	val assq : ('a * 'b) list -> 'a-> 'b
	val mem_assoc : ('a * 'b) list -> 'a -> bool
	val mem_assq : ('a * 'b) list -> 'a-> bool
	val remove_assoc : ('a * 'b) list -> 'a -> ('a * 'b) list
	val remove_assq : ('a * 'b) list -> 'a -> ('a * 'b) list

The more important changes are the first minor 3, the rest are
optional. What do you think? 

	Ohad.




^ permalink raw reply	[flat|nested] 43+ messages in thread
* Re: Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-10 18:52 Vyskocil Vladimir
  0 siblings, 0 replies; 43+ messages in thread
From: Vyskocil Vladimir @ 1999-10-10 18:52 UTC (permalink / raw)
  To: caml-list



>I would like to propose adding a new special type to ocaml,
>a categorical initial type. This type is the categorical dual
>of the categorical terminal type, unit. 


I ask for this some time ago, but it was said that "it's not a good thing"...

Vladimir.




^ permalink raw reply	[flat|nested] 43+ messages in thread
* Re:  Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-12 15:33 Damien Doligez
  0 siblings, 0 replies; 43+ messages in thread
From: Damien Doligez @ 1999-10-12 15:33 UTC (permalink / raw)
  To: caml-list

>From: skaller <skaller@maxtal.com.au>

>There proposal is for a syntactic designator (say '$') for the
>non-existant value of the initial type, which can
>be bound to a variable of any type.
>[You could say it has type 'a, as does 'raise SomeException']
>
>The effect of attempting to read this value from any type
>should be to raise the exception Uninitialised_value.

You could try to use "lazy (raise Uninitialised_value)", of type
'a lazy, with the advantage that the notion of "reading this value"
becomes clearly defined (it is using "force" on the value).


>A better name than $ is probably 'none'.
>Boxed values can use a null pointer for none.

OK.


>Integers and floats can be treated as follows:
>do not initialise them at all, if -unsafe is 
>specified. Otherwise, use the spare value of integers

What spare value ?


>and some NaN for floats,

This may or may not be possible, depending on the details of the IEEE
specification.


>Chars can be handled too, but it is probably not worth the
>effort until they are lifted to ISO10646, which has
>suitable code points available. [We could use 0xFF for
>8 bit chars]

No.  0xFF is already used, as well as the other 255 values.


-- Damien




^ permalink raw reply	[flat|nested] 43+ messages in thread
* Re: Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-12 15:44 Damien Doligez
  0 siblings, 0 replies; 43+ messages in thread
From: Damien Doligez @ 1999-10-12 15:44 UTC (permalink / raw)
  To: caml-list

>From: John Prevost <prevost@maya.com>

>val Array.make_with_option (or something) : unit -> 'a option array
>
>which in some sort of "unsafe" mode doesn't actually initialize the
>array and guarantee that all values are well-formed.

That would break the invariants of the memory manager.

-- Damien




^ permalink raw reply	[flat|nested] 43+ messages in thread
* RE: Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-13 16:42 Manuel Fahndrich
  1999-10-14 22:43 ` skaller
  0 siblings, 1 reply; 43+ messages in thread
From: Manuel Fahndrich @ 1999-10-13 16:42 UTC (permalink / raw)
  To: caml-list


skaller wrote:

	[...]

	> Like I've been saying, with option you can turn it off, with
Obj.magic, the
	> implementor ought to be damned sure he's doing things right.  But
with
	> these special "uninitialized value" sorts of things, people like
me
	> who've gotten used to good type systems keep looking over their
	> shoulders because they're afraid it might turn around and bite
them in
	> the butt.

		How is this different from Obj.magic? Can't that bite you
	in the ass too?

The difference is that in the first case of uninitialized values, they can
crop up anywhere in your program, since they get propagated. Using Obj.magic
within a special module such as resizable arrays confines the danger to that
module. The programmer can make sure (through extensive code reviews of a
finite piece of code) that outside the module, things cannot go awry.

-Manuel




^ permalink raw reply	[flat|nested] 43+ messages in thread
* RE: Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-14 23:16 Manuel Fahndrich
  1999-10-17  9:18 ` skaller
  0 siblings, 1 reply; 43+ messages in thread
From: Manuel Fahndrich @ 1999-10-14 23:16 UTC (permalink / raw)
  To: 'skaller'; +Cc: caml-list


I did not word what I meant correctly. In the case of initial values, errors
can occur anywhere in the code, namely, whenever I access an uninitialized
value. Since these values can live in records, and the records can be passed
around, the error can occur anywhere.

Now, with a well-defined and encapsulated use of Obj.magic, such errors can
be avoided. E.g. in the extensible array case, I can write the module in
such a way that no matter what code I write outside of that module (not
using Obj.magic), it cannot result in an error.

-Manuel


-----Original Message-----
From: skaller [mailto:skaller@maxtal.com.au]
Sent: Thursday, October 14, 1999 3:44 PM
To: Manuel Fahndrich
Cc: caml-list@inria.fr
Subject: Re: Proposal for study: Add a categorical Initial type to ocaml


Manuel Fahndrich wrote:
> 
> skaller wrote:
> 
>         [...]
> 
>         > Like I've been saying, with option you can turn it off, with
> Obj.magic, the implementor ought to be damned sure he's doing things
right.  
> But with these special "uninitialized value" sorts of things, people like
> me who've gotten used to good type systems keep looking over their
> shoulders because they're afraid it might turn around and bite
> them in the butt.
> 
>>                 How is this different from Obj.magic? Can't that bite you
>>         in the ass too?
> 
>>> The difference is that in the first case of uninitialized values, they
can
>>> crop up anywhere in your program, since they get propagated. Using
Obj.magic
>>> within a special module such as resizable arrays confines the danger to
that
>>> module. The programmer can make sure (through extensive code reviews of
a
>>> finite piece of code) that outside the module, things cannot go awry.

	No. It is the other way around. Obj.magic values can get
propagated, and so cause a problem. The special initial can NOT
be propagated. Any attempt to copy such a value raises an exception.
Ensuing this does not happen is also a matter of hiding within
a modular abstraction, but at least an exception will help
detect such localised errors.

-- 
John Skaller, mailto:skaller@maxtal.com.au
1/10 Toxteth Rd Glebe NSW 2037 Australia
homepage: http://www.maxtal.com.au/~skaller
downloads: http://www.triode.net.au/~skaller




^ permalink raw reply	[flat|nested] 43+ messages in thread
* RE: Proposal for study: Add a categorical Initial type to ocaml
@ 1999-10-18 16:48 Manuel Fahndrich
  0 siblings, 0 replies; 43+ messages in thread
From: Manuel Fahndrich @ 1999-10-18 16:48 UTC (permalink / raw)
  To: 'skaller'; +Cc: caml-list


I was comparing using Obj.magic in the particular case of writing an
extensible array module vs. adding uninitialized values to the language.

In the second case, having uninitialized values as a language feature will
make code more brittle since the uninitialized exception may be raised
anywhere in the code where a field access is made.

In the first case, the module can be constructed such that the use of
Obj.Magic can be deemed safe, namely by requiring all accesses of extensible
arrays to go through the module and that appropriate checks are in place
there.

-Manuel


-----Original Message-----
From: skaller [mailto:skaller@maxtal.com.au]
Sent: Sunday, October 17, 1999 2:19 AM
To: Manuel Fahndrich
Cc: caml-list@inria.fr
Subject: Re: Proposal for study: Add a categorical Initial type to ocaml


Manuel Fahndrich wrote:
> 
> I did not word what I meant correctly. 

	i thought you did OK ..

>In the case of initial values, errors
> can occur anywhere in the code, namely, whenever I access an uninitialized
> value. Since these values can live in records, and the records can be
passed
> around, the error can occur anywhere.
> 
> Now, with a well-defined and encapsulated use of Obj.magic, such errors
can
> be avoided. E.g. in the extensible array case, I can write the module in
> such a way that no matter what code I write outside of that module (not
> using Obj.magic), it cannot result in an error.

	I'm sorry. I do do not follow. You argument is comparative,
and appears unsound because it fails to make a distinction.
The magical encapsulation of Obj.magic within a module
or class, can be applied to initials just the same: maintaining
the invariant 'uninitialised values are initialised before use'
is the same in both cases, only the value representing it differs.
Where 'initial' might be used, obj.magic could be used too.
References to both may be propagated without error
(and indeed that is the whole point): the only difference
is that using an initial value is guarranteed to cause
an exception to be raised, whereas using a magical
value offers no guarrantees, and could core dump.

	The initial value is therefore easier
to debug. The other difference seems to be that it
is polymorphic whereas obj.magic needs explicit
casting.
 
-- 
John Skaller, mailto:skaller@maxtal.com.au
1/10 Toxteth Rd Glebe NSW 2037 Australia
homepage: http://www.maxtal.com.au/~skaller
downloads: http://www.triode.net.au/~skaller




^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~1999-10-19 17:25 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-10-06 13:25 Stdlib regularity Ohad Rodeh
1999-10-06 16:18 ` Markus Mottl
1999-10-08 14:06   ` Matías Giovannini
1999-10-10 20:09     ` Pierre Weis
1999-10-10 20:12       ` Matías Giovannini
1999-10-08 14:10   ` skaller
1999-10-08 19:21     ` Markus Mottl
1999-10-09 21:14     ` Dave Mason
1999-10-06 18:50 ` John Prevost
1999-10-07  7:33 ` skaller
1999-10-07  9:18 ` Francisco Valverde Albacete
1999-10-08 14:56   ` skaller
1999-10-09 22:26     ` Francois Rouaix
1999-10-10  5:38       ` skaller
1999-10-10 20:44         ` William Chesters
1999-10-10 21:43           ` Hongwei Xi
1999-10-11  0:36           ` skaller
1999-10-12  7:20             ` David Mentr{'e}
1999-10-08 16:38   ` Proposal for study: Add a categorical Initial type to ocaml skaller
1999-10-09 22:43     ` John Prevost
1999-10-10  3:18       ` chet
1999-10-10  6:14       ` skaller
1999-10-10 21:05         ` William Chesters
1999-10-10 22:36           ` chet
1999-10-10 22:38           ` chet
1999-10-11 19:30             ` John Prevost
1999-10-12  8:34             ` Option types and O'Labl merger Jacques Garrigue
1999-10-12 14:38               ` William Chesters
1999-10-13  5:35                 ` Frank A. Christoph
1999-10-13  8:48                   ` Jacques Garrigue
1999-10-11  0:51           ` Proposal for study: Add a categorical Initial type to ocaml skaller
1999-10-11 12:40         ` John Prevost
1999-10-12 19:20           ` skaller
1999-10-12 11:33         ` Jean-Francois Monin
1999-10-10 16:10       ` chet
1999-10-10 18:52 Vyskocil Vladimir
1999-10-12 15:33 Damien Doligez
1999-10-12 15:44 Damien Doligez
1999-10-13 16:42 Manuel Fahndrich
1999-10-14 22:43 ` skaller
1999-10-14 23:16 Manuel Fahndrich
1999-10-17  9:18 ` skaller
1999-10-18 16:48 Manuel Fahndrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).