Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'exception Exc of (string * string)' and 'exception Exc of string * string' not necessarily the same #4182

Closed
vicuna opened this issue Dec 7, 2006 · 5 comments

Comments

@vicuna
Copy link

vicuna commented Dec 7, 2006

Original bug ID: 4182
Reporter: cookedm
Status: closed (set by @damiendoligez on 2006-12-18T13:59:09Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 3.09.3
Fixed in version: 3.10+dev
Category: documentation

Bug description

If you have in your .mli file this

exception Exc of (string * string)

and in your .ml file this

exception Exc of string * string

then ocamlc will complain that
Exception declarations do not match:
exception Exc of string * string
is not included in
exception Exc of (string * string)

Note that this problem doesn't occur for type definitions.

Hardly a major bug, but it is surprising, as typexpr and (typexpr) should be equivalent.

Additional information

$ ocamlc -config
version: 3.09.3
standard_library_default: /opt/godi/lib/ocaml/std-lib
standard_library: /opt/godi/lib/ocaml/std-lib
standard_runtime: /opt/godi/bin/ocamlrun
ccomp_type: cc
bytecomp_c_compiler: gcc -fno-defer-pop -no-cpp-precomp -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT
bytecomp_c_linker: gcc -L/opt/godi/lib
bytecomp_c_libraries: -lcurses -lpthread
native_c_compiler: gcc -Wall -D_FILE_OFFSET_BITS=64 -D_REENTRANT
native_c_linker: gcc -L/opt/godi/lib
native_c_libraries:
native_partial_linker: ld -r
ranlib: ranlib
cc_profile: -pg
architecture: i386
model: default
system: macosx
ext_obj: .o
ext_asm: .s
ext_lib: .a
ext_dll: .so
os_type: Unix
default_executable_name: a.out
systhread_supported: true

@vicuna
Copy link
Author

vicuna commented Dec 13, 2006

Comment author: Colas

  • has precedence, thus
    exception Exc of string * string
    is
    (exception Exc of string) * string
    whichi is different from
    exception Exc of (string * string)

@vicuna
Copy link
Author

vicuna commented Dec 14, 2006

Comment author: @garrigue

exception E of string * string and exception E of (string * string) have different internal representations, so they are incompatible.
This is also true for types!
module M : sig type t = E of (string * string) end =
struct type t = E of string * string end;;
Type declarations do not match:
type t = E of string * string
is not included in
type t = E of (string * string)
All this is documented in the reference manual.

@vicuna
Copy link
Author

vicuna commented Dec 14, 2006

Comment author: cookedm

Responding to Colas:
If exception Exc of string * string is equal to (exception Exc of string) * string, then Exc ("a","b") should be a type error. Which it isn't. ((Exc "a"), "b") is, though.

Responding to garrigue:
The reference manual, 6.4 Type Expressions -> Parenthesized types, says:

The type expression ( typexpr ) denotes the same type as typexpr

I thought that was pretty clear :-)

The other problem is that the output produced by ocaml is the same for both
ways. Using types:

type t1 = E1 of string * string;;

type t1 = E1 of string * string

type t2 = E2 of (string * string);;

type t2 = E2 of (string * string)

E1 ("a", "b");;

  • : t1 = E1 ("a", "b")

E2 ("a", "b");;

  • : t2 = E2 ("a", "b")

so the pretty-printed version of the two values is identical.

Either:

  1. E of string * string and E of (string * string) should be identical
  2. or, they're different, and should act differently. For instance, E of string * string should be (E of string) * string (which isn't a valid type expression).

@vicuna
Copy link
Author

vicuna commented Dec 14, 2006

Comment author: @oandrieu

cookedm: there is a difference between a constructor with one tuple argument (declared by "E of (string * string)" and a constructor with multiple arguments "E of string * string".

The revised syntax of camlp4 makes this distinction way more clear by using a different keyword for the multiple arguments case:
type t = [ E of (string * string) ]
vs.
type t = [ E of string and string ]

But I'm not sure where this is documented in the reference manual. Section 6.8.1, "Type definitions" says: "The constructor declaration constr-name of typexpr declares the name constr-name as a non-constant constructor, whose argument has type typexpr." It doesn't explain anything about constructors with multiple arguments.

@vicuna
Copy link
Author

vicuna commented Dec 18, 2006

Comment author: @damiendoligez

Hardly a major bug, but it is surprising, as typexpr and (typexpr) should be equivalent.

In fact, it's a bug in the documentation. typexpr and (typexpr) are indeed equivalent,
but in "Exc of string * string", "string * string" is not parsed as a typexpr, it's two typexprs
separated by a "*" which is part of the syntax of exception declarations. As oandrieu notes,
this is made clear by the revised syntax. On the other hand, the documentation is currently
misleading on this subject.

The documentation will be fixed in 3.10.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant