V10/cmd/sml/doc/bugs
Known bugs, SML of NJ Version 0.43, 30 November 1989
Key: L = local Priority Key: A = should be done by release 1.0
E = Edinburgh P = will be fixed when parser redone
SB = Stony Brook B = should be done after 1.0
P = U Penn C = not a bug
--------------------------------------------------------------------------------
2. (L.3): Mispelled nonnullary constructors in patterns [parser]
Problem:
Mispelling a constructor with arguments in a pattern leads to misleading
error messages.
Version: 0.18
Code: (in typing/typecheck.sml)
...
app genType rvbs
end
| EXCEPTIONdec(ebs) =>
let fun checkWeak(VARty(ref(UNBOUND id))) =
^ -- should have been UBOUND
if tyvarWeakness id > abs
then condemn "type variable in exception type too strong"
...
Comment:
probably requires rewrite of pattern parsing [dbm]
Priority: P
--------------------------------------------------------------------------------
4. (L.5): duplicate specifications not checked
Problem:
No checking for duplicated specifications in signatures.
Version: 0.18
Comment:
This should be done when building the signature symbol table.
Priority: A
--------------------------------------------------------------------------------
7. (L.8): constructor representation
Problem:
There is a bug involving constructor representation. The compiler
examines the structure of a datatype and tries to determine an efficient
runtime representation for it. For example, for the list datatype, nil
can be represented as an integer, and :: can just be a pointer to its
tuple argument (integers and tuples are distinct). This fails in our system
at the structure level. For example:
Version: 0.18
Code:
signature S = sig
type 'a t
datatype 'a list = nil | :: of 'a t
end
structure A : S = struct
datatype 'a list = nil | :: of 'a t
withtype 'a t = 'a * 'a list
end
Comment:
Here the compiler can deduce the efficient representation for the
(local) list datatype in structure A; but this cannot be deduced in
the signature S (an object of type 'a t might not be a pointer).
Priority: A
--------------------------------------------------------------------------------
8. (L.9): interactive error recovery
Problem:
In the interactive mode, parser error recovery should be suppressed
(but isn't); the parser may continue to look for input after an error,
when the user would expect to be back at top level.
Version: 0.18
Priority: P
--------------------------------------------------------------------------------
10. (L.11): exhaustiveness messages at top-level
Problem: Top level bindings should not report on exhaustiveness, but they do.
Version: 0.18
Priority: C
--------------------------------------------------------------------------------
11. (L.12): poor error messages [parser]
Problem: Poor error message (parens are needed around the hd::tl pattern):
Version: 0.18
Code:
- fun f hd::tl = 4;
Messages:
Error: expected EQUAL, found ID (::)
Error: expected nonfix-identifier, found ID ::
Error: unbound variable bogus
Error: type error: operator and operand don't agree
operator : ((wrong*wrong list) -> wrong list)
operand : (wrong*('aA list -> 'aA list))
expression:
bogus :: tl
-
Comment:
The "unbound variable bogus" in particular is confusing.
Priority: P
--------------------------------------------------------------------------------
12. (L.14): loss of information in value printing
Problem:
When printing values formed using constructors created by functor application,
the argument type of the constructor can sometimes be lost, resulting in
inability to print the value accurately.
Version: 0.18
Code:
- functor F(type t) =
= struct
= datatype r = C of t end
= end;
- structure S = F(type t = int);
- S.C 3;
[1] val it = C - : S.r
But
- signature SS = sig type t datatype r = C of t end;
- structure S = struct type t = int datatype r = C of t end;
- S.C;
val it = fn : ?.t -> S.r
- S.C 3;
val it = C 3 : S.r
and
- structure S': SS = struct type t = int datatype r = C of t end;
- S'.C;
val it = fn : ?.t -> S'.r
- S'.C 3;
val it = C 3 : S'.r
Comments:
It does not seem possible to recover the context from the structure S, because
there is no simple way to get back from the type S.r or the DATACON C to the
structure environment. This may be a reason for having type constructors
contain a pointer to their home structure rather than just the symbolic
path. Another alternative would be to follow the path in S.r to find the
structure S so that we can use it as context for the type of C.
Priority: B
--------------------------------------------------------------------------------
13. (L.15): printing of types from abstraction structure
Problem:
Printing of types from an abstraction is not quite right.
Code: (test/sigs/test7)
signature FOO =
sig
type T1 and T2
val x1: T1 and x2: T2
sharing type T1 = T2
end
abstraction Foo: FOO =
struct
datatype T1 = CON
type T2 = T1
val x1 = CON and x2 = CON
end
[Foo.x1,Foo.x2];
Messages:
[-,-] : ?.T1 (* should be Foo.T1 *)
Priority: B
--------------------------------------------------------------------------------
15. (E.12): Error message
Problem: Unfortunate error message (I left out `type'):
Version: ?
Code:
- signature STWO = sig structure X:SIG and Y:SIG sharing X.t=Y.t end;
Messages:
Error: bad path in sharing specification
Comments:
Priority: A
--------------------------------------------------------------------------------
17. (E.25): Inaccurate line numbers
Problem:
Misleading line numbers for some things (eg. type errors in multi-line
datatype declarations). Could the system print something like
"Line 33ff", or a line range a la LaTeX, for these?
Version:
Code:
Messages:
Comments:
Priority: P
--------------------------------------------------------------------------------
20. (E.47): "print" is overloaded rather than polymorphic
Problem: print should be implemented as a pseudo-polymorphic function like =
Version: 0.19
Code:
- datatype Foo = FOO1 | FOO2;
- print FOO1;
Messages:
Error: type error: no match for overloaded variable:
print
Comments:
according to the original SML report, both "print" and "makestring"
should be polymorphic identity functions. In our [Edinburgh]
compiler, "print" is correctly polymorphic. "makestring" is
(incorrectly) overloaded, disallowing "makestring FOO1". Needless
to say, I want to be able to do "makestring" on datatypes.
Priority: C
--------------------------------------------------------------------------------
21. (E.48): Bad error recovery in the typechecker:
Problem:
Version: 0.15a
Code:
- signature SIG = sig
exception Foo of int
val A: int
val B: int
val C: int
end;
- structure S: SIG =
struct
exception Foo: int
^
val A = 1
val B = 2
val C = 3
end
Messages:
Error: Type in structure doesn't match signature
name = Foo
spec = (int -> exn)
actual = exn
Error: unmatched val spec: A
Error: unmatched val spec: B
Error: unmatched val spec: C
^ there can be a lot of these!
Comments:
Sometimes the exception error doesn't appear, just giving the unmatched
spec errors, rather misleadingly.
Priority: A
--------------------------------------------------------------------------------
24. (E.56): incomplete write
Problem: [nick]
I'm trying to put in some bullet-proof error recovery into my
subprocess software, so that "^C" at ML top-level doesn't
confuse the daemon. What happens if an "output" operation is
active when ^C is hit - does it do a partial write? I seem to be
getting some buffer corruption somewhere, as a partial write is
immediately followed by another complete write. It might make
my life easier if "output" could be guaranteed atomic under "^C"
(i.e. any single output operation will complete before Interrupt
gets raised).
Just a thought. I'll perhaps put timers into the daemon and ML code
so that they flush and restart properly - this may solve the problem.
Version: ?
Comments:
[Andrew] there should be a way to enable and disable interrupt.
Priority: B
--------------------------------------------------------------------------------
26. (E.58): export ML within a use
Problem:
Awkward behaviour when exportML is called while a file is being
"use"'d - the saved state raises Io_failure. Shouldn't
restarting clear the use stack?
Version:
Code:
Messages:
Comments:
Priority: C
--------------------------------------------------------------------------------
29. (E.62): use_string in structure definition
Submitter: Nick
Date: 3/24/88
Version: 0.18
Problem: use_string can cause uncaught Intmap exception
Code:
- structure Foo =
struct
val x = use_stream(open_string "val _ = Foo.x;")
end;
Messages:
[opening <instream>]
[closing <instream>]
uncaught exception Runbind
Comments: This code shouldn't work, but the Intmap exception should be caught.
Priority: C
--------------------------------------------------------------------------------
36. (L.26): overloading resolution and order of recursive definitions
Submitter: Dave
Date: 5/2/88
Version: 0.18
Problem:
overloading resolution can depend on the order in which mutually
recursive definitions occur
Code:
fun f x = length x
and g() = f "abc"
(* length is not resolved *)
fun g() = f "abc"
and f x = length x
(* length is resolved *)
Messages:
Comments:
Maybe this will remain a "feature".
Priority: A
--------------------------------------------------------------------------------
40. (L.28): Exception aliasing (match compiler)
Submitter: Dave
Date: 5/12/88
Version: 0.19
Problem:
Match compiler doesn't cope with exception aliasing (through functor
parameters, for instance).
Exceptions in different structures with the same name, or identical
exceptions with different names can cause problems for the match
compiler. Currently, in building the decision tree, the match
compiler examines constructor names to descriminate among them.
In a match like
A.foo =>
| B.foo =>
the second rule will be found redundant, even if the exceptions are
different. And in
exception foo
exception bar = foo
bar =>
| foo =>
the second rule will not be recognized as redundant.
The situation is even worse for exceptions which are functor parameters.
For example:
structure A = struct exception foo end
structure B = struct exception foo end
functor F(exception foo) =
struct
fun f A.foo = 1
| f foo = 2
| f B.foo = 3
end
Now in F(A.foo) the second case is redundant; in F(B.foo) the third case
is redundant; and in F(exception foo) no case is redundant. Redundancy
can't be computed statically while compiling F; and the match compiler
can't build a fancy decision tree without watching for functor parameters.
Here, the only correct tree would be a case by case check; things get more
complicated when tuples are involved.
One solution would be to assign stamps statically to exception declarations.
Exception specs would get a different class of stamp than exception
declarations. This would allow us to correctly produce efficient matches
in most cases, and detect cases where the runtime-dependent check is
necessary.
Code:
Messages:
Comments: a fairly nasty one!
Priority: B
--------------------------------------------------------------------------------
46. equality type checking and flexrecords
Submitter: Dave
Date: 6/3/88
Version: 0.20
Problem:
when flexrecords are used a nonequality type may be accepted in a context
where an equality record type is required
Code:
fun f(r as {a,...},true) = (r = r) (* checks only that a admits equality *)
| f({b,...},false) = b 3 (* oops, the b field is a function! *)
Messages:
val f = fn : {a:''a,b:int -> bool} * bool -> bool
(* argument type is not an equality type *)
Comments:
A fix probably requires a change in the way flexrecords are represented.
Priority: A
--------------------------------------------------------------------------------
48. printing of identity withtype declarations
Submitter: Dave
Date: 6/9/88
Version: 0.20
Problem:
A simple identity declaration in the withtype clause of a datatype declaration
will not be printed properly.
Code:
datatype foo = A
withtype t = int;
Messages:
datatype foo
con A : foo
type t = t
Comments:
This happens because the backpatching of the type constructor puts the new
name in the defining type as well as in the defined type binding.
Priority: B
---------------------------------------------------------------------------
63. curried, clausal def of infix function
Submitter: Paulson
Version: Version 0.20, 13 June 1988
System: Sun3/SunOS
Problem: parsing of infixes
Code: (minimal code fragment that causes bug)
- infix orelf;
- fun (f orelf g) x = 0;
Error: expected EQUAL, found RPAREN
Error: atomic expression expected
Error: declaration or expression expected, found RPAREN
- fun f orelf g = fn x => 0;
val orelf = fn : 'a * 'b -> 'c -> int
Comments:
This use of an infix in a pattern seems legal and is accepted by Poly/ML.
Priority: P
---------------------------------------------------------------------------
68. (E.72) spurious error message -- doesn't match sig spec
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
- structure S: sig val x: int end = struct val x = hd "s" end;
Error: operator and operand don't agree (tycon mismatch)
operator domain: 'S list
operand: string
in expression:
hd "s"
Error: value type in structure doesn't match signature spec
name: x
spec: int
actual: error
Priority: A
---------------------------------------------------------------------------
69. (E.73) printing of exn spec in inferred signature
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
- structure Blah = struct exception BLAH end;
structure Blah :
sig
exception BLAH of exn (* "of exn" should not appear *)
end
Priority: A
---------------------------------------------------------------------------
70. (E.74) constructor shouldn't appear in printed structure signature
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
signature SIG =
sig
type t
end
structure S:SIG =
struct
datatype t = foo of int
val x = 3
end
Messages:
structure S :
sig
datatype t
con foo : int -> t (* shouldn't be printed *)
end
Comment: constructor foo is not accessible as component of S
Also, from Dave Berry (2/2/89):
NJ ML prints the constructors of a datatype when that datatype is
matched against a "type" in a signature, even if the signature
doesn't include the constructors.
This seems a trivial point (except that it's confusing for the novices on
the course we teach). However, with some complicated programs the compiler
bombs out, raising the subscript exception. You are left in the ML system,
but it won't compile your code.
I don't have a small example of this. It first hit me preparing
examples for the aforementioned course, and it's just hit me again.
Priority: A
---------------------------------------------------------------------------
71. (E.75) Failure to restore enviroment after exception in "use"
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
For a file "y.sml" containing "val y = 4";
- val x = (use "y.sml";
let exception X in raise X end
);
[opening y.sml]
val y = 4 : int
[closing y.sml]
uncaught exception X
- (* so far so good... *)
- x;
uncaught exception Runbind
Comment: needs to be a protect around use to trap exceptions and restore env
Priority: A
---------------------------------------------------------------------------
72. equality types with abstype declarations
Submitter: kevin
Date: 11/30/88
Version: 0.24?
System: Sun 3
Code:
(* The following definition is accepted by the compiler, resulting in
the declaration test: ''a foo -> bool *)
abstype 'a foo = Foo of 'a list
with fun test(Foo x) = (x = []) end;
(* The next declaration fails with the error
Error: operator and operand don't agree (equality type required)
operator domain: ''S * ''S
operand: 'T foo * 'U foo
in expression:
x = Foo nil *)
abstype 'a foo = Foo of 'a list
with fun test(x as Foo _) = (x = Foo []) end;
(* I'm not sure why one should be allowed and not the other - the old
Edinburgh compiler accepted both. *)
Priority: A
---------------------------------------------------------------------------
73. strange function definition
Submitter: Trevor
Date: 12/10/88
Version: 0.24?
System: vax
Problem:
Code:
- fun add-a x = x+1;
val a = fn : int -> int
- a 3;
val it = 4 : int
Comments:
The intent was to have a hyphen in a function name
(something like "fun add_a ...".
Priority: P
---------------------------------------------------------------------------
77. unparenthesized infix expressions in fun lhs
Submitter: Dave Berry
Date: 12/22/88
Version: 0.24?
Code:
infix 4 %;
infix 3 %%;
datatype foo = op % of int * int;
fun a % b %% c % d = 0;
NJ ML accepts this, as does Edinburgh ML. It is incorrect; brackets
are required as follows:
fun (a % b) %% (c % d) = 0;
This is defined on page 68 of the definition. The lhs and rhs of the
infixed operator being defined are required to be atomic patterns.
Priority: P
---------------------------------------------------------------------------
79. withtype
Submitter: Simon (from abstract hardware) via Mike Fourman
Date: 1/31/88
Version: 0.24
Problem:
"Did you know that the following is not valid ML?
datatype type1 = T of type2 * type3
withtype type2 = int (* this could be a large expression *)
and type3 = type2 * string;
The reason is that the "datatype datbind withtype typbind" construct is
expanded out into "datatype datbind'; type typbind" where "datbind'" is
the the result of using "typbind" to expand "datbind". Note that this
construct does *not* expand "typbind" itself, so "type2" is out of scope
in its occurrence in "type3". This simultaneous definition property of
"withtype" is quite annoying, especially as there is no way to get the
effect of sequential definition (other than manually expanding out the
body of "type3" - but that is precisely the problem that "withtype" is
supposed to solve)."
Code:
-
datatype type1 = T of type2 * type3
withtype type2 = int (* this could be a large expression *)
and type3 = type2 * string;
- = = Error: Compiler bug: defineEqTycon/eqtyc 1
-
datatype type1 = T of type2 * type3
withtype type3 = type2 * string
withtype type2 = int (* this could be a large expression *);
- = = Error: unbound type constructor (in datatype): type2
Error: unbound type constructor (in datatype): type2
Error: Compiler bug: defineEqTycon/eqtyc 1
-
Priority: A
---------------------------------------------------------------------------
80. simultaneous type declarations
Submitter: Dave Berry
Date: 2/1/89
Version: 0.24
Code:
- type type2 = int
= and type3 = type2 * string;
type type2 = int
type type3 = type2 * string
Comments:
This is wrong: type2 shouldn't be bound before the declaration of type3.
Priority: B
---------------------------------------------------------------------------
83. unexpected parsing of erroneous datatype declaration
Submitter: Carl Gunter
Date: 2/24/88
Version: 0.20
Code:
- datatype complex = Complex (real,real);
datatype complex
con Complex : complex
val it = (fn,fn) : (int -> real) * (int -> real)
Comments:
implicit "val it = " inserted after constructor Complex breaks the
declaration into a valid datatype declaration and a top-level value
expression (implicit value declaration). This could probably be
detected and suppressed.
Priority: P
---------------------------------------------------------------------------
85. bad error message for failed signature match
Submitter: John Reppy
Date: 3/6/89
Version: 0.28
Code:
- structure Foo : sig
= type foo
= val f : foo -> int
= end = struct
= type Foo = int
= fun f x = x
= end;
Error: unmatched type spec: foo
Error: Compiler bug: tycStamp
Priority: A
---------------------------------------------------------------------------
86. incorrectly allows redefining of "="
Submitter: Dave Berry
Date: 3/15/89
Version: 0.29
Problem:
NJML handles the = symbol incorrectly in some cases.
- val op = = op = ;
- nonfix =;
- = (true, true);
Error: declaration or expression expected, found EQUAL
The = symbol may not be redefined (Definition, page 4). The top definition
does seem to redefine =, despite the lack of response from the system.
I can't see anything in the Definition that forbids making = nonfix,
so I suppose it should be possible to use it in a nonfix way.
Poly/ML gets this right.
> val op = = op = ;
Error- Pattern expected but = was found
Exception static_errors raised
> nonfix =;
nonfix =
> = (true, true);
val it = true : bool
It would be more pleasant if the error message said "Can't redefine =".
Edinburgh ML 3.5 (for what it's worth) forbids the rebinding, and doesn't
allow = to be nonfix.
- val op = = op = ;
Parse error:
Was expecting a Prefix/infix/suffix-identifier
In: ... val op <?> =
- nonfix =;
Parse error:
Insufficient repetition
In: ... nonfix <?> =
The "Insufficient repetition" message is the model of clarity we should all
be aiming for :-).
Priority: C
---------------------------------------------------------------------------
87. execute subprocess dies on interrupt on blocked input
Submitter: dbm
Date: 3/19/89
Version: 0.31
System: Sun3/100, SunOS 4.0.1; VAX8550, V9
Problem: interrupting blocked call of input from execute subprocess
kills subprocesss
Code:
val (ins,outs) = execute "cat"
input ins 5;
^Cuncaught exception Interrupt
Messages:
After interrupt, System.system("ps x"), indicates that "cat"
subprocess has disappeared, and subsequent attempt to flush output
to outs raises exeption Io("output: write failed").
Comments:
end_of_stream also blocks, and interrupting a call of end_of_stream
seems to have the same effect.
Priority: B
---------------------------------------------------------------------------
89. continuation line string escape at beginning of string
Submitter: dbm
Date: 4/3/89
Version: 0.33
System: Sun 3, SunOS 4.0.1
Code:
- "\ (* CR after \ at beginning of string *)
- akdk";
Error: unclosed string
= (* second CR typed *)
Error: unclosed string
Error: unbound variable kdk
= ;
Error: operator is not a function
operator: string
in expression:
"" kdk
Priority: B
---------------------------------------------------------------------------
90. secondary prompt is not set in multi-line strings and comments.
Submitter: dbm and duba
Date: 4/3/89
Version: 0.33
System: All
Priority: B
---------------------------------------------------------------------------
92. uncaught Nth exception after type constructor arity mismatch in sigmatch
Submitter: David Tarditi, Princeton University, drt@notecnirp.princeton.edu
Date: 6/23/89
Version: 0.33
System: Vax/4.3 BSD
Problem: Mismatching arities on types causes uncaught exception Nth
later in signature checking.
Example:
functor OrdSet(B : sig
type elem
val gt : elem * elem -> bool
val eq : elem * elem -> bool
end) =
struct
end
structure Bad =
struct
type 'a elem = int * 'a
val gt = fn ((a:int,_),(b,_)) => a > b
val eq = fn ((a:int,_),(b,_)) => a = b
end
structure X = OrdSet(Bad)
Result:
Standard ML of New Jersey, Version 0.33, 1 April 1989
val it = () : unit
std_in, line 18: Error: mismatching tycon arities: elem
uncaught exception Nth
Comments:
The uncaught exception Nth appears to occur while matching the actual types
of eq and gt against the types in the signature of the formal
structure parameter.
Priority: A
---------------------------------------------------------------------------
95. infix declaration interferes with type parsing
Submitter: David Tarditi, Princeton University, drt@notecnirp
Date: 4/30/89
Version: 0.33
System: Vax/4.3 BSD
Problem: Spurious declaration of infix for an identifier causes problems
when it is used as a type constructor later.
Sample Run:
Standard ML of New Jersey, Version 0.33, 1 April 1989
val it = () : unit
- type ('a,'b) --> = 'a -> 'b;
type ('a,'b) --> = 'a -> 'b
- val a = fn _ => 5;
val a = fn : 'a -> int
- a : ('a,int) -->;
val it = fn : 'a -> int
- infix -->;
- a : ('a,int) -->;
Error: (user) bound type variable propagated out of scope
it : 'aU -> int
Comments:
The declaration of an identifier to be infix should not
affect type constructors. Infix declarations apply only to data
constructors and value identifiers. The declaration of '-->' to
be infix should not affect the use of '-->' as a type constructor,
even though the declaration is spurious.
P.S.
Maybe there should be a way to declare type identifiers to be
infix. I was trying to declare '-->' to be infix because I was creating
different kinds of arrows for my effects inference. --> could denote
a function that is pure, while -*-> could denote a function with an
effect. I need to do this to bootstrap the pervasive environment
without assuming that all built-in functions have side-effects.
Priority: P
---------------------------------------------------------------------------
100. constructor not printed after open declaration
Submitter: Nick Rothwell
Date: 7/18/89
Version: 0.33
Problem:
In this case, a datatype is being printed as a type: the constructor isn't
shown (although it's still bound):
Code:
- signature X = sig datatype T = T end;
signature X =
sig
datatype T
con T : T
end
- structure X: X = struct datatype T = T end;
structure X :
sig
datatype T
con T : T
end
- open X;
type T = T
Priority: A
---------------------------------------------------------------------------
104. Labels with leading zeroes should not be accepted (this is made
explicit on page 5 of version 3 of the Standard).
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
- {0000002 = 999};
val it = {2=999} : {2:int}
Priority: B
---------------------------------------------------------------------------
105. Large numeric labels are disallowed.
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
- {9999999999999999999999 = 999};
Messages:
Error: integer too large
Error: nonpositive integer label, found 0
Priority: B
---------------------------------------------------------------------------
107. NJML disappears into an infinite loop when trying to parse large real numbers;
presumably some error recovery code is flakey.
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
- 1.0E308;
val it = 1.0E308 : real
- 1.0E309;
Error: Real constant out of range
- 2.0E308; (* wait a long time ... *)
val it = uncaught exception Interrupt
-
Comment:
Furthermore, a failing program elaboration or evaluation (such as the above)
should not rebind the variable "it" (ML Standard v3, rules 194 and 195).
NJML sometimes does (as above).
Furthermore, trying to print "it" when it has been bound to such an
exception sometimes seems to crash the system (it refuses to respond to
further input); at other times the exception Runbind is raised.
Priority: A
---------------------------------------------------------------------------
109. sharing of datatypes not handled properly
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
signature EQSIG =
sig
type r
datatype s = S of r
and t = T of s
sharing type r = t
end;
functor F(X : EQSIG) =
struct
fun test(x : X.t) = (x = x);
end;
Messages:
signature EQSIG =
sig
type r
datatype s
con S : r -> s
datatype t
con T : s -> t
end
Error: operator and operand don't agree (equality type required)
operator domain: ''S * ''S
operand: ?.t * ?.t
in expression:
x = x
Error: Compiler bug: abstractType
Comment:
Both are wrong, as the signature EQSIG elaborates to the same semantic object
as the following (which both treat correctly):
signature EQSIG =
sig
type r
datatype s = S of t
and t = T of s
sharing type r = t
end;
Priority: A
---------------------------------------------------------------------------
110. val rec
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: val rec form of definition rejected
Code:
- val x = 1 and rec y = fn z => z; (* should compile *)
Error: expected an atomic pattern, found REC
Error: expected EQUAL, found REC
Error: atomic expression expected, found REC
Error: declaration or expression expected, found REC
Comment: [Simon] the compiler should accept the above declaration.
Comment: [Andrew] The compiler should not accept the above declaration;
this is a case where the Def'n of SML is brain-damaged.
Priority: C
---------------------------------------------------------------------------
111. local polymorphic definitions
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: local polymorphic definitions rejected
Code:
- val q = let exception x of '_a in 1 handle x _ => 2 end;
Error: type variable in exception type not weak enough
- local exception x of '_a in val q = 1 handle x _ => 2 end;
Error: type variable in exception type not weak enough
Comment: the compiler should accept both the above definitions,
which are valid, since the imperative type variable '_a
is *not* free in the top level declaration.
Priority: A
---------------------------------------------------------------------------
112. equality
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: equality misbehaving
Code:
(0.0 = ~0.0, 0.0 = ~ 0.0, ~0.0 = ~ 0.0); (* (true,true,true) *)
infix eq; fun x eq y = x = y;
(0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,false,false) *)
infix eq; fun (x:real) eq y = x = y;
(0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,true,true) *)
Comment: the polymorphic equality function should give
consistent results, even when the type of its
argument is known to be real.
Priority: A
---------------------------------------------------------------------------
113. empty declarations
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Parsing empty declarations
Code:
let val x = 1; (* empty declaration *) ; val y = 2 in x + y end;
Error: expected IN, found SEMICOLON
Error: atomic expression expected, found SEMICOLON
Error: atomic expression expected, found VAL
Error: expected END, found VAL
Error: declaration or expression expected, found IN
Comment: the above program is syntactically correct.
Priority: P
---------------------------------------------------------------------------
115. cyclic signatures
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: cyclic signatures
Code:
(* shouldn't be allowed, since object (signature) is not cycle-free *)
signature bad =
sig
structure A :
sig
structure B : sig end;
end;
sharing A = A.B;
end;
Comment: NJML accepts the above signature declaration, which should be
rejected because it elaborates to a cyclic semantic object;
cyclic objects are not semantically admissible.
Not a bug? (signature will never match a structure)
Priority: C
---------------------------------------------------------------------------
116. pattern declares no variables warning (?)
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Missing warning message
Code:
let val _ = 1 in 2 end;
local val _ = 1 in val it = 2 end;
Comment: Each of the above should produce a "Pattern declares
no variables" warning message, but neither does.
Not a bug
Priority: C
---------------------------------------------------------------------------
117. sharing and equality attributes
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: problems with equality attribute
Code:
(***************************************************************************)
(* This is illegal in version 3 of the ML standard *)
(* s may only be elaborated to a non-equality type (+ extra bits) *)
(* t may only be elaborated to an equality type (for consistency with its *)
(* constructor environment) *)
(* Hence s and t can't share *)
(***************************************************************************)
signature BADSIG =
sig
datatype s = Dummy of bool -> bool
datatype t = Dummy of int
sharing type s = t;
end;
Comment: NJML accepts this signature but shouldn't. Getting the
equality attribute right in the presence of sharing
constraints seems to be quite a tricky problem.
Priority: A
---------------------------------------------------------------------------
118. deviation from Definition, div and mod
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: div / mod give non-standard results
Code:
fun divmod (m,n) = (m div n,m mod n);
(* should give (1,2) *) divmod(5,3); (* gives (1,2) *)
(* should give (~2,1) *) divmod(~5,3); (* gives (~1,~2) *)
(* should give (~2,~1) *) divmod(5,~3); (* gives (~1,2) *)
(* should give (1,~2) *) divmod(~5,~3); (* gives (1,~2) *)
Comments: I'd like the initial dynamic basis to conform to the Standard.
(More efficient, non-standard versions should be hidden away.)
Priority: A
---------------------------------------------------------------------------
119. deviation from Definition
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: I/O functions are curried, Standard has them uncurried
Code:
- input;
val it = fn : instream -> int -> string
Comments: I'd like the initial dynamic basis to conform to the Standard.
(More efficient, non-standard versions should be hidden away.)
Priority: C
---------------------------------------------------------------------------
120. deviation from Definition
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Prelude functions raise the wrong exceptions
Code:
0.0 / 0.0; (* raises Overflow *)
1.0 / 0.0; (* raises Real *)
Comments: I'd like the initial dynamic basis to conform to the Standard.
(More efficient, non-standard versions should be hidden away.)
This one is even trickier; Poly/ML doesn't raise any exception at all
for these (it prints NaN.0 and Infinity.0 respectively).
Priority: A
---------------------------------------------------------------------------
126. scope of explicit type variables
Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK>
Date: 7/11/89
Version: 0.33
Problem:
New Jersey ML (Version 33) does not accept the following declarations.
It complains that a user bound type variable escapes out of scope in `insert'.
But the scope of ''a and 'b is the whole of the fun declaration. The problem
seems to be associated with mutual recursion.
type (''a, 'b)map = (''a * 'b) list
fun plus(l:(''a,'b)map ,[]: (''a, 'b)map ): (''a, 'b)map = l
| plus(l,hd::tl) = plus(insert(l,hd), tl)
and insert([], p) = [p]
| insert((x,y)::rest, (x',y')) =
if x=x' then (x',y')::rest
else (x,y) :: insert(rest,(x',y'));
Priority: A
---------------------------------------------------------------------------
127. sharing and equality types
Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK>
Date: 7/11/89
Version: 0.33
Problem:
New Jersey ML does not accept the following functor declaration (it
complains that S.x is not of equality type). According to the
Definition, two types share only if they have the same name (stamp).
In particular, since equality is an attribute of type names (Version
3, page 16), one admits equality iff the other does (one cannot have
different ``views'' of equality).
Presumably the problem is a bug in the unification of type names.
Code:
functor f(structure S : sig type t val x: t end
structure T : sig eqtype t end
sharing S = T
)=
struct val b:bool = S.x = S.x
end;
Priority: A
---------------------------------------------------------------------------
133. overloading resolution is weaker than Edinburgh SML or Poly ML
Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk)
Date: 5/8/89
Version: 0.33
Problem:
Code:
datatype 'a tree = Stree of 'a list * (string * 'a tree) list
fun insert ((key::keys, x), Stree(xs,alist)) =
let fun inslist((keyi,tri)::alist) =
if key<keyi then alist else (keyi,tri) :: inslist alist
in Stree(xs, inslist alist) end;
Messages:
Error: overloaded variable "<" cannot be resolved
Priority: A
---------------------------------------------------------------------------
134. type checking
Submitter:
Erik Tarnvik
Department of Computing Science
University of Umea
SWEDEN
erikt@cs.umu.se
Date: 5/12/89
Version: 0.33
System: Sun3
Problem:
The compiler reports a type clash were it shouldn't.
Code:
type 'a ft = (int * 'a) list;
fun f ([]:'a ft) x = []:'a ft
| f (((y,fy)::l):'a ft) x =
if x = y
then l:'a ft
else (y,fy)::(f l x):'a ft
and g (l:'a ft) (x,fx) = (x,fx) :: (f l x):'a ft;
Messages:
type 'a ft = (int * 'a) list
line 10: Error: operator and operand don't agree (bound type var)
operator domain: (int * 'aU) list
operand: 'aU ft
in expression:
f l
Comments:
The Edinburgh SML (ver 3.3) does not report an error on this code.
If the 'and' in the last line is changed to 'fun', no error is reported.
I hope I haven't missunderstood something about SML. This is a bug, isn't it?
See #126.
Priority:
---------------------------------------------------------------------------
135. eqtype vs abstype
Submitted: Bernard Sufrin (sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK)
Date: 7/26/89
Version: 0.33
Problem: interaction of abstype and eqtype
I ran into this problem whilst writing you a long note concerning
abstraction bindings structure bindings and their respect for type and
eqtype specifications. Here's a miniature version of the larger
problem.
We want a pair of types Open and Shut, and transfer functions between
them. The two signatures below are candidates for describing such a
structure: the latter leaves visible the equality on Open, the former
should not.
signature T =
sig
type Shut
type Open
val Shut:Open->Shut
and Open: Shut->Open
end
signature U =
sig
type Shut
eqtype Open
val Shut:Open->Shut
and Open: Shut->Open
end
Now we design a functor which simply wraps something up in order to shut it.
functor absT(type Open) =
struct
type Open = Open
abstype Shut = SHUT of Open with
val Shut = SHUT
fun Open(SHUT x) = x
end
end
Now we instantiate it:
structure b:T = absT(type Open=int)
Compiler yields:
structure b :
sig
eqtype Shut <----- can't be right, surely
eqtype Open
val Open : Shut -> Open
val Shut : Open -> Shut
end
The equality on Shut has leaked, despite the fact that the actual
representation of Shut is an abstype. (The same happens if absT is
itself constrained to yield a T)
- b.Shut 3=b.Shut 4;
val it = false : bool
On the other hand using an abstraction binding
abstraction ab:T = absT(type Open=int)
Compiler yields, correctly,
structure ab :
sig
type Shut
type Open
val Open : Shut -> Open
val Shut : Open -> Shut
end
but I cannot actually apply ab.Shut to an integer (its domain is not
int, but an opaque and different type, namely ab.Open). Now let's try
abstraction au:U = absT(type Open=int)
Compiler yields, correctly,
structure au :
sig
type Shut
eqtype Open
val Open : Shut -> Open
val Shut : Open -> Shut
end
but I still can't apply au.Shut to an integer. Incidentally in my
original note I asked (a) whether I ought to be able to, (b) if so,
whether eqtype was not getting a bit overloaded [equality visible AND
representation visible] (c) if not, how could one do this sort of
thing at all?
Meanwhile
structure argh:U = absT(type Open=int)
still makes Open and Shut both eqtypes. More bizarrely, we have
abstype opaque = opaque of int with
val hide = opaque
val show = fn(opaque x)=>x
end
structure biz:T = absT(type Open=opaque)
Compiler yields
structure biz :
sig
eqtype Shut <--- wow!
type Open
val Open : Shut -> Open
val Shut : Open -> Shut
end
Shut is now an eqtype despite being an abstype whose representation
includes another abstype!
Priority: A
---------------------------------------------------------------------------
136. linkdata problem
Submitter: John Reppy (ulysses!jhr, jhr@cs.cornell.edu)
Date: 7/12/89
Version: 0.36
System: Sun 3, SunOS 4.0.3
Problem: failure to build
Code:
When I tried to build 0.36 on the sun-3, I got the message
ld: : Is a directory
on the load of the runtime system. The problem is with the allmo.o
file. I am able to build the system using "-noshare".
Priority: A
---------------------------------------------------------------------------
137. profiler failure
Submitter: Ian Dickinson, HP Labs, Information Systems Centre, Bristol
ijd%otter@hplabs.hp.com
Date: 9/28/89
Version: 0.33
System: HP 9000 HP-UX 6.3
Problem:
I have a small, compute intensive program (around 2K lines of code including
comments). With the profiler turned on, njml fails repeatably at the first
major collect:
- test 30 30;
Case 30: TOLUENE, A,O-DICHLORO
[Major collection... 54% used (2332228/4249436), 2483 msec]
unknown signal: 20
Process SML exited abnormally with code 148
Priority: A
--------------------------------------------------------------------------------
139.
Submitter: Brian Boutel, brian@comp.vuw.ac.nz
Date: 9 November 1989
Version: 0.36 & later
System: HP/Sun 3
Problem: compiling with gcc doesn't work
Description:
I have been trying again to port sml to H-P 68030 boxes running
MORE/bsd, using the Gnu C compiler.
We have a mix of Sun3 and H-P machines, and, although I have installed
sml on the suns, it would be convenient to have it available on the H-Ps as well.
The H-P port has not worked, and to separate the problems arising from
the Operating System from those arising from the use of gcc, I have
tried building sml on the suns with gcc (using the -traditional
option). The build completes, but the resulting sml dies immediately
while doing a major garbage collection. It does not get as far as
announcing itself as Standard ML of .....
I have tried various options, (optimiser on/off some of the gcc -f
options) without effect. Have you tried gcc? I am anxious to persue
this as I think getting a gcc compiled version to run on the suns is
the right first step towards porting to the H-Ps. Can you offer any suggestions?
I am using sml version 0.36. ( I tried today to ftp to
research.att.com to check for a later version, but found an empty
directory when logging on as anonymous, and was refused permission to
log on as mldist.)
Changes made to the source are summarised as
------
gnu C compiler requires f68881 to be changed to m68881
Changed in makeml by introducing $CCOMP, set to GNUCC for machine hp300,
otherwise "", and testing it in defining CFL for M68
----------------
for H-P, sys/exec.h defines MID_HP300 instead of M_68020
linkdata.c and export.c have conditional code if HP300 defined
makeml has to pass HP300 to make for linkdata
-------------
for H-P, callgc.c has FPE_TRAPV_TRAP undefined, and
TRAPV returns FPE_INTOVF_TRAP
so FPE_TRAPV_TRAP is defined as FPE_INTOVF_TRAP in callgc.c
----------
_minitfp_ and _fp_state_mc68881 not defined anywhere for H-P
.globl omitted if HP300 in M68.prim.s
--------------------
run dies because stack clobbered by apply
Registers saved ala NeXT/MACH in saveregs/restoreregs in prim.s if GNUCC
Priority: B
--------------------------------------------------------------------------------
141. interrupting gc dumps core
Submitter: peter@central.cis.upenn.edu (Peter Buneman)
Date: 18 November 1989
Version: 0.39
System: ??
Problem:
I've found occasions on which our current version of ML goes a bit
flakey after being interrupted during garbage collection. I haven't
been able to pin it down until now. The following interactive session
appears to be repeatable.
Code:
% sml
Standard ML of New Jersey, Version 0.39, 8 September 1989
val it = () : unit
- fun foo() = 1::foo();
val foo = fn : unit -> int list
- foo();
[Major collection...
[Increasing heap to 7144k]
70% used (1752720/2487664), 4810 msec]
[Increasing heap to 7280k]
[Major collection... 62% used (2484132/3975316), 7580 msec]
*** I typed <cntrl>C during this garbage collection
[Increasing heap to 11648k]
uncaught exception Interrupt
- fun bar() = bar();
val bar = fn : unit -> 'a
- bar(); *** I did not type <cntrl>C here !!
uncaught exception Interrupt
- bar(); *** nor here!!
uncaught exception Interrupt
-
Comments:
In 0.43d2 I can't repeat this behavior, but interrupting during gc causes
a bus error or segmentation fault. [dbm]
Priority: A
--------------------------------------------------------------------------------
142. import incompatible with interpreter only image
Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK>
Date: 27 Sept 1989
Version: 0.39
System: Sun 3 ?
Problem: import into interpreter
Description:
Problem: it is not possible to import precompiled stuff; the compiler
decides that the .bin file is not in the right format; tries to recompile,
and fails for lack of a code generator.
Here's an example...
- import "/prg/pl/sml/lib/lex";
[reading /prg/pl/sml/lib/lex.bin... ]
[/prg/pl/sml/lib/lex.bin is the wrong format; recompiling]
[closing /prg/pl/sml/lib/lex.bin]
[reading /prg/pl/sml/lib/lex.sml]
[reading /prg/pl/sml/lib/lib/lib/extend.bin... ]
[/prg/pl/sml/lib/lib/lib/extend.bin is the wrong format; recompiling]
[closing /prg/pl/sml/lib/lib/lib/extend.bin]
[reading /prg/pl/sml/lib/lib/lib/extend.sml]
/prg/pl/sml/lib/lib/lib/extend.sml, line 52: Error: Compiler bug: no code generator!
[closing /prg/pl/sml/lib/lib/lib/extend.sml]
[closing /prg/pl/sml/lib/lex.sml]
IMPORT failed (compile-time exception: Syntax)
When trying to reproduce the import bug
you might try making the dependency graph more than three arcs deep.
Comments:
Obviously we don't want to have to dispense with import
when using the intepreter-only (typically it'd be students loading
precompiled libraries), but I presume we don't want the complication of
lambda-formatted bin files as well as machine code bin files. May I
propose the following:
import from an ionly system should behave like import in the cg system if
everything is up-to-date.
if something is out of date, then import should either abort, or behave
like use (I prefer the latter, I think, but you might make it
controllable from a System.Control variable).
Priority: A?
--------------------------------------------------------------------------------
143.
Submitter: Jawahar Malhotra (malhotra%metasoft.uucp@BBN.COM)
Date: 26 October 1989
Version: ??
System: ??
Problem: use dumping core on magic input file length
Description:
I have a source file which contains a signature definition and a
functor definition. When I load it using the "use" statement, the
compiler responds with the signature defn and the functor defn but
then dumps core just before its prints the [<closing file>] line.
Strangely, if I add another blank line to the file, everything is
OK. If you like, I can mail you the file; please let me know if
you would like the file.
Here is a reproduction of the compiler's output:
- use "oareadattr.sml";
[opening oareadattr.sml]
signature OAREADATTR = ...
...
...
end
functor OAReadAttrFun : <sig>
Segmentation Fault (core dumped)
Comments:
Priority: A
--------------------------------------------------------------------------------
144. not waiting for child process
Submitter: Jawahar Malhotra, Meta Software; malhotra%metasoft@bbn.com
Date: 20 Oct 89
Version: 0.33
System: SUN OS 3.5
Problem:
njsml doesn't wait for child process (created by a call to
execute) to terminate. Suppose I execute the following
sml stmt:
- execute "ls /users/malhotra";
njsml creates a child process in which it runs ls. When ls
is done, it does an exit(0). In order for the exit to
complete, its parent process (njsml in this case) should
do a wait(). However, njsml doesn't do this and hence the
"ls" process blocks on its exit and remains until njsml
exits. The state of this process (as displayed by "ps") is:
malhotra 2376 0.0 0.1 0 0 p2 Z 0:00 <exiting>
Comments:
One fix would be to prevent the process created by "execute" from
being njsml's child. In this case, njsml would not have to wait to
collect the child's termination status. This can be done by
forking twice. Hence the code for execute might look like:
(assume njsml is process p1)
------------------------------------------------------------
/* in process p1 */
if (fork() == 0) { /* in p2 */
if (fork() == 0) { /* in p3 */
.........
execl(......);
.......
}
else { /* in p2 */
exit(0);
}
}
/* in p1 */
wait(0); /* wait for p2 to exit */
------------------------------------------------------------
Another fix (maybe easier to implement) is to install a signal
handler for SIGCHLD.
signal(SIGCHLD, ack);
where ack() is simply:
ack()
{
wait(0);
}
Final Comment:
You may remember that I once mentioned a problem with the processes
created by "execute". I have a solution which I thought I'd share
with you. I use the wait fn call:
fun wait status =
System.Unsafe.syscall(84, [System.Unsafe.cast status], 1);
For example, I could do
- execute "ls .";
> val....
- ......
- wait(0);
> val it = <pid of child>;
This will also be useful in predefining a sync "execute" i.e.
val sync_execute = fn file => (execute file; wait(0));
Priority: B
--------------------------------------------------------------------------------
145. stale top-level continuations cause type bugs
Submitter: Andrzej Filinski, CMU Computer Science (andrzej@cs.cmu.edu)
Date: Oct 11, 1989
Version: 0.39 (8 September 1989)
System: Sun3/4.3BSD
Problem: Capturing top-level continuation messes up the type system
Code:
val cl = ref([]:int cont list);
callcc (fn k=>(cl:=[k]; 42));
val u = throw (hd (!cl)) 65; (* value 65 with universal type! *)
u+1; (* u as integer *)
u^"str"; (* u as string *)
u:bool; (* u as boolean (cannot print) *)
u:real; (* u as real (core dump) *)
Comments: This may be a tricky problem, i.e. it is not quite clear
what the "right" behavior should be when the top-level continuation
is captured and carried across commands. Please don't take this as a
criticism of callcc/throw in general, though; they're great! Any plans
for integrating them more deeply in the language, like exceptions?
Priority: B
--------------------------------------------------------------------------------
149. infinite gc loop with insufficient swap space
Submitter: jhr@cs.cornell.edu (John Reppy)
Date: 18 Sept 89
Version: 0.39
System: Vax
Problem:
SML/NJ is being used at Cornell for a course this semester, and we've
run into a problem with it on multi-user vaxen. If there isn't sufficient
swap space for the system to run, it seems to get into an infinite loop
of garbage collection attempts. I should fail gracefully in this situation.
Priority: A
--------------------------------------------------------------------------------
150. incomplete sharing spec accepted
Submitter: Simon Finn <simon%abstract-hardware-ltd.co.uk@NSFnet-Relay.AC.UK>
Date: 13 Sept 89
Version: 0.33
Problem:
Both NJML (v0.33) and Poly/ML (v1.80x) erroneously parse the following:
signature SIG =
sig
type t
sharing type t
end;
Comments:
The above signature is illegal, since sharing constraints must involve
at least two types / structures ("n >= 2" in section 3.5, figure 7).
This bug was found by Mike Crawley.
Priority: A
--------------------------------------------------------------------------------
151. can't limit length of list printed
Submitter: Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK>
Date: 14 Sept 1989
Version: ??
Problem:
How do you tell New Jersey ML not to print all the elements of a list?
System.Control.Print.printDepth seems to consider nesting only.
Code:
- take(100,ms);
val it = [1861294,62685628,105212158,14112418,78287461,35512822,180290056,316473
64,72270388,168319897,212829007,43941079,142303594,174252739,117587239,56623288,
96050461,46119052,152678905,140061256,13973941,209088847,109015732,167261566,142
82215,159257329,69147538,162991570,121739197,19339324,52452037,18146911,23268574
,183534766,93272557,163056892,193407172,50009149,131379349,28143469,114167002,14
8862536,85731877,182107423,28619248,67440382,145320439,121674259,172092145,16412
2099,196052140,141367123,32002813,17851816,198701119,46866244,196351819,12166451
8,163288573,14499193,10976578,64526104,139008271,417145,67962574,64746709,994460
5,117181366,115999456,124879621,188830621,158322193,82998094,187333183,178599706
,158794345,17054389,62405431,142521907,182072470,22294474,162171034,163367647,12
3860254,25498117,13136599,105899185,53939356,184226566,191249065,66913411,177659
797,114495331,28730221,76001191,104114101,180588016,60920215,151887592,208100422
] : int list
- [[[[[[[[[[[4]]]]]]]]]]];
val it = [[[[[#]]]]] : int list list list list list list list list list list list
-
Priority: A
--------------------------------------------------------------------------------
152. floating point errors
Submitter: Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK>
Date: Thu, 14 Sep 89
Version: ??
Problem:
Why cannot New Jersey handle integers that are well within the maximum
available on the hardware?
Code:
- exp(31.0 * ln 2.0);
val it = 2147483648.0 : real
- floor 2000000000.0;
uncaught exception Floor
Priority: A? (partly fixed in 0.43?)
--------------------------------------------------------------------------------
153. interrupting corouting loop dumps core
Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK>
Date: Sep 15 11:14:13 1989
Version: 0.43
System: Sun 3
Problem: producer consumer segementation fault
interrupt consumer(producer) with a single ^c to cause a segmentation
fault
Code:
datatype state = S of state cont;
fun resume(S k: state) : state = callcc( fn k':state cont => throw k (S k'))
fun initiate(p:state -> unit) = callcc( fn k : state cont => (p(S k); S k))
val buf = ref 0;
fun producer(s:state):unit =
let val n=ref 0
val ccont : state ref = ref(resume s)
in
while true do (inc n; buf := !n; ccont := resume(!ccont))
end
fun consumer(prod: state->unit) : unit =
let val pcont = ref(initiate prod) in
while true do (pcont := resume(!pcont); print (!buf))
end
Priority: A
--------------------------------------------------------------------------------
154. import smashing memory
Submitter: Benjamin Pierce, CMU (bcp@cs.cmu.edu)
Date: 11/34/89
Version: 0.41
System: Sun3/SunOS 3.5.2
Problem: import seems to be smashing memory
Comments:
I've included a minimal version of program that exercises this bug on
my machine. Slightly different versions give different incorrect
results, or simply fail with bus errors. Removing the first line of
tconst.sml (the import of globals, which is never used here) gives the
correct answer.
Transcript:
Standard ML of New Jersey, Version 0.41, 25 October 1989
val it = () : unit
- use "main.sml";
[opening main.sml]
val it = () : unit
[reading checker.sml]
[reading tconst.sml]
[reading globals.sml]
[closing globals.sml]
[writing globals.bin... done]
[closing tconst.sml]
[writing tconst.bin... done]
[closing checker.sml]
[writing checker.bin... done]
signature GLOBALS
signature CHECKER
signature TCONST
functor TConstFun : <sig>
functor GlobalsFun : <sig>
functor CheckerFun : <sig>
structure TConst
val it = "\000\^VG\200" : ?.t <--- Should be "int"
[closing main.sml]
val it = () : unit
-
Code:
(* ------------------------ globals.sml: ---------------------- *)
signature GLOBALS = sig
val member: ''a -> ''a list -> bool
end
functor GlobalsFun() : GLOBALS = struct
fun member x [] = false
| member x (y::l) = (x=y) orelse (member x l)
end
(* ------------------------ tconst.sml: ---------------------- *)
import "globals";
signature TCONST = sig
type t
val from_string: string -> t
end
functor TConstFun((*structure Globals:GLOBALS*)): TCONST = struct
exception IllegalTConst of string
type t = string
fun member x [] = false
| member x (y::l) = (x=y) orelse (member x l)
fun from_string s = if not (member s ["int", "real", "bool"])
then raise IllegalTConst(s)
else s
end
(* ------------------------ checker.sml: ---------------------- *)
import "tconst";
signature CHECKER = sig
end (* CHECKER *)
functor CheckerFun() : CHECKER = struct
end (* CheckerFun *)
(* ------------------------ main.sml: ---------------------- *)
System.Control.Print.signatures := false;
import "checker";
(* structure Globals:GLOBALS = GlobalsFun(); *)
structure TConst:TCONST = TConstFun((*structure Globals=Globals*));
TConst.from_string "int";
Priority: A
--------------------------------------------------------------------------------
155. Compiler bug caused by of missing structure
Submitter: Banjamin Pierce (bcp@cs.cmu.edu)
Date: 11/3/89
Version: 0.39
System: Sun3/SunOS
Problem: Missing structure component shows up later as compiler bug
Transcript:
Standard ML of New Jersey, Version 0.39, 8 September 1989
- use "compilerbug.sml";
[opening compilerbug.sml]
val it = () : unit
signature GLOBALS
functor GlobalsFun : <sig>
signature SYMBOL
functor SymbolFun : <sig>
signature TCONST
functor TConstFun : <sig>
signature AST
functor AstFun : <sig>
structure Globals
structure TConst
structure Symbol
compilerbug.sml, line 225: Error: unmatched structure spec: TConst
compilerbug.sml, line 225: Error: Compiler bug: TypesUtil.lookTycPath.1
[closing compilerbug.sml]
-
Code:
System.Control.Print.signatures := false;
signature GLOBALS = sig
exception NotImplemented of string
val listtostring: ('a -> string)
-> string -> string -> string
-> ('a list)
-> string
val member: ''a -> ''a list -> bool
end
functor GlobalsFun() : GLOBALS = struct
exception NotImplemented of string
fun listtostring f init med fin is =
let fun lts [] = ""
| lts [i] = (f i)
| lts (i::is) = (f i) ^ med ^ (lts is)
in
init ^ (lts is) ^ fin
end
fun member x [] = false
| member x (y::l) = (x=y) orelse (member x l)
end
signature SYMBOL = sig
type symbol
val new_symbol: string -> symbol
val equal_symbol: symbol -> symbol -> bool
val tostring: symbol -> string
end
functor SymbolFun(): SYMBOL =
struct
type symbol = string
fun new_symbol s = s
fun equal_symbol s1 s2 = (s1=s2)
fun tostring s = s
end
signature TCONST = sig
type t
exception IllegalTConst of string
val from_string: string -> t
val tostring: t -> string
val le_const: t -> t -> bool
end
functor TConstFun(structure Globals:GLOBALS): TCONST = struct
open Globals
exception IllegalTConst of string
type t = string
fun tostring s = s
fun from_string s = if not (member s ["int", "real", "bool"])
then raise IllegalTConst(s)
else s
fun le_const s s' = (s=s') orelse ((s="int") andalso (s'="real"))
end
signature AST = sig
structure Symbol: SYMBOL
structure TConst: TCONST
type label
datatype const = INTCONST of int
| REALCONST of real
| STRINGCONST of string
type id
type type_var
datatype texp =
NS
| CONJ of texp * texp
| ARROW of texp * texp
| TYPECONST of TConst.t
| OBJECT of label * texp
| TVAR of type_var
datatype exp =
VAR of id
| CONST of const
| LAMBDA of id * exp
| TLAMBDA of id * texp list * exp
| APP of exp * exp
| BUILDOBJ of label * exp
| EXTRACTFIELD of exp * label
| MERGE of exp * exp
| BUILDSEQ of exp list
| REC of exp
| IF of exp * exp * exp
| LETTYPE of type_var * texp
| LETREC of (id * texp * exp) list * exp
val exptostring: exp -> string;
val texptostring: texp -> string;
end
functor AstFun(structure Symbol: SYMBOL
structure TConst: TCONST) = struct
structure Symbol = Symbol
(* ########################################################
Adding the line
structure TConst = TConst
makes the program work fine.
########################################################### *)
type label = Symbol.symbol
datatype const = INTCONST of int
| REALCONST of real
| STRINGCONST of string
(* | ... others? *)
type id = Symbol.symbol
type type_var = Symbol.symbol
datatype texp =
NS
| CONJ of texp * texp
| ARROW of texp * texp
| TYPECONST of TConst.t
| OBJECT of label * texp
| TVAR of type_var
datatype exp =
VAR of id
| CONST of const
| LAMBDA of id * exp
| TLAMBDA of id * texp list * exp
| APP of exp * exp
| BUILDOBJ of label * exp
| EXTRACTFIELD of exp * label
| MERGE of exp * exp
| BUILDSEQ of exp list
| REC of exp
| IF of exp * exp * exp
| LETTYPE of type_var * texp
| LETREC of (id * texp * exp) list * exp
fun exptostring e = "<exp>"
fun texptostring (NS) = "ns"
| texptostring (ARROW(t1,t2)) = "(" ^ (texptostring t1)
^ "->" ^ (texptostring t2) ^ ")"
| texptostring (CONJ(t1,t2)) = "(" ^ (texptostring t1)
^ "&" ^ (texptostring t2) ^ ")"
| texptostring (OBJECT(l,t1)) = "(" ^ (Symbol.tostring l)
^ ":" ^ (texptostring t1) ^ ")"
| texptostring (TYPECONST(i)) = TConst.tostring i
| texptostring (TVAR(i)) = Symbol.tostring i
end
structure Globals : GLOBALS = GlobalsFun();
structure TConst : TCONST = TConstFun(structure Globals=Globals);
structure Symbol : SYMBOL = SymbolFun();
(* commenting out the signature declaration on the next line results in
one additional error! *)
structure Ast : AST = AstFun(structure Symbol=Symbol
structure TConst=TConst);
signature SUBTYPE = sig
structure Ast: AST
val le : Ast.texp -> Ast.texp -> bool
end (* SUBTYPE *)
structure Subtype : SUBTYPE = struct
structure Ast = Ast
open Ast
structure Globals = Globals
open Globals
fun lei(s, ts, (NS)) = true
| lei(s, ts, (CONJ(t1,t2))) = lei(s, ts, t1) andalso lei(s, ts, t2)
| lei(s, ts, (ARROW(t1,t2))) = lei(s, (ts@[t1]), t2)
| lei((NS), ts, (t as TYPECONST(_))) = false
| lei(CONJ(s1,s2), ts, (t as TYPECONST(_))) =
lei(s1, ts, t) orelse lei(s2, ts, t)
| lei(ARROW(s1,s2), [], (t as TYPECONST(_))) = false
| lei(ARROW(s1,s2), ta::ts, (t as TYPECONST(_))) =
lei(ta, [], s1) andalso lei(s2, ts, t)
| lei((TYPECONST(sc)), ta::ts, (TYPECONST(tc))) = false
| lei((TYPECONST(sc)), [], (TYPECONST(tc))) = TConst.le_const sc tc
| lei(s, ts, t) = raise NotImplemented ("lei "
^ (Ast.texptostring s)
^ " "
^ (listtostring Ast.texptostring
"[" "," "]" ts)
^ " "
^ (Ast.texptostring t))
fun le s t = lei(s, [], t)
end (* SubtypeFun *)
Priority: A
--------------------------------------------------------------------------------
156. confusing parser error message
Submitter: dbm
Date: 4 Nov 1989
Version: 0.43
Problem:
Misspelled constructor (VALbind instead of VARbind) in line
| scan ((VALbind _)::_) = ...
causes inappropriate message:
basics/typesutil.sml, line 74: Error: identifiers in clauses don't match
Priority: P
--------------------------------------------------------------------------------
157. nested imports corrupt memory (same as 154?)
Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK
Date: 3 Nov 89
Version: 0.39
System: Sun 3
Problem:
I have had a good deal of trouble with transitive imports. Symptom is
segmentation failure on first call of a procedure defined in a functor
imported transitively.
parser:
defines abstractsyntax, lexer, and parser functors
codegen:
imports parser
defines code generator
main:
imports codegen
instantiates abstractsyntax, lexer, parser
crashes at first invocation of procedure defined in parser.
When I remove the "import parser" from codegen, and
import it directly from main, then all is well.
This actually arose in a student's system, and I haven't time to try it in
smaller contexts. Does the symptom sound familiar? If not, I can send the
whole lot to you.
Priority: A
--------------------------------------------------------------------------------
160. errorty fails to match sig spec
Submitter: dbm
Date: 18 Oct 89
Version: 0.43
System: Sun 3
Problem: error type not matched in checking signature spec
Messages:
typing/functor.sml, line 363: Error: value type in structure doesn't match
signature spec
name: abstractBody
spec: Structure * stampsets -> Structure
actual: Structure * error -> Structure
Priority: A
--------------------------------------------------------------------------------
162. ByteArray subscript exception expected
Submitter: Jawahar Malhotra, Meta Software Corp.,
malhotra%metasoft@bbn.com
Date: 10/17/89
Version: 0.33
System: Sun OS 3.5
Problem: ByteArray.extract doesn't raise Subscript exception when I
think it should.
Code:
val ba = ByteArray.array(4,0);
(* I feel that the following SHOULD raise an exception *)
ByteArray.extract(ba,4,0);
(* the following two statements CORRECTLY raise exceptions *)
ByteArray.extract(ba,5,0);
ByteArray.sub(ba,4);
Priority: C
--------------------------------------------------------------------------------
163. function definition syntax
Submitter: Andy Gordon, Cambridge University, adg@cl.cam.ac.uk
Date: Mon Oct 16 15:26:44 1989
Version: Version 0.33, 1 April 1989
System: Sun
Problem: another strange function definition
Code:
fun cps-fact n k = cps-fact n k;
Messages:
Error: Compiler bug: generalizeTy -- bad arg
fact : 'S -> 'T -> undef
Comments:
Like in bug 73, I was mistakenly trying to define a function whose identifier
contained a hyphen, but this time the compiler complains of a Compiler bug.
Priority: P
--------------------------------------------------------------------------------
164. NS32 in makeml
Submitter: Allan E. Johannesen, wpi, aej@wpi.wpi.edu
Date: 13-Oct-1989
Version: 0.39, maybe. That was the number in the README
System: Encore
Problem: makeml error
Code: makeml -encore
Messages: makeml: must specify machine type
Comments:
please put NS32 in $MACHINE case of makeml
maybe:
NS32)
if test "$OPSYS" != BSD
then
echo "makeml: bad os ($OPSYS) for encore"
exit 1
fi
if test -z "$MO"
then
MO="../mo.encore"
fi
MODULE="$MODULEKIND"Encore
;;
Priority: A
--------------------------------------------------------------------------------
167. repeated bound type variables in type declaration
Submitter: Nick Rothwell
Date: 5 Oct 89
Version: 0.39?
System: Sun 3
Problem: multiple binding occurences of type variable accepted
Code:
- datatype ('a, 'a, 'a) T = A of 'a | B of 'a;
datatype ('a,'b,'c) T
con A : 'a -> ('a,'b,'c) T
con B : 'a -> ('a,'b,'c) T
Priority: B
--------------------------------------------------------------------------------
168. profiling on sparc
Submitter: Tom Murtagh ( tpm@rice.edu)
Date: Oct 4, 1989
Version: 0.38
System: Sun4/SunOS 4.0.3c
Problem: unhandled exception Match in codegenerator when Profiling enabled
I stumbled across what appears to be another problem in the Sparc code
generator. It seems to fail when any function is compiled with
profiling enabled. This time I do have a minimal code fragment:
% sml
Standard ML of New Jersey, Version 0.38, 23 August 1989
val it = () : unit
- System.Control.Profile.profiling := true;
val it = () : unit
- (fn x => x);
?exception Match in SparcCM.storeindexl
uncaught exception Match
Status: fixed in 0.43 (?)
--------------------------------------------------------------------------------
169. inferring eqtypes in signatures
Submitter: Randy Pollack <rap%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK>
Date: Wed, 27 Sep 89
Problem: NJML (V0.39) is too liberal in inferring eqtypes in signatures
Code:
- functor F() = struct abstype t = E with val mk_t = E end end;
functor F : <sig>
- structure f = F();
structure f :
sig
eqtype t (*** incorrect ***)
val mk_t : t
end
however:
- structure f = struct abstype t = E with val mk_t = E end end;
structure f :
sig
type t (*** correct ***)
val mk_t : t
end
Priority: A
--------------------------------------------------------------------------------
170. error in makeml script
Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK
Date: Wed Sep 27
Transcript:
26 % makeml -sun3 -ionly -o smli -m 3
(cd runtime; make clean)
rm -f *.o lint.out prim.s linkdata allmo.s
rm -f mo
ln -s ../mo.m68 mo
(cd runtime; rm -f run allmo.o)
(cd runtime; make MACHINE=M68 linkdata)
cc -O -DM68 -o linkdata linkdata.c
runtime/linkdata [runtime/IntNull.mos] > runtime/allmo.o
(cd runtime; make MACHINE=M68 'DEFS= -DSUN3 -DSUN3 -DBSD' 'CFL=-n -Bstatic -f68881' 'ASMBLR=as')
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c run.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c gc.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c callgc.c
cc: Warning: Obsolete option -B
/lib/cpp -DM68 -DSUN3 -DSUN3 -DBSD M68.prim.s > prim.s
as -o prim.o prim.s
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c prof.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c export.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c objects.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c cstruct.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -mc68020 -c trace.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -o run run.o gc.o callgc.o prim.o prof.o export.o objects.o cstruct.o trace.o allmo.o
cc: Warning: Obsolete option -B
_Loader: ld: allmo.o: multiply defined
*** Error code 2
make: Fatal error: Command failed for target `run'
echo (System.Control.interp := true; exportML "smli"; output std_out System.version; output std_out "\n"); | runtime/run -m 3 -r 20 -h 2048 IntNull
makeml: runtime/run: cannot execute
Priority: A