caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Re: Syntax for label
@ 2000-03-14 16:53 Don Syme
  2000-03-14 18:05 ` Pierre Weis
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
  0 siblings, 2 replies; 60+ messages in thread
From: Don Syme @ 2000-03-14 16:53 UTC (permalink / raw)
  To: 'caml-list@inria.fr'

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1358 bytes --]



And why not "as", i.e. "t as x", as I explained once in a previous post.
I never did get an explanation as to why this wasn't an better solution.  It
reuses a rarely-used keyword in a perfectly backward-compatible way.  
I think it's simply a typical case of a new (and not necessarily terribly 
crucial) language feature muscling in on the limited "ultra-convenient" 
concrete syntax that's available!   No offence intended ;-)

Cheers,
Don


-----Original Message-----
From: Christophe Raffalli [mailto:Christophe.Raffalli@univ-savoie.fr]
Sent: 10 March 2000 18:45
To: caml-redistribution@pauillac.inria.fr
Subject: Syntax for label



It is clear that labels are a good thing ...

But why did you use the same character ":" for types and labels !

whit not (for instance) x:t to say that x as type t
and                     l#x to say that x as label l

the syntax l#x:t is much better than l:x : t !!

I know that # is allready used for methods ... but some characters are
still usable:

~
£ it looks like the l of labels (but its ascii code is greater than 128,
but is this really a problem ? probably ?)

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Syntax for label
  2000-03-14 16:53 Syntax for label Don Syme
@ 2000-03-14 18:05 ` Pierre Weis
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
  1 sibling, 0 replies; 60+ messages in thread
From: Pierre Weis @ 2000-03-14 18:05 UTC (permalink / raw)
  To: Don Syme; +Cc: caml-list

> And why not "as", i.e. "t as x", as I explained once in a previous post.
> I never did get an explanation as to why this wasn't an better solution.  It
> reuses a rarely-used keyword in a perfectly backward-compatible way.  

This is not backward-compatible since ident1 as ident2 is a special
case of pattern as ident. Hence ident1 as ident2 already has a
meaning in Caml: it means that you want to write ident2 as an alias
for ident1.

Best regards,

-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-14 16:53 Syntax for label Don Syme
  2000-03-14 18:05 ` Pierre Weis
@ 2000-03-15  3:15 ` Jacques Garrigue
  2000-03-15  6:58   ` Christophe Raffalli
                     ` (3 more replies)
  1 sibling, 4 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-15  3:15 UTC (permalink / raw)
  To: dsyme, Christophe.Raffalli; +Cc: caml-list

I include a proposal at the end, please comment if you feel concerned.

From: Don Syme <dsyme@microsoft.com>

> And why not "as", i.e. "t as x", as I explained once in a previous post.
> I never did get an explanation as to why this wasn't an better solution.  It
> reuses a rarely-used keyword in a perfectly backward-compatible way.  
> I think it's simply a typical case of a new (and not necessarily terribly 
> crucial) language feature muscling in on the limited "ultra-convenient" 
> concrete syntax that's available!   No offence intended ;-)

An none taken.

Seriously, I believe the decision for the syntax of labels has be done
on a number of bases, including ideas collected on the caml list (sorry
if we didn't give feedback for every proposition).

Basically the strongest criteria were

1) comfort. Call it crucial or not, in typical modern mode code you
   have several labels by line of code. Anything more than one
   character is going to be heavy. Remember that ML is this wonderful
   language in which application is expressed by 0 characters!

2) inertia. Objective Label has been around for several years already
   (in fact, just as long as Objective Caml), and users seemed to be
   satisfied with the syntax.

3) homogeneity. The only change has been in the syntax for default
   parameters, which is a bit more homogeneous now. The idea was from John
   Prevost.

From: Christophe Raffalli [mailto:Christophe.Raffalli@univ-savoie.fr]
> It is clear that labels are a good thing ...
> But why did you use the same character ":" for types and labels !
> 
> whit not (for instance) x:t to say that x as type t
> and                     l#x to say that x as label l


Our conclusion on that point was that spaces are significant, and
there is no real ambiguity. You have to put spaces around : in type
annotations.

Also, the superficial similarity is in fact good in some cases:

	val sub : string -> pos:int -> len:int -> string

Argument types here "look like" type annotations.

> the syntax l#x:t is much better than l:x : t !!

Well, you do not write the above directly. Here are real cases:

(t type of the result)
	let f l#x:t = ...
	let f l:x : t = ...
(t type of the argument)
	let f (l#x:t) = ...
	let f (l: x : t) = ...

Do you really think that not putting spaces enhances readability?
And that once you have put the spaces, it is still hard to read?

If you do, then it might mean that our choice was wrong.

*** Proposal

Objective Caml 3.00 is not yet released, and I believe we can still
have modifications on this point.

Here is an alternative proposal, to use `%' in place of `:'. Labels
are kept as a lexical entity. This still breaks some programs, since
`%' was registered as infix, but this is not so bad.

In this case, I suppose we should read `%' as `is'.

Pro:
* `%' reminds a bit of substitution, which is the intuitive role of
  labels in applications.
* I checked it on a reasonable corpus of code, and it is
  readable enough. Particularly -shumacher-clean-* looks nice.
* changes to the compiler are very small.

Con:
* I still think that `:' looks better, particularly inside types.
* On my keyboard I can type in `:' without pressing shift :-)
* We will need some tool to convert existing code.

Do you think it would be better?
Are there people around who would rather keep `:' ?

Examples:

        Objective Caml version 2.99+10

# List.map;;
- : fun%('a -> 'b) -> 'a list -> 'b list = <fun>
# List.map [1;2;3] fun%succ;;
- : int list = [2; 3; 4]
# let sub ?(%pos = 0) ?%len s =
    let len = match len with Some x -> x | None -> String.length s - pos in
    String.sub %pos %len s;;
val sub : ?pos%int -> ?len%int -> string -> string = <fun>

Regards,

Jacques
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
@ 2000-03-15  6:58   ` Christophe Raffalli
  2000-03-15 21:54     ` Julian Assange
  2000-03-15 11:56   ` Wolfram Kahl
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-15  6:58 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: dsyme, caml-list

Jacques Garrigue wrote:
> 
> In this case, I suppose we should read `%' as `is'.
> 

>         Objective Caml version 2.99+10
> 
> # List.map;;
> - : fun%('a -> 'b) -> 'a list -> 'b list = <fun>
> # List.map [1;2;3] fun%succ;;
> - : int list = [2; 3; 4]
> # let sub ?(%pos = 0) ?%len s =
>     let len = match len with Some x -> x | None -> String.length s - pos in
>     String.sub %pos %len s;;
> val sub : ?pos%int -> ?len%int -> string -> string = <fun>
> 

I really do think that it looks better !

You could continue to use ":" in types: because you are giving
information about the type of a label. this would make

# List.map;;
- : fun:('a -> 'b) -> 'a list -> 'b list = <fun>
# List.map [1;2;3] fun%succ;;
 - : int list = [2; 3; 4]
# let sub ?(%pos = 0) ?%len s =
    let len = match len with Some x -> x | None -> String.length s - pos
in
    String.sub %pos %len s;;
val sub : ?pos:int -> ?len:int -> string -> string = <fun>

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
  2000-03-15  6:58   ` Christophe Raffalli
@ 2000-03-15 11:56   ` Wolfram Kahl
  2000-03-15 13:58   ` Pierre Weis
  2000-03-15 20:39   ` Syntax for label (and more) Xavier Leroy
  3 siblings, 0 replies; 60+ messages in thread
From: Wolfram Kahl @ 2000-03-15 11:56 UTC (permalink / raw)
  To: caml-list; +Cc: garrigue


Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp> mentions ``%''
as possible alternative to ``:'' in the labelling syntax and writes:
 > 
 > In this case, I suppose we should read `%' as `is'.

I have difficulties with this --- after all
it is a ``percent'' glyph,
and more comfortable in a division context.

It would even be easier for me to read ``&'' as ``is'',
after all, ``&'' is ``et'',
so there is only one ``s'' missing to ``est''.    ;-)


For me, an additional argument for keeping ``:''
is that ``:'' is punctuation,
which I find appropriate for this use,
while ``%'' and ``#'' look more like infix operators.

I definitely prefer ``:''.


Concerning the use of ``:'' in type signatures,
I would write the blanks even if I didn't have to.
(I do so in Haskell.)


Regards,

Wolfram



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
  2000-03-15  6:58   ` Christophe Raffalli
  2000-03-15 11:56   ` Wolfram Kahl
@ 2000-03-15 13:58   ` Pierre Weis
  2000-03-15 15:26     ` Sven LUTHER
                       ` (7 more replies)
  2000-03-15 20:39   ` Syntax for label (and more) Xavier Leroy
  3 siblings, 8 replies; 60+ messages in thread
From: Pierre Weis @ 2000-03-15 13:58 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

[Sorry, no french version for this long message]

Abstract:

A long answer to Jacques's proposal. I do not discuss syntax but
semantic issues of the label extension. My conclusion is to be very
careful in adding labels into the standard libraries, and also state
as a extremely desirable design guideline to keep the usage of higher
order functions as simple as possible.

> *** Proposal
> 
> Objective Caml 3.00 is not yet released, and I believe we can still
> have modifications on this point.

Yes, you're perfectly right, we can still modify several points.
However, I think there are many other points that are more important
than the choice of ``%'' instead of ``:'', which is only cosmetic
after all.

Thus, I would prefer to discuss deeper and more semantic problems:

-- Problem1: labels can be reserved keywords. This is questionable
and it has been strongly criticised by some Caml users, especially when
reading in the code the awful sequence fun:begin fun ...

-- Problem2: labels that spread all over the standard libraries, even
when they do not add any good. I would cite:

   * the labels completely redundant with the types
     (E.g. char:char in the type of String.contains or String.index)

   * undesired labels: in many cases I don't want to have labels just
     because I don't want to remember their names. (E.g., I very often
     mispell the label acc since I've always used accu to name an
     accumulator; furthermore, when I do not mispell this label, I feel
     acc:accu extremely verbose). Also because labels are verbose at
     application.

   * labels that prevent you to use comfortably your traditional functions.
     This is particularly evident for the List.map or List.fold_right
     higher-order functionals.

This last point is a real problem. Compare the usual way of using
functionals to define the sum of the elements of a list:

$ ocaml
        Objective Caml version 2.99+10

# let sum l = List.fold_right ( + ) l 0;;
val sum : int list -> int = <fun>

Clearly application is denoted in ML with only one character: a space.

Now, consider using the so-called ``Modern'' versions of these
functionals, obtained with the -modern option of the compiler:

$ ocamlpedantic
        Objective Caml version 2.99+10

# let sum l = List.fold_right ( + ) l 0;;
                              ^^^^^
This expression has type int -> int -> int but is here used with type 'a list

Clearly, there is something wrong now! We may remark that the error
message is not that clear, but this is a minor point, since error
messages are never clear enough anyway!

The real problem is that fixing the code makes no good at all to its
readability (at least that's what I would say):

# let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
val sum : 'a -> int list -> int = <fun>

It seems that, in the ``modern'' mode, application of higher order
functions is now denoted by a new kind of parens opening by
``fun:begin fun'' and ending by ``end''. This is extremely explicit
but also a bit heavy (in my mind).

For all these reasons, I would suggest to carefully use labels into
the standard libraries: 

-- remove labels from higher-order functional
-- remove redundant labels: when no ambiguity can occur you need not
   to add a label.
-- use labels when typechecking ambiguity is evident (for instance
when there are two or more parameters with the same type).

Labels must enforce readability of code or help documenting the
libraries, it should not be an extra burden to the programmer and a
way of offuscating code.

Evidently, as any other extension, labels must not offuscate the
overall picture, that is they must not clobber the semantics, nor add
extra exceptional cases to the few general rules we have for the
syntax and semantics of Caml.

In this respect, optional labelled arguments might also be discussed,
particularly for the following facts:

-- syntactically identical patterns and expressions now may have
incompatible types:
   # let f ?style:x _ = x;;
   val f : ?style:'a -> 'b -> 'a option = <fun>

   As a pattern on the left-hand side x has type 'a, while as an
   expression on the right hand side it has type 'a option

-- some expressions can be only written as arguments in an application
   context:
   # let f ?style:x g = ?style:x;;
                        ^
   Syntax error
   # let f ?style:x g = g ?style:x;;
   val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>

-- the simple addition of a default value to an optional argument may
   trigger a typechecking error:

   # let f ?(style:x) g = g ?style:x;;
   val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>

   # let f ?(style:x = 1) g = g ?style:x;;
   This expression has type int but is here used with type 'a option

Do not forget the design decision that has always been used before in
the development of Caml: interesting but not universal extensions to
the language must carefully be kept orthogonal to the core language
and its libraries. This has been successfully achieved for the
important addition of modules (that do not prevent the users from
using the old interface-implementation view of modules) as well as for
the objects system addition that has been also maintained orthogonal
to the rest of the language (in particular the standard library has
never been ``objectified''). I don't know of any reason why labels
cannot follow the same safe guidelines.

> Here is an alternative proposal, to use `%' in place of `:'. Labels
> are kept as a lexical entity. This still breaks some programs, since
> `%' was registered as infix, but this is not so bad.

> Con:
> * I still think that `:' looks better, particularly inside types.
> * On my keyboard I can type in `:' without pressing shift :-)
> * We will need some tool to convert existing code.

I think that % should be the infix integer modulo symbol.

> Do you think it would be better?

No.

> Are there people around who would rather keep `:' ?

Yes. However this is syntax and we have to consider semantics in the
first place.

There are also people around that would like to keep Caml a true
functional language, where usage of higer order functions is easy and
natural.  We have to be careful not to lose what is the actual
strength of the language.

-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
@ 2000-03-15 15:26     ` Sven LUTHER
  2000-03-17  7:44       ` Pierre Weis
  2000-03-15 17:04     ` John Prevost
                       ` (6 subsequent siblings)
  7 siblings, 1 reply; 60+ messages in thread
From: Sven LUTHER @ 2000-03-15 15:26 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Jacques Garrigue, caml-list

On Wed, Mar 15, 2000 at 02:58:30PM +0100, Pierre Weis wrote:
> $ ocamlpedantic
>         Objective Caml version 2.99+10
> 
> # let sum l = List.fold_right ( + ) l 0;;
>                               ^^^^^
> This expression has type int -> int -> int but is here used with type 'a list

Is this not because the new definition of List.fold_right wants the list
first, and then only the function ?

Friendly,

Sven LUTHER



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
  2000-03-15 15:26     ` Sven LUTHER
@ 2000-03-15 17:04     ` John Prevost
  2000-03-17 10:11       ` Jacques Garrigue
  2000-03-15 17:06     ` Markus Mottl
                       ` (5 subsequent siblings)
  7 siblings, 1 reply; 60+ messages in thread
From: John Prevost @ 2000-03-15 17:04 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Jacques Garrigue, caml-list

As usual, best most consistent idea is at the end.  Please forgive my
rambling.

Pierre Weis <Pierre.Weis@inria.fr> writes:

> The real problem is that fixing the code makes no good at all to its
> readability (at least that's what I would say):
> 
> # let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> val sum : 'a -> int list -> int = <fun>
> 
> It seems that, in the ``modern'' mode, application of higher order
> functions is now denoted by a new kind of parens opening by
> ``fun:begin fun'' and ending by ``end''. This is extremely explicit
> but also a bit heavy (in my mind).

Whoa.  You can't just use fun:(+)??  There's a new acc label that's
used for folds?  I might have argued that fun: (or an alternative
which isn't a reserved word, which I would support) isn't so bad to
type.  But with the labeled argument to the argument of the HOF, this
is too much.

As for the other semantic badness (which I actually think is syntactic
badness to some degree) let's see what we can do:

> -- syntactically identical patterns and expressions now may have
> incompatible types:
>    # let f ?style:x _ = x;;
>    val f : ?style:'a -> 'b -> 'a option = <fun>
> 
>    As a pattern on the left-hand side x has type 'a, while as an
>    expression on the right hand side it has type 'a option

I think this could be made sane by a reform of how the optional
arguments work.  There are a couple of interesting possibilities:

# let f ?style:x _ = x;;
- val f : ?style:('a option) -> 'b -> 'a option

# let f (style:x : 'a option) _ = x
- val f : style:('a option) -> 'b -> 'a option

In the first case, the type of an optional labelled argument is always
an option.  (This makes sense in the context of what I'll say about
arguments with default values below.)

In the second case, any labelled argument with an option type becomes
an optional argument.  This has the disadvantage that it's impossible
to have a required option argument.  But one might argue that this
interpretation makes sense.

The first is dirty because there are two kinds of special arguments
(optional and non-optional).  The second because it gets into the type
system.  I think the second must lose, since "knowing" that something
is an option type is complex.

> -- some expressions can be only written as arguments in an application
>    context:
>    # let f ?style:x g = ?style:x;;
>                         ^
>    Syntax error
>    # let f ?style:x g = g ?style:x;;
>    val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>

I think you have to consider this sort of thing in the context of
"application involves labelled arguments now" and "this syntax is part
of application syntax and argument pattern syntax, not expressions or
arbitrary patterns".  It is a little dirty, but survivable.  A syntax
which made it more obvious what was going on might be nice.  I might write:

# let f ?style x g = ?style x
  Syntax error (label in non-application position)
# let f ?style x g = g ?style x
- val f : ?style 'a -> ?style ('a -> 'b) -> 'b

Now, ?label is a special token that changes the meaning of
application.  To some degree, like methods on objects.  ? would "bind"
more closely than application, because it's sort of like an infix.
But like #, it's more of a special effect on the following symbol.
This is why I write:

fooobj #method val

instead of

fooobj#method val

when I use the object syntax.

> -- the simple addition of a default value to an optional argument may
>    trigger a typechecking error:
>
>    # let f ?(style:x) g = g ?style:x;;
>    val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>
>
>    # let f ?(style:x = 1) g = g ?style:x;;
>    This expression has type int but is here used with type 'a option

Okay.  This is where my thought about changing the way this works
comes in.  From the point of view of the called function, an optional
argument with a default value is not optional at all!  From the
outside, of course, it is.  But what if we did it like this:

# let f ?(style:x) g = g ?style:x;;
- val f : ?style:('a option) -> ((?style:'a option) -> 'b) -> 'b = <fun>
# let f ?(style:x = 1) g = g ?style:x;;
                    -
  This expression has type int but here is used with type 'a option
# let f (style:x = 1) g = g ?style:x;;
                                   -
  This expression has type int but here is used with type 'a option
# let f ?(style:x = Some 1) g = g ?style:x;;
- val f : ?style:('a option) -> ((?style:'a option) -> 'b) -> 'b = <fun>
# let f (style:x = Some 1) g = g ?style:x;;
- val f : style:('a option) -> ((?style:'a option) -> 'b) -> 'b = <fun>


What's going on here?  The idea is that ? forms *always* require an
option as their value, and the bound value is always an option.  When
you pass a value with:

foo (?style:x)

foo must have type:

foo : (?style:'a option) -> 'b

Note that I have both optional and non-optional argument syntax above
with default values.  Above, we see how changes effect local code in
our function.  (As expected, if we cause the type of the bound
variable to change, the function breaks.  Otherwise it doesn't.)

What happens to people outside?  Well, if we switch from a ? form to a
non-? form, we're removing the implicit optionizing of the argument.
That is:

# let f (?style:x) = x;;
- val f : ?style:('a option) -> 'a option

# let f (style:x) = x;;
- val f : style:'a -> 'a

# let f (?style:x = Some 5) = x;;
- val f : ?style:('a option) -> 'a option

# let f (style:x = 5) = x;;
- val f : ?style:int -> int

Now, what's going on here?  The ? in the type relates only to whether
the argument is required or not.  When the argument is declared with
?, this must be an option!  When it is declared without ?, it may be
anything.


Come to think of it, this doesn't work either.  It makes everything
keep working as long as you keep the external type the same--but I
just realized that telling the difference between labels that should
be "optioned" and labels that shouldn't is hard.

Okay.  One last try.

What if we drop back one and say that there is only one kind of
labeled argument, written in this way (for my sake writing this):

# let f ?style x = x;;
- val f : ?style 'a -> 'a

Okay.  So how to optional arguments work?

# let f ?style x () = x;;
- val f : ?style 'a -> unit -> 'a
# f ();;
- : '_a option = None
# f ?style (Some 27) ();;
- : int option = Some 27

What's going on here?  Well--let's extend the syntax to cover default
arguments:

# let f (?style x = 5) () = x;;
- val f : ?style int -> int
# f ();;
- : int = 5

# let f (?style x = None) () = x;;
- val f : ?style 'a option -> 'a option
# f ();;
- : '_a option = None

and again, for reference:

# let f (?style x) () = x;;
- val f : ?style 'a -> 'a
# f ();;
- : '_a option = None

So how is this happening--what's the interpretation?





Oh shoot.  This doesn't work either.  I was going to suggest that you
can always leave out a label, and that the default value will be
substituted in, or if you didn't give a default, None will be
substituted in.  But that doesn't account for the top case above.  One
possibility is that it doesn't make sense to use a non-option default
value:

# let f (?style x = 5) () = x;;
- val f : ?style int -> int
* Warning: default value is not an option

# f ();;
  f ?style None ();;
           ----
  This expression has type 'a option but is here used with type int

# f ?style 3 ();;
- : int = 3

This is consistent, but sort of weird.  It does certainly provide a
fairly simple model of what optional arguments are, though.  The only
nastiness is that you need to do extra typing for each optional value
given.  I think this is a reasonable price to pay for sanity.

# let f (?style x = Some 5) () = x;;
- val f : ?style int option -> int option
# let g (?style Some x = Some 5) () = x
  Warning: this pattern-matching is not exhaustive.
  Here is an example of a value that is not matched:
  None
- val g : ?style int option -> int = <fun>
# f ();;
- : int option = Some 5
# g ();;
- : int = 5



Of course, this is all radically different from O'Labl, so it will
never happen.

John.



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
  2000-03-15 15:26     ` Sven LUTHER
  2000-03-15 17:04     ` John Prevost
@ 2000-03-15 17:06     ` Markus Mottl
  2000-03-15 19:11     ` Remi VANICAT
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 60+ messages in thread
From: Markus Mottl @ 2000-03-15 17:06 UTC (permalink / raw)
  To: Pierre Weis; +Cc: OCAML

> -- Problem1: labels can be reserved keywords. This is questionable
> and it has been strongly criticised by some Caml users, especially when
> reading in the code the awful sequence fun:begin fun ...

Although this is a bit off-topic, I would also like to point out some
identifier problems with polymorphic variants as they are implemented at
the moment (maybe this could also be changed before the major release):

First of all, the initial quote ` can be followed by whitespace - and
worse: by comments! I feel that this is really somewhat insane, even if
most users won't use polymorphic variants like this.

Secondly, I am not sure whether it is such a good idea to allow lowercase
initial letters. They can sometimes clash with keywords and here they
really do, because (see above) of they way they are parsed. This can lead
to syntax errors which will surely confuse beginners (and also confused me
once...). If parsing were changed, this wouldn't be a problem anymore, but
I think that the relation between normal variants and polymorphic ones
should stay evident - having to use capitals for the first letter with both
of them seems more regular to me.

> -- Problem2: labels that spread all over the standard libraries, even
> when they do not add any good. I would cite:
> 
>    * labels that prevent you to use comfortably your traditional functions.
>      This is particularly evident for the List.map or List.fold_right
>      higher-order functionals.

I fully agree - labels in higher order functions make their application
really a pain, especially if one wants to use curried functions. Being able
to just pass the name of functions as argument is one of the major
"features" of functional languages - it's probably not worse the extra type
checking information to lose it.

What concerns syntax: I would also rather prefer the version with ":"...

> Do not forget the design decision that has always been used before in
> the development of Caml: interesting but not universal extensions to
> the language must carefully be kept orthogonal to the core language
> and its libraries.

This is an aspect I particularly like about OCaml - one can try out new
styles of programming without being forced to use them throughout.

Regards,
Markus Mottl

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
                       ` (2 preceding siblings ...)
  2000-03-15 17:06     ` Markus Mottl
@ 2000-03-15 19:11     ` Remi VANICAT
  2000-03-17  8:30       ` Pierre Weis
  2000-03-15 21:30     ` Syntax for label, NEW PROPOSAL John Max Skaller
                       ` (3 subsequent siblings)
  7 siblings, 1 reply; 60+ messages in thread
From: Remi VANICAT @ 2000-03-15 19:11 UTC (permalink / raw)
  To: caml-list

Pierre Weis <Pierre.Weis@inria.fr> writes:

> $ ocamlpedantic
>         Objective Caml version 2.99+10
> 
> # let sum l = List.fold_right ( + ) l 0;;
>                               ^^^^^
> This expression has type int -> int -> int but is here used with type 'a list
> 
> Clearly, there is something wrong now! We may remark that the error
> message is not that clear, but this is a minor point, since error
> messages are never clear enough anyway!
> 
> The real problem is that fixing the code makes no good at all to its
> readability (at least that's what I would say):
> 
> # let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> val sum : 'a -> int list -> int = <fun>

here, i prefer to use parenthesis as :

let sum l = List.fold_right fun:(fun x acc:y -> x + y) acc:0;;

it's more readable

also i do want the fun: label (you may change the name, but a label
here is useful) to be able to write 

let sum l = List.fold_right acc:0
              fun:(fun long multi line function  definition here)

but i agreed that the acc label (in fun x acc:y -> x + y) is a pain,
because he forbid the use of usual function here 

-- 
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat



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

* Re: Syntax for label (and more)
  2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
                     ` (2 preceding siblings ...)
  2000-03-15 13:58   ` Pierre Weis
@ 2000-03-15 20:39   ` Xavier Leroy
  2000-03-17 10:03     ` Christian RINDERKNECHT
  2000-03-21  1:29     ` Markus Mottl
  3 siblings, 2 replies; 60+ messages in thread
From: Xavier Leroy @ 2000-03-15 20:39 UTC (permalink / raw)
  To: caml-list

There have been quite a few interesting topics raised on this list
recently, so here is a bunch of quick replies:

- Renaming of exceptions: this will be in 3.00, with the syntax
"exception E = E'".  I implemented this some time ago, but it didn't
make it in 2.04 for various reasons.

- Inclusion of structures into larger structures (in the style of
"open" in SML): I agree this is desirable, and we already have the
syntax for it ("struct ... include S ... end").  It requires a little
more implementation work than exception renaming, so I'll probably do
it for 3.01.

- User contributions to the standard library: I'm open to concrete
proposals on this.  One of the reasons why the OCaml standard library
modules have remained minimal is that it's often hard to know what
would be useful to a significant fraction of users (as opposed to
functions that only their author is going to use).  Also, we must be
careful to keep the standard library manageable, e.g. with consistent
naming conventions and good documentation.  For all these aspects,
some kind of peer reviewing of new extensions sounds good.

- Regarding user accounts on a CVS repository at INRIA: we can open
accounts on the "auxiliary" CVS server, camlcvs.inria.fr, if anyone
needs them.  That server is currently an aging Sparc 10 under SunOS
4(!), and therefore not very pleasant to use, but I have more modern
hardware available to upgrade it; it's just a question of finding time
to install it.  Also, note that for security reasons, you'll have to
use SSH to access it.  If you'd rather use Sourceforge or a similar
system, that's fine with us too, we'll put links on our Web sites.

- Syntax of labels and labeling policy for libraries: now is an
excellent time to discuss those issues, because it's much easier to
change now than after 3.00 is out.  Concerning the syntax of labels,
":" reads nicely, but I'm a bit bothered by having to type "(x : t)"
for a type constraint rather than "(x: t)".  Backward compatibility
with OLabl is an argument, but backward compatibility with OCaml, Caml
Light, SML, Classic ML, etc, is a much stronger one!

Looking at the OCaml lexer, the following 1-character symbols are
(mostly) up for grabs:
        $       (user-definable infix symbol currently)
        %       (ditto)
        &       (currently deprecated synonymous for &&)
        \       (never used so far)
        ~       (user-definable prefix symbol currently)

I can't say that any of these look particularly good as a label
delimiter, although (tongue in cheek) those of us who type a lot of
TeX are already used to "a~b" meaning some kind of punctation between
a and b...

Opinions?

- Xavier Leroy



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
                       ` (3 preceding siblings ...)
  2000-03-15 19:11     ` Remi VANICAT
@ 2000-03-15 21:30     ` John Max Skaller
  2000-03-16  2:55     ` Jacques Garrigue
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-15 21:30 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Jacques Garrigue, caml-list

Pierre Weis wrote:

> Clearly, there is something wrong now! We may remark that the error
> message is not that clear, but this is a minor point, since error
> messages are never clear enough anyway!

	This is not a 'minor' point, but the most significant obstacle
in the way of adoption of languages (like ocaml) that do a lot of type
inference. Incomprehensible -- indeed plain wrong -- error messages
crop up regularly with ocaml, and vie with the kind of gibberish
errors instantiating C++ templates usually give for 
'most obscuficated error message' competition :-)

	The recent addition of better error messages in the case
of missing cases of matches has been a _major_ improvement IMHO:
it has already saved me significant time; since I often enhance
the set of cases of a variant, and need to chase down every
match and update it.

	I'm not using -modern mode and the main reason is the scary
error messages. Even the polymorphic variants are scary, since one
looses the ability to 'spell check' variant tags. I actually tried
to take a fairly large, fundamental, type in Vyper (the type of most
language terms and runtime values) and use polymorphic variants
to classify them (the classes overlap, which ordinary variants
cannot handle), and gave up, because I couldn't understand the
error messages.

	Recent discussions in the Python types-SIG concerning
type inference showed a strong indication (mainly from ex-ML 
users) NOT to use any kind of type inference that could lead
to incomprehensible error messages.

	I personally use errors to drive development.
I expect a compiler to tell me the line that next needs editing.
Ocaml is fairly good here now, but I still cringe in fear
when i get too incompatible object types and pages of
method signatures the compiler claims are different.

Why can't it tell me the differences more often?
I does well sometimes telling me that one sig has a method the
other lacks. 

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15  6:58   ` Christophe Raffalli
@ 2000-03-15 21:54     ` Julian Assange
  0 siblings, 0 replies; 60+ messages in thread
From: Julian Assange @ 2000-03-15 21:54 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Jacques Garrigue, dsyme, caml-list, proff

Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr> writes:

> Jacques Garrigue wrote:
> > 
> > In this case, I suppose we should read `%' as `is'.
> > 
> 
> >         Objective Caml version 2.99+10
> > 
> > # List.map;;
> > - : fun%('a -> 'b) -> 'a list -> 'b list = <fun>
> > # List.map [1;2;3] fun%succ;;
> > - : int list = [2; 3; 4]
> > # let sub ?(%pos = 0) ?%len s =
> >     let len = match len with Some x -> x | None -> String.length s - pos in
> >     String.sub %pos %len s;;
> > val sub : ?pos%int -> ?len%int -> string -> string = <fun>
> > 
> 
> I really do think that it looks better !

I don't. % is a heavy character, only '#' and '@' are worse. '-' would
be far better, although this might break existing code. The natural
meaning is closest to "-" and ":". There is no relation to '%' or '#'.

Cheers,
Julian.



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
                       ` (4 preceding siblings ...)
  2000-03-15 21:30     ` Syntax for label, NEW PROPOSAL John Max Skaller
@ 2000-03-16  2:55     ` Jacques Garrigue
  2000-03-17 15:13       ` Pierre Weis
                         ` (2 more replies)
  2000-03-16  8:50     ` Syntax for label, NEW PROPOSAL Pascal Brisset
  2000-03-18  0:04     ` Syntax for label, ANOTHER " Steven Thomson
  7 siblings, 3 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-16  2:55 UTC (permalink / raw)
  To: Pierre.Weis; +Cc: caml-list

From: Pierre Weis <Pierre.Weis@inria.fr>

> > *** Proposal
> > 
> > Objective Caml 3.00 is not yet released, and I believe we can still
> > have modifications on this point.
> 
> Yes, you're perfectly right, we can still modify several points.
> However, I think there are many other points that are more important
> than the choice of ``%'' instead of ``:'', which is only cosmetic
> after all.

Well, I think I've got enough reactions to rule out %.
These are of the small details of syntax you want to check for
sure. And that are very hard to change afterwards.

> Thus, I would prefer to discuss deeper and more semantic problems:
> 
> -- Problem1: labels can be reserved keywords. This is questionable
> and it has been strongly criticised by some Caml users, especially when
> reading in the code the awful sequence fun:begin fun ...

Well, maybe just because I've grown used to it, I do not find it awful
at all.

The rationale behind allowing the use of keywords as labels is that
there are lots of keywords in Caml, and many of them are good
candidates for labels. Not allowing them makes often choice more
difficult, or forces to use longer names.

On the other hand, their particular use in the standard library may be
another subject of discussion.
If I remember correctly, there are only 2 keywords used as label in
the standard library: `fun' (in functionals) and `to' (in output
functions).

If we want to remove them, I think a good policy would be to change
the "default" length of labels from 3 to 4. Since many Caml keywords
are of length 3, we avoid lots of conflicts!

This would mean:

fun -> func
to -> chan or dest
acc -> accu             :-)
src -> orig             (src meant a lot to a now disappeared company)
dst -> dest             (maybe because I'm French, dst reminds me of something)
buf -> buff             ???
...
Still it seems reasonable to keep pos: and len:.

Beware however that label changes are inherently dangerous: you often
realize afterwards that a choice was not so good, and I really hoped
that we could definitively fix the standard library labels in 3.00.

> -- Problem2: labels that spread all over the standard libraries, even
> when they do not add any good.

Well, the current policy (as defined in the manual) is to put labels
on at least all arguments but one (with some very special exceptions
like printf). This is necessary to allow commuting between arguments,
which is also an important theme of labels. As such I would not say
that they do not do any good.

> I would cite:
> 
>    * the labels completely redundant with the types
>      (E.g. char:char in the type of String.contains or String.index)

Following the above policy, I would say that these are not ideal
choices, but then what other possibility is there?

Moreover, even if this label is redundant in types, it is not
necessarilly so in code.

>    * undesired labels: in many cases I don't want to have labels just
>      because I don't want to remember their names. (E.g., I very often
>      mispell the label acc since I've always used accu to name an
>      accumulator; furthermore, when I do not mispell this label, I feel
>      acc:accu extremely verbose). Also because labels are verbose at
>      application.

Isn't there a classic mode for that?
If you think that labels are verbose, you can use it, and it even
provides some partial support for label checking when you want it.

I suppose we should have a precise idea of what labels are there for.
For me they are a systematic mechanism, and the fact we allow to have
no label on one argument in function types is just a little comfort,
particularly useful when working with functionals.

>    * labels that prevent you to use comfortably your traditional functions.
>      This is particularly evident for the List.map or List.fold_right
>      higher-order functionals.
> 
> This last point is a real problem. Compare the usual way of using
> functionals to define the sum of the elements of a list:
> 
> # let sum l = List.fold_right ( + ) l 0;;
> val sum : int list -> int = <fun>

Whether you consider this readable or not is a question of taste.  I
personally believe that you need quite a background in HO formalisms
to understand the above. But of course most current Caml users have
this background.

> # let sum l = List.fold_right ( + ) l 0;;
>                               ^^^^^
> This expression has type int -> int -> int but is here used with type 'a list

Aargh, that's right, error messages are a pain. I believe I worked a
lot making them informative, but there are still difficult situations.
I'll try to improve this.

Remark however that, in modern mode, it is already strange to have an
application with no labels at all...

> The real problem is that fixing the code makes no good at all to its
> readability (at least that's what I would say):
> 
> # let sum = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> val sum : 'a -> int list -> int = <fun>

You do not have to use begin .. end everywhere.
I do personally write:
# let sum = List.fold_right acc:0 fun:(fun x :acc -> x + acc);;

Remark that here you didn't care about whether acc is the first or
second argument of the passed function, just because (+) is
commutative. However, in general functions are not commutative, and I
always have to think a lot when using List.fold_left or
List.fold_right without labels, just because I may write wrong code
without the type checker telling me anything.

> For all these reasons, I would suggest to carefully use labels into
> the standard libraries: 
> 
> -- remove labels from higher-order functional
> -- remove redundant labels: when no ambiguity can occur you need not
>    to add a label.
> -- use labels when typechecking ambiguity is evident (for instance
> when there are two or more parameters with the same type).
> 
> Labels must enforce readability of code or help documenting the
> libraries, it should not be an extra burden to the programmer and a
> way of offuscating code.

This seems to boil down to using labels for documentation purposes
only. If you reduce them to such an extent, I'm afraid they will not
do very much for code readability anymore. And I stated above, you get
typechecking holes in functionals.

By the way, I do not see how labels can help obfuscating code.
What you are probably intending to say is that they make more
difficult to write some combinator-based HO-style code. Does it mean
we should have a version of the List module without labels for such
uses?

> Evidently, as any other extension, labels must not offuscate the
> overall picture, that is they must not clobber the semantics, nor add
> extra exceptional cases to the few general rules we have for the
> syntax and semantics of Caml.
> 
> In this respect, optional labelled arguments might also be discussed,
> particularly for the following facts:
> 
> -- syntactically identical patterns and expressions now may have
> incompatible types:
>    # let f ?style:x _ = x;;
>    val f : ?style:'a -> 'b -> 'a option = <fun>
> 
>    As a pattern on the left-hand side x has type 'a, while as an
>    expression on the right hand side it has type 'a option

Well, internally the left-hand side is also 'a option, but option is
abbreviated because it is redundant. I do not think people want to see
the left-hand side option, but maybe this technical part should be
made more explicit in the manual.

Conversion from 'a to 'a option is done at application. I do not
think there is any semantical problem here.

> -- some expressions can be only written as arguments in an application
>    context:
>    # let f ?style:x g = ?style:x;;

?style:x is not an expression: labels are part of the application
node, not of the arguments.

> -- the simple addition of a default value to an optional argument may
>    trigger a typechecking error:
> 
>    # let f ?(style:x) g = g ?style:x;;
>    val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>
> 
>    # let f ?(style:x = 1) g = g ?style:x;;
>    This expression has type int but is here used with type 'a option

That one is more serious. This is not a "simple addition". Default
values unroll some syntactic sugar, changing the type of the
argument. Whether this is a good idea to have such syntactic sugar in
the language is an interesting question. However I believe it provides
some real comfort.

> Do not forget the design decision that has always been used before in
> the development of Caml: interesting but not universal extensions to
> the language must carefully be kept orthogonal to the core language
> and its libraries. This has been successfully achieved for the
> important addition of modules (that do not prevent the users from
> using the old interface-implementation view of modules) as well as for
> the objects system addition that has been also maintained orthogonal
> to the rest of the language (in particular the standard library has
> never been ``objectified''). I don't know of any reason why labels
> cannot follow the same safe guidelines.

I just believed that it was agreed that labelizing the standard
library was a progress. Of course this also means that you do not stay
100% compatible in modern mode. Still, there are no optional arguments
in the standard library, meaning that you stay 100% compatible in classic
mode.

> There are also people around that would like to keep Caml a true
> functional language, where usage of higer order functions is easy and
> natural.  We have to be careful not to lose what is the actual
> strength of the language.

Of course, I agree with that.

A first approach would be to say that one can always use classic mode.
Modern is not pedantic, it is just another typing discipline.
But this would endanger the unicity of the language, so this cannot be
an universal answer.

Now, the problem we are talking about seems to boil down to higher
order functions in modern mode. And more particularly List.fold_left
and List.fold_right, since these are about the only two functions
where the argument itself has labels.

It would cost nothing to add 4 more unlabelled functions to the List
module.

val foldl : fun:('a -> 'b -> 'a) -> 'a -> 'b list -> 'a
val foldr : fun:('a -> 'b -> 'b) -> 'a list -> 'b -> 'b
val foldl2 : fun:('a -> 'b -> 'c -> 'a) -> 'a -> 'b list -> 'c list -> 'a
val foldr2 : fun:('a -> 'b -> 'c -> 'c) -> 'a list -> 'b list -> 'c -> 'c

This way you can write

# let sum l = List.foldr fun:(+) l 0

The same additions would also apply to the Array module.
There is also the problem of iteri and mapi, where i: may be not
that important in practice (even when working on an array of integers,
I wouldn't expect anybody to make such a mistake).

val iteri : fun:(i:int -> 'a -> unit) -> 'a array -> unit
val mapi : fun:(i:int -> 'a -> 'b) -> 'a array -> 'b array

One may even insist that fun: is superfluous.
Then it would probably be better to have another List module without
labels at all. Again, this is pretty easy to do, and does not incur
any code blow in general.

Or do you think that the problem is deeper, and that labels are
breaking the foundations of the language ?

Amicalement,

Jacques
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
                       ` (5 preceding siblings ...)
  2000-03-16  2:55     ` Jacques Garrigue
@ 2000-03-16  8:50     ` Pascal Brisset
  2000-03-17 11:15       ` Sven LUTHER
  2000-03-18  0:04     ` Syntax for label, ANOTHER " Steven Thomson
  7 siblings, 1 reply; 60+ messages in thread
From: Pascal Brisset @ 2000-03-16  8:50 UTC (permalink / raw)
  To: Pierre Weis; +Cc: Jacques Garrigue, caml-list

Pierre Weis writes:
> For all these reasons, I would suggest to carefully use labels into
> the standard libraries: 
> 
> -- remove labels from higher-order functional
> -- remove redundant labels: when no ambiguity can occur you need not
>    to add a label.
> -- use labels when typechecking ambiguity is evident (for instance
> when there are two or more parameters with the same type).

 Would it be possible to organize a vote for removing all labels from the
standard library ?

--Pascal Brisset



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 15:26     ` Sven LUTHER
@ 2000-03-17  7:44       ` Pierre Weis
  0 siblings, 0 replies; 60+ messages in thread
From: Pierre Weis @ 2000-03-17  7:44 UTC (permalink / raw)
  To: luther; +Cc: caml-list

> >         Objective Caml version 2.99+10
> > 
> > # let sum l = List.fold_right ( + ) l 0;;
> >                               ^^^^^
> > This expression has type int -> int -> int but is here used with type 'a list
> 
> Is this not because the new definition of List.fold_right wants the list
> first, and then only the function ?

Unfortunately no: List.fold_right expects its arguments as usual:

latour:~ ocaml -modern
        Objective Caml version 2.99+10

# List.fold_right;;
- : fun:('a -> acc:'b -> 'b) -> 'a list -> acc:'b -> 'b = <fun>

Friendly,
-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 19:11     ` Remi VANICAT
@ 2000-03-17  8:30       ` Pierre Weis
  2000-03-17 14:05         ` Jacques Garrigue
  0 siblings, 1 reply; 60+ messages in thread
From: Pierre Weis @ 2000-03-17  8:30 UTC (permalink / raw)
  To: Remi VANICAT; +Cc: caml-list

> > # let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> > val sum : 'a -> int list -> int = <fun>
> 
> here, i prefer to use parenthesis as :
> 
> let sum l = List.fold_right fun:(fun x acc:y -> x + y) acc:0;;
> 
> it's more readable

:)

Me too, ``here, i prefer to use parenthesis as :'' List.fold_right ( + ) 0

> also i do want the fun: label (you may change the name, but a label
> here is useful) to be able to write 
> 
> let sum l = List.fold_right acc:0
>               fun:(fun long multi line function  definition here)
> 
> but i agreed that the acc label (in fun x acc:y -> x + y) is a pain,
> because he forbid the use of usual function here 

I don't think this ``long multi line function  definition here'' is a
really good argument. Several years ago, I thought the same, so that I
defined *_on version of list functionals with list in the first place
instead of at the end; for instance, I could write:

map_on l (fun x -> long multi line function)

Now I'm sure this is not the right solution to a real problem: the
elegant way to deal with that is to name the function using a let.

let eta_expand x =
 ... in

map eta_expand l.

Several arguments are in favor of a let binding:

- we still have only one functional and one way to call it
- we have no unreadable long inline function definitions
- the name we give to the function helps to understand its semantics
- we can use the same construction in case of more complex function
even in case of recursive function, where the fun x -> construct is
hopeless (to solve this problem a ``fun rec'' construct have been
proposed once, but the let rec way is much simpler, regular and
elegant!)
- the let way is a general solution to the general problem of long
multi-line expressions in every construct of the language, including
arithmetic operations.

Best regards,
-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label (and more)
  2000-03-15 20:39   ` Syntax for label (and more) Xavier Leroy
@ 2000-03-17 10:03     ` Christian RINDERKNECHT
  2000-03-17 17:19       ` Christophe Raffalli
  2000-03-21  1:29     ` Markus Mottl
  1 sibling, 1 reply; 60+ messages in thread
From: Christian RINDERKNECHT @ 2000-03-17 10:03 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

> Xavier Leroy wrote:
> - [...] ":" reads nicely, but I'm a bit bothered by having to type "(x : t)"
> for a type constraint rather than "(x: t)".  Backward compatibility
> with OLabl is an argument, but backward compatibility with OCaml, Caml
> Light, SML, Classic ML, etc, is a much stronger one!

I fully agree. For instance I found yesterday in the OCaml 2.99
(99/12/08) doc (manual004.html), two "Syntax error" messages due to
this weird lexical rule...


> Looking at the OCaml lexer, the following 1-character symbols are
> (mostly) up for grabs:
>         $       (user-definable infix symbol currently)
>         %       (ditto)
>         &       (currently deprecated synonymous for &&)
>         \       (never used so far)
>         ~       (user-definable prefix symbol currently)
> [...]
> Opinions?

They are all right for me.

Cheers,

-- 

Christian

-----------------------------------------------------------------------
Christian Rinderknecht                     Phone +33 (0)1 60 76 44 43
Institut National des Télécommunications   Fax   +33 (0)1 60 76 47 11
Département Logiciels Réseaux (LOR)        WWW
9, Rue Charles Fourier, F-91011 Évry Cedex



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-15 17:04     ` John Prevost
@ 2000-03-17 10:11       ` Jacques Garrigue
  0 siblings, 0 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-17 10:11 UTC (permalink / raw)
  To: prevost; +Cc: caml-list

Hi John,

> I think this could be made sane by a reform of how the optional
> arguments work.  There are a couple of interesting possibilities:
> 
> # let f ?style:x _ = x;;
> - val f : ?style:('a option) -> 'b -> 'a option
> 
> # let f (style:x : 'a option) _ = x
> - val f : style:('a option) -> 'b -> 'a option

Bingo, you've just found how it's implemented!
Omitting the option constructor for optional arguments is just
a small comfort. This can be pretty important when you have 10 or 20
optional arguments in the same function.

By the way, having a default case for a non-optional argument was
legal in O'Labl. I just didn't include it in O'Caml because I thought
I would be more confusing than useful.

> The first is dirty because there are two kinds of special arguments
> (optional and non-optional).  The second because it gets into the type
> system.  I think the second must lose, since "knowing" that something
> is an option type is complex.

In fact the distinction between optional and non-optional arguments is
useful, because it allows a nice interaction between classic and
modern mode.  Optional ones behave the same in both modes, only
non-optional ones behave differently.

[..]
> Of course, this is all radically different from O'Labl, so it will
> never happen.

I do not intend to be so exclusive...
In fact there are even a number of differences between ocaml 2.99 and
olabl, and some from you.
The only point is that O'Labl has been around for a while, and we have
had the time to test in practice that this model works, and is not
difficult to grasp. Another model would take lots of time testing
again.

Best regards,

Jacques



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-16  8:50     ` Syntax for label, NEW PROPOSAL Pascal Brisset
@ 2000-03-17 11:15       ` Sven LUTHER
  0 siblings, 0 replies; 60+ messages in thread
From: Sven LUTHER @ 2000-03-17 11:15 UTC (permalink / raw)
  To: Pascal Brisset; +Cc: Pierre Weis, Jacques Garrigue, caml-list

On Thu, Mar 16, 2000 at 09:50:49AM +0100, Pascal Brisset wrote:
> Pierre Weis writes:
> > For all these reasons, I would suggest to carefully use labels into
> > the standard libraries: 
> > 
> > -- remove labels from higher-order functional
> > -- remove redundant labels: when no ambiguity can occur you need not
> >    to add a label.
> > -- use labels when typechecking ambiguity is evident (for instance
> > when there are two or more parameters with the same type).
> 
>  Would it be possible to organize a vote for removing all labels from the
> standard library ?

I thought that all labels added to the standard library are only there because
they can be added in a totally transparent way of doing things, because a
labeled function can be used unlabeled if you like it. 

Friendly,

Sven LUTHER



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-17  8:30       ` Pierre Weis
@ 2000-03-17 14:05         ` Jacques Garrigue
  2000-03-17 16:08           ` Pierre Weis
  2000-03-18 10:32           ` Syntax for label, NEW SOLUTION Christophe Raffalli
  0 siblings, 2 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-17 14:05 UTC (permalink / raw)
  To: Pierre.Weis; +Cc: remi.vanicat, caml-list

> > also i do want the fun: label (you may change the name, but a label
> > here is useful) to be able to write 
> > 
> > let sum l = List.fold_right acc:0
> >               fun:(fun long multi line function  definition here)
> > 
> > but i agreed that the acc label (in fun x acc:y -> x + y) is a pain,
> > because he forbid the use of usual function here 
> 
> I don't think this ``long multi line function  definition here'' is a
> really good argument. Several years ago, I thought the same, so that I
> defined *_on version of list functionals with list in the first place
> instead of at the end; for instance, I could write:
> 
> map_on l (fun x -> long multi line function)
> 
> Now I'm sure this is not the right solution to a real problem: the
> elegant way to deal with that is to name the function using a let.
> 
> let eta_expand x =
>  ... in
> 
> map eta_expand l.
> 
> Several arguments are in favor of a let binding:
> 
> - we still have only one functional and one way to call it
> - we have no unreadable long inline function definitions
> - the name we give to the function helps to understand its semantics
> - we can use the same construction in case of more complex function
> even in case of recursive function, where the fun x -> construct is
> hopeless (to solve this problem a ``fun rec'' construct have been
> proposed once, but the let rec way is much simpler, regular and
> elegant!)
> - the let way is a general solution to the general problem of long
> multi-line expressions in every construct of the language, including
> arithmetic operations.

There may indeed be good reasons for let-binding.
However, if you look at the sources of ocaml, you will see that in
many, many places such functions are defined inline without
let-binding. I see two reasons for that:
* you often don't want to think of a name for such a function
  (most of them are just 2 or 3 line long)
* it forces you to move the code around in a way that is not
  necessarily very natural. It's a bit like RPN: first define a
  function, then apply a functional to it.
  (We could of course ressucite the where clause :-)

More generally, my experience is that more freedom in the way to
layout them increases the use of functionals. After all there are many
ways to see the same function, different logical understanding of its
meaning. And the fact you can use all these ways with the same function
avoids confusion.

Why should we decide that one way is right, and others are wrong?

Jacques



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-16  2:55     ` Jacques Garrigue
@ 2000-03-17 15:13       ` Pierre Weis
  2000-03-17 17:33         ` Wolfram Kahl
  2000-03-18 11:59         ` Jacques Garrigue
  2000-03-21 16:51       ` Pascal Brisset
  2000-03-21 22:22       ` Unsigned integers? John Max Skaller
  2 siblings, 2 replies; 60+ messages in thread
From: Pierre Weis @ 2000-03-17 15:13 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

> > Thus, I would prefer to discuss deeper and more semantic problems:
> > 
> > -- Problem1: labels can be reserved keywords. This is questionable
> > and it has been strongly criticised by some Caml users, especially when
> > reading in the code the awful sequence fun:begin fun ...
> 
> Well, maybe just because I've grown used to it, I do not find it awful
> at all.

At least more verbose than (fun ) or f (if the function is named as I
would recommend to any programmer that is fond of readability).

> The rationale behind allowing the use of keywords as labels is that
> there are lots of keywords in Caml, and many of them are good
> candidates for labels. Not allowing them makes often choice more
> difficult, or forces to use longer names.

The problem is that we have just a few rule for the Caml syntax, and
this violates this elementary one:

``In Caml, keywords are RESERVED identifiers''

Following this rule, we cannot use keywords as identifiers, even if it
would be very convenient ones such as ``val'' and, even if there is no
syntactic ambiguity, ``val'' is not allowed in patterns.

> This would mean:
> 
> fun -> func

Could also consider fn

[...]

> Beware however that label changes are inherently dangerous: you often
> realize afterwards that a choice was not so good, and I really hoped
> that we could definitively fix the standard library labels in 3.00.
> 
> > -- Problem2: labels that spread all over the standard libraries, even
> > when they do not add any good.
> 
> Well, the current policy (as defined in the manual) is to put labels
> on at least all arguments but one (with some very special exceptions
> like printf). This is necessary to allow commuting between arguments,
> which is also an important theme of labels. As such I would not say
> that they do not do any good.

I'm afraid I don't agree with you: commuting between arguments is not
worth the extra burden of having labels, I'm not sure it is even
desirable. I think that when arguments of a function are not always
passed in the same order the readibility of the code is jeopardized.

> > I would cite:
> > 
> >    * the labels completely redundant with the types
> >      (E.g. char:char in the type of String.contains or String.index)
> 
> Following the above policy, I would say that these are not ideal
> choices, but then what other possibility is there?

Remove the label.

> Moreover, even if this label is redundant in types, it is not
> necessarilly so in code.

May be not redundant, we can say useless or nocive ?

> >    * undesired labels: in many cases I don't want to have labels just
> >      because I don't want to remember their names. (E.g., I very often
> >      mispell the label acc since I've always used accu to name an
> >      accumulator; furthermore, when I do not mispell this label, I feel
> >      acc:accu extremely verbose). Also because labels are verbose at
> >      application.
> 
> Isn't there a classic mode for that?
> If you think that labels are verbose, you can use it, and it even
> provides some partial support for label checking when you want it.

If we must always use the no modern option of the compiler, I think
there is some kind of drawback in the label world...

> I suppose we should have a precise idea of what labels are there for.
> For me they are a systematic mechanism, and the fact we allow to have
> no label on one argument in function types is just a little comfort,
> particularly useful when working with functionals.

Wao! So, the normal evolution would be to have labels as ``a
systematic mechanism'' ? I'm afraid this is really a dogmatic view,
and may be some Caml users will object ...

> >    * labels that prevent you to use comfortably your traditional functions.
> >      This is particularly evident for the List.map or List.fold_right
> >      higher-order functionals.
> > 
> > This last point is a real problem. Compare the usual way of using
> > functionals to define the sum of the elements of a list:
> > 
> > # let sum l = List.fold_right ( + ) l 0;;
> > val sum : int list -> int = <fun>
> 
> Whether you consider this readable or not is a question of taste.  I
> personally believe that you need quite a background in HO formalisms
> to understand the above. But of course most current Caml users have
> this background.

No, this is not a question of taste, since whatever readable you
consider this definition, it is still more readable, easier to
understand and easier to write than the labelized version:

let sum = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;

> > # let sum l = List.fold_right ( + ) l 0;;
> >                               ^^^^^
> > This expression has type int -> int -> int but is here used with type 'a list
> 
> Aargh, that's right, error messages are a pain. I believe I worked a
> lot making them informative, but there are still difficult situations.
> I'll try to improve this.
> 
> Remark however that, in modern mode, it is already strange to have an
> application with no labels at all...

Aargh, is that the future of Caml programming, as the ``modern'' flag
tends to suggest ? :(

> > The real problem is that fixing the code makes no good at all to its
> > readability (at least that's what I would say):
> > 
> > # let sum = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> > val sum : 'a -> int list -> int = <fun>
> 
> You do not have to use begin .. end everywhere.
> I do personally write:
> # let sum = List.fold_right acc:0 fun:(fun x :acc -> x + acc);;

Hum... I do personnaly got this idea by reading the code from the files
editor.ml, fileselect.ml, jg_multibox.ml, searchid.ml, ..., in the
directory otherlibs/labltk/browser/ of the compiler distribution.

> Remark that here you didn't care about whether acc is the first or
> second argument of the passed function, just because (+) is
> commutative. However, in general functions are not commutative, and I
> always have to think a lot when using List.fold_left or
> List.fold_right without labels, just because I may write wrong code
> without the type checker telling me anything.

Yes functions in general are not commutative, but I cannot imagine how
labels may prevent you from thinking when using List.fold_right...

> > For all these reasons, I would suggest to carefully use labels into
> > the standard libraries: 
> > 
> > -- remove labels from higher-order functional
> > -- remove redundant labels: when no ambiguity can occur you need not
> >    to add a label.
> > -- use labels when typechecking ambiguity is evident (for instance
> > when there are two or more parameters with the same type).
> > 
> > Labels must enforce readability of code or help documenting the
> > libraries, it should not be an extra burden to the programmer and a
> > way of offuscating code.
> 
> This seems to boil down to using labels for documentation purposes
> only. If you reduce them to such an extent, I'm afraid they will not
> do very much for code readability anymore. And I stated above, you get
> typechecking holes in functionals.

Do you suggest the current version of Objective Caml comes with a
typechecker that gives you ``holes in functionals'' ?

> By the way, I do not see how labels can help obfuscating code.

In several ways, I think labels may help obfuscating code, for
instance if they allows you to treat the arguments of functions as a
set instead of an ordered list: if arguments are never passed in the
same order, the code is much harder to read, since it is much more
difficult to remember the profile of functions (unless you remember
the set of labels associated with the function's profile AND the types
associated with the labels).

> What you are probably intending to say is that they make more
> difficult to write some combinator-based HO-style code. Does it mean
> we should have a version of the List module without labels for such
> uses?

You said so.

> > Evidently, as any other extension, labels must not offuscate the
> > overall picture, that is they must not clobber the semantics, nor add
> > extra exceptional cases to the few general rules we have for the
> > syntax and semantics of Caml.
> > 
> > In this respect, optional labelled arguments might also be discussed,
> > particularly for the following facts:
> > 
> > -- syntactically identical patterns and expressions now may have
> > incompatible types:
> >    # let f ?style:x _ = x;;
> >    val f : ?style:'a -> 'b -> 'a option = <fun>
> > 
> >    As a pattern on the left-hand side x has type 'a, while as an
> >    expression on the right hand side it has type 'a option
> 
> Well, internally the left-hand side is also 'a option, but option is
> abbreviated because it is redundant. I do not think people want to see
> the left-hand side option, but maybe this technical part should be
> made more explicit in the manual.

This is not the problem: the problem is this is an exception to a simple
and intuitive rule of the Caml static semantics:

``In Caml, variables bound by patterns have a unique type''

Corollary: when used in expressions, variables bound by patterns have
the same type as their pattern type.

> Conversion from 'a to 'a option is done at application. I do not
> think there is any semantical problem here.

I do think there is a problem here, since once more this violates a
simple rule of Caml semantics:

``In Caml, there is no implicit coercions.''

Admittedly, this is a burden for arithmetic operations, but this is
also extraordinarily simple to explain and understand.

> > -- some expressions can be only written as arguments in an application
> >    context:
> >    # let f ?style:x g = ?style:x;;
> 
> ?style:x is not an expression: labels are part of the application
> node, not of the arguments.

I know that and find it counter-intuitive, since once more it breaks
a very simple and intuitive rule of Caml:

``Caml expressions possess the sub-term property: sub-expressions are
also expressions''

(Hence, if e1 e2 is an application, then e1 and e2 are valid expressions).

> > -- the simple addition of a default value to an optional argument may
> >    trigger a typechecking error:
> > 
> >    # let f ?(style:x) g = g ?style:x;;
> >    val f : ?style:'a -> (?style:'a -> 'b) -> 'b = <fun>
> > 
> >    # let f ?(style:x = 1) g = g ?style:x;;
> >    This expression has type int but is here used with type 'a option
> 
> That one is more serious. This is not a "simple addition". Default
> values unroll some syntactic sugar, changing the type of the
> argument.

Once more, I know those technical reasons, but I do not get for
granted that technical reasons are a valid answer to violations of the
simplicity and intuitive understanding of the language. If technical
reasons cannot handle some nice feature but force you to turn this
feature into a bad hack, then you must choose not to incorporate the
feature since it is no more a nice feature.

> Whether this is a good idea to have such syntactic sugar in
> the language is an interesting question. However I believe it provides
> some real comfort.

You must carefully balance this comfort with the extra cost in terms
of complexity and exceptions to the usual semantics (either static or
dynamic) ...

> > Do not forget the design decision that has always been used before in
> > the development of Caml: interesting but not universal extensions to
> > the language must carefully be kept orthogonal to the core language
> > and its libraries. This has been successfully achieved for the
> > important addition of modules (that do not prevent the users from
> > using the old interface-implementation view of modules) as well as for
> > the objects system addition that has been also maintained orthogonal
> > to the rest of the language (in particular the standard library has
> > never been ``objectified''). I don't know of any reason why labels
> > cannot follow the same safe guidelines.
> 
> I just believed that it was agreed that labelizing the standard
> library was a progress.

It can be a progress if labels are introduced when they avoid
some (common) errors or ambiguities.

> A first approach would be to say that one can always use classic mode.
> Modern is not pedantic, it is just another typing discipline.
> But this would endanger the unicity of the language, so this cannot be
> an universal answer.

You're right, so we still have to think hard on the subject, and try
not to violate the few intuitive rules we have in Caml.

> Now, the problem we are talking about seems to boil down to higher
> order functions in modern mode. And more particularly List.fold_left
> and List.fold_right, since these are about the only two functions
> where the argument itself has labels.
> 
> It would cost nothing to add 4 more unlabelled functions to the List
> module.

And do the same for modules List and Hashtbl and Array and Set and
Map, ... this will cost a bit I think.

[...]

> One may even insist that fun: is superfluous.
> Then it would probably be better to have another List module without
> labels at all. Again, this is pretty easy to do, and does not incur
> any code blow in general.
>
> Or do you think that the problem is deeper, and that labels are
> breaking the foundations of the language ?

In my opinion some fundamental rules are broken in the current
situation of the labels addition, and I think we should try to
overcome this drawback to let the language simple to explain and use.

Amicalement,
-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-17 14:05         ` Jacques Garrigue
@ 2000-03-17 16:08           ` Pierre Weis
  2000-03-18 10:32           ` Syntax for label, NEW SOLUTION Christophe Raffalli
  1 sibling, 0 replies; 60+ messages in thread
From: Pierre Weis @ 2000-03-17 16:08 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

> There may indeed be good reasons for let-binding.
> However, if you look at the sources of ocaml, you will see that in
> many, many places such functions are defined inline without
> let-binding. I see two reasons for that:
> * you often don't want to think of a name for such a function
>   (most of them are just 2 or 3 line long)

Is this argument relevant to the problem at hand ? You were speaking
of the advantage of using a label fun: for applying map to a ``long
multi line function definition'':

>               fun:(fun long multi line function  definition here)

If the function is ``long'' and multi line, I definitively prefer a let
binding. If it is not ``long'' I prefer no label and a short and
elegant (fun x -> ...).

> * it forces you to move the code around in a way that is not
>   necessarily very natural. It's a bit like RPN: first define a
>   function, then apply a functional to it.
>   (We could of course ressucite the where clause :-)

Yes that's fundamentally the way it goes in Caml: define first
something then use it (static binding). I'm sorry, we removed the
where construct a long time ago exactly with this argument.

As you say below ``More generally, my experience is that''

* once anonymous functions are named, the code is clearer
* when anonymous functions are ``long multi line'' the code is obscure.

> More generally, my experience is that more freedom in the way to
> layout them increases the use of functionals. After all there are many
> ways to see the same function, different logical understanding of its
> meaning. And the fact you can use all these ways with the same function
> avoids confusion.
> Why should we decide that one way is right, and others are wrong?

You already answered to this question in your paragraph: I would answer
in the first place with the very reasons you are advocating to ask why
we should decide; you wrote ``my experience'', ``logical
understanding'', ``avoids confusion''.

So, we should decide that one way is right based on experience, theorems,
confusion avoidance, logical understanding, ....

Amicalement,

-- 
Pierre Weis

INRIA, Projet Cristal, http://pauillac.inria.fr/~weis



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

* Re: Syntax for label (and more)
  2000-03-17 10:03     ` Christian RINDERKNECHT
@ 2000-03-17 17:19       ` Christophe Raffalli
  0 siblings, 0 replies; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-17 17:19 UTC (permalink / raw)
  To: Christian RINDERKNECHT; +Cc: Xavier Leroy, caml-list

Christian RINDERKNECHT wrote:

> > Looking at the OCaml lexer, the following 1-character symbols are
> > (mostly) up for grabs:
> >         $       (user-definable infix symbol currently)
> >         %       (ditto)
> >         &       (currently deprecated synonymous for &&)
> >         \       (never used so far)
> >         ~       (user-definable prefix symbol currently)
> > [...]
> > Opinions?
> 
> They are all right for me.

For me too. Whatever we choose, we will get use to it and it will aquire
the intended meaning in our mind !

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-17 15:13       ` Pierre Weis
@ 2000-03-17 17:33         ` Wolfram Kahl
  2000-03-18 11:59         ` Jacques Garrigue
  1 sibling, 0 replies; 60+ messages in thread
From: Wolfram Kahl @ 2000-03-17 17:33 UTC (permalink / raw)
  To: caml-list


As a long time user of OLabl, I was very happy when the ``great merger''
was announced. I was also very happy that there were quite a few
very positive reactions on this list, and that there was the understanding
that the merger should serve both those who wanted to stay in their old
worlds, be it the world with or the world without labels
(by making libraries written in the other world accessible to them),
and those who wanted to do some border-crossing.

In the last few days, however,
the tone seems to have changed considerably ---
before a religious war breaks out,
I would recommend reading ``Nathan der Weise'' by Lessing ;-)


More to the point:

Pierre Weis <Pierre.Weis@inria.fr> writes:
 > I'm afraid I don't agree with you: commuting between arguments is not
 > worth the extra burden of having labels, I'm not sure it is even
 > desirable. I think that when arguments of a function are not always
 > passed in the same order the readibility of the code is jeopardized.

To me, for some functions the arguments are in the wrong order
whichever order you put them.
Even for some functions in the standard library.

So when writing applications of these functions,
I have to look them up anyway --- and for me it is faster
to do this via LablBrowser/CamlBrowser than via the local
installation of the HTML version of the manual.

When reading the code, however, with labels
I do not have to look up the function at all!


I find code with heavy use of functions with more than three arguments
hard to read without labels --- no matter whether ML or Haskell.
I find myself routinely writing functions
with around ten non-optional arguments.
And I am glad that I can add another five optional arguments,
should the need arise,
to spare me the copy-and-paste of the function definition for a new variant.
I find labels indispensable for this.
I often do copy-and-paste for the labelled applications ;-),
and labels help to find the place to be changed.
But the real pay-off comes at the time of reading the code
(which I do, sometimes :-),
when I can read it without having to look up the definition.


Of course, there are other programming styles, too,
and very algebraic combinator-style programming
will profit much less from labels, and look nicer in classic style.


I love higher order functions, too, so initially the requirement
to do long eta normal forms seemed to be a drawback to me
just the same way as to some people on the list.


However, nowadays I find myself doing ``fold_right (+)'' much less
than ``fold_right myfunction'', where ``myfunction'' often is
a partial application of a more-argument function
that has been let-defined a few lines above ---
this application can still be multi-line,
but since the more-argument function has been let-defined for the purpose
of having its instances used in fold_right,
I find that adding this one extra label in the let-definition
does no harm at all, on the contrary,
it adds to the readability of the definition of the more-argument function.


So for me, labels have proved to be the right thing for what I do
with OCaml/OLabl --- but then, I do not claim to be a typical user:
When doing combinator-style programming, I prefer Haskell,
and, half joking, I consider OCaml/OLabl an imperative programming language
just by virtue of its not being purely functional
(I do not use other imperative programming languages,
 (except shells), and I also recommend my students not
 to use other imperative programming languages ---
 some even understand and follow :-).


Maybe the question to be discussed
is which kind of mixtures between the two styles
should be enabled by the compiler.
For my perception of OCaml-3.0, however,
I think it is sufficient if it just puts the two worlds
of no-label-users and label-users
on a common technical basis,
without forcing anybody to really change their style
(which is, as I perceive and understand it,
 the design philosophy followed so far).


Best regards,

Wolfram



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

* Re: Syntax for label, ANOTHER NEW PROPOSAL
  2000-03-15 13:58   ` Pierre Weis
                       ` (6 preceding siblings ...)
  2000-03-16  8:50     ` Syntax for label, NEW PROPOSAL Pascal Brisset
@ 2000-03-18  0:04     ` Steven Thomson
  7 siblings, 0 replies; 60+ messages in thread
From: Steven Thomson @ 2000-03-18  0:04 UTC (permalink / raw)
  To: caml-list


Pierre Weis wrote: [part of long post omitted]
> 
> $ ocaml
>         Objective Caml version 2.99+10
> 
> # let sum l = List.fold_right ( + ) l 0;;
> val sum : int list -> int = <fun>
> 
> Clearly application is denoted in ML with only one character: a space.
> 
> Now, consider using the so-called ``Modern'' versions of these
> functionals, obtained with the -modern option of the compiler:
> 
> $ ocamlpedantic
>         Objective Caml version 2.99+10
> 
> # let sum l = List.fold_right ( + ) l 0;;
>                               ^^^^^
> This expression has type int -> int -> int but is here used with type 'a list
> 
> Clearly, there is something wrong now! We may remark that the error
> message is not that clear, but this is a minor point, since error
> messages are never clear enough anyway!
> 
> The real problem is that fixing the code makes no good at all to its
> readability (at least that's what I would say):
> 
> # let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;;
> val sum : 'a -> int list -> int = <fun>
> 
> It seems that, in the ``modern'' mode, application of higher order
> functions is now denoted by a new kind of parens opening by
> ``fun:begin fun'' and ending by ``end''. This is extremely explicit
> but also a bit heavy (in my mind).
> 
> For all these reasons, I would suggest to carefully use labels into
> the standard libraries:
> 
> -- remove labels from higher-order functional

I don't think that merely omitting labels from higher-order functional
arguments really solves the problem.  Consider the following:

  $ ocaml -modern
          Objective Caml version 2.99 (99/12/08)

  # let add' :acc x = acc + x;;
        val add' : acc:int -> int -> int = <fun>
  # let rec fold_left' f accu l =
    match l with
      [] -> accu
    | a::l -> fold_left' f (f accu a) l;;
        val fold_left' : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = <fun>
  # let sum' = fold_left' add' 0;;
      Characters 24-28:
  This expression has type acc:int -> int -> int but is here used with
type
    'a -> 'b -> 'a

If the definition of fold_left' does NOT use a label, we still get a
compile error whenever we try to use an argument that DOES have a label.

My proposal is to introduce an operator that can be used to tell the
compiler to ignore labels when type-checking a higher-order functional
argument.  This could be thought of as a pragma which locally switches
the compiler from modern to classic mode.

Some possible variations:

1. A prefix operator, here shown as "~", that causes only the following
expression to be evaluated in classic mode: 

  let sum = List.fold_left fun:~(+) acc:0
  let sum' = fold_left' ~add' 0

2. A bracketing construct, here shown as [~ ~], that causes everything
inside the brackets to be evaluated in classic mode. 

  let sum = List.fold_left fun:[~(+)~] acc:0
  let sum' = fold_left' [~add'~] 0

option 2 is not as visually lightweight, but might be more useful if
there are several arguments that need to be altered:
  let aaa = bbb ccc:~ddd eee:~fff ggg:~hhh ~iii jjj
versus
  let aaa = bbb [~ ccc:ddd eee:fff ggg:hhh iii ~] jjj



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

* Re: Syntax for label, NEW SOLUTION
  2000-03-17 14:05         ` Jacques Garrigue
  2000-03-17 16:08           ` Pierre Weis
@ 2000-03-18 10:32           ` Christophe Raffalli
  2000-03-19  2:29             ` Jacques Garrigue
  1 sibling, 1 reply; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-18 10:32 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: Xavier.leroy, caml-list


First to clarify, there are two distinct problems with labels:

- Their syntax: Anything that let me put (or not put) spaces where I
want will suit me. (If people are not happy with the final syntax let
them use camlp4 :-)

- Their semantics in modern mode.

I quite agree, their should not be two modes, because this will means
two communities of users and therefore at some point two standards
libraries because each kind of users will have different needs. This is
dangerous ...
soon there would not be only one big caml community anymore.

But there may be a solution in three step:

1) Let's have only the modern mode. But let it accept any expressions
with no amibiguities. This means that if according to both types AND
labels there is a unique valid order of arguments then the compiler do
not complain.

At this point you can use blit with

> Array.blit a src_pos:x b dst_pos:y len

If both array a and b have not the same types and

> Array.blit src:a src_pos:x b dst_pos:y len

If they have the same type.

This is reasonnable ! 

But can this be implemented ? I think that this is what people wants for
labels (at least what I want). And if this is not implementable at this
time let's wait for a solution ! 

2) let's turn error messages about labels ambiguities into warning and
-modern option into an option to print or not these warnings. This is
more reasonnable and conform to the usage in a lot of programming
languages.

3) For the problem of List.fold_left (+), there is a solution: tell to
the compiler that (+) is commutative ! Or more generally find a syntax
to tell that two or more arguments of the same types may be commuted
without changing the behaviour of the function. Then there would be no
ambiguities when you type List.fold_left (+) and the compiler wii not
complain ! There would be a problem only with  List.fold_left (/) but
then writing the labels explicitely may be better (or rewrite it with a
product).

 


 
-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-17 15:13       ` Pierre Weis
  2000-03-17 17:33         ` Wolfram Kahl
@ 2000-03-18 11:59         ` Jacques Garrigue
  1 sibling, 0 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-18 11:59 UTC (permalink / raw)
  To: Pierre.Weis; +Cc: caml-list

From: Pierre Weis <Pierre.Weis@inria.fr>

> > The rationale behind allowing the use of keywords as labels is that
> > there are lots of keywords in Caml, and many of them are good
> > candidates for labels. Not allowing them makes often choice more
> > difficult, or forces to use longer names.
> 
> The problem is that we have just a few rule for the Caml syntax, and
> this violates this elementary one:
> 
> ``In Caml, keywords are RESERVED identifiers''

This can be discussed indeed. Formally the rule is not broken: in the
manual labels are defined as an alphanumeric string ending by `:',
which is lexically different from any keyword. But this definition may
seem strange.  Before definitively deciding on this, we can start by
the standard library.

> > This would mean:
> > 
> > fun -> func
> 
> Could also consider fn

I don't know why, but I don't like very much fn:, maybe because it
reminds me of another language :-)
In general, I think consonant-only labels are not very good, because
you have to mentally add the missing vowels when reading.
That's pretty subjective, though.

> > > -- Problem2: labels that spread all over the standard libraries, even
> > > when they do not add any good.
> > 
> > Well, the current policy (as defined in the manual) is to put labels
> > on at least all arguments but one (with some very special exceptions
> > like printf). This is necessary to allow commuting between arguments,
> > which is also an important theme of labels. As such I would not say
> > that they do not do any good.
> 
> I'm afraid I don't agree with you: commuting between arguments is not
> worth the extra burden of having labels, I'm not sure it is even
> desirable. I think that when arguments of a function are not always
> passed in the same order the readibility of the code is jeopardized.

That's where I think there are really two approaches and two
philosophies.

I thought that the goal of the merger between ocaml and olabl was not
only to integrate some olabl features, but also to merge the two
communities.
The O'Labl community has a different philosophy of programming.
If you consider this as an heresy, we cannot go very far.

I really believed that, especially because it is ocaml, we could have
an oecumenic approach: accept everybody and every style, with their
differences.

To achieve this goal, the classic mode was carefully designed so as to
allow what is your view of labels: an optional help to readability,
but no commutation.
It also ensures the interoperability between both styles.
I'm really curious of why you persist in ignoring its existence (and
the fact this is the default mode).

On the other hand, the modern mode, which should probably renamed
-labels or rather -commute mode, since this is its main difference
with classic mode, is really intended for people who more or less
agree with the olabl philosophy, and consider label commutation as an
important feature.

If you consider that such diversity is bad, and that there should be
only one mode, I do not really see what we can do. One solution would
be to have two different standard libraries, but this creates 3
problems:
* technical problems when linking code based on the two libraries.
* basically it doesn't solve the problem of all other libraries.
  Non-labellers will still find that there are too many labels in
  labelled libraries, and they will be discouraged from adding
  documentation labels to their own libraries, which in turn will make
  them incomfortable to use for labellers.
* ocamlbrowser looses a great part of its interest, which is to be
  able to see the labels as documentation.

> > I suppose we should have a precise idea of what labels are there for.
> > For me they are a systematic mechanism, and the fact we allow to have
> > no label on one argument in function types is just a little comfort,
> > particularly useful when working with functionals.
> 
> Wao! So, the normal evolution would be to have labels as ``a
> systematic mechanism'' ? I'm afraid this is really a dogmatic view,
> and may be some Caml users will object ...

The meaning of systematic here is just about the standard way to put
labels, not the way to use them. I do not intend to impose the use of
labels to anybody. Nor to force anybody to comply with the standard.

The theoretical background of the commuting mode is the selective
lambda-calculus, in which no label is also a label.  From this point
of view having functions with no labels is just having functions where
all arguments have the same label.  This is just a pain.

> > > # let sum l = List.fold_right ( + ) l 0;;
> > > val sum : int list -> int = <fun>
> > 
> > Whether you consider this readable or not is a question of taste.  I
> > personally believe that you need quite a background in HO formalisms
> > to understand the above. But of course most current Caml users have
> > this background.
> 
> No, this is not a question of taste, since whatever readable you
> consider this definition, it is still more readable, easier to
> understand and easier to write than the labelized version:

I maintain this is a subjective judgment. The labelled version is in
my opinion easier to understand from an algorithmic point of view.

But I don't ask you to agree with that, just to admit that other
people may have other opinions. I perfectly respect yours.

> > Remark that here you didn't care about whether acc is the first or
> > second argument of the passed function, just because (+) is
> > commutative. However, in general functions are not commutative, and I
> > always have to think a lot when using List.fold_left or
> > List.fold_right without labels, just because I may write wrong code
> > without the type checker telling me anything.
> 
> Yes functions in general are not commutative, but I cannot imagine how
> labels may prevent you from thinking when using List.fold_right...

Here is an example:

# let make_set l =
    List.fold_right (fun x l -> if List.mem x l then l else x::l) [] l ;;
val make_set : 'a list -> 'a list = <fun>

At first sight it looks right. But if you look carefully you will
realise that in List.fold_right (contrary to List.fold_left) the
starting value comes last. So this function is just the identity!

Now, if I put a label (even in classic mode),
# let make_set l =
    List.fold_right (fun x l -> if List.mem x l then l else x::l) acc:[] l ;;
                                                                      ^^
Expecting function has type 'a list -> acc:'b -> 'b
This argument cannot be applied with label acc:

The system tells me that this is wrong, and I do not have to think
carefully about whether the accumulator comes first or last.

I'm just waiting for the day we will discover this kind of bug inside
the compiler itself...

By the way, this also connects to the fact we need two different
typings for folding functions, depending on whether the used function
is a symmetrical one (which has no label) or an asymmetric one like
above.

That is, if considering both that having acc: in the expected function
is a pain, and that acc: on fold itself is useful, we choose the type

val fold_left : fun:('a -> 'b -> 'a) -> acc:'a -> 'b list -> 'a

we are no longer able to write fold_matrix as we can now:

# let fold_matrix fun:f = List.fold_left fun:(List.fold_left fun:f);;
val fold_matrix : fun:(acc:'a -> 'b -> 'a) -> acc:'a -> 'b list list -> 'a

So we need two functions: one with acc: in both places, and one with
neither.

> In several ways, I think labels may help obfuscating code, for
> instance if they allows you to treat the arguments of functions as a
> set instead of an ordered list: if arguments are never passed in the
> same order, the code is much harder to read, since it is much more
> difficult to remember the profile of functions (unless you remember
> the set of labels associated with the function's profile AND the types
> associated with the labels).

On what experience do you base this judgment ?
This is certainly not that of olabl users.

By the way the point is that you do not need to remember the profile
of functions at reading: it is explicit in the syntax.  Labels are
often more informative than types.

> > >    # let f ?style:x _ = x;;
> > >    val f : ?style:'a -> 'b -> 'a option = <fun>
> > > 
> > >    As a pattern on the left-hand side x has type 'a, while as an
> > >    expression on the right hand side it has type 'a option
> > 
> > Well, internally the left-hand side is also 'a option, but option is
> > abbreviated because it is redundant. I do not think people want to see
> > the left-hand side option, but maybe this technical part should be
> > made more explicit in the manual.
> 
> This is not the problem: the problem is this is an exception to a simple
> and intuitive rule of the Caml static semantics:
> 
> ``In Caml, variables bound by patterns have a unique type''
> 
> Corollary: when used in expressions, variables bound by patterns have
> the same type as their pattern type.

But this is the case (they have same type).  I do not see how they
could have a different type.  'a is not the type of the pattern, but
of the expected value, and where option is abbreviated for the above
reason.

The "exception" actually is not the above case, but rather

# let f ?(:style = 0) () = style;;
val f : ?style:int -> unit -> int = <fun>

Here the type of the pattern is int (not int option, since there is a
default value), but the type of the expected value is int option.

We could make everything consistent and just say that the expected
value is of type int rather than int option, by requiring a default
value for all optional arguments, and hide completely the
implementation.
However, this would greatly weaken the system: the nice thing with
optional arguements is that they can depend on each other, and that we
can checked whether a value was passed or not. Remark also that if we
do that we loose nice properties of the current system (particularly
compared with other systems of default arguments, that are often based
on overloading), like eta-expansion:

# fun ?:style -> f ?:style;; 
- : ?style:int -> unit -> int = <fun>

> > Conversion from 'a to 'a option is done at application. I do not
> > think there is any semantical problem here.
> 
> I do think there is a problem here, since once more this violates a
> simple rule of Caml semantics:
> 
> ``In Caml, there is no implicit coercions.''

No, this conversion is not based on types, and there is an untyped
semantics for optional arguments in both classic and commuting modes.

Types are used in the compiler, but just to make it more efficient.

> > > -- some expressions can be only written as arguments in an application
> > >    context:
> > >    # let f ?style:x g = ?style:x;;
> > 
> > ?style:x is not an expression: labels are part of the application
> > node, not of the arguments.
> 
> I know that and find it counter-intuitive, since once more it breaks
> a very simple and intuitive rule of Caml:
> 
> ``Caml expressions possess the sub-term property: sub-expressions are
> also expressions''

This is false: (1 +) is not an expression in Caml.

> Once more, I know those technical reasons, but I do not get for
> granted that technical reasons are a valid answer to violations of the
> simplicity and intuitive understanding of the language. If technical
> reasons cannot handle some nice feature but force you to turn this
> feature into a bad hack, then you must choose not to incorporate the
> feature since it is no more a nice feature.

Yes in general, but do you really think that there is a deep
violation, and that this is a bad hack?

All the systems of optional arguments I know of are based on worse
hacks, like overloading, dynamic processing of a list of pairs
label/value, values in interfaces, etc...
I would rather say that we can be proud of avoiding all these.

> > Whether this is a good idea to have such syntactic sugar in
> > the language is an interesting question. However I believe it provides
> > some real comfort.
> 
> You must carefully balance this comfort with the extra cost in terms
> of complexity and exceptions to the usual semantics (either static or
> dynamic) ...

Agreed.  Dynamic semantics get (much) more complex.  However, you can
understand it as a series of conservative extensions over the original
simple semantics of Caml.

> > Now, the problem we are talking about seems to boil down to higher
> > order functions in modern mode. And more particularly List.fold_left
> > and List.fold_right, since these are about the only two functions
> > where the argument itself has labels.
> > 
> > It would cost nothing to add 4 more unlabelled functions to the List
> > module.
> 
> And do the same for modules List and Hashtbl and Array and Set and
> Map, ... this will cost a bit I think.

Well, not in Hashtbl and Map since there the operation accepted by
fold takes 3 arguments, meaning that you won't apply it to an
arbitrary predefined operator.

So, this is only List, Array and Set (currently).
I don't know what is you scale for cost, but I just meant that this is
only adding
        let foldl = fold_left
to the implementation, and
        val foldl : ...
to the interface, with no code duplication.

By the way, this is not the first time we have to add one more
function just for typing reasons. Remember Sys.signal and
Sys.set_signal.

> > Or do you think that the problem is deeper, and that labels are
> > breaking the foundations of the language ?
> 
> In my opinion some fundamental rules are broken in the current
> situation of the labels addition, and I think we should try to
> overcome this drawback to let the language simple to explain and
> use.

I'm afraid there is no miracle to expect there.  OLabl itself was
based on serious theoretical work, and we have thought seriously
(together) of how to make OCaml 2.99 clean.  If anybody has a perfect
solution, which also satisfies olabl users, then I applaude, but I am
very dubitative.

Amicalement,

Jacques
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Syntax for label, NEW SOLUTION
  2000-03-18 10:32           ` Syntax for label, NEW SOLUTION Christophe Raffalli
@ 2000-03-19  2:29             ` Jacques Garrigue
  2000-03-20 18:25               ` Christophe Raffalli
                                 ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-19  2:29 UTC (permalink / raw)
  To: Christophe.Raffalli, Don Syme, John Prevost, Damien Doligez
  Cc: Xavier.leroy, caml-list

Since I do not want to flood the caml-list with messages, I answer
several messages together.  This makes the answer a bit long, but bear
with me if you are interested.

From: Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>

> First to clarify, there are two distinct problems with labels:
> 
> - Their syntax: Anything that let me put (or not put) spaces where I
> want will suit me. (If people are not happy with the final syntax let
> them use camlp4 :-)

That's not easy, but maybe we can find something.
After your idea of keeping `:' in types, and only change the syntax
for terms, I first thought that this would be bad, in particular this
would cause technical problems in the lexer, since we do not want a
special lexing rule for `:' anymore. However if we decide that
labels cannot have keyword names, this should be possible to work it
out at the parser level (the :label form is no longer needed).

As Xavier included `\' in his list (which surprised me a little, since
for me '\' was taboo), I would go for it.

That is, replace ':' by '\' in terms, but keep ':' in types.
Any counter-proposals?

> - Their semantics in modern mode.
> 
> I quite agree, their should not be two modes, because this will means
> two communities of users and therefore at some point two standards
> libraries because each kind of users will have different needs. This is
> dangerous ...
> soon there would not be only one big caml community anymore.

There is a misunderstanding here.  There are currently two
communities, and one goal of the merger is to have a big caml
community again.  I think that having two modes is a good way to reach
this goal.  All this discussion just shows that this would be very
difficult with only one mode.

> But there may be a solution in three step:
> 
> 1) Let's have only the modern mode. But let it accept any expressions
> with no amibiguities. This means that if according to both types AND
> labels there is a unique valid order of arguments then the compiler do
> not complain.
> 
> At this point you can use blit with
> 
> > Array.blit a src_pos:x b dst_pos:y len
> 
> If both array a and b have not the same types and
> 
> > Array.blit src:a src_pos:x b dst_pos:y len
> 
> If they have the same type.
> 
> This is reasonnable ! 

I do not understand very well your proposal.  If you let arguments
commute when there is no ambiguity, then this is just a big mess,
because the concept of no ambiguity is only understood by the
compiler. If you do not let them commute, then I do not see how this
improves on classic mode, which already allows you to check labels
when you want.

> 3) For the problem of List.fold_left (+), there is a solution: tell to
> the compiler that (+) is commutative ! Or more generally find a syntax
> to tell that two or more arguments of the same types may be commuted
> without changing the behaviour of the function. Then there would be no
> ambiguities when you type List.fold_left (+) and the compiler wii not
> complain ! There would be a problem only with  List.fold_left (/) but
> then writing the labels explicitely may be better (or rewrite it with a
> product).

Woa. Teaching properties of functions to the compiler would be very
nice, but I'm afraid type checking technology is not nearly mature
enough for that. That's a good subject for research :-)

From: Don Syme <dsyme@microsoft.com>

> I really don't see people clamouring for lots of labels in the standard
> library (besides the inventors of the language feature, who don't really
> count, for lots of obvious reasons - over exposure to the feature, over
> familiarity with the label names, a natural bent to program in a particular
> way that led them to the feature in the first place, self-selection as
> people who think the feature is the best thing ever).

Maybe they're just decent, and do not like flame wars.
I do not like either, and have to force myself to write these messages.
I can only tell you that ocaml-2.99 has a few labels less that olabl,
and that I already had comments from olabl users who thought it was "odd".
There were also several messages in this forum insisting for then fun:
label on functionals, and this is the function fold_right which
started all this discussion.

> o The fact that you've had to resort to "modes" at all indicates something
> is wrong.  The point about O'Caml is that you shouldn't have to understand
> _anything_ about labels, objects, modules or syntax modes to use the system
> as a new user.  You shouldn't have to see any labels, nor have to ask "what
> are these two modes all about", nor have to try to understand why some of
> the arguments have labels and some don't.

Well, before that there were two compilers.  I think this is a progress.

> o The "just documentation" response doesn't really hold water, because if
> the labels were just documentation, then they would different.  For example,
> "fun", being a keyword, is highly confusing and not terribly descriptive -
> any sensible prototype would probably just use "f".  And C prototypes look
> _horrible_ when you have both higher order arguments and argument names.

If you think that some labels are not that good as documentation, then
make suggestions.  Since most people will only use them as
doumentation, this should be a priority.  And if they are good
documentation, then will certainly be good to use in programs also.
The problem about C prototypes and higher-order functions is really a
problem with the way you write function types in C, not about the
variable names.

From: John Prevost <prevost@maya.com>

> If we could come up with a semantics where labels are always optional,
> I think I would accept things like acc in the standard library.  But
> when you have to make a choice between optional labels and no useful
> functionality, it's a harder sell.

Some people really want to eat the cake and still have it.
I already explained a while ago why it was not possible to have labels
both optionals and commuting in a curried language.
Even if it were possible, I would fully agree with Pierre on this
point: this is going to make programs unreadable.  If you do not
decide clearly which is your policy, then you end up with Perl!
Do not confuse the fact of having two reasonably consitent modes with
having only one in which any strange thing is allowed.

From: Damien Doligez <Damien.Doligez@inria.fr>

> I agree, and I would even go further.  I think the current labeling of
> the standard library is way too verbose.  "fun" should not be "func"
> or even "fn", but simply "f".  That's the usual name for a generic
> function.  Likewise, we should replace char:char with c:char and so
> on (maybe even the predicate function in List.for_all should be
> labeled f).
> 
> Also, in the List module, I found this:
> 
>     val nth : 'a list -> pos:int -> 'a
> 
> This is really bad design, unless the goal is to confuse the reader
> (two different names for the same number).  It should be either
> 
>     val nth : 'a list -> n:int -> 'a
> 
> or
> 
>     val posth : 'a list -> pos:int -> 'a
> .
> 
> I think we need to develop a systematic set of abbreviations (and a
> document to explain it) that will allow us to limit almost all labels
> to be at most one character in length.  It would (at least partially)
> solve the problem of expression cluttering that we have with the long
> labels currently in the library.  As a side-effect, it would also
> solve the problem of keywords as labels: there isn't any keyword of
> length 1.

That sounds reasonable. I would also personally prefer "f:" to "fn:".
My choice of labels has been driven by voices from olabl users who
insisted that labels should be as readable as possible, but having
short names is ok if they are readable.  Still I would not support
reducing _all_ labels to 1 character, while it might be ok for most
of them in the standard library.  Having a document for it is only
bearable as long as it is standard

The choice of pos: rather than n: in List.nth was driven by an attempt
at homogeneizing labels with other modules, in which pos: is used.
But too much homogeneity is not always good.  If the meaning does not
exactly match, then it might be better to use another label.

Remark that if we are going to do such extensive changes, we must have
a coordination to choose labels, and that it will take some time.

> This is an excellent suggestion, and I have implemented it (as of
> version 2.99+12) : I replaced the command-line option "-modern" with
> "-label".  I kept "-modern" as an alias to "-label" for the time
> being, but I certainly hope we'll retire it before we release 3.00.

You're a bit fast Damien. Personally I would really prefer -commute.
Labels are also available in classic mode, it is just that they do not
commute there.

Also a very personal comment: why do you persist in erasing the date
from the version number? I really think it helps to trace back
problems :-)

Best regards to everybody,

Jacques
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Syntax for label, NEW SOLUTION
  2000-03-19  2:29             ` Jacques Garrigue
@ 2000-03-20 18:25               ` Christophe Raffalli
  2000-03-22  8:37                 ` Claudio Sacerdoti Coen
  2000-03-21 23:29               ` John Max Skaller
  2000-03-29  8:42               ` Semantic of label: The best (only ?) solution to merge both mode Christophe Raffalli
  2 siblings, 1 reply; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-20 18:25 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: caml-list

Jacques Garrigue wrote:
> 
> As Xavier included `\' in his list (which surprised me a little, since
> for me '\' was taboo), I would go for it.
> 
> That is, replace ':' by '\' in terms, but keep ':' in types.
> Any counter-proposals?

I would still vote for ~ because it denotes some kind of equivalence
spcialy when you write "fun x~x -> " which fell like somthing reflexive
even if it is not symmetric.

> > - Their semantics in modern mode.
> >
> > I quite agree, their should not be two modes, because this will means
> > two communities of users and therefore at some point two standards
> > libraries because each kind of users will have different needs. This is
> > dangerous ...
> > soon there would not be only one big caml community anymore.
> 
> There is a misunderstanding here.  There are currently two
> communities, and one goal of the merger is to have a big caml
> community again.  I think that having two modes is a good way to reach
> this goal.  All this discussion just shows that this would be very
> difficult with only one mode.

Ok, and I agree ! What I mean is that it could happend sooner if there
was a mode that is conservetive over both modern and classic modes. I
will give a first working answer ...

> > But there may be a solution in three step:
> >
> > 1) Let's have only the modern mode. But let it accept any expressions
> > with no amibiguities. This means that if according to both types AND
> > labels there is a unique valid order of arguments then the compiler do
> > not complain.
> > ....
> I do not understand very well your proposal.  If you let arguments
> commute when there is no ambiguity, then this is just a big mess,
> because the concept of no ambiguity is only understood by the
> compiler. If you do not let them commute, then I do not see how this
> improves on classic mode, which already allows you to check labels
> when you want.

What I want is that it is possible to assign an unlabeled argument to a
function waiting for a labeled one. I give a simple modification of
Ocaml which seems to verify that in can compile both the programs
written for classic and modern mode.

An example with Array.blit:

> ocaml -modern
        Objective Caml version 2.99 (99/12/08)
 
# let f a x b y len = Array.blit a src_pos:x b dst_pos:y len;;
Warning: Argument without label used when waiting for a label
Warning: Argument without label used when waiting for a label
Warning: Argument without label used when waiting for a
label                                                                     
val f : 'a array -> int -> 'a array -> int -> int -> unit = <fun> 
# let g a x b y len = Array.blit a b len src_pos:x dst_pos:y;;
Warning: Argument without label used when waiting for a label
Warning: Argument without label used when waiting for a label
Warning: Argument without label used when waiting for a
label                                                                     
val g : 'a array -> int -> 'a array -> int -> int -> unit = <fun> 
                                                                      
This is a very simple trick which is a bit dirty (just look at it). I
think one could do much better, specially if unification over types had
been purely functional in Caml (then one could try to type in some way,
fail and try something else).

The main problem is that now Ocaml must print a warning when there are
more than one way to assign an unlabeled argument to a function waiting
for a labeled one. Otherwise, one of the role of labels is lost: capture
more bugs)

The List.fold_left fun:(+) does not work yet because I did not modify
the unification algorithm ... A simple solution is to ignore the
Clflags.classic in unification as no permutation are done by unification
anyway !

> > 3) For the problem of List.fold_left (+), there is a solution: tell to
> > the compiler that (+) is commutative ! Or more generally find a syntax
> > to tell that two or more arguments of the same types may be commuted
> > without changing the behaviour of the function. Then there would be no
> > ambiguities when you type List.fold_left (+) and the compiler wii not
> > complain ! There would be a problem only with  List.fold_left (/) but
> > then writing the labels explicitely may be better (or rewrite it with a
> > product).
> 
> Woa. Teaching properties of functions to the compiler would be very
> nice, but I'm afraid type checking technology is not nearly mature
> enough for that. That's a good subject for research :-)
>

Just giving yourself some indication like

val (+) : a:int -> a:int -> int 
(* same labels means permutation is irrelevant ! *)

To get less warnings should not be difficult.

-----------
-----------

Here are the diff for the 4 modified files : 
  btype.ml btype.mli typecore.ml and typecore.mli

>> diff btype.ml.ori btype.ml

247c247,284
< let extract_label l ls = extract_label_aux [] l ls
---
> let rec extract_label_aux' count hd = function
>     [] -> raise Not_found
>   | (l',t as p) :: ls ->
>       if !count = 0 && label_name l' = "" then (l', t, List.rev hd, ls)
>       else begin
>       if label_name l' = "" then decr count;
>       extract_label_aux' count (p::hd) ls
>       end
>
> let num_unlabeled_arrow ty =
>     let rec fn acc = function
>       {desc=Tarrow (l, ty, ty_fun)} ->
>         fn (if l = "" then acc+1 else acc) ty_fun
>       |       _ -> acc
>     in fn 0 ty
>
> let num_unlabeled_clarrow ty =
>     let rec fn acc = function
>       Tcty_fun (l, ty, ty_fun) ->
>         fn (if l = "" then acc+1 else acc) ty_fun
>       |       _ -> acc
>     in fn 0 ty
>
> let extract_label count opt l ls mls =
>   try
>     let (l', ls0, ls1, ls2) = extract_label_aux [] l ls
>     in (l', ls0, ls1 @ ls2, mls, false)
>   with Not_found -> try
>     let (l', ls0, ls1, ls2) = extract_label_aux [] l mls
>     in (l', ls0, ls @ ls1, ls2, false)
>   with Not_found when not opt ->
>     let count = ref count in
>     try
>       let (l', ls0, ls1, ls2) = extract_label_aux' count [] ls
>       in (l', ls0, ls1 @ ls2, mls, true)
>     with Not_found ->
>       let (l', ls0, ls1, ls2) = extract_label_aux' count [] mls
>       in (l', ls0, ls @ ls1, ls2, true)                                                                                         

>>diff typecore.ml.ori typecore.ml 

926,932c926,927
<             let (l', sarg0, sargs, more_sargs) =
<               try
<                 let (l', sarg0, sargs1, sargs2) = extract_label name
sargs
<                 in (l', sarg0, sargs1 @ sargs2, more_sargs)
<               with Not_found ->
<                 let (l', sarg0, sargs1, sargs2) = extract_label name
more_sargs
<                 in (l', sarg0, sargs @ sargs1, sargs2)
---
>             let (l', sarg0, sargs, more_sargs, unlab_args) =
>             extract_label (num_unlabeled_arrow ty_fun') (is_optional l) name sargs more_sargs
933a929,931
>           if unlab_args then
>             Location.print_warning sarg0.pexp_loc
>               (Warnings.Other "Argument without label used when waiting for a label");                                          

>> diff typeclass.ml.ori typeclass.ml
637,645c637,639
<                 let (l', sarg0, sargs, more_sargs) =
<                   try
<                     let (l', sarg0, sargs1, sargs2) =
<                       Btype.extract_label name sargs
<                     in (l', sarg0, sargs1 @ sargs2, more_sargs)
<                   with Not_found ->
<                     let (l', sarg0, sargs1, sargs2) =
<                       Btype.extract_label name more_sargs
<                     in (l', sarg0, sargs @ sargs1, sargs2)
---
>                 let (l', sarg0, sargs, more_sargs, unlab_args) =
>                 Btype.extract_label (Btype.num_unlabeled_clarrow ty_fun)
>                   (Btype.is_optional l) name sargs more_sargs
646a641,643
>               if unlab_args then
>                 Location.print_warning sarg0.pexp_loc
>                   (Warnings.Other "Argument without label used when waiting for a label");                                      

and modify like this the the end of btype.mli (I forgot to keep the
original)

val num_unlabeled_arrow : type_expr -> int
val num_unlabeled_clarrow : class_type -> int

val extract_label :
    int -> bool -> label -> (label * 'a) list -> (label * 'a) list ->
    label * 'a * (label * 'a) list * (label * 'a) list * bool
    (* actual label, value, before list, after list *)

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Syntax for label (and more)
  2000-03-15 20:39   ` Syntax for label (and more) Xavier Leroy
  2000-03-17 10:03     ` Christian RINDERKNECHT
@ 2000-03-21  1:29     ` Markus Mottl
  1 sibling, 0 replies; 60+ messages in thread
From: Markus Mottl @ 2000-03-21  1:29 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: OCAML

> - User contributions to the standard library: I'm open to concrete
> proposals on this.  One of the reasons why the OCaml standard library
> modules have remained minimal is that it's often hard to know what
> would be useful to a significant fraction of users (as opposed to
> functions that only their author is going to use).  Also, we must be
> careful to keep the standard library manageable, e.g. with consistent
> naming conventions and good documentation.  For all these aspects,
> some kind of peer reviewing of new extensions sounds good.

There are some questions concerning upgrading the standard library that
should be cleared before, I think:

Firstly, is there already a specific plan for the further development of
the standard library? Adding a function here and there is unlikely to lead
to consistent functionality. There is probably already a TODO-list for the
next "big" steps in compiler development, but is this also the case for the
libraries?

Maybe a "two way" approach would be appropriate, where also users might
want to help: in one branch we just (conservatively!) extend the current
standard library, letting the main developers decide when to adopt the
changes, in another we create completely new components, which might either
provide for new functionality or replace older modules at some point of
time (again, the decision for adopting new modules or declaring old ones
obsolete should be up to the main developers).

The latter "branch" raises the following questions:

  - Which abstract data types, what kind of special purpose libraries are
    wanted/required in the distribution?

  - Would it be a good idea to provide for different implementations for
    the same interface if this has significant impact on performance or is
    one "generally acceptable" implementation the better way?

  - Version control for the developers is fine - but what about the users?
    How can we guarantee that they do not easily end up with legacy
    software if their systems make use of older libraries?

The last part, for example, seems to uncover a problem that has already
been discussed on the mailing list from time to time: packaging of
libraries and dependency management (there are also dependencies on
versions).

If this problem is conveniently solved, we won't have to be so reluctant
changing things in the standard library. Disk space is really not a topic
anymore today so having subdirectories in the distribution that contain
older releases of libraries will surely not hurt.

Users who need to guarantee that their older systems compile with new
releases could possibly do so, for example, by writing

  open Stdlib_V3_1

or similar at the top of their files (would require that directories can be
treated like a module with submodules) - but maybe there are better ways to
do this?


For the beginning, we could try the "small" branch first to see whether the
nice ideas (collaborative work, peer reviews) really work. So if nobody
objects, would it be possible to set up a directory at "camlcvs", where
users could experiment with "their" standard library? - Of course, each
user would have to ask personally for access to this account, but this
shouldn't be a problem, I hope...

Comments?

Best regards,
Markus Mottl

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-16  2:55     ` Jacques Garrigue
  2000-03-17 15:13       ` Pierre Weis
@ 2000-03-21 16:51       ` Pascal Brisset
  2000-03-23 11:14         ` Nicolas barnier
  2000-03-21 22:22       ` Unsigned integers? John Max Skaller
  2 siblings, 1 reply; 60+ messages in thread
From: Pascal Brisset @ 2000-03-21 16:51 UTC (permalink / raw)
  To: caml-list; +Cc: Jacques Garrigue, Pierre.Weis

Jacques Garrigue writes:
> From: Pierre Weis <Pierre.Weis@inria.fr>
> >    * undesired labels: in many cases I don't want to have labels just
> >      because I don't want to remember their names. (E.g., I very often
> >      mispell the label acc since I've always used accu to name an
> >      accumulator; furthermore, when I do not mispell this label, I feel
> >      acc:accu extremely verbose). Also because labels are verbose at
> >      application.
> 
> Isn't there a classic mode for that?

 Something I do not understand: how could I use Labltk, for which I want
to be modern, and List.fold_right, for which I do not want labels, in the
same file ?
 By the way, the label "acc" (or even "accu") does not mean anything for me
in fold_right: the iterator associates one function to each
constructor of the type so I would prefer

val fold_right: cons:(hd:'a -> tl:'b -> 'b) -> nil:'b -> list:'a list -> 'b

[...]

> It would cost nothing to add 4 more unlabelled functions to the List
> module.

 Please add a smiley when you write such a sentence !

[...]

> Or do you think that the problem is deeper, and that labels are
> breaking the foundations of the language ?

 Please ! The debate is about presence of labels in the standard library,
not in the language.
 Today, it is possible to teach Ocaml without speaking about objects,
modules (functors are not so common in libraries), streams, etc. If labels
are in the standard library you will have to explain one more (nice
and not so simple) feature before being able to use one
simple list iterator ...

Amicalement

--Pascal



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

* Unsigned integers?
  2000-03-16  2:55     ` Jacques Garrigue
  2000-03-17 15:13       ` Pierre Weis
  2000-03-21 16:51       ` Pascal Brisset
@ 2000-03-21 22:22       ` John Max Skaller
  2000-03-22 16:22         ` Sven LUTHER
                           ` (2 more replies)
  2 siblings, 3 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-21 22:22 UTC (permalink / raw)
  Cc: caml-list

I have some code for processing ISO-10646 characters and UTF-8,
which uses caml integers. ISO-10646 has 2^31 code points, which
can be covered by caml integers on a 32bit machine. Using an
unboxed type is mandatory for performance.

Unfortunately, caml integers are signed, which makes most of the
code I have written wrong (I haven't taken the care to handle
integers over 2^30 correctly).

What is the best way to handle this problem?
Would a (standard?) library module (written in C), that treats
integers as unsigned be a reasonable solution?

[This may require writing 'uint_add x y' instead of 'x+y',
but that doesn't matter in the above mentioned application,
since the integers are being used to represent characters]

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Syntax for label, NEW SOLUTION
  2000-03-19  2:29             ` Jacques Garrigue
  2000-03-20 18:25               ` Christophe Raffalli
@ 2000-03-21 23:29               ` John Max Skaller
  2000-03-29  8:42               ` Semantic of label: The best (only ?) solution to merge both mode Christophe Raffalli
  2 siblings, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-21 23:29 UTC (permalink / raw)
  To: caml-list

Jacques Garrigue wrote:

> There is a misunderstanding here.  There are currently two
> communities, and one goal of the merger is to have a big caml
> community again.  I think that having two modes is a good way to reach
> this goal.  

	I do not: in the short term, two modes is a good compromise.
In the longer term, one language is better. I am glad for the two 
modes at present. I hope they will go away in the future.

> > o The fact that you've had to resort to "modes" at all indicates something
> > is wrong.  

> Well, before that there were two compilers.  I think this is a progress.

	I agree. Particularly, I was attracted by some of the
olabl software but was not willing to use two compilers. Now I have
the nice olabl software, and still have  my ocaml software too.
 
> > If we could come up with a semantics where labels are always optional,
> > I think I would accept things like acc in the standard library.  But
> > when you have to make a choice between optional labels and no useful
> > functionality, it's a harder sell.
> 
> Some people really want to eat the cake and still have it.

	Sure, why not?

> I already explained a while ago why it was not possible to have labels
> both optionals and commuting in a curried language.

	Sure it is. The question is whether the error messages
are readable.  Python supports 

	1) positional arguments
	2) labelled arguments
	3) default values for missing trailing positional parameters
	4) optional labelled AND positional arguments

It does not support currying, but it does diagnose missing arguments,
and such could be re-implemented as partial applications.

	FYI the rules are: for a definition:

	def f(x,y,z=1,q=2,*args, **kwds): ...

and calls

	f(1,2)
	f(1,2,3,4,5,6,7)
	f(1,z=6,y=4, extra=22)


	1) bind parameters to the given positional arguments positionally.
	If there are too many, the extra ones go into the tuple 'args' if
given,
	else error.

	2) try to bind the remaining positional arguments from labelled ones.
	If there is a duplication of labelled and positional arguments, error.
	If there are still missing required arguments, 
		then use the default if there is one,
		else error (change to 'curry' for our purposes)

	3) if **kwds is given,
		put all the labelled arguments into dictionary kwds (even those
		used to fill in required arguments)

	4) if there are excess labelled arguments and no kwds, then error.

Thousands of Python programmers use this scheme every day. 
Currying missing arguments would disable error checking,
so in Python you have to use a separate function definition.

[This could actually be fixed by sugar: use f(x, curry) to signify
intentional currying]

	I'm not suggesting to use thd Python scheme, only that
it _is_ possible to support optional commuting labelled arguments
and optional arguments, and default arguments, and variable
length argument lists and arbitrary option sets coherently.

> Do not confuse the fact of having two reasonably consitent modes with
> having only one in which any strange thing is allowed.

	Also do not confuse 'we cannot think of a synthesis of the
modes which makes sense' with 'there exists no such synthesis' :-)
 
> That sounds reasonable. I would also personally prefer "f:" to "fn:".
> My choice of labels has been driven by voices from olabl users who
> insisted that labels should be as readable as possible, but having
> short names is ok if they are readable.  Still I would not support
> reducing _all_ labels to 1 character, while it might be ok for most
> of them in the standard library.  Having a document for it is only
> bearable as long as it is standard

	Why not allow several (synonymous) labels?

	let f c: chr: character: the_really_verbose_character: c' = c'

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Syntax for label, NEW SOLUTION
  2000-03-20 18:25               ` Christophe Raffalli
@ 2000-03-22  8:37                 ` Claudio Sacerdoti Coen
  0 siblings, 0 replies; 60+ messages in thread
From: Claudio Sacerdoti Coen @ 2000-03-22  8:37 UTC (permalink / raw)
  To: caml-list

On Mon, Mar 20, 2000 at 19:25:04 +0100, Christophe Raffalli wrote:
> Ok, and I agree ! What I mean is that it could happend sooner if there
> was a mode that is conservetive over both modern and classic modes. I
> will give a first working answer ...

There could be also another simple, backward compatible (w.r.t. OCaml)
solution that would get rid of the "labels in the library" fight.
Only, I don't know if it is (semantically) feasible. Here it is:

If I write

 Moo.foo x a:y z;;

or

 open Moo;;
 foo x a:y z;;

or

 let module M = Moo in
  M.foo x a:y z;;

than foo is label-checked as in classic mode.

Instead, if I write 

 open Moo in commutating mode;;  (* or something like that *)
 foo x a:y z;;

than foo is label-checked as in modern mode.

So, for example, I could write

open List;;
open Unix as in moder mode.
open Tk as in moder mode.

What am I overlooking?

					C.S.C.

-- 
-----------------------------------------
Real Name: Claudio Sacerdoti Coen
Graduating students at the
 Department of Computer Science,
 university of Bologna
Address: via del Colle n.6
	 S. Lazzaro di Savena (BO)
	 Italy
e-mail:  sacerdot@cs.unibo.it
-----------------------------------------



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

* Re: Unsigned integers?
  2000-03-21 22:22       ` Unsigned integers? John Max Skaller
@ 2000-03-22 16:22         ` Sven LUTHER
  2000-03-23  2:08           ` Max Skaller
  2000-03-22 17:05         ` Jean-Christophe Filliatre
  2000-03-22 19:47         ` Xavier Leroy
  2 siblings, 1 reply; 60+ messages in thread
From: Sven LUTHER @ 2000-03-22 16:22 UTC (permalink / raw)
  To: John Max Skaller; +Cc: caml-list

On Wed, Mar 22, 2000 at 09:22:15AM +1100, John Max Skaller wrote:
> I have some code for processing ISO-10646 characters and UTF-8,
> which uses caml integers. ISO-10646 has 2^31 code points, which
> can be covered by caml integers on a 32bit machine. Using an
> unboxed type is mandatory for performance.
> 
> Unfortunately, caml integers are signed, which makes most of the
> code I have written wrong (I haven't taken the care to handle
> integers over 2^30 correctly).
> 
> What is the best way to handle this problem?
> Would a (standard?) library module (written in C), that treats
> integers as unsigned be a reasonable solution?
> 
> [This may require writing 'uint_add x y' instead of 'x+y',
> but that doesn't matter in the above mentioned application,
> since the integers are being used to represent characters]

Just use the caml integer and ignore the fact that they are signed ?

after the moto :  that doesn't matter in the above mentioned application,
since the integers are being used to represent characters] 

But then i don't know what you use it for ...

And also, you would have to check exactly how integer overflow work, but in my
experience max_int+1 = min_int.

Friendly,

Sven LUTHER



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

* Re: Unsigned integers?
  2000-03-21 22:22       ` Unsigned integers? John Max Skaller
  2000-03-22 16:22         ` Sven LUTHER
@ 2000-03-22 17:05         ` Jean-Christophe Filliatre
  2000-03-22 19:10           ` Markus Mottl
  2000-03-23  2:41           ` Max Skaller
  2000-03-22 19:47         ` Xavier Leroy
  2 siblings, 2 replies; 60+ messages in thread
From: Jean-Christophe Filliatre @ 2000-03-22 17:05 UTC (permalink / raw)
  To: John Max Skaller; +Cc: caml-list


In his message of Wed March 22, 2000, John Max Skaller writes: 
> 
> Unfortunately, caml integers are signed, which makes most of the
> code I have written wrong (I haven't taken the care to handle
> integers over 2^30 correctly).
> 
> What is the best way to handle this problem?
> Would a (standard?) library module (written in C), that treats
> integers as unsigned be a reasonable solution?

I wrote such a C library to handle (boxed) 32 or 64 bits integers (you
can find  it on my  web page).  But it appeared  that it was  not very
efficient, and  when I rewrote my  program using an  encoding with two
Caml integers, it was really faster.

So I  would suggest you to  write such a  library in Caml. For  a good
starting point, you  may have a look at the  module Nativeint in ocaml
sources (in utils/nativeint.ml).

Best regards,
-- 
Jean-Christophe Filliatre    
  Computer Science Laboratory   Phone (650) 859-5173
  SRI International             FAX   (650) 859-2844
  333 Ravenswood Ave.           email  filliatr@csl.sri.com
  Menlo Park, CA 94025, USA     web    http://www.csl.sri.com/~filliatr

  



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

* Re: Unsigned integers?
  2000-03-22 17:05         ` Jean-Christophe Filliatre
@ 2000-03-22 19:10           ` Markus Mottl
  2000-03-23  2:41           ` Max Skaller
  1 sibling, 0 replies; 60+ messages in thread
From: Markus Mottl @ 2000-03-22 19:10 UTC (permalink / raw)
  To: filliatr; +Cc: OCAML

> So I  would suggest you to  write such a  library in Caml. For  a good
> starting point, you  may have a look at the  module Nativeint in ocaml
> sources (in utils/nativeint.ml).

Or even more conveniently: check out the current CVS-repository at INRIA!
Seems that the problems with integers are soon going to be history...

  -> ocaml/stdlib/int32.mli
     ocaml/stdlib/int64.mli

Though, I fear that unboxed, complete native integers will never be
supported. Anyway, if you only need complete 32-bit-ints, you may as well
purchase a real processor (Alpha)... ;-)

Best regards,
Markus Mottl

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl



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

* Re: Unsigned integers?
  2000-03-21 22:22       ` Unsigned integers? John Max Skaller
  2000-03-22 16:22         ` Sven LUTHER
  2000-03-22 17:05         ` Jean-Christophe Filliatre
@ 2000-03-22 19:47         ` Xavier Leroy
  2000-03-23 12:55           ` John Max Skaller
  2 siblings, 1 reply; 60+ messages in thread
From: Xavier Leroy @ 2000-03-22 19:47 UTC (permalink / raw)
  To: John Max Skaller; +Cc: caml-list

> I have some code for processing ISO-10646 characters and UTF-8,
> which uses caml integers. ISO-10646 has 2^31 code points, which
> can be covered by caml integers on a 32bit machine. Using an
> unboxed type is mandatory for performance.

OCaml 3.00 includes three new library modules, Int32, Int64 and
Nativeint, implementing (boxed) 32-bit, 64-bit and platform-native
integers, resepctively.  (Platform-native integers are 32 bits on 32
bit processors and 64 bits on 64 bit processors).  The native-code
compiler was modified to inline the operations on those types,
including elimination of unnecessary boxing/unboxing, like for floats.
That may or may not be efficient enough for your application.  

> Unfortunately, caml integers are signed, which makes most of the
> code I have written wrong (I haven't taken the care to handle
> integers over 2^30 correctly).

Actually, on 2's-complement machines at least, arithmetic operations
over usigned integers are exactly identical to those over signed
integers of the same size, except divisio, modulus, and
comparisons <, >, <=, >=.   So, for your application, Caml's "int"
type could be good enough, although you may need special comparison
functions (which you can write in C, using casts to unsigned long int,
or in Caml, by treating the sign bit specially).

- Xavier Leroy



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

* Re: Unsigned integers?
  2000-03-22 16:22         ` Sven LUTHER
@ 2000-03-23  2:08           ` Max Skaller
  2000-03-23  7:50             ` Sven LUTHER
                               ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Max Skaller @ 2000-03-23  2:08 UTC (permalink / raw)
  To: luther; +Cc: John Max Skaller, caml-list

Sven LUTHER wrote:
> 
> On Wed, Mar 22, 2000 at 09:22:15AM +1100, John Max Skaller wrote:
> > I have some code for processing ISO-10646 characters and UTF-8,
> > which uses caml integers. ISO-10646 has 2^31 code points, which
> > can be covered by caml integers on a 32bit machine. Using an
> > unboxed type is mandatory for performance.
> >
> > Unfortunately, caml integers are signed, which makes most of the
> > code I have written wrong (I haven't taken the care to handle
> > integers over 2^30 correctly).
> >
> > What is the best way to handle this problem?
> > Would a (standard?) library module (written in C), that treats
> > integers as unsigned be a reasonable solution?
> >
> > [This may require writing 'uint_add x y' instead of 'x+y',
> > but that doesn't matter in the above mentioned application,
> > since the integers are being used to represent characters]
> 
> Just use the caml integer and ignore the fact that they are signed ?
> 
> after the moto :  that doesn't matter in the above mentioned application,

Perhaps my explanation was unclear. In my code, I must 
calculate a UTF-8 encoding from a ISO-10646 code point,
and calculate an ISO-10646 code point from a UTF-8 encoding.

The code is below. The code works for values <2^30,
but fails when and int goes negative.

I would be happy to replace, in this code,
evey use of 'lor', 'land', + - * < etc with
'ulor' 'uland' 'uplus' 'uminus' 'uless' etc, if only
I could define them. (I could do this in C .. but then,
I could write the below routines in C too)

Note these operations MUST be extremely fast,
and in particular, compact storage of ISO-10646
code points in arrays of integers is OK,
while arrays of boxed values is out of the question.
(So I can't use int32).

-------------------------------------------------------


let parse_utf8 (s : string)  (i : int) : int * int =
  let ord = int_of_char 
  and n = (String.length s)  - i
  in if n <= 0 then begin print_endline "FAILURE"; (-1),i end
  else let lead = ord (s.[i]) in
    if (lead land 0x80) = 0 then 
      lead land 0x7F,i+1 (* ASCII *)
    else if lead land 0xE0 = 0xC0 && n > 1 then
      ((lead land 0x1F)  lsl  6) lor
        (ord(s.[i+1]) land 0x3F),i+2
    else if lead land 0xF0 = 0xE0 && n > 2 then
      ((lead land 0x1F) lsl 12) lor
        ((ord(s.[i+1]) land 0x3F)  lsl 6) lor
        (ord(s.[i+2]) land 0x3F),i+3
    else if lead land 0xF8 = 0xF0 && n > 3 then
      ((lead land 0x1F) lsl 18) lor
        ((ord(s.[i+1]) land 0x3F)  lsl 12) lor
        ((ord(s.[i+2]) land 0x3F)  lsl 6) lor
        (ord(s.[i+3]) land 0x3F),i+4
    else if lead land 0xFC = 0xF8 && n > 4 then
      ((lead land 0x1F) lsl 24) lor 
        ((ord(s.[i+1]) land 0x3F)  lsl 18) lor
        ((ord(s.[i+2]) land 0x3F)  lsl 12) lor
        ((ord(s.[i+3]) land 0x3F)  lsl 6) lor
        (ord(s.[i+4]) land 0x3F),i+5
    else if lead land 0xFE = 0xFC && n > 5 then
      ((lead land 0x1F) lsl 30) lor
        ((ord(s.[i+1]) land 0x3F)  lsl 24) lor
        ((ord(s.[i+2]) land 0x3F)  lsl 18) lor
        ((ord(s.[i+3]) land 0x3F)  lsl 12) lor
        ((ord(s.[i+4]) land 0x3F)  lsl 6) lor
        (ord(s.[i+5]) land 0x3F),i+6
    else lead, i+1  (* error, just use bad character *)

(* convert an integer into a utf-8 encoded string of bytes *)
let utf8_of_int i =
  let chr x = String.make 1 (Char.chr x) in
  if i < 0x80 then 
     chr(i)
  else if i < 0x800 then 
     chr(0xC0 lor ((i lsr 6) land 0x1F))  ^
      chr(0x80 lor (i land 0x3F))
  else if i < 0x10000 then 
     chr(0xE0 lor ((i lsr 12) land 0xF)) ^
      chr(0x80 lor ((i lsr 6) land 0x3F)) ^
      chr(0x80 lor (i land 0x3F))
  else if i < 0x200000 then 
     chr(0xF0 lor ((i lsr 18) land 0x7)) ^
      chr(0x80 lor ((i lsr 12) land 0x3F)) ^
      chr(0x80 lor ((i lsr 6) land 0x3F)) ^
      chr(0x80 lor (i land 0x3F))
  else if i < 0x4000000 then 
     chr(0xF8 lor ((i lsr 24) land 0x3)) ^
      chr(0x80 lor ((i lsr 18) land 0x3F)) ^
      chr(0x80 lor ((i lsr 12) land 0x3F)) ^
      chr(0x80 lor ((i lsr 6) land 0x3F)) ^
      chr(0x80 lor (i land 0x3F))
  else chr(0xFC lor ((i lsr 30) land 0x1)) ^
    chr(0x80 lor ((i lsr 24) land 0x3F)) ^
    chr(0x80 lor ((i lsr 18) land 0x3F)) ^
    chr(0x80 lor ((i lsr 12) land 0x3F)) ^
    chr(0x80 lor ((i lsr 6) land 0x3F)) ^
    chr(0x80 lor (i land 0x3F))


	

-- 
John (Max) Skaller at OTT [Open Telecommications Ltd]
mailto:maxs@in.ot.com.au      -- at work
mailto:skaller@maxtal.com.au  -- at home



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

* Re: Unsigned integers?
  2000-03-22 17:05         ` Jean-Christophe Filliatre
  2000-03-22 19:10           ` Markus Mottl
@ 2000-03-23  2:41           ` Max Skaller
  1 sibling, 0 replies; 60+ messages in thread
From: Max Skaller @ 2000-03-23  2:41 UTC (permalink / raw)
  To: Jean-Christophe Filliatre; +Cc: John Max Skaller, caml-list

Jean-Christophe Filliatre wrote:
 
> I wrote such a C library to handle (boxed) 32 or 64 bits integers (you
> can find  it on my  web page).  But it appeared  that it was  not very
> efficient, and  when I rewrote my  program using an  encoding with two
> Caml integers, it was really faster.
> 
> So I  would suggest you to  write such a  library in Caml. For  a good
> starting point, you  may have a look at the  module Nativeint in ocaml
> sources (in utils/nativeint.ml).

OK. This is probably the way to do it.

-- 
John (Max) Skaller at OTT [Open Telecommications Ltd]
mailto:maxs@in.ot.com.au      -- at work
mailto:skaller@maxtal.com.au  -- at home



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

* Re: Unsigned integers?
  2000-03-23  2:08           ` Max Skaller
@ 2000-03-23  7:50             ` Sven LUTHER
  2000-03-24  2:50             ` Jacques Garrigue
  2000-03-24 14:50             ` Xavier Leroy
  2 siblings, 0 replies; 60+ messages in thread
From: Sven LUTHER @ 2000-03-23  7:50 UTC (permalink / raw)
  To: Max Skaller; +Cc: John Max Skaller, caml-list

On Thu, Mar 23, 2000 at 01:08:54PM +1100, Max Skaller wrote:
> Sven LUTHER wrote:
> > 
> > On Wed, Mar 22, 2000 at 09:22:15AM +1100, John Max Skaller wrote:
> > > I have some code for processing ISO-10646 characters and UTF-8,
> > > which uses caml integers. ISO-10646 has 2^31 code points, which
> > > can be covered by caml integers on a 32bit machine. Using an
> > > unboxed type is mandatory for performance.
> > >
> > > Unfortunately, caml integers are signed, which makes most of the
> > > code I have written wrong (I haven't taken the care to handle
> > > integers over 2^30 correctly).
> > >
> > > What is the best way to handle this problem?
> > > Would a (standard?) library module (written in C), that treats
> > > integers as unsigned be a reasonable solution?
> > >
> > > [This may require writing 'uint_add x y' instead of 'x+y',
> > > but that doesn't matter in the above mentioned application,
> > > since the integers are being used to represent characters]
> > 
> > Just use the caml integer and ignore the fact that they are signed ?
> > 
> > after the moto :  that doesn't matter in the above mentioned application,
> 
> Perhaps my explanation was unclear. In my code, I must 
> calculate a UTF-8 encoding from a ISO-10646 code point,
> and calculate an ISO-10646 code point from a UTF-8 encoding.
> 
> The code is below. The code works for values <2^30,
> but fails when and int goes negative.
> 
> I would be happy to replace, in this code,
> evey use of 'lor', 'land', + - * < etc with
> 'ulor' 'uland' 'uplus' 'uminus' 'uless' etc, if only
> I could define them. (I could do this in C .. but then,
> I could write the below routines in C too)
> 

just redefine the above mentioned operations in caml, taking the overflow in
account, it should not be too difficult, altough it should be a bit less
efficient than the normal +, -, ... (altough i am not sure about it, maybe you
could just ignore it and use the normal functions. At least for + and - it
should work without problem.

to test them, use a function to print the type as unsigned int, and use
#install_printer to use it as default printer for ints.

Friendly

Sven LUTHER



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

* Re: Syntax for label, NEW PROPOSAL
  2000-03-21 16:51       ` Pascal Brisset
@ 2000-03-23 11:14         ` Nicolas barnier
  2000-03-24  9:54           ` labels & ocaml 3 & co David Mentré
  0 siblings, 1 reply; 60+ messages in thread
From: Nicolas barnier @ 2000-03-23 11:14 UTC (permalink / raw)
  To: caml-list

I'm quite tired with all this polemic. I agree
with Pierre Weis: labels are a pain within HO
args (acc:, i:) and fun:(fun ...) is ugly and
verbose (and it contains its own sad smiley :).
So I do not want (arbitrary) labels in my good
old standard library, but I find them very useful
in Labltk. Moreover, two compile modes are not
a very good idea for obvious portability reasons.
So I think we should switch to a single modern
mode because labels in modern mode are useful
and simple (at least in Labltk), and withdraw
labels in the standard library because they're
often a pain (and the lib is small enough to
learn without the need for labels). We would
then keep labels an orthogonal improvment.

Cheers

-- Nicolas

P.S.: I saw in the lib that the *.mli are
written with labels whereas the *.ml do not
contain a single one. Can we conclude on which
side stands Xavier ?



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

* Re: Unsigned integers?
  2000-03-22 19:47         ` Xavier Leroy
@ 2000-03-23 12:55           ` John Max Skaller
  0 siblings, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-23 12:55 UTC (permalink / raw)
  To: Xavier Leroy; +Cc: caml-list

Xavier Leroy wrote:
> 
> > I have some code for processing ISO-10646 characters and UTF-8,
> > which uses caml integers. ISO-10646 has 2^31 code points, which
> > can be covered by caml integers on a 32bit machine. Using an
> > unboxed type is mandatory for performance.
> 
> OCaml 3.00 includes three new library modules, Int32, Int64 and
> Nativeint, implementing (boxed) 32-bit, 64-bit and platform-native
> integers, resepctively.  (Platform-native integers are 32 bits on 32
> bit processors and 64 bits on 64 bit processors).  The native-code
> compiler was modified to inline the operations on those types,
> including elimination of unnecessary boxing/unboxing, like for floats.
> That may or may not be efficient enough for your application.

	This is probably enough, provided I can write
conversions to/from ints.

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Unsigned integers?
  2000-03-23  2:08           ` Max Skaller
  2000-03-23  7:50             ` Sven LUTHER
@ 2000-03-24  2:50             ` Jacques Garrigue
  2000-03-24 15:59               ` Xavier Leroy
  2000-03-25  4:03               ` John Max Skaller
  2000-03-24 14:50             ` Xavier Leroy
  2 siblings, 2 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-24  2:50 UTC (permalink / raw)
  To: maxs; +Cc: caml-list

From: Max Skaller <maxs@in.ot.com.au>

> Note these operations MUST be extremely fast,
> and in particular, compact storage of ISO-10646
> code points in arrays of integers is OK,
> while arrays of boxed values is out of the question.
> (So I can't use int32).

If compact storage is the problem, ocaml 3.00 also provides bigarrays,
which allow you to store int32 values in flat arrays (even
multidimensional).
For the cost of boxing/unboxing in int32 computations, you will
probably have to test whether it meets your needs or not.

By the way, is there any plan to do for int32 the same kind of
optimizations as are done for floats (no boxing/unboxing in the middle
of a computation)? Already done?

---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* labels & ocaml 3 & co.
  2000-03-23 11:14         ` Nicolas barnier
@ 2000-03-24  9:54           ` David Mentré
  2000-03-24 12:19             ` David Mentré
  0 siblings, 1 reply; 60+ messages in thread
From: David Mentré @ 2000-03-24  9:54 UTC (permalink / raw)
  To: Nicolas barnier; +Cc: caml-list

Nicolas barnier <barnier@recherche.enac.fr> writes:

> I'm quite tired with all this polemic.

so do I. 

> Moreover, two compile modes are not a very good idea for obvious
> portability reasons.

I agree.

> So I think we should switch to a single modern mode because labels in
> modern mode are useful and simple (at least in Labltk),

Agree.

> and withdraw labels in the standard library because they're often a
> pain (and the lib is small enough to learn without the need for
> labels).

Agree. But another proposal : why not use *only optional labels* in the
standard library?

Therefore :

- traditionnal (classic) caml users are not forced to use labels at all
  (even if they are available)

- label (modern) caml users can use them freely, with arguments
  commutativity and so on


> We would then keep labels an orthogonal improvment.

I think everybody agree on this (only? :-) point. 


Sincerely,
david
-- 
 David.Mentre@irisa.fr -- http://www.irisa.fr/prive/dmentre/
 Opinions expressed here are only mine.



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

* Re: labels & ocaml 3 & co.
  2000-03-24  9:54           ` labels & ocaml 3 & co David Mentré
@ 2000-03-24 12:19             ` David Mentré
  0 siblings, 0 replies; 60+ messages in thread
From: David Mentré @ 2000-03-24 12:19 UTC (permalink / raw)
  To: Nicolas barnier; +Cc: caml-list, garrigue

David.Mentre@irisa.fr (David Mentré) writes:

> Agree. But another proposal : why not use *only optional labels* in the
> standard library?

Oops. I think I've confused optionnal *arguments* and optionnal
*labels*. Sorry.

So the best way is probably to avoid using labels in stdlib at all.

BTW, Jacques Garrigue, is it mandatory to have labels to exploit label
commutativity? For example, an application without labels would be
considered as a standard ocaml2 application, whereas application with
labels would be an ocaml3-modern label-commutative application. If this
could be possible, we could combine best of both worlds (ie no labels or
commutative-labels for stdlib).

Best regards,
d.
-- 
 David.Mentre@irisa.fr -- http://www.irisa.fr/prive/dmentre/
 Opinions expressed here are only mine.



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

* Re: Unsigned integers?
  2000-03-23  2:08           ` Max Skaller
  2000-03-23  7:50             ` Sven LUTHER
  2000-03-24  2:50             ` Jacques Garrigue
@ 2000-03-24 14:50             ` Xavier Leroy
  2 siblings, 0 replies; 60+ messages in thread
From: Xavier Leroy @ 2000-03-24 14:50 UTC (permalink / raw)
  To: Max Skaller, caml-list

> The code is below. The code works for values <2^30,
> but fails when and int goes negative.

It is easy to fix this.  The "parse_utf8" function needs not be
modified.  For "utf8_of_int", just replace all tests i < CST by
i >= 0 && i < CST, e.g.

> let utf8_of_int i =
>   let chr x = String.make 1 (Char.chr x) in
>   if i >= 0 && i < 0x80 then 
>      chr(i)
>   else if i >= 0 && i < 0x800 then 
>      chr(0xC0 lor ((i lsr 6) land 0x1F))  ^
>       chr(0x80 lor (i land 0x3F))
>   else if i >= 0 && i < 0x10000 then 
>      chr(0xE0 lor ((i lsr 12) land 0xF)) ^
>       chr(0x80 lor ((i lsr 6) land 0x3F)) ^
>       chr(0x80 lor (i land 0x3F))
>   else if i >= 0 && i < 0x200000 then 
>      chr(0xF0 lor ((i lsr 18) land 0x7)) ^
>       chr(0x80 lor ((i lsr 12) land 0x3F)) ^
>       chr(0x80 lor ((i lsr 6) land 0x3F)) ^
>       chr(0x80 lor (i land 0x3F))
>   else if i >= 0 && i < 0x4000000 then 
>      chr(0xF8 lor ((i lsr 24) land 0x3)) ^
>       chr(0x80 lor ((i lsr 18) land 0x3F)) ^
>       chr(0x80 lor ((i lsr 12) land 0x3F)) ^
>       chr(0x80 lor ((i lsr 6) land 0x3F)) ^
>       chr(0x80 lor (i land 0x3F))
>   else chr(0xFC lor ((i lsr 30) land 0x1)) ^
>     chr(0x80 lor ((i lsr 24) land 0x3F)) ^
>     chr(0x80 lor ((i lsr 18) land 0x3F)) ^
>     chr(0x80 lor ((i lsr 12) land 0x3F)) ^
>     chr(0x80 lor ((i lsr 6) land 0x3F)) ^
>     chr(0x80 lor (i land 0x3F))

or special-case i < 0 immediately and treat it as in the last "else"
clause.

> Note these operations MUST be extremely fast,
> and in particular, compact storage of ISO-10646
> code points in arrays of integers is OK,
> while arrays of boxed values is out of the question.
> (So I can't use int32).

If they MUST be extremely fast, you'd rather avoid the repeated "^"
operations and allocate and fill the resulting string directly, e.g.

>   else if i >= 0 && i < 0x800 then begin
        let res = String.create 2 in
        res.[0] <- chr(0xC0 lor ((i lsr 6) land 0x1F));
        res.[1] <- chr(0x80 lor (i land 0x3F));
        res
    end else ...

Hope this helps,

- Xavier Leroy



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

* Re: Unsigned integers?
  2000-03-24  2:50             ` Jacques Garrigue
@ 2000-03-24 15:59               ` Xavier Leroy
  2000-03-25  4:03               ` John Max Skaller
  1 sibling, 0 replies; 60+ messages in thread
From: Xavier Leroy @ 2000-03-24 15:59 UTC (permalink / raw)
  To: Jacques Garrigue, maxs; +Cc: caml-list

> By the way, is there any plan to do for int32 the same kind of
> optimizations as are done for floats (no boxing/unboxing in the middle
> of a computation)? Already done?

Already done!  For int32, nativeint, and even for int64 on 64-bit
processors.

The only difference between boxed integers and floats, as far as
boxing elimination in ocamlopt goes, is that there is a hack to unbox
floats in arrays, but no corresponding hack for arrays of boxed
integers.  As Jacques said, the new Bigarray module does provide
arrays of unboxed int32 / nativeint / int64, although of a different
type than the standard Caml arrays.

- Xavier Leroy



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

* Re: Unsigned integers?
  2000-03-24  2:50             ` Jacques Garrigue
  2000-03-24 15:59               ` Xavier Leroy
@ 2000-03-25  4:03               ` John Max Skaller
  1 sibling, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-25  4:03 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: maxs, caml-list

Jacques Garrigue wrote:
 
> If compact storage is the problem, ocaml 3.00 also provides bigarrays,
> which allow you to store int32 values in flat arrays (even
> multidimensional).

BTW: all these new 'specialisations' for generic constructions
just shows that C++ isn't so bad after all. :-)

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Semantic of label: The best (only ?) solution to merge both mode
  2000-03-19  2:29             ` Jacques Garrigue
  2000-03-20 18:25               ` Christophe Raffalli
  2000-03-21 23:29               ` John Max Skaller
@ 2000-03-29  8:42               ` Christophe Raffalli
  2000-03-29  9:53                 ` Christophe Raffalli
  2000-03-30  9:39                 ` John Max Skaller
  2 siblings, 2 replies; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-29  8:42 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: Xavier.leroy, caml-list


I posted a first solution to merge modern and classic mode. It was a bit
wrong. But there is indeed a reasonnable solution:

The trick is not to consider the absence of label as a specific label
like the actual modern mode does.

Then we can have:
- possibility to write or not label when applying a function
- possibility to permutte arguments if labels are written
- optional arguments

---

BUT we need a restriction over admissible types. One can choose between
two restrictions:

- Strong restriction: all the arguments have a label in types. Only
arrows of the form l:t -> t' are allowed.

- Weak restriction: all the arguments without labels in types comes
after arguments with labels. If a function returns a polymorphic results
(type 'a) all arguments have labels. (So function like List.assoc or
List.fold_left still must have a label for all the arguments).

These restrictions are stable by substitution so they are meaningful and
implementable.

These restrictions are reasonable because they only force you to add
labels when defining functions. Not when applying them ! It does not
cost much to add labels when defining functions especially if you do not
have to write labels when you apply arguments to the function. 

Then you can implement the following rule for applying a function to an
argument:

f (a:l) means a is the argument corresponding to the first occurence of
the 
        label l in the type of f (optional or not) (permuttation are 
        possible)

f a     means a is the argument corresponding to the first non
optionnal    
        argument of f

This is quite simple to explain and use and
modifying the actual code to get this is trivial (I can post it if you
want, but it does bootstrap because I did not modify the library which
does not respect any of the restrictions).

I see only two problems:
	
- One must make existing library compatible with one of the restriction:
I think the restriction is not too strong because we have not to always
write labels when applying functions.

- If you do not write labels you can not capture at compile time bugs
caused by incorrect permuttation of arguments. But the user is free to
write the label !

What do you think about this ?

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-29  8:42               ` Semantic of label: The best (only ?) solution to merge both mode Christophe Raffalli
@ 2000-03-29  9:53                 ` Christophe Raffalli
  2000-03-30  9:49                   ` John Max Skaller
  2000-03-30  9:39                 ` John Max Skaller
  1 sibling, 1 reply; 60+ messages in thread
From: Christophe Raffalli @ 2000-03-29  9:53 UTC (permalink / raw)
  To: Jacques Garrigue, Xavier.leroy, caml-list

A small mistake:

f a     means a is the argument corresponding to the first non
optionnal    
        argument of f WHICH IS NOT GIVEN LATER WITH AN EXPLICIT LABEL !

Another precision: the restriction on types is just to make the
implementation possible:

When compiling f a1 ... an, 

If f has type (l:t -> t') one can first look for an argument with the
label l (this is done like this by moderne mode) and if not found and if
l is not optionnal, one can take the first argument (that's the new
part). 

If f has type (t -> t') there is no more labeled argument (because of
the restriction) and one can take the first argument.

Given the restriction, this coresponds to the semantics I gave. Without
the restriction, it is a bit messy ! 



-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-29  8:42               ` Semantic of label: The best (only ?) solution to merge both mode Christophe Raffalli
  2000-03-29  9:53                 ` Christophe Raffalli
@ 2000-03-30  9:39                 ` John Max Skaller
  2000-03-31  4:34                   ` Jacques Garrigue
  1 sibling, 1 reply; 60+ messages in thread
From: John Max Skaller @ 2000-03-30  9:39 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Jacques Garrigue, Xavier.leroy, caml-list

Christophe Raffalli wrote:
> Then you can implement the following rule for applying a function to an
> argument:
> 
> f (a:l) means a is the argument corresponding to the first occurence of
> the

	You mean f (l:a)

>         label l in the type of f (optional or not) (permuttation are
>         possible)
> 
> f a     means a is the argument corresponding to the first non
> optionnal
>         argument of f

	Which 'default' arguments are passed when?
 
> This is quite simple to explain and use and
> modifying the actual code to get this is trivial (I can post it if you
> want, but it does bootstrap because I did not modify the library which
> does not respect any of the restrictions).

	This means that

	f (l:a)

is a version of f with one parameter bound to a, like (f a), except
currying can now be done on any argument?

	Hmm. So we could write:

	f la:a x lb:b y z lc:c ...

which now means:

	(((((f la:a) x) lb:b) y) z) lc:c)

When the last argument is 'used up', all remaining optional arguments
are bound and the 'final' function applied?

> I see only two problems:
> 
> - One must make existing library compatible with one of the restriction:
> I think the restriction is not too strong because we have not to always
> write labels when applying functions.

	I agree. Mandatory writing of labels on definition
is not as onerous as mandatory writing on use.
 
> What do you think about this ?

	This gives the olabl people their old labels back,
while merely requiring classic uses to decorate definitions
with labels. In this case a temporary compiler mode switch
to allow classic users to upgrade piecemeal would be ideal.

	To me, this proposal appeals. (Will it work? Do I understand it?)

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-29  9:53                 ` Christophe Raffalli
@ 2000-03-30  9:49                   ` John Max Skaller
  0 siblings, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-03-30  9:49 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Jacques Garrigue, Xavier.leroy, caml-list

Christophe Raffalli wrote:
> 
> A small mistake:
> 
> f a     means a is the argument corresponding to the first non
> optionnal
>         argument of f WHICH IS NOT GIVEN LATER WITH AN EXPLICIT LABEL !

	This is a complication. In ocaml 2.0x, application is
left associative:

	f a b c d .. = ((((f a) b) c) d)

but this would not be the case with the above rule. I propose instead
the simpler description you gave where a function is applied
to _one_ argument to produce a curried function which is then
applied to the next: the next argument is 'used up', labelled or not,
immediately. Therefore consider:

	let f l1:p1 l2:p2 .. =
	f a l1:b

means precisely:

	((f a) l1:b)

and gives an error because 'l1:' is NOT a label of the function (f a),
which is like

	let fa l2:p2 ... =

By your interpretation, the function call would be correct and
equivalent to


	f l2:a l1:b

or

	f b a

So I think your original unqualified version is actually better :-)


-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-30  9:39                 ` John Max Skaller
@ 2000-03-31  4:34                   ` Jacques Garrigue
  2000-04-01  1:53                     ` John Max Skaller
                                       ` (2 more replies)
  0 siblings, 3 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-03-31  4:34 UTC (permalink / raw)
  To: skaller, Christophe.Raffalli; +Cc: caml-list

From: John Max Skaller <skaller@maxtal.com.au>

> 	This gives the olabl people their old labels back,
> while merely requiring classic uses to decorate definitions
> with labels. In this case a temporary compiler mode switch
> to allow classic users to upgrade piecemeal would be ideal.
> 
> 	To me, this proposal appeals. (Will it work? Do I understand it?)

OK, I think that the problem is that the people do not understand all
the constraints which must be fulfilled by the label system.

One is that we must keep compatibility with non-labelled mode,
virtually forever.  We just cannot force anybody to switch to labelled
mode.  We are talking about ML, not a new language starting from
scratch.

Another one is that there is a whole bunch of theoretical properties
that must be kept.  Maybe you don't even know about them, but this is
thanks to them that you can be confident when the compiler tells you
that your program is OK. (At least much more confident than in weakly
typed languages.)

Now the answer is very short: you cannot provide simultaneously (in
the same mode)
1) backward compatibility
2) commutation of (non-optional) labels
3) labels as documentation (that is, anywhere you feel like putting them)

Here is a proof of that.
Suppose you have two functions with same types but different labels
in the standard library (3 above). A good example of that is

Pervasives.output: out_channel -> buf:string -> pos:int -> len:int -> unit
Buffer.add_substring: Buffer.t -> string -> pos:int -> len:int -> unit

If you apply them both on their first argument, you obtain functions
whose difference is limited to labels.
Now, you could want to put these functions in a list.

        let l = [output oc; Buffer.add_substring b];;

This must work for backward compatibility (1).
What type shall we give to l? There's no unique answer, and this is
actually the case that the classic mode will give you either
(buf:string -> ...) list or (string -> ...) list depending on the
order in which you listed the functions.
This is not a problem since in classic mode you will anyway have to
consume arguments in a fixed order, and labels are just a decoration.
(For label check to work properly (in theory), you must use it only on
function whose type is known, as are all library functions.)

Now suppose you base yourself on this non-deterministic type
information to reorder arguments by commutation according to the
labels given in the application (2).
Well, this is as you would expect, anything can happen.
Including the compiler passing parameters in the wrong order and not
telling you anything about the commutation done!
More generally, I can also write:
        let l' : (string -> len:int -> pos:int -> unit) list = l;;
Since labels have to be ignored during unification, this must be
accepted.
Now, what will be the outcome of this application?
        (List.hd l') "Hello" pos:1 len:2
"l", not "el" as it should.

So, please do not ask for something that is just plain impossible.
Classic mode is already providing the maximum one can expect:
* backward compatibility
* commutation for optional arguments
* fully transparent (and yet useful) labels for non-optional ones
This is the default mode, and would have been probably the only one
if olabl had not existed.

Now, the commuting label mode is just for those who are ready
to change a bit their habits.
And since it is my personal creation (with others), I will just
refrain from explaining why it is so wonderfully clean theoretically.

Best regards,

Jacques
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-31  4:34                   ` Jacques Garrigue
@ 2000-04-01  1:53                     ` John Max Skaller
  2000-04-02 19:24                     ` Christophe Raffalli
  2000-04-03  7:57                     ` backward compatibility Christophe Raffalli
  2 siblings, 0 replies; 60+ messages in thread
From: John Max Skaller @ 2000-04-01  1:53 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: Christophe.Raffalli, caml-list

Jacques Garrigue wrote:
> From: John Max Skaller <skaller@maxtal.com.au>
> 
> >       This gives the olabl people their old labels back,
> > while merely requiring classic uses to decorate definitions
> > with labels. In this case a temporary compiler mode switch
> > to allow classic users to upgrade piecemeal would be ideal.
> >
> >       To me, this proposal appeals. (Will it work? Do I understand it?)
> 
> OK, I think that the problem is that the people do not understand all
> the constraints which must be fulfilled by the label system.
> 
> One is that we must keep compatibility with non-labelled mode,
> virtually forever.  We just cannot force anybody to switch to labelled
> mode.  We are talking about ML, not a new language starting from
> scratch.

	My programs in ocaml are NOT ML programs.
They're ocaml programs. I use objects (classes), for example,
which are not available in ML.

> Now the answer is very short: you cannot provide simultaneously (in
> the same mode)
> 1) backward compatibility
> 2) commutation of (non-optional) labels
> 3) labels as documentation (that is, anywhere you feel like putting them)

	Of course. So we throw out both (1) and (3). The proposal is that
USE of functions be compatible, but not definition.

	I will show the effect on your example:
 
> Here is a proof of that.
> Suppose you have two functions with same types but different labels
> in the standard library (3 above). A good example of that is
> 
> Pervasives.output: out_channel -> buf:string -> pos:int -> len:int -> unit
> Buffer.add_substring: Buffer.t -> string -> pos:int -> len:int -> unit
> 
> If you apply them both on their first argument, you obtain functions
> whose difference is limited to labels.
> Now, you could want to put these functions in a list.

	You can't. They have a different type. The labels are not
decoration. For two function types to agree, they must have the same
number of parameters, all labelled in the same order, with the same type
and label.
So when it comes to typing functions, the interpretation is strict:
labels are mandatory: Pervasives.output as given is not a valid
function type. 

	Lets retry with definitons:

output: chan:out_channel -> buf:string -> pos:int -> len:int -> unit
add_substring: buf:Buffer.t -> substr:string -> pos:int -> len:int ->
unit
 
>         let l = [output oc; Buffer.add_substring b];;

	with the labels given above, the SHOULD fail.
We WANT it to fail. it is an error well detected by the fact that
not only must the types agree, but also the labels must agree.
This requires a parameter be associated with a label which has
a coherent 'kinding' meaning IN ADDITION to the usual type information.

	It is this very kinding which prevents mixing up the
position and length arguments.

> This must work for backward compatibility (1).

	It will work IF and ONLY IF the labels of the two
functions agree.

	Suppose I have a function f (p1:a1 : int) (p2:a2 : int) : int,
and I want to fold it with

	fold_left 
	(fn:f : (x1:a1 : int) (x2:a2 : int) : int) 
	(acc:a : int)
	(ls:l : int list)
	: int

Here, saying 'fold_left fn:f' will not work, since the labels are
in disagreement. We can fix this by redefining the function
to have the right labels:

	let f2 (x1:a1) (x2:a2) = f p1:a1 p2:a2
	fold_left fn:f2 (* OK now *)

This is a 'kinding' coercion. It is messy to have to redefine the
function like this, we need a short hand syntax like:

	fold_left (f<x1:=p1,x2:=p2>)

this syntax is typechecked, and f is passed 'as if' it had labels x1:
and x2:
instead of p1: and p2: (that is, this really is a type conversion, since
labels are part of type information now).

There's no doubt this will BREAK every function I have written.
It isn't compatible with (either) classic or modern mode.

However, the mandatory 'relabelling' of function labels exhibited above
is good, since it exhibits what amounts to a paradigm shift 
(changing the labelling framework) physically in the code.

This WILL produce some extra 'clutter', but one can argue it only
appears when two incompatible labelling schemes must be 
made compatible.

As usual, a stricter typing regime has problems that one sometimes
finds the typing _overly_ strict, but this is always true for any
static type system I've seen (and at the same time, it is not strict
enough .. :-)

Is this a good compromise? I don't know. 
If the ocaml team wants to keep (1) compatibility, then the answer is
no.
I'm just following Einstein's principle: if you have a difficult
to prove property you want, make it an axiom, and try adjusting
the existing ones, instead of handing on to them.

-- 
John (Max) Skaller, mailto:skaller@maxtal.com.au
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
checkout Vyper http://Vyper.sourceforge.net
download Interscript http://Interscript.sourceforge.net



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-03-31  4:34                   ` Jacques Garrigue
  2000-04-01  1:53                     ` John Max Skaller
@ 2000-04-02 19:24                     ` Christophe Raffalli
  2000-04-04  5:50                       ` Jacques Garrigue
  2000-04-03  7:57                     ` backward compatibility Christophe Raffalli
  2 siblings, 1 reply; 60+ messages in thread
From: Christophe Raffalli @ 2000-04-02 19:24 UTC (permalink / raw)
  Cc: skaller, caml-list


> Now, the commuting label mode is just for those who are ready
> to change a bit their habits.
> And since it is my personal creation (with others), I will just
> refrain from explaining why it is so wonderfully clean theoretically.

Ok keep two modes if you want ...

Let's only talk about the modern mode !

I wanted to really use commuting labels, I was ready to change my habit,
but I found them to restrictive. I find my proposal, which is just to
change a bit the semantics of function application (and nothing else) on
non-labelled arguments quite nice and useful (no need to always remember
all the label names if you prefer to remember the order of the
arguments). 

As my proposal only cost to change about 20 lines why not have an option
to the modern mode to let people try it for real and see what they think
?

About the "so wonderfully clean theoretically" .. it is not so clear:
look at this example:

> lama-d134:~> ocaml -modern
>         Objective Caml version 2.99 (99/12/08)
>  
> # let h f = f x:1 y:2;;
> val h : (x:int -> y:int -> 'a) -> 'a = <fun>
> # let h f = f y:1 x:2;;
> val h : (y:int -> x:int -> 'a) -> 'a =
> <fun>                                                    
> 
> The infered type depends on the way you write thing while one could think 
> they are equivalent (the labels commute in modern mode, don't they ?)
 
I could live with this kind of problem ... but in the current version
labels are more painful than useful in modern mode (this is my opinion)
!


-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: backward compatibility
  2000-03-31  4:34                   ` Jacques Garrigue
  2000-04-01  1:53                     ` John Max Skaller
  2000-04-02 19:24                     ` Christophe Raffalli
@ 2000-04-03  7:57                     ` Christophe Raffalli
  2 siblings, 0 replies; 60+ messages in thread
From: Christophe Raffalli @ 2000-04-03  7:57 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: skaller, caml-list


> Now the answer is very short: you cannot provide simultaneously (in
> the same mode)
> 1) backward compatibility
> 2) commutation of (non-optional) labels
> 3) labels as documentation (that is, anywhere you feel like putting them)

1) has never been a requirement from me as a user or from the Caml team.
Caml-light and ocaml are not compatible Ocaml had also incompatible
change not to speak about the difference between Caml (the old one) and
Caml-Light !

I really think 1) is a VERY VERY BAD idea ! OCaml is a reasearch
language that is also really usable. But I want it to progress toward an
always better language. So 1) is not a reasonable constraint.

The only questions are: 
  - How hard is to port your code ? 
  - Can it be done automatically ?

So if an improvement is worth it add it to OCaml regardless of backward
compatibility !

-- 
Christophe Raffalli
Université de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tél: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI



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

* Re: Semantic of label: The best (only ?) solution to merge both mode
  2000-04-02 19:24                     ` Christophe Raffalli
@ 2000-04-04  5:50                       ` Jacques Garrigue
  0 siblings, 0 replies; 60+ messages in thread
From: Jacques Garrigue @ 2000-04-04  5:50 UTC (permalink / raw)
  To: Christophe.Raffalli; +Cc: caml-list

From: Christophe Raffalli <Christophe.Raffalli@univ-savoie.fr>

> Let's only talk about the modern mode !
> 
> I wanted to really use commuting labels, I was ready to change my habit,
> but I found them to restrictive. I find my proposal, which is just to
> change a bit the semantics of function application (and nothing else) on
> non-labelled arguments quite nice and useful (no need to always remember
> all the label names if you prefer to remember the order of the
> arguments). 

* They are (a bit) restrictive. This is intentional.
  (Still, there will be less labels in the standard library in 3.00.)
  Experience with olabl shows that non-optional labels are more useful
  as documentation than for commutation. If you don't have to write
  them, you will probably not write them, and you loose the benefit.
  Sometimes you have to be forced to do things that are good for you :-)
  And please do not compare this with ADA: these are only a few more
  characters, in an already very compact language.

* For you this is just a matter of remembering either position or
  labels.  But if someone is to read your code, he will have to switch
  from one to the other at each application, according to the one you
  choosed. Not so nice.


> As my proposal only cost to change about 20 lines why not have an option
> to the modern mode to let people try it for real and see what they think
> ?

This is not a problem of number of lines.
Before putting even one line of code in the type checker, we have to
be sure it is not breaking anything in the language.
I asked you to produce
1) type inference rules (which must mix with the rest of the language)
2) an untyped reduction semantics, including optional arguments
   (you cannot use the type of the function to decide how it should
    be evaluated, only its value)
These are pre-conditions.
If you do not produce these, this is just an idea, not a proposal.
And I don't see why I should do the work for you, since I am satisfied
with the current system.


> About the "so wonderfully clean theoretically" .. it is not so clear:
> look at this example:
> 
> > lama-d134:~> ocaml -modern
> >         Objective Caml version 2.99 (99/12/08)
> >  
> > # let h f = f x:1 y:2;;
> > val h : (x:int -> y:int -> 'a) -> 'a = <fun>
> > # let h f = f y:1 x:2;;
> > val h : (y:int -> x:int -> 'a) -> 'a =
> > <fun>                                                    
> > 
> > The infered type depends on the way you write thing while one could think 
> > they are equivalent (the labels commute in modern mode, don't they ?)

This is just an example of how keeping the theory clean may force you
to weaken the implementation.
In olabl those two types were to a great extent equivalent, but this
resulted in breaking the call-by-value semantics in some special
cases. We add to back on this.
If you really want those two types to be equivalent, you will have to
pay (probably a lot) in terms of efficiency. Considering that
commutation is not very useful in this particular case, it is better
to have the compiler refuse this code than turn it into an innefficient
blurb. Call it a trade-off. Not between theory and practice, just
between power and efficiency.

Regards,

Jacques Garrigue
---------------------------------------------------------------------------
Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>



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

* Re: Unsigned integers?
@ 2000-03-23 19:42 Damien Doligez
  0 siblings, 0 replies; 60+ messages in thread
From: Damien Doligez @ 2000-03-23 19:42 UTC (permalink / raw)
  To: caml-list; +Cc: maxs

>From: Max Skaller <maxs@in.ot.com.au>

>I would be happy to replace, in this code,
>evey use of 'lor', 'land', + - * < etc with
>'ulor' 'uland' 'uplus' 'uminus' 'uless' etc, if only
>I could define them. (I could do this in C .. but then,
>I could write the below routines in C too)

For ulor, uland, uplus, uminus, umult, as well as lsr and lsl, they
are identical to their signed counterparts, so you don't need to do
anything.

For uless, since you are only ever comparing to a positive constant
less than max_int, I suggest replacing "if i < constant" with
"if 0 <= i && i < constant".


>Note these operations MUST be extremely fast,

If the above works, I doubt you can go any faster.  For more complex
code, you may have to use a full-blown unsigned comparison:
(not tested; could be wrong)

  let uless x y = if (x < 0) = (y < 0) then x < y else x > y;;


The only difficulty would be with division and modulo, as noted by
Xavier, but I gather you don't need them for this application.

-- Damien



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

end of thread, other threads:[~2000-04-06 13:21 UTC | newest]

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-14 16:53 Syntax for label Don Syme
2000-03-14 18:05 ` Pierre Weis
2000-03-15  3:15 ` Syntax for label, NEW PROPOSAL Jacques Garrigue
2000-03-15  6:58   ` Christophe Raffalli
2000-03-15 21:54     ` Julian Assange
2000-03-15 11:56   ` Wolfram Kahl
2000-03-15 13:58   ` Pierre Weis
2000-03-15 15:26     ` Sven LUTHER
2000-03-17  7:44       ` Pierre Weis
2000-03-15 17:04     ` John Prevost
2000-03-17 10:11       ` Jacques Garrigue
2000-03-15 17:06     ` Markus Mottl
2000-03-15 19:11     ` Remi VANICAT
2000-03-17  8:30       ` Pierre Weis
2000-03-17 14:05         ` Jacques Garrigue
2000-03-17 16:08           ` Pierre Weis
2000-03-18 10:32           ` Syntax for label, NEW SOLUTION Christophe Raffalli
2000-03-19  2:29             ` Jacques Garrigue
2000-03-20 18:25               ` Christophe Raffalli
2000-03-22  8:37                 ` Claudio Sacerdoti Coen
2000-03-21 23:29               ` John Max Skaller
2000-03-29  8:42               ` Semantic of label: The best (only ?) solution to merge both mode Christophe Raffalli
2000-03-29  9:53                 ` Christophe Raffalli
2000-03-30  9:49                   ` John Max Skaller
2000-03-30  9:39                 ` John Max Skaller
2000-03-31  4:34                   ` Jacques Garrigue
2000-04-01  1:53                     ` John Max Skaller
2000-04-02 19:24                     ` Christophe Raffalli
2000-04-04  5:50                       ` Jacques Garrigue
2000-04-03  7:57                     ` backward compatibility Christophe Raffalli
2000-03-15 21:30     ` Syntax for label, NEW PROPOSAL John Max Skaller
2000-03-16  2:55     ` Jacques Garrigue
2000-03-17 15:13       ` Pierre Weis
2000-03-17 17:33         ` Wolfram Kahl
2000-03-18 11:59         ` Jacques Garrigue
2000-03-21 16:51       ` Pascal Brisset
2000-03-23 11:14         ` Nicolas barnier
2000-03-24  9:54           ` labels & ocaml 3 & co David Mentré
2000-03-24 12:19             ` David Mentré
2000-03-21 22:22       ` Unsigned integers? John Max Skaller
2000-03-22 16:22         ` Sven LUTHER
2000-03-23  2:08           ` Max Skaller
2000-03-23  7:50             ` Sven LUTHER
2000-03-24  2:50             ` Jacques Garrigue
2000-03-24 15:59               ` Xavier Leroy
2000-03-25  4:03               ` John Max Skaller
2000-03-24 14:50             ` Xavier Leroy
2000-03-22 17:05         ` Jean-Christophe Filliatre
2000-03-22 19:10           ` Markus Mottl
2000-03-23  2:41           ` Max Skaller
2000-03-22 19:47         ` Xavier Leroy
2000-03-23 12:55           ` John Max Skaller
2000-03-16  8:50     ` Syntax for label, NEW PROPOSAL Pascal Brisset
2000-03-17 11:15       ` Sven LUTHER
2000-03-18  0:04     ` Syntax for label, ANOTHER " Steven Thomson
2000-03-15 20:39   ` Syntax for label (and more) Xavier Leroy
2000-03-17 10:03     ` Christian RINDERKNECHT
2000-03-17 17:19       ` Christophe Raffalli
2000-03-21  1:29     ` Markus Mottl
2000-03-23 19:42 Unsigned integers? Damien Doligez

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).