Number: 201 Title: funny tycon aliasing behavior Keywords: types, modules Submitter: John Reppy Date: 8/18/89 Version: 0.33 Transcript Standard ML of New Jersey, Version 0.33, 1 April 1989 val it = () : unit - structure A = struct datatype foo = Bar of int end = ; structure A : sig datatype foo con Bar : int -> foo end - structure B : sig datatype foo' = Bar of int end = struct = open A = type foo' = foo = end; structure B : sig datatype foo' con Bar : int -> A.foo end Status: fixed in 0.56 -------------------------------------------------------------------------------- Number: 202 Title: type error not caught? Keywords: modules, functors, type checking Submitter: Norman Ramsey Date: 8/28/89 Version: ? Problem: I believe that the following file should generate a type error, but it doesn't. In particular, the line val _ = begin_str "replicas" ufanout(c,chans) should force chans to be type 'a chan list when c is type 'a chan. Code: datatype 'a chan = CHAN of 'a signature BADGUYS = sig val mkchan : unit -> '1a chan val ufanout : '2a chan * '2a chan list -> 'b val begin_str : string -> ('a -> 'b) -> 'a -> unit end signature WONKY = sig val ureplicas : int -> '2a chan -> '6b chan list (* wrong! should be int -> '2a chan -> '2a chan list *) end functor buggy(bad:BADGUYS):WONKY = struct open bad fun ureplicas n c = (* n unsynchronized copies of channel c *) let fun channels(l,0) = l | channels(l,n) = channels(mkchan()::l,n-1) val chans = channels(nil,n) val _ = begin_str "replicas" ufanout(c,chans) in chans end end Transcript: (0.52) - use "code/bug.202"; [opening code/bug.202] code/bug.202:16.36-28.3 Error: value type in structure doesn't match signature spec name: ureplicas spec: int -> '2a chan -> '6b chan list actual: int -> '1a chan -> '6b chan list Status: fixed in 0.56 -------------------------------------------------------------------------------- Number: 203 Title: printing of infix specs in signatures Keywords: modules, signatures, printing Submitter: Trevor Jim Date: 4/3/89 Version: 0.32, 0.52 Problem: infix specs are printed with two precedence numbers Transcript: - signature SS = sig infix 5 bar end; signature SS = sig infix 10 10 bar end Status: fixed in 0.54 -------------------------------------------------------------------------------- Number: 204 Title: constructors printed when not accessible Keywords: modules, signatures, printing Submitter: Dave Berry Date: 2/2/89 Version: 0.52 Problem: constructors of a datatype in a structure are printed in the structure signature even though they are masked out by a signature constraint. Transcript: - signature S1 = sig type d end; signature S1 = sig type d end - structure A : S1 = struct datatype d = A | B of int end; structure A : sig datatype d con A : d con B : int -> d end Status: fixed in 0.56 -------------------------------------------------------------------------------- Number: 205 Title: performance problem with many opens in a structure Keywords: modules, top level, open Submitter: Jawahar Malhotra Date: 3/15/90 Version: 0.56 Problem: many opens Code: structure A = struct (* 30 val declarations *) end structure B,C,D... similar structure S = struct open A B C D E F G end Status: fixed in 0.58 ------------------------------------------------------------------------------ Number: 206 Title: unhelpful parser error message (new parser) Keywords: Submitter: Dave Date: 3/15/90 Version: 0.52 Transcript: - structure A = struct val x = if true then if true then 1 else 2 end; std_in:4.1 Error: syntax error found at END - Comment: what we need is %prefer ELSE 0, that is, the ability to give a hint for the insertion of two tokens in a row. Right now, %prefer can only hint about single-token insertions. This fix has to be done in mlyacc. Fix: multitoken inserts Status: fixed in 1.03f ------------------------------------------------------------------------------- Number: 207 Title: uncaught tycStamp exception Keywords: types, modules, signatures, functors Submitter: Nevin.Heintze@PROOF.ERGO.CS.CMU.EDU Date: 4/3/90 Version: 0.44 (0.53) Problem: tycStamp raised during compilation Code: (file bug207.sml) signature SS = sig datatype t = B of t | A of t list end functor F(X:SS) = struct fun f(X.B(v)) = (v :: nil = v :: nil) | f _ = false end Transcript: Standard ML of New Jersey, Version 0.44, 4 December 1989 val it = () : unit - use "bug.sml"; [opening bug.sml] bug.sml, line 11: Error: Compiler bug: tycStamp equal: type = ?.ttt list [closing bug.sml] - Comments: The problem appears to be the typing of the equality test. It is sensitive to the use of lists, both in the datatype definition and the equality test. Status: fixed in 0.56 ------------------------------------------------------------------------------- Number: 208 Title: bug in optimizer causing bad free variable Keywords: Submitter: Appel & MacQueen Date: 4/27/90 Version: 0.56 Problem: impossible error in cpsopt phase, on MIPS machine, with default optimization settings Code: functor MipsCoder(val emit : 'a -> unit) = struct fun needs _ = true fun pass now = let fun gen inst = if now andalso needs() then () else if now then let fun gen1() = gen(raise Match) in case inst of NONE => gen1() | SOME b => let fun bc1f offset = () fun bc1t offset = () in if inst=NONE then (emit((if b then bc1t else bc1f) inst); gen1()) else () end end else () in gen end val assemble = pass true end Comment: this can be avoided by setting closurestrategy to 2, which we now do; Trevor may fix this bug eventually. Status: fixed in 0.60 (avoided) ------------------------------------------------------------------------------- Number: 209 Title: equality types and functors, again Keywords: modules, functors, equality Submitter: Appel & MacQueen Date: 4/30/90 Version: 0.56 Problem: Problem in eqtypes/defineEqTycon/eqty. failure when attempting to reevaluate equality properties of generative/defined tycons in functor body after functor is applied. Code: signature S1 = sig type t end; structure A = struct type t = int end; functor F(X : S1) = struct structure B = struct datatype s1 = K of X.t end type s = B.s1 end; structure C = F(A); Comments: we've put in a warning message, and assumed a non-equality type when this happens. (still causes impossible error in 0.56). Fix: "fixed" by following the lead of the Definition and not recalculating equality properties on functor applications. Status: fixed in 0.66 -------------------------------------------------------------------------------- Number: 210 Title: sharing checking with fixed stamps Keywords: modules, signatures, sharing Submitter: Appel & MacQueen Date: 5/3/90 Version: 0.56 Problem: Union exception is not caught when sharing specs try to identify two distinct types or structures (with differing fixed stamps). Code: structure S = struct end; structure T = struct end; signature Q = sig sharing S=T end; Comments: Easy to fix. Just add a handler for the Union exception in Sharing.doSharing and produce and appropriate error message. Status: fixed in 0.57 -------------------------------------------------------------------------------- Number: 211 Title: Union exception processing correct sharing in functor body Keywords: modules, functors, sharing Submitter: MacQueen Date: 5/4/90 Version: 0.56 Problem: Union exception is raised in doSharing when processing correct sharing specs in a functor body. Code: (* bug211.sml *) functor F(type t) = struct structure K = struct type s = t end structure M : sig structure L : sig type s sharing type s = t end sharing L=K end = struct structure L = K end end; Comments: The bug occurs because the type definition shortcut (for "type s = t", s is made a copy (modulo path) of t) is not done when t has a bound stamp, as in the code above. Here s is a DEFtyc tycon with a different stamp from t. Status: fixed in 0.58 -------------------------------------------------------------------------------- Number: 212 Title: polymorphic exception declarations Keywords: exceptions, polymorphism Submitter: Dave Berry (for Jo Blishen) (submitted to ml-bugs) Date: 5/11/90 Version: 0.56 Severity: major Problem: rejects proper weak polymorphic type for locally declared exception Code: fun f (l:'_a) = let exception E of '_a in (raise (E l)) handle E t => t end; Comments: Worked in 0.44a. Status: fixed in 0.58 (suspect related bugs because of the way TyvarSet.union_tyvars is defined.) -------------------------------------------------------------------------------- Number: 213 Title: equality on int*int Keywords: equality Submitter: Soren Christensen, University of Aarhus, Computer Science Dep., Denmark schristensen@daimi.dk Date: 5/16/90 Version: 0.56 System: Sun4/280 / SunOS 4.0.1 Severity: Critical Problem: failure compiling equality on type int*int Code: (* filename: bug213.sml *) (3,3,) = (3,3); Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - use "fun"; [opening fun] datatype 'a $$$ con $ : 'a -> 'a $$$ con $$ : 'a $$$ LOOKUP FAILS in close(FIX 2795 2799 2707 2996 ) on 2927 in environment: 2792 2790 2791 [closing fun] uncaught exception Match - val x = 5; Illegal instruction Comments: [Christensen] It looks like the compiler is messed up after this error. It core-dumps parsing the next declaration. Version 0.44 has no problem handling this declaration. [dbm] The code "(3,3) = (3,3);" reproduces the bug. Haven't been able to reproduce the core dump. Status: fixed in 0.58 (bug was in codegen) -------------------------------------------------------------------------------- Number: 214 Title: Compiler bug: EnvAccess.lookPath when printing Keywords: modules, functors, printing Submitter: Frank Pfenning (Frank.Pfenning@proof.ergo.cs.cmu.edu Date: 5/17/90 Version: 0.56 Severity: critical Problem: Compiler bug: EnvAccess.lookPath occurs when printing a top-level result. Code: signature TERM = sig datatype term = Const of string and varbind = Varbind of string * term end functor Term ( ) : TERM = struct datatype term = Const of string and varbind = Varbind of string * term end signature BUG = sig structure Term : TERM type progentry val bug : progentry list end functor Bug ( structure Term : TERM ) : BUG = struct structure Term = Term open Term datatype progentry = Progentry of string * Term.term * Term.varbind list * Term.term val bug = [Progentry("test",Const "test", [Varbind("v",Const("test"))],Const("test"))] end structure Term : TERM = Term (); structure Bug : BUG = Bug ( structure Term = Term ); Bug.bug; Status: fixed in 0.58 -------------------------------------------------------------------------------- Number: 215 Title: sin gives incorrect values Keywords: Submitter: Thomas M. Breuel (tmb@ai.mit.edu) Date: 5/18/90 Version: 0.59 System: SPARC/SunOS 4.0.3c Severity: major Problem: sin function is incorrect Transcript: (* SparcStation 1, SunOS 4.0 *) Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - sin(4.0); val it = ~0.756802495307928 : real - sin(5.0); val it = ~0.958924274663138 : real - sin(6.0); val it = 0.279415498198926 : real - (* ^^^^^^^^^^^^^^^^^ this should be negative, since it is between pi and 2 pi *) Comments: Probably someone transcribed the sin function from the Berkeley math library incorrectly in boot/math.sml. Status: fixed in 0.58 (Appel) -------------------------------------------------------------------------------- Number: 216 Title: floating point on SPARC Keywords: Submitter: tmb@ai.mit.edu Date: 19/5/90 Version: 0.56 System: Sun SS1, Sun OS 4.0.3 Severity: critical Problem: floating point broken in Sparc compiler?! Transcript: (everything that begins with a TAB comes from an actual transcript) Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - fun ilist(from:int,to:int,step:int) = f = if (from (int -> 'a) -> 'a list - ilist(0,10,1) (fn x => x); val it = [0,1,2,3,4,5,6,7,8,9] : int list - ilist(0,10,1) print; 0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list all is as it should be--so far - fun rlist(from:real,to:real,step:real) f = = if (from (real -> 'a) -> 'a list this is the same definition with different type constraints - rlist(0.0,10.0,1.0) (fn x => x); val it = [] : real list ??? - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list same expression, different result??? - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list now it seems to work... - rlist(0.0,10.0,1.0) print; 0.0val it = [()] : (unit) list but it still doesn't work with "print" - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list - Comments: These problems don't occur on the m68 version of SML. In fact, the problem with "sin" that I reported previously also doesn't occur with the m68 version. Maybe this is an installation problem, but if it is, then there is probably something wrong with the makeml script. The Sparc version was generated with "makeml -sun4 -sunos" if I remember correctly. Here is the transcript from a Sun-3: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - [opening /tmp_mnt/home/vi/tmb/cad/bad.sml] val identity = fn : 'a -> 'a val ilist = fn : int * int * int -> (int -> 'a) -> 'a list val rlist = fn : real * real * real -> (real -> 'a) -> 'a list [closing /tmp_mnt/home/vi/tmb/cad/bad.sml] val it = () : unit these are the same definitions as above - ilist(0,10,1) (fn x => x); val it = [0,1,2,3,4,5,6,7,8,9] : int list - ilist(0,10,1) print; 0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list - rlist(0.0,10.0,1.0) (fn x => x); val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] : real list - rlist(0.0,10.0,1.0) print; 0.01.02.03.04.05.06.07.08.09.0val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list - sin 6.0; val it = ~0.279415498198926 : real - sin 5.0; val it = ~0.958924274663138 : real - Status: fixed in 0.58 (Reppy) -------------------------------------------------------------------------------- Number: 217 Title: simultaneous opens Keywords: Submitter: Larry Paulson (lcp@lfcs.ed.ac.uk) Date: 5/25/90 Version: 0.56 Severity: major Problem: opening several structures simultaneously can result in Runbind Code: code/bug217.sml structure A = struct val x = 3 end; structure B = struct structure A = A; end; open A B; x; Comments: This works if "open A B;" is replaced with "open A; open B;" Status: fixed in 0.59 -------------------------------------------------------------------------------- Number: 218 Title: compiler bug after unbound variable Keywords: types, type checking Submitter: John Reppy (jhr@cs.cornell.edu) Date: 5/26/90 Version: 0.57 Severity: major Problem: Compiler bug: generalizeTy -- bad arg occurs after top level unbound var Transcript: - x; std_in:2.1 Error: unbound variable x Error: Compiler bug: generalizeTy -- bad arg Status: fixed in 0.59 -------------------------------------------------------------------------------- Number: 219 Title: parsing layered patterns Keywords: Submitter: Andrew Appel Date: 5/1/90 Version: 0.56 and later Severity: minor Problem: parsing of layered pattern is too liberal. An atomic pattern is accepted where a variable is required by the Definition syntax. Code: let val (x) as (y :: z) = [1,2] in x end Comments: Seems to require nontrivial change to the mlyacc grammar Status: fixed in 1.04 (actually 1.03f) -------------------------------------------------------------------------------- Number: 220 Title: Match exception after error Keywords: modules, signatures, signature matching Submitter: John Reppy Date: 6/1/90 Version: 0.58 System: Sun 4 Severity: minor Problem: uncaught exception Match after signature matching error Code: signature S = sig type foo val f : int -> foo end structure Foo : S = struct datatype foo_t = Foo of int val f = Foo end Transcript: xxx.sml:6.21-9.3 Error: unmatched type spec: foo xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec name: f spec: int -> [closing xxx.sml] uncaught exception Match - Comment: Now produces std_in:10.21-13.3 Error: unmatched type spec: foo std_in:10.21-13.3 Error: value type in structure doesn't match signature spec name: f spec: int -> NULLtyc actual: int -> foo_t The NULLtyc is undesirable. Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 221 Title: profiling broken Keywords: profiling Submitter: Benjamin Pierce (Benjamin.Pierce%proof.ergo.cs.cmu.edu Date: 5/22/90 System: 0.56 (and later) Problem: Profiling provides call counts bug not timings. For separately compiled modules, profiling provides neither call counts nor timings. Transcript: (1) for separately compiled code %time cumsecs #call ms/call name .00 0 (toplevel) .00 0 (gc) .00 0 (unprofiled) (2) for "used" code %time cumsecs #call ms/call name .00 2398 .0000 anon.AType.==.anon .00 2398 .0000 anon.AType.== .00 2051 .0000 anon.Id.==.anon .00 2051 .0000 anon.Id.== .00 1890 .0000 anon.AType.apply_rule.anon [etc...] Fix: Some of the problems may be caused by handleprof() in runtime/signal.c being braindamaged. I changed it to be: SIGH_RET_TYPE handleprof () { extern ML_val_t current0[]; ML_val_t cur_barray = current0[1]; cur_barray[1] = (unsigned int)INT_incr(cur_barray[1],1); } and it seemed to work for simple examples. However, I'm not too sure that the times mean anything for larger examples. Perhaps there's some bad interaction with GC? Status: fixed in 0.70 -------------------------------------------------------------------------------- Number: 222 Title: equality on ref types Keywords: equality Submitter: Larry Paulson Date: 11/6/90 Version: 0.56, 0.59 Severity: major Problem: ref type not being recognized as unconditionally an equality type Transcript: - fun silly x = (ref x = ref x); val silly = fn : ''1a -> bool - silly not; std_in:4.1-4.9 Error: operator and operand don't agree (equality type required) operator domain: ''0S operand: bool -> bool in expression: silly not And anyway the type checker behaves inconsistently by admitting the following: - ref not = ref not; val it = false : bool Status: fixed in 0.65 --- before -------------------------------------------------------------------------------- Number: 223 Title: nontty standard input and uncaught exceptions Keywords: Submitter: KINOSHITA Yoshiki yoshiki@etl.go.jp Date: 6/4/90 Version: SML of NJ 0.56 System: Sparc Station 330 (SUN4), SUN-OS 4.0.3 (generic version) Severity: major Problem: If the standard input is a pipe, the system ends abnormally after it sends an error message. Code: None. The problem concerns with the interface to UNIX. Transcript: % cat - | sml Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - foo; std_in:2.1-2.3 Error: unbound variable foo uncaught exception Stop ^Z Stopped % jobs [1] + Stopped cat - | Done sml % Comments: This problem makes it impossible to use the system with its input sent through a UNIX filter. from jhr: You might call this a feature. It appears that the person who wrote the top-level loop code (interact.sml), decided that exceptions should only be caught at the top-level loop when std_in is a tty (look at lines 292-309 in interact.sml). The following work-around avoids the problem cat - | sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - set_term_in(std_in, true); val it = () : unit - foo; std_in:3.1-3.3 Error: unbound variable foo - 1+2; val it = 3 : int - But, maybe the code should change. It isn't clear to me what the correct semantics are in this case. This problem came up here at Cornell when Bill Aitken was using "rsh" to run sml on a remote machine. Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 224 Title: weakness 0 type variables in let declaration Keywords: types, type checking, weak types Submitter: Larry Paulson Date: 6/4/90 Version: 0.56, 0.59 Severity: major Problem: A weakness 0 type variable should be admitted, but not generalized, in local declarations. Transcript: - let val f = ref(fn x => x) in f := not; !f true end; std_in:1.9-1.26 Error: nongeneric weak type variable f : ('0Y -> '0Y) ref std_in:1.9-1.26 Error: nongeneric weak type variable f : ('0Y -> '0Y) ref Comments: This worked in 0.44. Status: fixed in 0.65 --- (before) -------------------------------------------------------------------------------- Number: 225 Title: import broken in 0.59 Keywords: Submitter: Lars Bo Nielsen Date: 6/5/90 Version: Version 0.59 System: Sparc/sunos Severity: critical Problem: import broken. A simple 'import "file"' doesn't work, if only 'file.sml' is present. If 'file.bin' is present it works. I DIDN'T have this problem with version 0.56. Transcript: The following example shows the problem. SHELL% ll total 68 2 calc.dsl 11 calc.grm.sml 31 calc.parser.sml 3 calc.grm 1 calc.instr 2 calc.sml 4 calc.grm.desc 2 calc.lex 1 calc.grm.sig 11 calc.lex.sml SHELL% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - import "calc.parser"; uncaught exception SystemCall - ^Z Stopped SHELL% touch calc.parser.bin SHELL% fg sml - import "calc.parser"; [reading calc.parser.bin... ] [calc.parser.bin is the wrong format; recompiling [closing calc.parser.bin] [reading calc.parser.sml] [Major collection... 69% used (1475096/2123360), 1700 msec] [Increasing heap to 4451k] ..... etc ..... Status: fixed in 0.60 (jhr) -------------------------------------------------------------------------------- Number: 226 Title: uncaught exception Match while printing type (same as 220) Keywords: modules, types, printing Submitter: John Reppy Date: 6/1/90 Version: 0.56 Severity: major Problem: Uncaught Match exception occurs when printing out the spec type in an error message. Code: signature S = sig type foo val f : int -> foo end structure Foo : S = struct datatype foo_t = Foo of int val f = Foo end Transcript: xxx.sml:6.21-9.3 Error: unmatched type spec: foo xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec name: f spec: int -> [closing xxx.sml] uncaught exception Match - Status: fixed in 0.65 --- partially fixed (before 0.65) -------------------------------------------------------------------------------- Number: 227 Title: equality property of datatypes Keywords: types, datatypes, equality Submitter: Brian Boutel (brian@comp.vuw.ac.nz) Date: 5/25/90 Version: 0.56 System: Sun3/sunos and H-P workstation (More/bsd) Severity: major Problem: Equality test for recursive types may fail in various ways (similar to bug 45, reported fixed) Description: Given datatype 'a d1 = c11 | c12 of ('a * 'a d1); datatype 'a d2 = c21 | c22 of ('a d2 * 'a ); datatype d3 = c31 | c32 of ( d3 * int); a) c11 = c11 works correctly b) c12(1,c11) = c12(1,c11) gets uncaught exception Match (* ok in 0.59 *) c) c21 = c21 loops forever (* in 0.59 as well *) d) c22(c21,1) = c22(c21,1) gets uncaught exception Match (* ok in 0.59 *) e) c31 = c31 works correctly f) c32(c31,1) = c32(c31,1) gets uncaught exception Match (* ok in 0.59 *) Transcript: (with System.Control.debugging := true) b) - c12(1,c11) = c12(1,c11); parse semantics BEFORE: val it = = (c12 (1,c11),c12 (1,c11)) AFTER: val it = = (c12 (1,c11),c12 (1,c11)) test: int d1 test: int d1 find: int d1 find-notfound enter: int d1 test: int * int d1 find: int * int d1 find-notfound enter: int * int d1 test: int test: int test: int d1 find: int d1 translate reorder convert cpsopt closure LOOKUP FAILS in close(FIX 4146 4150 ) on 4161 in environment: 4143 4141 4142 globalfix spill codegen uncaught exception Match - c) - c21 = c21; parse semantics BEFORE: val it = = (c21,c21) AFTER: val it = = (c21,c21) test: ''S d2 test: ''S d2 find: ''S d2 find-notfound enter: ''S d2 test: ''S d2 * ''S find: ''S d2 * ''S find-notfound enter: ''S d2 * ''S test: ''S d2 find: ''S d2 find-notfound enter: ''S d2 test: ''S d2 * ''S find: ''S d2 * ''S find-notfound enter: ''S d2 * ''S test: ''S d2 find: ''S d2 find-notfound ..... Status: fixed in 0.60 -------------------------------------------------------------------------------- Number: 228 Title: string to real conversion Keywords: Submitter: jubu@tub.UUCP or jubu@tub.BITNET (Juergen Buntrock TUB) Date: 27/4/90 Version: 0.44 System: Sun4, SunOS Release 4.0.3c Severity: critical Code: and Transcript: Script started on Fri Apr 27 13:49:54 1990 jubu@curry mlj/handel 1) cat bug.sml exception bad_number; fun string2real (s : string) = let val (fac,li) = case explode s of "-" :: li => (~1.0,li) | "+" :: li => (1.0,li) | li => (1.0,li) val (res,_) = (revfold (fn (c,(a,fac1)) => let val n = ord c - ord "0" in output std_out ""; (* comiler bug ! *) if fac1 > 0.0 then if n < 0 orelse n > 9 then raise bad_number else (a + fac1 * (real n),fac1/10.0) else if c = "." then (a,1.0/10.0) else if n < 0 orelse n > 9 then raise bad_number else (10.0 * a + (real n),0.0) end) li (0.0,0.0)) in res * fac end fun string2real_bug (s : string) = let val (fac,li) = case explode s of "-" :: li => (~1.0,li) | "+" :: li => (1.0,li) | li => (1.0,li) val (res,_) = (revfold (fn (c,(a,fac1)) => let val n = ord c - ord "0" in if fac1 > 0.0 then if n < 0 orelse n > 9 then raise bad_number else (a + fac1 * (real n),fac1/10.0) else if c = "." then (a,1.0/10.0) else if n < 0 orelse n > 9 then raise bad_number else (10.0 * a + (real n),0.0) end) li (0.0,0.0)) in res * fac end jubu@curry mlj/handel 2) sml Standard ML of New Jersey, Version 0.44, 4 December 1989 val it = () : unit - use"bug.sml"; [opening bug.sml] exception bad_number val string2real = fn : string -> real val string2real_bug = fn : string -> real [closing bug.sml] val it = () : unit - string2real "123.456"; val it = 123.456 : real - string2real_bug "123.456"; val it = 12346.0 : real - open System.Control.CG; structure M68 : sig val trapv : bool ref end val reducemore = ref 15 : int ref val printit = ref false : bool ref val knowngen = ref 12 : int ref val etasplit = ref true : bool ref val comment = ref false : bool ref val knowncl = ref 0 : int ref val scheduling = ref true : bool ref val printsize = ref false : bool ref val reduce = ref true : bool ref val closureprint = ref false : bool ref val stdgen = ref 64 : int ref val alphac = ref true : bool ref val profile = ref false : bool ref val hoist = ref true : bool ref val foldconst = ref true : bool ref val tailrecur = ref true : bool ref val path = ref false : bool ref val rounds = ref 1 : int ref val closureStrategy = ref 1 : int ref val recordopt = ref true : bool ref val bodysize = ref 0 : int ref val tail = ref true : bool ref - script done on Fri Apr 27 13:55:57 1990 Comments: the Sun3 Compiler is correct Status: fixed in 0.56 -------------------------------------------------------------------------------- Number: 229 Title: uncaught Match after signature spec error Keywords: modules, signatures, signature matching Submitter: Peter Buneman Date: 4/21/89 Version: 0.59 Severity: major Problem: Following code produces uncaught Match exception Code: signature SS = sig type t1 val t2:t1 end; structure ss:SS = struct local datatype t = T of int in val t2 = T 3 end end; Comment: Output in 0.65 is std_in:8.1-12.3 Error: unmatched type spec: t1 std_in:8.1-12.3 Error: value type in structure doesn't match signature spec name: t2 spec: NULLtyc actual: ?.ss.t NULLtyc for spec is undesirable (similar to 220,226 problem). Status: fixed in 0.65 --- partially fixed (before 0.65) -------------------------------------------------------------------------------- Number: 230 Title: printing reals on mips Keywords: Submitter: David MacQueen, Andrew Tolmach Date: 6/12/90 Version: 0.59 System: MIPS, RISCos Severity: critical Problem: Uncaught exception Overflow when printing real numbers at top level. Infinite loop in other cases (e.g. code/bug230.sml). Transcript: - 1.0; val it = uncaught exception Overflow - Comment: works ok on Sun3 and Sun4. works ok on DECsystem (with MIPS chip) / Ultrix Status: fixed in 0.64 -------------------------------------------------------------------------------- Number: 231 Title: equality property of DEFtyc Keywords: types, equality Submitter: Nick Rothwell Date: 6/21/90 Version: 0.56? Severity: major Problem: A type abbreviation for an abstract type admits equality. Code: abstype A = A with type B = A end; fn (x: B) => (x=x); Comments: The type name associated with A (and therefore with B) should be stripped of its equality attribute outside the "abstype". Status: fixed in 0.69 -------------------------------------------------------------------------------- Number: 232 Title: user bound type variable in exception declaration Keywords: types, type variables, exceptions Submitter: Jo Blishen, Nick Rothwell Date: 6/20/90 Version: 0.59 Severity: minor Problem: User-bound tyvar is not generalized at val binding containing it. Transcript: - fun f l = let exception E of '_a in (raise (E l)) handle E t => t end; std_in:2.30-2.32 Error: unbound tyvars in exception declaration Comments: According to the Definition '_a should be considered bound at the outermost val (fun f l ...) where it is the type of the lambda-bound variable l. Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 233 Title: opening locally declared structure causes Runbind Keywords: modules, open, dynamic env Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 6/20/90 Version: 0.56 (applies to 0.59 as well I believe) System: Sun3, SunOS 4.1 Severity: You decide.... Problem: You cannot declare a local structure and open it. Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 val it = () : unit - local = structure Bug = = struct = val message = "Try to evaluate me !" = end = in = open Bug = end ; open Bug - message; uncaught exception Runbind - Status: fixed in 0.60 -------------------------------------------------------------------------------- Number: 234 Title: Compiler Bug: abstractBody.abstractType 1 Keywords: modules, functors Submitter: deutsch@poly.polytechnique.fr. Alain Deutsch, Laboratoire d'Informatique de l'Ecole Polytechnique (LIX) 91128 Palaiseau Cedex France. Date: 6/19/90 Version: Standard ML of New Jersey, Version 0.56, 13 April 1990 System: Sun 3/60, SunOS Release 4.0_Export Severity: major (?) Problem: Compiler Bug: abstractBody.abstractType 1 Code: Too long, ommited. Transcript: - use "/home/icsla/deutsch/ESTFM/basic_ev.sml"; [opening /home/icsla/deutsch/ESTFM/basic_ev.sml] [reading Powerset.bin... done] signature FunctionLattice signature ProductLattice signature OrderedSet signature Lattice signature Product signature PartialFunction signature TotalFunction functor Powerset [reading HashTable.bin... done] signature arrayext functor HashTable functor arrayext [reading lattice.sig.bin... done] signature FunctionLattice signature ProductLattice signature OrderedSet signature Lattice signature Product signature PartialFunction signature TotalFunction [reading Syntax.sig.bin... done] signature Syntax [reading StrgHash.sig.bin... done] signature StrgHash [reading Error.sig.bin... done] signature Error [reading ListUtilities.sig.bin... [Major collection... 66% used (2325300/3480644), 2680 msec] [Increasing heap to 7023k] done] signature ListUtilities [reading Io.sig.bin... done] signature Io [closing /home/icsla/deutsch/ESTFM/basic_ev.sml] /home/icsla/deutsch/ESTFM/basic_ev.sml:20.3 Compiler Bug: abstractBody.abstractType 1 - Comments: the bug is not systematic, and hard to reproduce, this is why the source code has been ommited, as I have not been able to isolate the faulty part of the source. Status: fixed in 0.65 (same as 261) -------------------------------------------------------------------------------- Number: 235 Title: repeated type variables in typdesc and datdesc Keywords: modules, signatures, type variables, duplicate bindings Submitter: Don Sannella Date: 6/13/90 Version: 0.44? Severity: major Problem: The Definition of SML seems to allow repeated type variables in a typdesc and datdesc, making the following signatures legal: signature SIG1 = sig eqtype ('a,'a) t1 type ('a,'a) t2 end signature SIG2 = sig datatype ('a,'a) t3 = foo of 'a end Section 2.9 forbids repeated variables in a typbind and datbind, but I don't see anything forbidding it in a typdesc or datdesc. I assume below that the omission of a syntactic restriction here was intentional. Repeated type variables in a typdesc seem unproblematic if strange, since the semantics only looks at the number of variables. SML-NJ accepts SIG1 above, and treats it the same as a signature without repeated type variables, which is correct. Repeated type variables in a datdesc are more of a problem, since the constructors refer to them. According to the Definition, foo in SIG2 above gets type 'a -> ('a,'a) t3. Both of the following structures then match SIG2: structure A = struct datatype ('a,'b) t3 = foo of 'a end structure B = struct datatype ('a,'b) t3 = foo of 'b end SML-NJ (version 0.44a) says foo : 'a -> ('a,'b) t3, which is wrong. The result of this is that A matches SIG2 but B does not. I don't know about Poly-SML, since I don't have it here. Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 236 Title: Mach problems in 0.59 Keywords: Submitter: David Tarditi Date: 6/18/90 Version: 0.59 System: Mach Severity: critical Comments: I have installed version 0.59 on Vaxes, Suns, and Pmaxes running Mach. There were two problems: VAX.prim.s contained a reference to the variable maskSignals. The name should be _maskSignals instead. The file export.c should also include the file ml_os.h, which contains some definitions needed for Decstations running Mach. Status: fixed in 0.60 -------------------------------------------------------------------------------- Number: 237 Title: Can't parse most-negative integer constant Keywords: Submitter: David Berry Date: 6/5/90 Version: 0.56 System: All Severity: mild Comments: - ~1073741823; exception Overflow - ~1073741822; val it = ~1073741822: int - it - 1; val it = ~1073741823: int Status: fixed in 0.60 -------------------------------------------------------------------------------- Number: 238 Title: div is unreliable at extremes Keywords: Submitter: Andrew Appel Date: 7/5/90 Version: 0.56 System: All Severity: mild Comments: - val a = ~1073741822 - 2; val a = ~1073741824: int - a div 2; uncaught exception Overflow; Status: fixed in 0.60 -------------------------------------------------------------------------------- Number: 239 Title: INCONSISTENT exception raised in sharing analysis Keywords: modules, signatures, sharing, functors Submitter: Nick Date: 7/13/90 Version: 0.56, 0.59 System: Severity: Serious Problem: Internal exception raised in the typechecker during sharing analysis Code: signature A = sig type A datatype Foo = FOO of A end; signature B = sig type B end; signature C = sig datatype C = C of int -> int end; functor XYZZY(structure A: A structure B: B sharing type A.A = B.B structure C: C sharing type C.C = B.B ) = struct end; Transcript: signature A = sig type A datatype Foo con FOO : A -> Foo end signature B = sig type B end signature C = sig datatype C con C : (int -> int) -> C end [closing Kit/foo.sml] uncaught exception INCONSISTENT Status: fixed in 0.61 (dbm) -------------------------------------------------------------------------------- Number: 240 Title: concrete printing of abstype value Keywords: types, abstypes, sharing Submitter: Allen Leung. allen@sbcs.sunysb.edu Date: 7/12/90 Version: v59 4 June, 1990 System: SUN 3 on bsd Severity: minor Problem: Toplevel printing of abstype is transparent. Code: - abstype Foo = Foo of int = with fun foo i = Foo i end = val bar = foo 0; > type Foo > val foo = fn : int -> Foo > val bar = Foo 0 : Foo (* instead of - : Foo *) - Transcript: Comments: Is this a new feature of v59+? It does help debugging. Status: fixed in 0.64 -------------------------------------------------------------------------------- Number: 241 Title: sharing constraint error ignored Keywords: modules, signatures, functors, sharing Submitter: David Turner Date: 7/12/90 Version: 0.59 System: Sun4 Severity: Slightly irritating Problem: Ignores error in sharing constraint even though it obviously detects it. Input: - signature S = sig type t end; - functor F (structure A : S structure B : S sharing type B.t = A.s) = struct end; Output: Error: unbound type in structure: s functor F : Comment: Nonstandard function used in doSharing to report the bug. In 0.65 error message is: std_in:9.6-11.23 Error: unbound type in structure: s This doesn't provide as much useful information as it should. Error message should read something like "unbound type A.s in sharing spec". Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 242 Title: incorrect forward referencing allowed Keywords: modules, functors, scoping Submitter: Nick Date: 7/12/90 Version: 0.56, 0.59 System: Irrelevant Severity: Major (& Embarrassing?) Problem: Incorrect forward referencing when analysing SPECs in functor arguments. Input: signature SIG = sig type t end functor F(structure STR1: sig type t end sharing type STR1.t = Foo.t structure Foo: SIG ) = struct end; Output: functor F: Status: fixed in 0.73 -------------------------------------------------------------------------------- Number: 243 Title: include compiler bug Keywords: modules, signatures, include Submitter: Nick Rothwell Date: 7/5/90 Version: 0.59 Problem: The following file produces the error Compiler bug: Parse.includeSig.newTyc. Code: (* This "batch" file has been generated from the original sources by MAKE. If you want to make alterations, make them to the originals, and execute Make.make_task again. *) (*$DECTREE_DT*) (* Just the bare datatype for decision trees. *) signature DECTREE_DT = sig type lab type lvar type longvar type longcon type longexcon type scon type pat type type_info eqtype (*pah!*) RuleNum sharing type RuleNum = int type Decision type (''a, 'b) map datatype 'a option = NONE | SOME of 'a datatype DecisionTree = LAB_DECOMPOSE of {bind: lvar, parent: lvar, lab: lab, child: DecisionTree, info: type_info } | CON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree} | EXCON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree} | CON_SWITCH of {arg: lvar, selections: (longcon, DecisionTree) map, wildcard: DecisionTree option, (* An `option' because we may notice that all the constructors are present. *) info: type_info } | SCON_SWITCH of {arg: lvar, selections: (scon, DecisionTree) map, wildcard: DecisionTree } | EXCON_SWITCH of {arg: lvar, selections: (longexcon * DecisionTree) list, wildcard: DecisionTree } | END of {ruleNum: RuleNum, environment: (longvar, lvar) map } | FAIL end; (*$MATCH_COMPILER: DECTREE_DT*) (* The match compiler interface; the actual match compiler is built from a number of sub-functors, but this top-level interface is the only one which the rest of the compiler cares about. Given a series of patterns, it returns a DecisionTree (which is essentially an abstract form of the final lambda-code), in which all the lvars for identifiers and temporaries have been generated. At each leaf of the decision tree, there's a single rule number (the rule reached by this series of decisions), and an environment from identifiers to lvars, which is used to compile the right-hand-side expression for this rule. Nice, huh? *) signature MATCH_COMPILER = sig include DECTREE_DT val matchCompiler: lvar * pat list * {warnInexhaustive: bool, warnNoBindings: bool} -> DecisionTree (* these flags are set when the warnings are required. *) type StringTree val layoutDecisionTree: DecisionTree -> StringTree end; Status: fixed in 0.69 ------------------------------------------------------------------------------- Number: 244 Title: compiler bug on product of large integer constants on SPARC Keywords: Submitter: Bennet Vance (bennet@cse.ogi.edu) Date: 7/1/90 Version: 0.59 System: Sun 4/60 - SunOS Release 4.0.3c Severity: minor Problem: compiler bug on large products of integer constants Transcript: val it = () : unit - 2*268435455; val it = 536870910 : int - 2*268435456; Error: Compiler bug: [SparcCM.ashr] Status: fixed in 0.61 (jhr) -------------------------------------------------------------------------------- Number: 245 Title: NeXT installation problem Keywords: Submitter: Lyman Taylor ( respond to lyman@portia.stanford.edu ) Date: 07/12/90 Version: 0.56 System: NeXT , 8M , hard disk , & OD ( build done on OD ) Severity: major Problem: install script does not excute Code: none Transcript: following ouput of makeml ( machine name helen ) helen> makeml -next makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.m68 mo makeml> (cd runtime; rm -f run allmo.o) makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT -DRUNTIME=\"runtime\"' linkdata) cc -O -DM68 -DBSD -DNeXT -DRUNTIME=\"runtime\" -o linkdata linkdata.c makeml> runtime/linkdata [runtime/IntM68.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT' CPP=/lib/cpp 'CFL=' 'AS=as') cc -O -DM68 -DBSD -DNeXT -c run.c ml_os.h:113: can't find include file `sys/syscall.h' *** Exit 1 Stop. Comments: I'm not skilled at development for the NeXT. I was just looking to compile the latest version of SMLNJ so I could try it out there is an older version ( 0.43 ) on the Sparcs around here but the Next allows me to dump all this onto an OD so noone can complain about the space all the source is taking up. Status: fixed in 0.59 (jhr) -------------------------------------------------------------------------------- Number: 246 Title: repeated import consumes too much memory Keywords: Submitter: Peter Canning Date: 6/27/90 Version: 0.56 System: HP900S370 (m68030) HP-UX 7.0 Severity: major Problem: repeated use of the import facility causes the heap to grow Comments: In particular, if I repeatedly modify a file, import the file, then run the program defined in the file (the standard edit/compile/debug loop), my sml image seems to grow (and never shink again). When I was just using "use", sml would garbage collect freqently, but the process size would stay between 4000 and 5000 Kbytes. Using import (working on the same program), the process has grown as large as 11000 Kbytes. It appears that for some reason some data related to importing/compiling files is not being reclaimed by the garbage collector. Status: not a bug --- (defunct feature) -------------------------------------------------------------------------------- Number: 247 Title: close_out std_out Keywords: Submitter: Mark R. Leone Date: 6/29/90 Version: 0.59 Problem: If standard output is closed, the top level exits ungracefully: Transcript: [r.ergo]/usr/mleone/sml/hypo-pl> sml Standard ML of New Jersey, Version 0.59, 4 June 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - close_out std_out; Uncaught exception Io with "output "": closed outstream" Status: not a bug -------------------------------------------------------------------------------- Number: 248 Title: abstract types are not abstract Keywords: types, abstypes Submitter: Dave MacQueen Date: 7/16/90 Version: 0.59 (0.57 and later) Severity: major Problem: Abstract types defined by abstype declarations are not made abstract (i.e. converted from DATAtyc to ABStyc form), and their equality property is not reset to NO. Equality properties of types defined in terms of the abstype are not recomputed (see bug 231.) Comments: After the abstype body has been processed, the concrete form of the abstract types must be replaced by the abstract form throughout the 'signature' of the exported bindings (values, constructors, types). Also equality properties of exported types have to be reevaluated. Currently, there is a function that attempts to transform the tycons in the type checker, but it affects only the abstract syntax, and not the static environment. The problem results from the removal of the ref around tycons in 0.57. Status: fixed in 0.64 -------------------------------------------------------------------------------- Number: 249 Title: separate compilation printing problems Keywords: Submitter: Nick Rothwell (also Richard O'Neill) Date: 7/5/90 Version: 0.59 Severity: minor Problem: 0. If only one or other of the files exists (say, Foo.sml without Foo.bin or vice versa), the exception SystemCall gets raised. 1. The error message [Foo.bin is in the wrong format; recompiling] seems to have lost its closing "]" in 0.59. 2. The final bindings from a separately compiled module get printed on one line, as in: signature Asignature Bsignature Csignature D- rather than signature A signature B etc. Fix: (Richard O'Neill) For some reason the function printBindingTbl in print/printdec.sml was changed from its form in release 0.56 to a slightly modified forn in 0.59. The new form is functionally equivalent appart from omiting to generate newlines. Fix (currently untried): Return printBindingTbl to it 0.56 form. Status: fixed in 0.64 (?) -------------------------------------------------------------------------------- Number: 250 Title: interpreter broken Keywords: Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 7/17/90 Version: 0.59 System: Sun3, SunOS 4.1 Severity: Major Problem: In interpret mode, version 0.59 fails with no explanation when compiling a grammar from mlyacc (slightly modified to use 'import'), whilst in compile mode, the grammar is compiled correctly. Version 0.56 does not exhibit the same problem. This seems a significant problem since using compile mode takes significant time and memory. Equally, I cannot use version 0.56 due to some of its bugs which manifest themselves when compiling other modules. I have not included the files as they are rather long (being an mlyacc generated parser and the relevant support files). I can supply you with a uuencoded compressed tar archive of them all if you desire. Transcript: unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - System.Control.interp; val it = ref true : bool ref - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... done] [closing clean.grm.sml] IMPORT failed (compile-time exception: SystemCall) - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... done] [reading clean.grm.sig.bin... done] [Major collection... 60% used (648480/1067380), 1900 msec] [Major collection... 96% used (1015412/1055228), 3000 msec] [Increasing heap to 3088k] [Major collection... 96% used (1526764/1586468), 4740 msec] [Increasing heap to 4640k] [Major collection... 96% used (2287536/2378284), 7480 msec] [Increasing heap to 6952k] [Major collection... [Increasing heap to 10528k] 96% used (3515248/3635044), 11120 msec] [Increasing heap to 10632k] [closing clean.grm.sml] IMPORT failed (compile-time exception: Cascade) - ^D unix% old-sml Standard ML of New Jersey, Version 0.56, 13 April 90 val it = () : unit - System.Control.interp; val it = ref true : bool ref - import "clean.grm"; [clean.grm.bin is out of date; recompiling] [reading clean.grm.sml] [reading lib/token.sig.bin... ] [lib/token.sig.bin is the wrong format; recompiling] [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... ] [lib/lrtable.sig.bin is the wrong format; recompiling] [closing lib/lrtable.sig.bin] [reading lib/lrtable.sig.sml] [writing lib/lrtable.sig.bin... done] [closing lib/lrtable.sig.sml] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading clean.grm.sig.bin... ] [clean.grm.sig.bin is the wrong format; recompiling] [closing clean.grm.sig.bin] [reading clean.grm.sig.sml] [reading lib/parserdata.sig.bin... ] [lib/parserdata.sig.bin is the wrong format; recompiling] [closing lib/parserdata.sig.bin] [reading lib/parserdata.sig.sml] [reading lib/token.sig.bin... ] [import(s) of lib/token.sig are out of date; recompiling] [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... done] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading lib/lrtable.sig.bin... done] [writing lib/parserdata.sig.bin... done] [closing lib/parserdata.sig.sml] [writing clean.grm.sig.bin... done] [closing clean.grm.sig.sml] [Major collection... 66% used (1058292/1581868), 3360 msec] [Increasing heap to 3249k] [Major collection... 96% used (1629952/1687576), 5020 msec] [Increasing heap to 4929k] [Major collection... 96% used (2478864/2562240), 7800 msec] [Increasing heap to 7481k] [Major collection... 30% used (1226344/3978648), 4200 msec] [Decreasing heap to 4153k] [Major collection... 92% used (1982616/2147092), 6060 msec] [Increasing heap to 6081k] [Major collection... 85% used (2731764/3199400), 8480 msec] [Increasing heap to 8593k] [Major collection... 62% used (2809816/4478688), 9180 msec] [Increasing heap to 8657k] [Major collection... 60% used (2770384/4573952), 8920 msec] [Major collection... 62% used (2804296/4452412), 8980 msec] [Increasing heap to 8721k] [Major collection... 67% used (3031468/4473120), 8700 msec] [Increasing heap to 9033k] [writing clean.grm.bin... done] [closing clean.grm.sml] signature Clean_TOKENS signature TOKEN signature PARSER_DATA signature Clean_LRVALS signature LR_TABLE functor CleanLrValsFun - ^D unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - System.Control.interp := false; val it = () : unit - import "clean.grm"; [reading clean.grm.bin... ] [clean.grm.bin is the wrong format; recompiling [closing clean.grm.bin] [reading clean.grm.sml] [reading lib/token.sig.bin... ] [lib/token.sig.bin is the wrong format; recompiling [closing lib/token.sig.bin] [reading lib/token.sig.sml] [reading lib/lrtable.sig.bin... ] [lib/lrtable.sig.bin is the wrong format; recompiling [closing lib/lrtable.sig.bin] [reading lib/lrtable.sig.sml] [writing lib/lrtable.sig.bin... done] [closing lib/lrtable.sig.sml] [writing lib/token.sig.bin... done] [closing lib/token.sig.sml] [reading clean.grm.sig.bin... ] [clean.grm.sig.bin is the wrong format; recompiling [closing clean.grm.sig.bin] [reading clean.grm.sig.sml] [reading lib/parserdata.sig.bin... ] [lib/parserdata.sig.bin is the wrong format; recompiling [closing lib/parserdata.sig.bin] [reading lib/parserdata.sig.sml] [reading lib/token.sig.bin... done] [reading lib/lrtable.sig.bin... done] [writing lib/parserdata.sig.bin... done] [closing lib/parserdata.sig.sml] [writing clean.grm.sig.bin... done] [closing clean.grm.sig.sml] [Major collection... 61% used (679180/1109552), 2060 msec] [Increasing heap to 2240k] [Major collection... 80% used (932040/1158752), 2780 msec] [Increasing heap to 2848k] [Major collection... 95% used (1403328/1463408), 4240 msec] [Increasing heap to 4272k] [Major collection... 96% used (2109420/2194020), 6680 msec] [Increasing heap to 6408k] [Major collection... [Increasing heap to 9656k] 96% used (3255168/3361612), 10700 msec] [Increasing heap to 9824k] [Major collection... 36% used (1914068/5201708), 6400 msec] [Decreasing heap to 6208k] [Major collection... 85% used (2811340/3298792), 8620 msec] [Increasing heap to 8816k] [Major collection... 61% used (2810740/4607236), 8320 msec] [Major collection... 63% used (2882812/4569184), 8900 msec] [Increasing heap to 8928k] [Major collection... 57% used (2705236/4669212), 8360 msec] [Major collection... 61% used (2854268/4612180), 8560 msec] [writing clean.grm.bin... done] [closing clean.grm.sml] signature Clean_TOKENSsignature TOKENsignature PARSER_DATAsignature Clean_LRVALSsignature LR_TABLEfunctor CleanLrValsFun- Comment: import and interpreter mode are currently incompatible Status: not a bug ------------------------------------------------------------------------------- Number: 251 Title: omits tests for repeated bindings Keywords: duplicate bindings Submitter: Dave Berry db@lfcs.ed.ac.uk Date: 7/18/90 Version: 0.59 System: All (I presume; actually tested on a Sun 3 with SunOS 4.0) Severity: minor Problem: omits tests for repeated bindings Code: type t = int and t = string; exception E and E; val rec f = fn x => x + 1 and f = fn n => if n > 0 then 1 else n * f (n - 1); Transcript: - type t = int and t = string; type t = int type t = string - exception E and E; exception E exception E - val rec f = fn x => x + 1 = and f = fn n => if n > 0 then 1 else n * f (n - 1); val f = fn : int -> int val f = fn : int -> int Comments: I expect that few people would make these mistakes in "real" code, but they might be more common when teaching. The tests are made for repeated constructors in a datatype, and in some (non-recursive?) value bindings, e.g. - datatype a = A | A; std_in:3.14-3.18 Error: duplicate constructor name - val a = 1 and a = 2; std_in:2.5-2.19 Error: duplicate variable-name `a' in pattern(s) Page 9 is the relevant part of the definition. Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 252 Title: include broken in 0.59 Keywords: modules, signatures, sharing, include Submitter: Nick Date: 7/17/90 Version: 0.59 System: Irrelevant Severity: Major Problem: Inclusion of signatures with shared types: >Blam!<. Code: signature SIG1 = sig type ty sharing type ty = int end; signature SIG2 = sig include SIG1 end; Transcript: signature SIG1 = sig eqtype ty end Error: Compiler bug: Parse.includeSig.newTyc Comments: Works in 0.56 (which has different problems - see a previous report). Status: fixed in 0.64 -------------------------------------------------------------------------------- Number: 253 Title: SML Dumping core compiling mlyacc with -pervshare Keywords: Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 7/18/90 Version: 0.59 System: Sun3/50, SunOS 4.1 Severity: You decide... Problem: Attempting to compile mlyacc (as supplied with version 0.56 of SML of NJ) with a '-pervshare' version of SML of NJ 0.59 causes a Segmentation Fault. This does not seem to happen with the sharable SML compiler. I have the core dump if that would help... Status: fixed in 0.74 --- sometime between 0.59 and 0.74 -------------------------------------------------------------------------------- Number: 254 Title: failure to detect type error Keywords: modules, functors, types Submitter: Andrew Appel Date: 7/23/90 Version: 0.60 Severity: critical Problem: type error not detected Code: signature SIG = sig type EA val fopt : ((EA * EA) -> unit) option end functor CPSgen(M: SIG) : sig end = struct val g = case M.fopt of SOME f => let fun h x = f (x,x) in h end val x = g 2 end Comments: Caused by missing case in scan function in the definition of Unify.instantiate. Status: fixed in 0.61 (dbm) -------------------------------------------------------------------------------- Number: 255 Title: space leak with redeclaration of variables Keywords: Submitter: John Reppy Date: 7/24/90 Version: 0.60 Severity: major Problem: I think that there is a space leak in the top-level loop/environment. If I keep redefining the same identifiers, the amount of live data grows, when it should be fairly constant. I assume that the problem is that the top-level symbol table is holding onto something it shouldn't. Transcript: Here is a simple demonstration of the space leak (60 bytes/iteration): Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (516680/526692), 610 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517100/525980), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517160/526388), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517220/526448), 550 msec] structure S : sig end - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end; [Major collection... 98% used (517280/526508), 540 msec] structure S : sig end Comment: (appel) This is the top-level line-number information, and is a few bytes per line, regardless of size of defined structures. Status: fixed in 0.65 (actually, it's now a 48-byte leak) ------------------------------------------------------------------------------- Number: 256 Title: mcopt compiler bug with improper function definition Keywords: Submitter: John Mitchell (jcm@iswim.stanford.edu) Date: 7/24/90 Version: 0.60 Severity: critical Problem: Compiler bug "r_o in mcopt" raised as a result of improper clausal function definition. Transcript: - datatype 'a stack = empty | stk of 'a *'a stack; datatype 'a stack con empty : 'a stack con stk : 'a * 'a stack -> 'a stack - fun pop stk(e,s) = s; Error: Compiler bug: r_o in mcopt adding parens fixes the problem, so not serious as is: fun pop (stk (e,s)) = s; std_in:2.5-2.23 Warning: match not exhaustive stk (e,s) => ... val pop = fn : 'a stack -> 'a stack >Submitter: Sergio Antoy, antoy@vtodie.cs.vt.edu >Date: 8/9/90 >Version: SML of NJ version number 056 >System: DEC3100 V2.2 (Rev. 15) >Severity: >Problem: "using" following file sml generates "Compiler bug" msg >Code: datatype 'a Xlist = Xnil | Xcons of 'a * 'a Xlist | Xappend of 'a Xlist * 'a Xlist; fun incr Xappend(Xnil,Xnil) = Xnil | incr Xappend(Xnil,Xcons(a,b)) = Xcons(a,b); Transcript: goliat[8]% sml Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - use "trans.sml"; [opening trans.sml] datatype 'a Xlist con Xappend : 'a Xlist * 'a Xlist -> 'a Xlist con Xcons : 'a * 'a Xlist -> 'a Xlist con Xnil : 'a Xlist Error: Compiler bug: r_o in mcopt [closing trans.sml] - Status: fixed in 0.62? -------------------------------------------------------------------------------- Number: 257 Title: Compiler bug: EnvAccess.lookPath with imported functors (bug 214 again) Keywords: modules, functors Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 7/30/90 Version: 0,59, 0.60 System: Sun3/180, SunOS 4.1 Severity: Major Problem: Bug #214 ('Compiler bug: EnvAccess.lookPath occurs when printing a top level result') has not been laid to rest, it still occurs with imported functors. Transcript: unix% cat > one.sml functor classes () = struct datatype symbol_class = DataClass of data_class | SpecialClass of special_class and data_class = Int | Real | Bool | String and special_class = Any | None end ^D unix% cat > two.sml signature classes = sig datatype symbol_class = DataClass of data_class | SpecialClass of special_class and data_class = Int | Real | Bool | String and special_class = Any | None end functor nodes ( structure Classes : classes ) = struct structure Classes = Classes local open Classes in datatype node = ClassNode of symbol_class | ValueNode of data_class end end ^D unix% sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "one" "two"; [reading one.sml] [writing one.bin... done] [closing one.sml] functor classes [reading two.sml] [writing two.bin... done] [closing two.sml] signature classes functor nodes - structure Classes = classes () = structure Nodes = nodes ( structure Classes = Classes ) = open Classes Nodes ; structure Classes : sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end structure Nodes : sig structure Classes : sig...end datatype node con ClassNode : symbol_class -> node con ValueNode : data_class -> node end open Classes Nodes - ClassNode (DataClass Int); val it = ClassNode Error: Compiler bug: EnvAccess.lookPath - ValueNode Int; val it = ValueNode Int : node - ^D unix% sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - app use ["one.sml","two.sml"]; [opening one.sml] functor classes : [closing one.sml] [opening two.sml] signature classes = sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end functor nodes : [closing two.sml] val it = () : unit - structure Classes = classes () = structure Nodes = nodes ( structure Classes = Classes ) = open Classes Nodes ; structure Classes : sig datatype special_class con Any : special_class con None : special_class datatype symbol_class con DataClass : data_class -> symbol_class con SpecialClass : special_class -> symbol_class datatype data_class con Bool : data_class con Int : data_class con Real : data_class con String : data_class end structure Nodes : sig structure Classes : sig...end datatype node con ClassNode : symbol_class -> node con ValueNode : data_class -> node end open Classes Nodes - ClassNode (DataClass Int); val it = ClassNode (DataClass Int) : node - ValueNode Int; val it = ValueNode Int : node - ^D Status: fixed in 0.66 (?) -------------------------------------------------------------------------------- Number: 258 Title: System.Directory.cd failure Keywords: Submitter: Dave MacQueen Date: 8/15/90 Version: 0.63 Problem: System.Directory.cd applied to nonexistent directory name raises uncaught exception Transcript: - System.Directory.cd "foo"; uncaught exception SysError - Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 259 Title: uncaught exception Match compiling normperv.sml Keywords: Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 8/14/90 Version: 0.63 (not in 0.62 or earlier) System: Sun3/180, SunOS 4.1 Severity: Critical Problem: Version 0.63 has a new bug whereby it cannot compile dbguser/normperv.sml This prevents creating the '-debug' version. Transcript: unix% sml Standard ML of New Jersey, Version 0.63, 10 August 1990 val it = () : unit - use "dbguser/normperv.sml"; [opening dbguser/normperv.sml] [closing dbguser/normperv.sml] uncaught exception Match - Comments: Smlc, version 0.62, created the 680X0 '.mo' files from which a -pervshare runtime system was built using gcc. This runtime system was then used to build a normal and then a -debug system (which failed). I've marked the severity as critical because it is a critical problem for this version. For me however, its not so critical as I seem to be managing OK with 0.62. Status: fixed in 0.75 approxiamtely -------------------------------------------------------------------------------- Number: 260 Title: failure to raise overflow Keywords: Submitter: David.Tarditi@B.GP.CS.CMU.EDU Date: 8/13/90 Version: 0.63? Problem: The following program should raise an Overflow exception on all 32-bit 2's complement machines but it doesn't: ------- fun exp 0 = 1 | exp i = 2 * exp (i-1); val a = exp 29; val minint = ~a + ~a; (* should raise overflow *) val test = minint div ~1; ------- An overflow exception was not raised in version 0.59 on a Sun 3 running Mach emluating 4.3 BSD. It was raised in version 0.59 on a MicroVax 3 running Mach emulating 4.3 BSD. Comments: This is the only case where overflow can occur in division. It occurs since MININT = -(MAXINT+1) in 2's complement. Division of MININT by -1 causes an overflow. Status: fixed in 0.64 ------------------------------------------------------------------------------- Number: 261 Title: Compiler Bug: abstractBody.abstractType 1 (assumed same as 234) Keywords: modules, functors Submitter: George Beshers, beshers@sun2.brc.uconn.edu Date: 8/9/90 Version: 0.56, sparc Severity: Significant Problem: Compiler generates ``Regex.sml:21.17 Compiler Bug: abstractBody.abstractType 1'' Note: this is somewhat delicate to reproduce. If you break the following into files and start a clean sml and do "use Regex.sml;" it consistently generates the error. However, if you *repeat* the use Regex.sml it compiles (however I have a lingering suspision about the correctness of the code produced...). On one occasion I tried "using" all the files in sequence and that worked OK, at least the working parts of the module did. Also I have tried to cut parts of the Regex.sml file and reproduce the error but without success. In particular, the error is dependent on at least some of the code appearing later in the file. Code: (*---------------------------- Ordinal.sml ---------------------*) signature ORD_RANGE = sig type elem val ord : elem -> int and de_ord : int -> elem end functor NatFn() : ORD_RANGE = struct type elem = int fun ord x = x fun de_ord x = x end functor CharFn() : ORD_RANGE = struct type elem = string val ord = String.ord val de_ord = chr end (*------------------------ BitSet.sml ---------------------------*) import "Ordinal"; signature BITSET = sig structure Elem : ORD_RANGE exception NoSuchElement type bitset val empty: bitset and singleton : Elem.elem -> bitset and range : Elem.elem * Elem.elem -> bitset and setFromList : Elem.elem list -> bitset and exists : Elem.elem -> bitset -> bool and union : bitset * bitset -> bitset and intersect : bitset * bitset -> bitset and difference : bitset * bitset -> bitset val isempty : bitset -> bool and eq : bitset * bitset -> bool and subset : bitset * bitset -> bool and subset': bitset * bitset -> bool val select : bitset * (Elem.elem -> bool) -> bitset val lowest : bitset -> Elem.elem val lowest' : bitset -> Elem.elem -> Elem.elem val highest : bitset -> Elem.elem val highest' : bitset -> Elem.elem -> Elem.elem val totOrder : bitset * bitset -> bool val forall : bitset -> Elem.elem list val makeString : bitset -> string end; (* trivialized version *) functor BitSetFn(Elem1 : ORD_RANGE) : BITSET = struct structure Elem = Elem1 local open Elem Bits val bits_per_int = 30; val all_bits = 1073741823 (* 077777777777 *) in datatype bitset = BS of {lo : int, hi : int, setx : int array} val empty = BS{lo = 0, hi = ~1, setx = array(0, 0)} fun singleton x = empty fun range(l, h) = empty fun exists x (BS{lo, hi, setx}) = false fun union(set1, set2) = empty exception NoSuchElement fun lowest (BS{lo,...}) = de_ord lo fun lowest' (BS{lo,...}) start = de_ord lo fun highest (BS{hi,...}) = de_ord hi fun highest' (BS{hi,...}) start = de_ord hi fun reduce bs = empty fun intersect(set1, set2) = empty fun difference(set1, set2) = empty fun isempty (BS{lo, hi,...}) = hi < lo fun eq (set1, set2) = true fun op subset(s1, s2) = isempty (reduce (difference (s1, s2))) fun op subset'(s1, s2) = isempty (reduce (difference (s1, s2))) andalso (not (isempty (reduce (difference (s2, s1))))) fun lowQuery (bs, q) = let val BS{lo, hi, setx} = bs val i = ref lo in de_ord (!i) end fun highQuery (bs, q) = let val BS{lo, hi, setx} = bs val i = ref hi in de_ord (!i) end fun select (bs, q) = bs fun totOrder (set1, set2) = true fun forall s = nil fun makeString s = "" fun setFromList (l' : Elem.elem list) = empty end end (*------------------------------ RedBlack.sml ------------------*) signature RED_BLACK = sig type tree type key val empty : tree val insert : key * tree -> tree val lookup : key * tree -> key exception notfound of key end functor RedBlack(B : sig type key val > : key*key->bool end): RED_BLACK = struct open B datatype color = RED | BLACK datatype tree = empty | tree of key * color * tree * tree exception notfound of key fun insert (key,t) = let fun f empty = tree(key,RED,empty,empty) | f (tree(k,BLACK,l,r)) = if key>k then case f r of r as tree(rk,RED, rl as tree(rlk,RED,rll,rlr),rr) => (case l of tree(lk,RED,ll,lr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(rlk,BLACK,tree(k,RED,l,rll), tree(rk,RED,rlr,rr))) | r as tree(rk,RED,rl, rr as tree(rrk,RED,rrl,rrr)) => (case l of tree(lk,RED,ll,lr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(rk,BLACK,tree(k,RED,l,rl),rr)) | r => tree(k,BLACK,l,r) else if k>key then case f l of l as tree(lk,RED,ll, lr as tree(lrk,RED,lrl,lrr)) => (case r of tree(rk,RED,rl,rr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(lrk,BLACK,tree(lk,RED,ll,lrl), tree(k,RED,lrr,r))) | l as tree(lk,RED, ll as tree(llk,RED,lll,llr), lr) => (case r of tree(rk,RED,rl,rr) => tree(k,RED,tree(lk,BLACK,ll,lr), tree(rk,BLACK,rl,rr)) | _ => tree(lk,BLACK,ll,tree(k,RED,lr,r))) | l => tree(k,BLACK,l,r) else tree(key,BLACK,l,r) | f (tree(k,RED,l,r)) = if key>k then tree(k,RED,l, f r) else if k>key then tree(k,RED, f l, r) else tree(key,RED,l,r) in case f t of tree(k,RED, l as tree(_,RED,_,_), r) => tree(k,BLACK,l,r) | tree(k,RED, l, r as tree(_,RED,_,_)) => tree(k,BLACK,l,r) | t => t end fun lookup (key,t) = let fun look empty = raise (notfound key) | look (tree(k,_,l,r)) = if k>key then look l else if key>k then look r else k in look t end end (*------------------------ Regex.sml ------------------------*) import "Ordinal"; import "BitSet"; import "RedBlack"; signature CHAR_REG_EXP = sig structure Alphabet : ORD_RANGE structure AlphaSet : BITSET structure range : ORD_RANGE structure Set : BITSET sharing type Set.Elem.elem = range.elem = int type pattern datatype Ch_Reg_Exp = CONCAT of Ch_Reg_Exp list | ALTERNATE of Ch_Reg_Exp list | STAR of Ch_Reg_Exp | PLUS of Ch_Reg_Exp | OPTION of Ch_Reg_Exp | LETTER of AlphaSet.bitset | AUG (* For internal use only *) type Aug_Reg_Exp val re_to_Aug : Ch_Reg_Exp -> {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} val Aug_to_Follow : {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} -> Set.bitset array val Build_FSM : {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} * Set.bitset array -> pattern val Print : Aug_Reg_Exp -> unit end functor Reg_ExpFn() (* : CHAR_REG_EXP *) = struct structure Alphabet = CharFn() structure AlphaSet : BITSET = BitSetFn(Alphabet) structure range = NatFn() structure Set : BITSET = BitSetFn(range) type InfoTy = { fp : Set.bitset, lp : Set.bitset, null : bool } datatype pattern = Pat datatype Ch_Reg_Exp = CONCAT of Ch_Reg_Exp list | ALTERNATE of Ch_Reg_Exp list | STAR of Ch_Reg_Exp | PLUS of Ch_Reg_Exp | OPTION of Ch_Reg_Exp | LETTER of AlphaSet.bitset | AUG (* Internal use only *) datatype Aug_Reg_Exp = AugCONCAT of InfoTy * Aug_Reg_Exp list | AugALTERNATE of InfoTy * Aug_Reg_Exp list | AugSTAR of InfoTy * Aug_Reg_Exp | AugPLUS of InfoTy * Aug_Reg_Exp | AugOPTION of InfoTy * Aug_Reg_Exp | AugLETTER of InfoTy * AlphaSet.bitset | AugAUG of InfoTy fun mkInfo () = { Fpos = Set.empty, Lpos = Set.empty, Nullable = false } fun info (AugCONCAT(inf, _)) = inf | info (AugALTERNATE(inf, _)) = inf | info (AugSTAR(inf, _)) = inf | info (AugPLUS(inf, _)) = inf | info (AugOPTION(inf, _)) = inf | info (AugLETTER(inf, _)) = inf | info (AugAUG(inf)) = inf (* type 'a Aug = {aug_re : Aug_Reg_Exp, count : int, leafList : Aug_Reg_Exp list} *) fun re_to_Aug re = let fun app_map cnt nil = (nil : Aug_Reg_Exp list, cnt, nil) | app_map cnt (hd::tl) = let val hd' = pass1(cnt, hd) val {aug_re=ar, count=c, leafList=le} = hd' val (arTl, cntTl, leTl) = app_map c tl in (ar::arTl, cntTl, le@leTl) end and pass1 (counter, CONCAT(re_l)) = let val (ar', cnt', le') = app_map counter re_l fun foldConcat (a, b) = let val {fp = fpA, lp = lpA, null = nuA} = a val {fp = fpB, lp = lpB, null = nuB} = b val n = nuA andalso nuB val fp' = if nuB then Set.union (fpA, fpB) else fpB val lp' = if nuA then Set.union (lpA, lpB) else lpA in print "foldConcat\n"; print " given A "; print " fpA="; print (Set.makeString fpA); print " lpA="; print (Set.makeString lpA); print nuA; print "\n"; print " given B "; print " fpB="; print (Set.makeString fpB); print " lpB="; print (Set.makeString lpB); print nuB; print "\n"; print " results "; print " fp'="; print (Set.makeString fp'); print " lp'="; print (Set.makeString lp'); print n; print "\n"; {fp = fp', lp = lp', null = n} end val base = {fp = Set.empty, lp = Set.empty, null = true} val _ = (print " base "; print " fp'="; print (Set.makeString (#fp base)); print " lp'="; print (Set.makeString (#lp base)); print (#null base); print "\n") val info = revfold foldConcat (map info ar') base in {aug_re = AugCONCAT(info, ar'), count = cnt', leafList = le'} end | pass1 (counter, ALTERNATE(re_l)) = let val (ar', cnt', le') = app_map counter re_l fun foldAlt (a, b) = let val {fp = hdA, lp = lpA, null = nuA} = a val {fp = hdB, lp = lpB, null = nuB} = b in {fp = Set.union (hdA, hdB), lp = Set.union (lpA, lpB), null = nuA orelse nuB} end val base = {fp = Set.empty, lp = Set.empty, null = false} val info = fold foldAlt (map info ar') base in {aug_re = AugALTERNATE(info, ar'), count = cnt', leafList = le'} end | pass1 (counter, STAR(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = true} in {aug_re = AugSTAR(info, ar), count = c, leafList = le} end | pass1 (counter, PLUS(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = nu} in {aug_re = AugPLUS(info, ar), count = c, leafList = le} end | pass1 (counter, OPTION(re)) = let val {aug_re=ar, count=c, leafList=le} = pass1(counter, re) val {fp = fp', lp = lp', null = nu} = info ar val info = {fp = fp', lp = lp', null = true} in {aug_re = AugOPTION(info, ar), count = c, leafList = le} end | pass1 (counter, LETTER(a)) = let val c = Set.singleton counter val info = {fp = c, lp = c, null = false} val aug_r = AugLETTER(info, a) in {aug_re = aug_r, count = counter+1, leafList = [aug_r]} end | pass1 (counter, AUG) = let val c = Set.singleton counter val info = {fp = c, lp = c, null = false} val aug_r = AugAUG(info) in {aug_re = aug_r, count = counter+1, leafList = [aug_r]} end in pass1 (0, CONCAT [re, AUG]) end fun prFollow fp = let val l = Array.length fp fun prx i = (print i; print " "; print (Set.makeString (fp sub i)); print "\n") fun p i = if i < l then (prx i; p (i + 1)) else () in p 0 end fun Aug_to_Follow {aug_re, count, leafList} = let val followPos = array(count, Set.empty) val count = ref 0 fun updSet fp i = update(followPos, i, Set.union(followPos sub i, fp)) fun pass2 (AugCONCAT(inf, re_l)) = let fun foldConcat (x, y) = let val updList = Set.forall y val {fp, lp, ...} = info x val updSet' = updSet fp fun ms nil = "" | ms (x::y) = (makestring x) ^ (ms y) in print ("[" ^ (ms updList) ^ "]" ^ "\n"); print (Set.makeString lp ^ "\n"); app updSet' updList; lp end val c = !count in inc count; print "before fold "; print c; print "\n"; prFollow followPos; print "\n"; revfold foldConcat re_l Set.empty; print "after fold "; print c; print "\n"; prFollow followPos; print "\n"; app pass2 re_l; print "after app "; print c; print "\n"; prFollow followPos; print "\n" end | pass2 (AugALTERNATE(inf, re_l)) = app pass2 re_l | pass2 (AugSTAR(inf, re)) = let val {fp, lp, ...} = info re val updSet' = updSet fp in app updSet' (Set.forall lp); pass2 re end | pass2 (AugPLUS(inf, re)) = let val {fp, lp, ...} = info re val updSet' = updSet fp in app updSet' (Set.forall lp); pass2 re end | pass2 (AugOPTION(inf, re)) = pass2 re | pass2 (AugLETTER(inf, _)) = () | pass2 (AugAUG(inf)) = () in pass2 aug_re; followPos end datatype transition = TR of AlphaSet.bitset * state and state = ST of {posSet : Set.bitset, stId : int, trans : transition list} fun le (ST{posSet = pS1,...}, ST{posSet = pS2,...}) = Set.totOrder (pS1, pS2) fun getPosSet (ST{posSet,...}) = posSet structure table = RedBlack(struct type key = state val op > = le end) fun Build_FSM ({aug_re, count, leafList}, followPos) = let (* get character set at position i *) fun cSetAt i = case nth (leafList, i) of AugLETTER(inf, x) => x | AugAUG(_) => AlphaSet.empty (* test to see if character has transition at position i *) fun atPos c i = AlphaSet.exists c (cSetAt i) (* Is this position a final position *) fun final i = case nth (leafList, i) of AugAUG(_) => true | _ => false (* return only those elements which match query *) fun sublist query l = let fun ss nil = nil | ss (hd::tl) = let val x = (ss tl) in if query hd then hd::x else x end in ss l end val cnt = ref 1 fun build_auto states unmarked = if unmarked = nil then states else let val T = hd unmarked val _ = print ("build_auto " ^ (Set.makeString T) ^ "\n") val allchar = let fun f (i, x) = AlphaSet.union(cSetAt i, x) in fold f (Set.forall T) AlphaSet.empty end val _ = print (" allchar = " ^ (AlphaSet.makeString allchar) ^ "\n"); fun eachChar states unmarked trans allchar = if AlphaSet.isempty allchar then (states, unmarked, trans) else let val _ = print "eachChar\n" fun next cSet = let val x = AlphaSet.lowest cSet val _ = print ("next cSet=" ^ (AlphaSet.makeString cSet) ^ " ") val _ = print (makestring (AlphaSet.Elem.ord x) ^ "\n") val posSet = Set.select (T, atPos x) val _ = print "Check\n" fun findSet i ch = if i = count then ch else let val y = if Set.exists i posSet then AlphaSet.intersect(ch, cSetAt i) else AlphaSet.difference(ch, cSetAt i) in findSet (i + 1) y end in (findSet 0 cSet, posSet) end (* next *) val (cSet, posSet) = next allchar val _ = print (" cSet=" ^ (AlphaSet.makeString cSet) ^ ", posSet = " ^ (Set.makeString posSet) ^ "\n") fun makeU s = let fun f (i, x) = Set.union (followPos sub i, x) in fold f (Set.forall posSet) Set.empty end (* makeU *) val U = makeU posSet val _ = print (" U=" ^ (Set.makeString U) ^ "\n") fun FindInsert st u = let val dummy = ST{posSet = u, stId = 0, trans = []} in (table.lookup(dummy, st), st, unmarked) handle table.notfound _ => let val u' = ST{posSet = u, stId = !cnt, trans=[]} val st' = table.insert(u', st) in inc cnt; (u', st', unmarked@[u]) end end (* FindInsert *) val (ToState, states', unmarked') = FindInsert states U val trans' = TR(cSet, ToState)::trans in eachChar states' unmarked' trans' (AlphaSet.difference (allchar, cSet)) end (* eachChar *) val (states', unmarked', trans') = eachChar states unmarked [] allchar val dummy = ST{posSet = T, stId = 0, trans = []} val ST{stId = Tid,...} = table.lookup(dummy, states') val s = ST{posSet = T, stId = Tid, trans = trans'} val states2 = table.insert(s, states') in build_auto states' (tl unmarked') end (* build_auto *) val {fp = st',...} = info aug_re val startstate = ST{posSet = st', stId = 0, trans = []} val stTable = table.insert (startstate, table.empty) val autoList = build_auto stTable [st'] in autoList end fun Print re = let val depth = ref 0 fun printInfo ({fp, lp, null} : InfoTy) = ( print "Fpos="; print (Set.makeString (fp)); print " Lpos="; print (Set.makeString (lp)); if null then print " nullable\n" else print "\n" ) fun Pr (AugCONCAT(inf, re_l)) = ( print "CONCAT "; printInfo inf; app Pr1 re_l ) | Pr (AugALTERNATE(inf, re_l)) = ( print "ALTERN "; printInfo inf; app Pr1 re_l ) | Pr (AugSTAR(inf, re)) = ( print "KLEENE "; printInfo inf; Pr1 re ) | Pr (AugPLUS(inf, re)) = ( print "POSITV "; printInfo inf; Pr1 re ) | Pr (AugOPTION(inf, re)) = ( print "OPTION "; printInfo inf; Pr1 re ) | Pr (AugLETTER(inf, _)) = ( print "LETTER "; printInfo inf ) | Pr (AugAUG(inf)) = ( print "AUGMEN "; printInfo inf ) and Pr1 x = let val i = ref 0; in ( while (!i) < (!depth) do (print " "; inc i); inc depth; Pr x; dec depth ) end in Pr1 re end; end; structure RRP_Test = Reg_ExpFn(); open RRP_Test; val a = LETTER(AlphaSet.singleton "a") val b = LETTER(AlphaSet.singleton "b") val c = LETTER(AlphaSet.singleton "c") val d = LETTER(AlphaSet.singleton "d") val a_b_c = ALTERNATE([a, b, c]); val aug = re_to_Aug a_b_c; Print (#aug_re aug); val fol = Aug_to_Follow aug; prFollow fol; print "Before Build_FSM\n"; val t = Build_FSM(aug, fol); print "\n\n\n"; val abc = CONCAT([a, b, c]); val aug' = re_to_Aug abc; Print (#aug_re aug'); val fol' = Aug_to_Follow aug'; prFollow fol'; val t' = Build_FSM(aug', fol'); Status: fixed in 0.64 ------------------------------------------------------------------------------- Number: 262 Title: Using the LIBRARY with v0.62 Keywords: Submitter: "Soren P. Christensen" Date: 8/8/90 Problem: I just tried to build the library found in /dist/ml/LIBRARY.tar.Z and this fails. We are using a spark version of 0.62. I am not dependent on the Library and the reson I report this is only so that you can use it in your testing. I had to make small changes like the definition of the quit function by means of cleanup. 1) There seems to be problems with the exceptions. --------------- Transcript: Standard ML of New Jersey, Version 0.62, 1 August 1990 val it = () : unit - fn () => (() handle Interrupt=>()); val it = fn : unit -> unit - exception xx = Interrupt; std_in:3.16-3.24 Error: unbound exn: Interrupt - raise Interrupt; std_in:1.7-1.15 Error: unbound variable Interrupt std_in:1.1-1.15 Error: argument of raise is not an exception raised: undef in expression: raise Interrupt ---------------- 2) later on it terminates with a runbind, I think this is related to the exceptions too. Comments: (1) The Interrupt exception constructor has gone away, and Interrupt handling should be replaced by handling the interrupt signal. (2) The runbind exception seems to be a genuine bug. Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 263 Title: problem with input via datakit con Keywords: Submitter: pjw Date: 8/8/90 Transcript: con tempel connected to tempel.mesgdcon on /net/dk/4 $ cd /usr/dbm/sml/60/src $ sml Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - -3; std_in:2.1 Error: nonfix identifier required std_in:2.1-2.2 Error: operator and operand don't agree (tycon mismatch) operator domain: 'Z * 'Z operand: int in expression: - 3 std_in:2.1 Error: overloaded variable "-" cannot be resolved uncaught Io exception (Loader): input "": negative character count $ Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 264 Title: No type-explicitness check in nj-sml Keywords: modules, signatures, type-explicitness Submitter: David Turner Date: 7/8/90 Version : SML of NJ 0.56 and 0.59 System : Sun Severity : Dunno, but its pretty anti-social Problem : The compiler doesn't seem to check for type explicitness in signatures (see section 5.8 and also rule 65 of the ML definition). This means many signatures which can never be matched are still accepted as valid signatures. Transcript : - signature X = sig type t val x : t type t end; signature X = sig type t val x : ?.t end Status: fixed in 0.73 -------------------------------------------------------------------------------- Number: 265 Title: strong type variables accepted in exception declarations Keywords: types, exceptions, weak types Submitter: Dave Berry, db@lfcs.ed.ac.uk Date: 8/7/90 Version: 0.56, 0.59 Severity: Minor (although it presumably means that the type system can be broken!) Problem: The compiler doesn't reject applicative type variables in exception declarations. Code: val id: 'a -> 'a = let exception dummy of 'a in fn x => x end; Transcript: The above code produces: val id = fn : 'a -> 'a Status: fixed in 0.65 -------------------------------------------------------------------------------- Number: 266 Title: uncaught Io exception in use Keywords: From: John Reppy Date: 8/6/90 System: 0.62 Problem: I've noticed the following new (I think) bug. An Io error in use results in an uncaught exception. Standard ML of New Jersey, Version 0.62, 1 August 1990 val it = () : unit - use "foo"; [cannot open foo] uncaught exception Io "open_in "foo": open failed, No such file or directory" The problem is that in "use_file" in build/interact.sml (line 307), the exception Io gets re-raised. Was this changed for the debugger? [dbm, 8/30/90] Fixed so that exceptions are handled even for nonterminal input. Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 267 Title: sharing again Keywords: modules, functors, signatures, sharing From: Simon Finn Date: 8/2/90 Version: d64 Problem: The following program breaks Poly/ML v1.88 and NJML v0.44a (the most recent version to which I have access). Code: signature S1 = sig eqtype t val x : t end; signature S2 = sig structure A : sig end structure C : sig structure A : S1 end sharing A = C.A end; functor F(structure A:S1 structure B:S2 sharing A = B.A) = struct val y = (A.x = B.C.A.x) end; Transcript: Standard ML of New Jersey, Version d64, ? August 1990 val it = () : unit - signature S1 = sig eqtype t val x : t end signature S2 = sig structure A : sig...end structure C : sig...end end std_in:21.11-21.25 Error: operator and operand don't agree (tycon mismatch) operator domain: ?.t * ?.t operand: ?.t * ?.t in expression: = (A.x,B.C.A.x) Comment: This program is valid, since structure A shares with B.A which shares with B.C.A, hence A.t and B.C.A.t must be the same (equality) type. However: [dbm, 11/11/97] Not a bug in SML '97. Status: fixed in 0.73 -------------------------------------------------------------------------------- Number: 268 Title: import, equality Keywords: modules, functors, equality Submitter: Jason Fischl Date: 4/9/90 Version: 0.44 System: Sparcstation 1 Severity: major Problem: The module system has a bug in it with regard to equality types (I think). The following is a pretty concise description of what will cause the bug to occur. Code: (*-----------------FILE: term.sig.sml----------------------*) signature termsig = sig datatype term = Const of string | Var of string | Func of string * term list end; (*--------------FILE: term.sml-------------------------*) import "term.sig"; functor termFC ():termsig = struct datatype term = Const of string | Var of string | Func of string * term list end; (*------------FILE: parse_term.sml---------------------------*) import "term.sig"; functor parse_termFC (structure TERM:termsig) = struct open TERM fun term_nil x = (x:term list) = [] end; (*---------------------------------------*) Transcript: - import "parse_term"; [parse_term.bin is out of date; recompiling] [reading parse_term.sml] [reading term.sig.bin... done] parse_term.sml, line 11: Error: Compiler bug: tycStamp equal: type = ?.term list import: code generation failed [closing parse_term.sml] IMPORT failed (codegen) - Comments: I couldn't find any reference to it in the bug reports so I had to assume it was all new. It would have been much nicer if the error message had been a bit more descriptive. All I knew was that it was a type problem. There was no info as to which line the error occurred on or which function or anything really. I would appreciate a reply at some point if you could manage since I am curious as to the nature of my problem. Undoubtedly it will get me again! Fix: In order to fix the problem I had to define the fun term_nil inside the term functor and then also put it in the termsig signature. This took me on the order of 8 hours to figure out! Status: fixed in 0.65 --- (before) ------------------------------------------------------------------------------- Number: 269 Title: failure in abstractBody with embedded signature Keywords: modules, functors, signatures Submitter: Dave MacQueen Date: 8/29/90 Version: 0.63 Code: functor F() = struct datatype d = D structure A : sig type s val x : s * d end = struct datatype s = MKs val x = (MKs,D) end end; structure B = F(); val (_,B.D) = B.A.x; Transcript: - use "bug269.sml"; [opening bug269.sml] functor F : structure B : sig structure A : sig...end datatype d con D : d end bug269.sml:16.5-16.19 Error: pattern and expression in val dec don't agree (tycon mis match) pattern: B.A.s * B.d expression: B.A.s * ?.d in declaration: (_,D) = B.A.x [closing bug269.sml] Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 270 Title: Compiler bug: TypesUtil.lookTycPath: NULLstr Keywords: modules, functors Submitter: Dave MacQueen Date: 8/29/90 Version: 0.63 Problem: failure to interpret path for X.d in embedded signature Formal paramter X was not bound properly. Code: functor F(X: sig datatype d = A end) = struct structure S : sig val x : X.d end = struct val x = X.A end end Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 271 Title: secondary compiler bug Keywords: modules, functors, error recovery Submitter: Gary T. Leavens leavens@bambam.cs.iastate.edu Date: 8/29/90 Version: 0.64 System: HP 9000/370, HP-UX 7.0 Severity: minor Problem: get compiler bug report Code: the following in a file "report" signature IntMapSig = sig type 'a map val apply: ('a map)*int -> 'a exception NotFound end; signature ValueSig = sig type value end; signature SymbolSig = sig type sym val hash: sym -> int end; functor SymTblFct(structure IntMap: IntMapSig structure Val: ValSig structure Sym: SymSig): sig type table exception Lookup val lookup: table * Sym.sym -> Val.value val update: table * Sym.sym * Val.value -> table end = struct datatype table = TBL of (Sym.sym * Val.value)list IntMap.map exception Lookup fun find(sym,[]) = raise Lookup | find(sym,(sym',v)::rest) = if sym = sym' then v else find(sym,rest); fun lookup(TBL map, s) = let val n = Sym.hash(s) val l = IntMap.apply(map,n) in find(s,l) end handle IntMap.NotFound => raise Lookup (* ... *) end; Transcript: a transcript of session illustrating problem follows Standard ML of New Jersey, Version 0.64, ? August 1990 val it = () : unit - [opening report] signature IntMapSig = sig type 'a map exception NotFound val apply : 'a map * int -> 'a end signature ValueSig = sig type value end signature SymbolSig = sig type sym val hash : sym -> int end report:20.20-20.25 Error: unbound signature: ValSig [closing report] std_in:1.1 Compiler Bug: ModUtil.shiftStamps.newEnv - bad arg - Comments: obviously the code has bugs, but I thought you'd want to see the "compiler bug" anyway, since it may be triggered by the bugs in the program. Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 272 Title: generalizing user bound type variables Keywords: types, polymorphism Submitter: Elsa Date: 9/7/90 Version: 0.65 Problem: user bound variables are occurring in the final type of a function. Code: fun f(x) = let val y : 'a -> 'a = x in y y end; Transcript: - fun f(x) = let val y : 'a -> 'a = x in y y end; val f = fn : ('aU -> 'aU) -> 'a -> 'a - f (fn x: 'a => x); std_in:2.1-2.16 Error: operator and operand don't agree (bound type var) operator domain: 'aU -> 'aU operand: 'aU -> 'aU in expression: f ((fn : 'aU => x)) Comments: Error should be detected when function f is defined, rather than when it is applied. Test: bug272.sml Status: fixed in 0.70 ------------------------------------------------------------------------------- Number: 273 Title: generalizing weak variables inside fn abstractions Keywords: types, weak types, polymorphism Submitter: Dave MacQueen Date: 10/3/90 Version: 0.52 and earlier Problem: let-bound variables were being generalized with too strong a weak type. Transcript: - val x = fn y => let val f = ref in f end; val x = fn : 'a -> '3b -> '3b ref Comments: Second bound type variable should be '2b instead of '3b. Fix: Added abs field to POLYty constructor to remember abstraction level at point where type generalization took place. Status: fixed in 0.53 ------------------------------------------------------------------------------- Number: 274 Title: weakness lost with flex record pattern Keywords: types, weak types, polymorphism Submitter: Colin Meldrum Date: 3/19/90 Version: 0.66 Problem: flex record patterns can cause weakness to be dropped, resulting in whole in type system. Code: - val a = let val foo = ref nil in (fn x as {...} => foo:=[x] | (y,z) => (); foo) end > val a = ref [] : ('a * 'b) list ref Comment: This is very unsafe and can for example allow the definition of a 'cast' function... fun cast (x) = ((a := (x,0) :: (!a)); #1(hd (!a))); Comment: regression failure. Now results in compiler bug. See also 1066. bug274E.sml:4.7-4.24 Warning: value restriction prevents type variable generalization : 'Z Error: Compiler bug: PickMod: uninstatiated VARty in pickmod Test: bug274.sml Status: fixed in 109.26 [dbm, 3/18/97. see bug 1066] ------------------------------------------------------------------------------- Number: 275 Title: illegal token with structure named ? Keywords: modules Submitter: Nick Rothwell Date: 3/16/90 Version: ? Transcript: - structure ? = struct val x = 3 end; [succeeds] - ?.x; [fails with "illegal token"] - let open ? in x end; [succeeds] Status: fixed in 0.66 ------------------------------------------------------------------------------- Number: 276 Title: overriding included value spec Keywords: modules, signatures, include Submitter: Dave Berry (db@lfcs.ed.ac.uk) Date: 3/22/90 Version: 0.66 Severity: major Problem: If a value spec in an included signature is redefined in the including signature, the value identifier keeps the type from the included signature, but it is printed as the type from the including signature. Transcript: signature Foo1 = sig val foo: string end; signature Foo2 = sig include Foo1 val foo: bool end; structure Foo: Foo2 = struct val foo = true end; Error: value type in structure doesn't match signature spec name: foo spec: string actual: bool Comments: Note: Once I worked out what was going on I was actually grateful, because I hadn't realised that the names clashed. Perhaps it would be useful if implementations could warn about such cases? Test: bug276.1.sml, bug276.2.sml Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 277 Title: incorrect "inconsistent equality property" error Keywords: modules, functors, equality Submitter: dbm Date: 3/16/90 Version: 0.66 Severity: major Problem: Code: bug277.sml signature S1 = sig type d end; functor F(X: S1) : sig datatype a = C of X.d end = struct datatype a = C of X.d val f = fn (x : a) => x end; Transcript: bug277.sml: 11.3-11.24 Error: inconsistent equality properties (2) Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 278 Title: local structure declaration at top level Keywords: modules, top level, local Submitter: R. M. O'Neill (cmp7130@sys.uea.ac.uk) Date: 4/3/90 Version: 0.44a System: Sun 3/50 & 3/160S SunOS 3.5 Severity: Minor (but, should be easy to fix and I would prefer it fixed) Problem: Using 'local ... in ... end' with structures does not work at the top level, but does work when wrapped in a 'struct ... end' construct Code: local structure Internal = struct val x=1 val y=2 end in structure First : sig val x : int end = Internal structure Second : sig val y : int end = Internal end [** As a TOP-LEVEL declaration **] Transcript: - local = structure Internal = struct val x=1 val y=2 end Error: expected IN, found STRUCTURE Error: expected END, found STRUCTURE = in Error: declaration or expression expected, found IN - structure First : sig val x : int end = Internal = structure Second : sig val y : int end = Internal Error: unbound structure name: Internal Error: unmatched val spec: x = end ; Error: unbound structure name: Internal Error: unmatched val spec: y Error: declaration or expression expected, found END - Compare-With: - structure Kludge = struct = local = structure Internal = struct val x=1 val y=2 end = in = structure First : sig val x : int end = Internal = structure Second : sig val y : int end = Internal = end = end ; structure Kludge : sig structure First : sig...end structure Second : sig...end end - Comments: Parser problem ? ( Expecting an 'ldec' rather than an 'sdec' ? ) [ I'm no SML internal workings guru !] Status: fixed in 0.66 ------------------------------------------------------------------------------- Number: 279 Title: big integers causing uncaught exception Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 4/4/90 Version: 0.55 System: ? Severity: major Problem: There seems to be a problem in the compiler with integers that are larger than 2^29-1. Transcript: Standard ML of New Jersey, Version 0.55, 1 April 1990 val it = () : unit - fun f (i : int, two_i : int) = ( = print i; print ": "; print two_i; print "\n"; f(i+1, two_i+two_i)); val f = fn : int * int -> 'a - f(0, 1); 0: 1 1: 2 2: 4 3: 8 ... 27: 134217728 28: 268435456 29: 536870912 uncaught exception - 536870912; uncaught exception - 536870911; val it = 536870911 : int Status: fixed in 0.66 on mipsb ------------------------------------------------------------------------------- Number: 280 Title: included infix specs not printed Keywords: modules, signatures, include, infix Submitter: John Reppy Date: 4/17/90 Version: 0.56 Severity: minor Problem: I noticed that if you include a signature that contains an infix specification, the infix specification doesn't get printed. Code: Transcript: - signature S1 = sig infix ## end; signature S1 = sig infix 0 ## end - signature S2 = sig include S1 end; signature S2 = sig end Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 281 Title: Import bombs out when it can't find files. Keywords: Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 7/17/90 Version: 0.59 System: Sun3, SunOS 4.1 Severity: You decide... Problem: Importing new files (ones which do not already have a '.bin' file) fails (with an uncaught exception) whilst attempting to import files which do not exist produces the same unfriendly message. Transcript: unix% ls file.sml unix% sml Standard ML of New Jersey, Version 0.59, 4 June 1990 - import "file"; uncaught exception SystemCall - import "nofile"; uncaught exception SystemCall - Perceived Reason: The timeFile function in sepcomp/importer.sml believes that the SysIO.mtime function will raise an Io exeption if it cannot find the file. In fact this exception is never returned by any of the routines in the SysIO module. When they encounter a problem they raise the SystemCall exception. Fix (currently untried): Option 1: Change the code for timeFile to trap the SystemCall exeption instead of the Io exception. e.g. *** sepcomp/importer.sml.orig Fri Jun 1 14:08:02 1990 --- sepcomp/importer.sml Tue Jul 17 10:29:22 1990 *************** *** 159,165 **** in SOME sec end ! handle (Io _) => NONE fun createBinary(indent, filename, statModule: statModule, --- 159,165 ---- in SOME sec end ! handle (SystemCall _) => NONE fun createBinary(indent, filename, statModule: statModule, Option 2: Create a new exception SysIO wich the module SysIO raises on failure and trap that. ( This is to my mind better since SystemCall is a rather wide exception to be trapping ). Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 282 Title: 'sharable' & 'pervshare' compilers produce different .bin Keywords: Submitter: Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 7/23/90 Version: 0.60 System: Sun3/50, SunOS 4.1 Severity: You decide... Problem: The 'bin' files produced by the normal and the '-pervshare' versions of the compiler are different and each 'version' cannot load the other's '.bin' file reliably. Perhaps I have built the two versions differently, but I cannot see how since they were both built at the same time with the same .mo files (compiled with the 0.59 batch compiler). Below is a comprehensive transcript which should help in reproducing the bug, if it can be reproduced... Transcript: unix% cat > bug.sml functor test () = struct val it = "testing, testing, 1, 2, 3..." end unix% sml.pervshare Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.sml] [writing bug.bin... done] [closing bug.sml] functor test - ^D unix% sml.sharable Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.bin... done] [Major collection... 99% used (530424/535668), 1500 msec] [Increasing heap to 6920k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 11160k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 17520k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22288k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22656k] [Major collection... 100% used (530424/530424), 1420 msec] [Increasing heap to 22744k] [Major collection... 100% used (530424/530424), 1400 msec] [Increasing heap to 22752k] [Major collection... 100% used (530424/530424), 1400 msec] Warning: can't increase heap Ran out of memory unix% mv bug.bin bug.bin.sharable unix% sml.sharable Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.sml] [writing bug.bin... done] [closing bug.sml] functor test - ^D unix% sml.pervshare Standard ML of New Jersey, Version 0.60, 13 July 1990 val it = () : unit - import "bug"; [reading bug.bin... done] functor test - structure Test=test (); insttyc: NULLtyc Error: Compiler bug: Functor.applyFunctor.insttyc - ^D unix% mv bug.bin bug.bin.pervshare unix% cmp bug.bin.sharable bug.bin.pervshare bug.bin.sharable bug.bin.pervshare differ: char 62, line 2 unix% ll bug.bin.* -rw------- 1 cmp7130 1415 Jul 23 10:21 bug.bin.pervshare -rw------- 1 cmp7130 17331 Jul 23 10:18 bug.bin.sharable Status: not a bug --- (defunct feature) ------------------------------------------------------------------------------- Number: 283 Title: openread (run.c) checking Keywords: Submitter: Peter Weinberger Date: 8/17/90 Version: ? Severity: minor Problem: openread() in run.c does not check to see if it runs off the end of its allowed space. Comments: in practice, this shouldn't be a problem, since openread() only reads the first two or three mo files, which should be smaller than the initial heap size. Status: fixed in 0.74 ------------------------------------------------------------------------------- Number: 284 Title: Poor type specification handling in mutually recursive functions. Keywords: types Submitter: Richard O'Neill (rmo%sys.uea.ac.uk@nsfnet-relay.ac.uk) Date: 8/14/90 Version: 0.64, 0.62, 0.56, ... System: Sun3/180, SunOS 4.1 Problem: When processing mutually recursive functions, Sml of NJ's current type mechanism prefers its own inferred types of functions to those specifically declared by the user. Code: type 'a foobar = {foo:'a, bar:'a} fun Foo (acc : 'a list foobar) (nil : 'a list) = acc | Foo {foo, bar} (h :: t) = Bar {foo=(h :: foo), bar=bar} t and Bar (acc : 'a list foobar) (nil : 'a list) = acc | Bar {foo, bar} (h :: t) = Foo {foo=foo, bar=(h :: bar)} t Transcript: unix% sml Standard ML of New Jersey, Version 0.64, 24 August 1990 val it = () : unit - use "code.sml"; [opening code.sml] type 'a foobar = {bar:'a,foo:'a} val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar val Bar = fn : {bar:'a list,foo:'a list} -> 'a list -> 'a list foobar [closing code.sml] - - (* One would expect Foo & Bar to have the SAME type *) Comments: The type system seems to be deciding on the type of 'Bar' when it encounters it in the definition of 'Foo', and then sticking to that. Whilst it checks to see whether the type in the declaration of foo matches the type it has inferred, it does not change the 'Foo's type to be in line with its declaration. One can work around the problem by making sure that 'Bar' has the desired type the first time it is encountered. Thus, if Foo is defined as :- fun Foo (acc : 'a list foobar) (nil : 'a list) = acc | Foo {foo,bar} (h :: t) = Bar ({foo=(h :: foo), bar=bar} : 'a list foobar) t the correct types result :- type 'a foobar = {bar:'a,foo:'a} val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar val Bar = fn : 'a list foobar -> 'a list -> 'a list foobar My (ancient) version of Poly/ML also exhibits the same behaviour. Status: not a bug; type abbreviations are not new types ------------------------------------------------------------------------------- Number: 285 Title: Bus error Keywords: modules Submitter: Alain Deutsch, Laboratoire d'Informatique, LIX, Ecole Polytechnique, 91128 Palaiseau Cedex, France. Date: 8/30/90 Version: Standard ML of New Jersey, Version 0.56, 13 April 1990 System: ULTRIX V4.0 (Rev. 174) System #1: Sat Feb 10 01:14:11 MET 1990 UWS V4.0 (Rev. 164) Severity: critical Problem: Bus error. Code: use "bug.sml"; (see enclosed files below, tarmail format) Transcript: Standard ML of New Jersey, Version 0.56, 13 April 1990 Warning: input and output are now uncurried, arithmetic exceptions are re-arranged, div and mod are different; see doc/NEWS val it = () : unit - [opening /usr/users/lix/icsla/deutsch/ModeleSemantique/Bug/bug.sml] [opening Extensions.sml] type 'a printer = outstream * 'a -> unit type 'a transformer = 'a -> 'a [closing Extensions.sml] val it = () : unit [opening Utilities.sig.sml] signature Utilities = sig val assoc : ''a * (''a * 'b) list -> 'b option val butlast : 'a list -> 'a list val cartesian_product : 'a list * 'b list -> ('a * 'b) list val display_list : string * string * string * 'a printer -> 'a list printer val display_pair : string * string * string * 'a printer * 'b printer -> ('a * 'b) printer val error : string * string -> 'a val is_prefix : ''a list * ''a list -> bool val makestring_list : string * string * string * ('a -> string) -> 'a list -> string val member : ''a * ''a list -> bool val replace_prefix : (''a list * ''a list) * ''a list -> ''a list val update_alist : ''a * 'b * (''a * 'b) list -> (''a * 'b) list end [closing Utilities.sig.sml] val it = () : unit [opening Strings.sig.sml] signature Strings = sig type T val < : T * T -> bool val Display : T printer val Hash : T -> int val MakeString : T -> string val New : string -> T end [closing Strings.sig.sml] val it = () : unit [opening Aliases.sig.sml] signature Aliases = sig type Aliases type Path datatype Accessor con IntAcc : int -> Accessor con NamedAcc : string -> Accessor val ++ : Path * Accessor -> Path val Add : Path * Path -> Aliases transformer val Adds : Path list * Path list -> Aliases transformer val Aliased : Path * Path -> Aliases -> bool val Aliases : Path * Aliases -> Path list val DisplayAccessor : Accessor printer val DisplayPath : Path printer val MakeStringAcc : Accessor -> string val MakeStringPath : Path -> string val NewPath : Accessor list -> Path val PathDrop : Path * int -> Path val PathLength : Path -> int val PathNth : Path * int -> Accessor val Remove : Path list -> Aliases transformer val SetVariable : Path * Path -> Aliases transformer end [closing Aliases.sig.sml] val it = () : unit [opening Object.sig.sml] signature Object = sig type T val Display : T printer end [closing Object.sig.sml] val it = () : unit [opening OrderedSet.sig.sml] signature OrderedSet = sig type T val < : T * T -> bool val Display : T printer end [closing OrderedSet.sig.sml] val it = () : unit [opening Map.sml] Map.sml:125.6-127.68 Warning: match not exhaustive tree ((key,_),_,empty,_) => ... tree ((key,_),_,nonempty_subtree,_) => ... pid 4566 (sml) was killed on unaligned access, at pc 0x6016e0 Process SML bus error Comments: The files loaded in "use.sml" are indeed necessary to reproduce the bug. Removing any one of them suppresses that particular occurence of the bug, bug, but only shifts the problem. Fix: Perhaps the GC, as suggested by the vanishing nature of the bug. Enclosed files: see bug285.tarmail Status: fixed in 0.73 (approximately) ------------------------------------------------------------------------------- Number: 286 Title: Compiler bug: inststr NULLstr Keywords: Submitter: Bob Harper (Robert.Harper@cs.cmu.edu) Date: 9/6/90 Version: ? Severity: minor Problem: Compiler bug secondary error Code: functor AbsSyn( structure Id : ID and UnOp : UNOP and BinOp : BINOP ): ABSSYN = struct end; structure AbsSyn : ABSSYN = AbsSyn( structure Id = Id ); (* because I forgot to add in the extra parameters *) Transcript: The result on execution is: /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: UnOp /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: BinOp Error: Compiler bug: inststr NULLstr Status: fixed in 0.70 ------------------------------------------------------------------------------- Number: 287 Title: cosine function incorrectly defined Keywords: Submitter: Valerio Pinci Date: 9/6/90 Version: 0.62 System: Sparc Station 1, SUN OS 0.43 Severity: major Problem: cos function returns wrong values. Code: cos 0.0; Transcript: - cos 0.0; val it = 0.0 : real Fix: In boot/math.sml, change "fun cos x = sin(PI-x)" to "fun cos x = sin(PIo2-x)". Status: fixed in 0.66 ------------------------------------------------------------------------------- Number: 288 Title: extraneous "match not exhaustive" warning Keywords: Submitter: John (jhr@cs.cornell.edu) Date: 9/8/90 Version: 0.64 System: sun-4 Severity: minor Problem: extraneous "match not exhaustive" warning Code: Transcript: Standard ML of New Jersey, Version 0.64, 24 August 1990 val it = () : unit - fun f 0 = 0 | f i = 1; std_in:1.5-1.21 Warning: match not exhaustive val f = fn : int -> int - fun f 0 = 0 | f _ = 1; std_in:3.5-3.21 Warning: match not exhaustive val f = fn : int -> int - f 5; val it = 1 : int Comments: [Appel] I tried this on version 0.64 on our dec 5810, and it works fine (no extraneous "match not exhaustive" messages). Was yours a profiling version or something like that? I tried it on a sun-4 here (version 0.64) and the bug did not show up, so it's not machine-specific. Status: fixed in 0.69 ------------------------------------------------------------------------------- Number: 289 Title: 0.65 prerelease core dumps Keywords: Submitter: Bob Ballance (ballance@cascade.cs.unm.edu Date: 9/13/90 Version: 0.65 System: ? Severity: critical Problem: core dump Code: >>>>>>>>>> Sample file --- Causes failure of 0.65. Running "agcd" after failed load causes core dump.<<<<<<<<< (* * Stephen R. Wheat, 9/6/90 * CS550 - HW1 *) (* * Find the greatest common divisor *) fun gcd(1,b) = 1 (* avoid an endless situation *) | gcd(a,1) = 1 (* avoid an endless situation *) | gcd(0,b) = b (* most likely the one evenly divides the other *) | gcd(a,0) = a (* most likely the one evenly divides the other *) | gcd(a,b) = if (a '_a) -> '_a stream val cons : '_a * '_a stream -> '_a stream val get : '_a stream -> '_a * '_a stream end Comments: same as 282 Status: not a bug --- (defunct feature) ------------------------------------------------------------------------------- Number: 291 Title: floating point on sparc Keywords: Submitter: Bernard Sufrin Date: 9/18/90 Version: 0.56 System: Sparc Problem: The ``bad'' functions seem to compile incorrectly on Sparc machines but ok on 68020 machines. Looks like >=0.0 is compiled wrongly, but the circumstances are mystifying. Why does the presence of the pair parameter seem to be critical (offset calculation in the machine-specific code-generator?). Code: (* try ??bad(0.0, 0.0) (~0.2) *) fun bad (x, y) l = if l >= 0.0 then x else bad(x+l, y) (~l); fun alsobad (x, y) l = if l>0.0 orelse l=0.0 then x else alsobad(x+l, y) (~l); fun good (x, y) l = if 0.0 <= l then x else good(x+l, y) (~l); fun alsogood x y l = if l >= 0.0 then x else alsogood(x+l) y (~l); Status: fixed in 0.65 ------------------------------------------------------------------------------- Number: 292 Title: debugger and interpreter incompatible Keywords: debugger Submitter: Todd Knoblock Todd@eecs.umich.edu Date: 9/24/90 Version: 0.65 System: Decstation 3100 under bsd AND Sun4/sparc under sunos Severity: Very Minor Problem: Compilation of sml with interpretor and debug packages fails Transcript: command: makeml -decstation bsd -i -debug or makeml -sun4 sunos -i -debug appears to progress normally until [closing dbguser/hio.sml] val it = () : unit [opening dbguser/hstore.sml] [opening debug/weak.sml] Error: Compiler bug: bad primop in interp [closing debug/weak.sml] [closing dbguser/hstore.sml] [closing dbguser/userlevel.sml] Comments: Running the compilation without the -i works on both platforms. If the interpretor and debugger are truly incompatible, then makeml should flag it. (apt) They aren't incompatible: the interpreter was broken. Status: fixed in 0.88, but interpreter breaks elsewhere on debugger code. ------------------------------------------------------------------------------- Number: 293 Title: debug problems Keywords: debugger, emacs Submitter: Todd Knoblock, todd@eecs.umich.edu Date: 9/26/90 Version: SML 0.65, emacs 18.55.1 System: Decstation under ultrix and Sun sparc under sunos Severity: error message: minor, no output: critical Synopsis: I am having two problems with the emacs debug package. The first is quite minor: on start-up on a non-x-display (like my terminal at home), emacs reports the following error when loading sml-init: file mode specification error: (void-variable-x-button-m-left). The second is more serious. When sending to the sml process, I do not get output until I move (c-x o/c-x b) into the process buffer. For example, if I have this in a buffer fun f(0) = 1 | f(x) = x*(f (x-1)); and type c-c c-c, then if sml has not been run before, emacs will bring up a window, and start it properly. However, the only output is Standard ML of New Jersey, Version 0.65, 10 September 1990 val it = () : unit - emacsInit (); cd "/afs/engin.umich.edu/user/t/o/todd/"; [opening /tmp/sml.tmp.a02351] Once I move into the buffer, then I get the rest of the output: val f = fn : int -> int [closing /tmp/sml.tmp.a02351] If sml is already running, and the window is not visible, then sending to the buffer does not cause it to become visible. Comments: If I disable the debugging code, by removing the two "hooks" in sml-init, then the interface works as in the past. I am running emacs version 18.55.1, and have tried it on two platforms: decstation under ultrix, and a sparc under sunos. Finally, it appears that the file outdent.el is redundant now, and could be removed from the distribution. Comments: [apt, 2/1/93] These bugs aren't fixed. The first is just a trivial error message. As to the second: we don't really guarantee that c-c c-c and similar emacs interface tricks will work with the debugger. You could "not a bug" these if you want, though they should get addressed eventually -- I deliberately didn't spend time on minor emacs-related problems last summer. Owner: Status: open ------------------------------------------------------------------------------- Number: 294 Title: weak polymorphic types Keywords: types, weak types, polymorphism Submitter: David Berry Date: 9/24/90 Version: 0.65 Severity: major Problem: The Memo structure in the Library still doesn't compile under SML-NJ 0.65 It compiles under Poly/ML, and is based on a version for Edinburgh ML. Transcript: - use "memo.sml"; [opening memo.sml] [opening ../signatures/Memo.sml] signature Memo = sig val memo : (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a -> '_b) * ('a -> '_b) val memo2 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_ c) -> 'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c) val memo3 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> ( ('a -> '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_ d) * ('a -> '_b -> '_c -> '_d) val version : real end [closing ../signatures/Memo.sml] val it = () : unit memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:41.7-53.33 Error: nongeneric weak type variable memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU -> '~3Z) * ('aU -> '~3Z) memo.sml:58.5-58.76 Error: operator and operand don't agree (circularity) operator domain: ('Z -> '~3Y) -> 'Z -> '~3Y operand: ('Z -> '~3Y) -> 'Z -> '~3X -> '~3Y in expression: memo expfn injy ((fn _ => (fn ))) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:60.5-63.43 Error: nongeneric weak type variable memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W -> '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V) memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo spec: (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a -> '_ b) * ('a -> '_b) actual: (Nat -> Nat) -> ('a -> Nat) -> (('a -> '~3Z) -> 'a -> '~3Z) -> ('a -> '~3Z) * ('a -> '~3Z) memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo2 spec: (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_c) -> 'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c) actual: (Nat -> Nat) -> ('a -> Nat) -> ('~3Z -> Nat) -> (('a -> '~3Y) -> 'a -> '~3Z -> '~3Y) -> error memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec name: memo3 spec: (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> (('a -> '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_d) * ( 'a -> '_b -> '_c -> '_d) actual: (Nat -> Nat) -> ('a -> Nat) -> ('b -> Nat) -> ('~3Z -> Nat) -> (('a -> '~3Y) -> 'a -> 'b -> '~3Z -> '~3Y) -> ('a -> '~3Y) * ('a -> '~3Y) [closing memo.sml] - Comment: for Memo.sml to compile, the name of structure Array in Bytearray.sml has to be changed. Status: fixed in 0.74 ------------------------------------------------------------------------------- Number: 295 Title: Compiler bug: r_o in mcopt Keywords: Submitter: Kung Chen Date: 9/30/90 Version: 0.56 System: Sparc, Sun OS Problem: the optimization phase of pattern-mtaching dies Code: (* Categorical Abstract Machine simulator*) (* D. Rabin, 5-aug-90, translated to SML by K. Chen, 10-sept-90*) structure Cam = struct (* CAM instructions*) datatype 'val CAMinstr = QuoteInstr of 'val | PrimInstr of int * string | AccInstr of int | ConsInstr | CdrInstr | CarInstr | PushInstr | SwapInstr | BranchInstr of 'val CAMinstr list * 'val CAMinstr list | CurInstr of 'val CAMinstr list | AppInstr | ReturnInstr | UpdInstr | IdInstr type 'val Code = 'val CAMinstr list datatype 'const Val = Simple of 'const | Close of 'const Val * 'const Val CAMinstr list | Pair of 'const Val * 'const Val | Truth of bool | Save of 'const Val CAMinstr list (* CAM state*) datatype 'const CAMstate = CAMst of 'const Val * 'const Val list * (('const Val) CAMinstr) list | Halt (* CAM state transition function*) (* fun step : 'const CAMstate -> 'const CAMstate *) fun step CAMst(x, s, []) = Halt |step CAMst(x, s, IdInstr::is) = CAMst(x, s, is) |step CAMst(Pair(x, y), s, CarInstr::is) = CAMst(x ,s, is) |step CAMst(Pair(x, y), s, CdrInstr::is) = CAMst(y, s, is) |step CAMst(x, s , PushInstr::is) = CAMst(x, (x :: s), is) |step CAMst(x, (y :: s), SwapInstr::is) = CAMst(y ,(x :: s), is) |step CAMst(x, (y :: s), ConsInstr::is) = CAMst(Pair(x, y), (x :: s), is) |step CAMst(x, s, CurInstr(code)::is) = CAMst(Close(x, code), s ,is) |step CAMst(Pair(Close(x, code), y), s, AppInstr :: is) = CAMst(Pair(x, y), Save(is)::s, code) |step CAMst(x, Save(code)::s, ReturnInstr::is) = CAMst(x, s, code) |step CAMst(x, s, QuoteInstr(c)::is) = CAMst(c, s, is) |step CAMst(Pair(x,Truth(true)), s, BranchInstr(ifTrue, ifFalse)::is) = CAMst(x, s, ifTrue) |step CAMst(Pair(x, Truth(false)), s, BranchInstr(ifTrue, ifFalse)::is) = CAMst(x, s, ifFalse) |step CAMst(x, (y :: s), UpdInstr::is) = CAMst(y, s, is) end Transcript: - use "cam.sml"; [opening cam.sml] Error: Compiler bug: r_o in mcopt [closing cam.sml] Status: fixed in 0.69 ------------------------------------------------------------------------------- Number: 296 Title: patch for HP/MORE Keywords: Submitter: Brian Boutel (brian@comp.vuw.ac.nz) Date: 10/11/90 Version: 0.66 System: m68020 (H-P workstation) more/bsd Severity: Problem: source error in src/runtime/ml_os.h. Will not compile. Code: n/a Transcript: n/a Comments: I reported this for 0.56, the first version in which my patches for more/bsd on H-P workstations were included. The line in the source has been changed, but only to include the same fix for NeXT machines. Fix: src/runtime/ml_os.h. Add the underlined code: /* where to find syscall.h, used for getting the #define SYS_open */ #if defined(VAX) || defined(NeXT) || defined(MORE) ~~~~~~~~~~~~~~~~ #include #else #include #endif Status: fixed in 0.71 ------------------------------------------------------------------------------- Number: 297 Title: Bits.lshift on Sun4 Keywords: Submitter: Eric Cooper Date: 10/11/90 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun4, both SunOS and Mach Severity: minor Problem: 1. Calls to Bits.lshift with constant arguments that should raise Overflow cause a compiler error message instead. 2. With non-constant arguments, Bits.lshift expressions that should raise Overflow don't. Code: (1) Bits.lshift(1,30); (2) fun lshift (x, y) = Bits.lshift (x, y); lshift (1, 30); lshift (1000000, 64); Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - fun lshift (x, y) = Bits.lshift (x, y); val lshift = fn : int * int -> int - lshift (1, 30); val it = ~1073741824 : int (* should raise Overflow *) - lshift (1000000, 64); val it = 1000000 : int (* shifting by any multiple of 32 appears to be equivalent to shifting by 0; should raise Overflow *) - Bits.lshift (1, 30); Error: Compiler bug: [SparcCM.ashr] - (); SIGILL code 0x2 Comments: [Cooper] The number of bits to shift is evidently being reduced modulo 32. [jhr] The lshift operation does not raise Overflow (Andrew's decision). I'll look at the other problem. [jhr] When there is a compiler bug (at least in the backend), the state of the system gets screwed up in such a way that the system core dumps. Is it possible to do a better job of cleaning up when a compiler bug is detected? An example is (on 0.66/sparc) - Bits.lshift (1, 30); Error: Compiler bug: [SparcCM.ashr] - (); SIGILL code 0x2 [appel] I don't see where the Definition of Standard ML says that lshift should raise Overflow! Status: fixed in 0.66? ------------------------------------------------------------------------------- Number: 298 Title: tags inconsistency Keywords: representation Submitter: Allen Leung allen@sbcs.sunysb.edu Date: 10/12/90 Version: NJSML v0.66 System: sun4 Severity: very minor Problem: runtime tags of evaled and unevaled suspension has been reversed Comments: The runtime tags of evaluated and unevaluated suspension in System.Tags are inconsistent with the ones in tags.h Status: fixed in 0.70 ------------------------------------------------------------------------------- Number: 299 Title: user-bound tyvars Keywords: types, type variables Submitter: John Reppy Date: 10/12/90 Version: 0.66 Severity: major Problem: There are two versions of the first line of the sync function: one produces the error, the other works. Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "compbug.sml"; [opening compbug.sml] compbug.sml:8.3-57.5 Error: value type in structure doesn't match signature spec name: sync spec: 'a event -> 'a actual: 'a event -> 'aU [closing compbug.sml] Code: compbug.sml signature INTERNAL_CML = sig type 'a event val sync : 'a event -> 'a end functor ConcurML () : INTERNAL_CML = struct exception Never and Escape exception Sync (* for signature compatability *) datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK type 'a base_evt = { pollfn : unit -> evt_sts, dofn : unit -> 'a, blockfn : bool ref -> 'a } datatype 'a event = EVT of 'a base_evt list local datatype 'a ready_evts = NO_EVTS (* no ready events *) | ANY_EVTS of (int * (unit -> 'a) list) (* list of ready anyevents *) | RDY_EVTS of (int * (unit -> 'a) list) (* list of ready events *) fun extract _ = NO_EVTS (* Generate index numbers for "non-deterministic" selection. We use a * round-robin style policy. *) val cnt = ref 0 fun random i = let val j = !cnt in cnt := j+1; (j mod i) end fun selectEvt (_, [f]) = f() | selectEvt (n, l) = (nth(l, random n)) () in (* sync : 'a event -> 'a *) fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **) (* fun sync ((EVT []) : 'a event) = raise Never *) (** THIS WORKS **) | sync (EVT el) = ( case (extract el) of NO_EVTS => callcc (fn sync_k => let val evtflg = ref false fun log ({blockfn, ...} : 'a base_evt)= (throw sync_k (blockfn evtflg)) handle Escape => () in app log el; (*atomicDispatch()*) raise Sync end) | ANY_EVTS anyevts => selectEvt anyevts | RDY_EVTS evts => selectEvt evts) end (* local *) end (* functor ConcurML *) Status: not a bug? (check with MacQueen) ------------------------------------------------------------------------------- Number: 300 Title: uncaught exceptin RegBind Keywords: Submitter: Soren Christensen, University of Aarhus, Computer Science Dep., Denmark schristensen@daimi.dk Date: 10/17/90 Version: 0.65 System: Sun4/280 / SunOS 4.0.1 Severity: Critical Problem: Code: (* filename: nb *) datatype ''a ms = !! of ( (int * ''a) * (''a ms) ) | empty; fun cr (0,_) = empty | cr (coef,col) = (!!((coef,col),empty)); fun foo (c:int ms ref) = true andalso (1 = length [1]) andalso (cr (1,1) = (!c)) andalso (empty = (!c)); Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "nb"; [opening nb] datatype 'a ms con !! : (int * 'a) * 'a ms -> 'a ms con empty : 'a ms val cr = fn : int * 'a -> 'a ms [closing nb] uncaught exception Regbind - val x = 5; Illegal instruction Status: fixed in 0.69 ------------------------------------------------------------------------------- Number: 301 Title: Compiler bug: tycPath Keywords: Submitter: Andrew Appel Date: 10/24/90 Version: 0.66 Severity: minor Problem: The following program gets Error: Compiler bug: tycPath after all the syntax errors. Perhaps it should be a CASCADE. Code: struct VMat : sig type v4 = real*real*real*real type m4 = v4*v4*v4*v4 val vmul = v4*v4 -> v4 val vdot = v4*v4 -> real val vmmul = v4*m4 -> v4 val mmul = m4*m4 -> m4 end = struct fun vmul((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) = (v1x * v2x, v1y * v2y, v1z * v2z, v1w * v2w) fun vdot((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) = v1x * v2x + v1y * v2y + v1z * v2z + v1w * v2w fun vmmul(v, (a, b, c, d)) = (vdot(v, a), vdot(v, b), vdot(v, c), vdot(v, d)) fun mmul((a, b, c, d), m) = (vmmul(a, m), vmmul(b, m), vmmul(c, m), vmmul(d, m)) end Status: fixed in 0.71 ------------------------------------------------------------------------------- Number: 302 Title: match not exhaustive warnings from import have wrong location Keywords: Submitter: Peter Canning Date: 10/24/90 Version: 0.66 System: 68020 HP-UX 7.0 Severity: major Problem: match not exhaustive warnings from import have wrong location Code: functor foo() = struct datatype T = I of int | B of bool | S of string fun foo(I i) = i | foo(B b) = if b then 1 else 0 end; Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - import "foo"; [reading foo.sml] foo.sml:0.0-0.0 Warning: match not exhaustive I i => ... B b => ... [writing foo.bin... done] [closing foo.sml] functor foo Comments: The warning message should give line.column different from 0.0-0.0 Status: not a bug --- (defunct feature) ------------------------------------------------------------------------------- Number: 303 Title: bad error reporting Keywords: Submitter: Nick Date: 10/25/90 Version: 0.66 System: irrelevant Severity: minor Problem: junk error reporting Code: foobar + 3; Transcript: (OK:) Comments:std_in:1.1-1.6 Error: unbound variable foobar (bogus:)std_in:1.1-1.10 Error: operator and operand don't agree (type mismatch) operator domain: undef * undef operand: undef * int in expression: + (foobar,3) (bogus:)std_in:1.8 Error: overloaded variable "+" not defined at type: undef Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 304 Title: SIGEMT on sparc Keywords: Submitter: Nick Rothwell Date: 10/25/90 Version: 0.66 System: sparc Severity: major Problem: 0.66 has a SIGEMT problem on SPARC's, on hitting ^C (sometimes). Will try and narrow down if I can. Also from Mike Crawley , in 0.73: I have been able to repeat the following bug a number of times. Pressing ^C to interrupt sml while it is busy can sometimes crash it. The saved image I was using was 10MB at the time. ^C SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0x9dd8) Mike Crawley. Abstract Hardware Ltd. Status: fixed in 0.73 ------------------------------------------------------------------------------- Number: 305 Title: Strange floating point error Keywords: Submitter: tmb@ai.mit.edu (Thomas M. Breuel) Date: 11/28/90 Version: 0.66 System: Sun4/SunOS4.1 Problem: division by zero causes "strange floating point error" Code: 0.0/0.0 Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 0.0/0.0; strange floating point error Process Inferior sml exited abnormally with code 3 Comments: Other division-by-zero errors for floating point numbers raise Div. Status: fixed in 0.69 ------------------------------------------------------------------------------- Number: 306 Title: list printing, printlength Keywords: Submitter: tmb@ai.mit.edu Date: 10/28/90 Version: SML of NJ 0.66 System: Sun 4/SunOS 4.0 Severity: minor Problem: extraneous "dots" printed Code: [1,2,3,4,5,6,7,8,9,10,11,12]; Transcript: - [1,2,3,4,5,6,7,8,9,10,11,12,13]; val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list - [1,2,3,4,5,6,7,8,9,10,11,12]; val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list - Comments: Since there are no unprinted elements in the 12 element list, there should be no ellipsis either. Status: fixed in 0.74 ---------------------------------------------------------------------------- Number: 307 Title: signature matching in 0.69 Keywords: modules, signatures, signature matching Submitter: Greg Morrisett jgmorris@cs.cmu.edu Date: 4/29/91 Version: 0.67 and 0.69 System: DECstation 3100, Mach and Sun-3 Mach Severity: critical? Problem: nested structures and signature matching Code: signature SIG1 = sig structure T : sig type t end structure U : sig structure V : sig val s : T.t end end end structure S : SIG1 = struct structure T = struct datatype t = FOO end structure U = struct structure V = struct val s = T.FOO end end end Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "bug.sml"; [opening bug.sml] $$ lookTycPath 1: 0 0 tyconInContext: [0,0] [closing bug.sml] uncaught exception Subscript - Comments: I reduced this down to as small a problem as I could. For instance, removing any of the enclosing structures makes the bug go away. This works under version 0.64 and 0.65. This came up in some "real" code and there is no easy work-around... Fix: ??? Status: fixed in 0.73 --------------------------------------------------------------------------- Number: 308 Title: Mips RC6280 code generation bug Keywords: Submitter: Toshinori Maeno Computer Center, Tokyo Institute of Technology Date: 6/1/91 Version: 0.66 System: MIPS RC6280, 128MB; Riscos 4.52 Severity: critical (at least for us :-) Problem: makeml dumps core after successful make of runtime/run Code: makeml -mips riscos Transcript: makeml> (cd runtime; make clean) rm -f *.o lint.out prim.s linkdata allmo.s run makeml> rm -f mo makeml> ln -s ../mo.mipsb mo makeml> (cd runtime; rm -f run allmo.o allmo.s) makeml> (cd runtime; make MACHINE=MIPS 'CFL= -systype bsd43' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata) cc -g -signed -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c makeml> runtime/linkdata [runtime/IntMipsBig.mos] runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o makeml> (cd runtime; make MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as') cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run_ml.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c callgc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c gc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c /lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s as -o prim.o prim.s cc -g -signed -systype bsd43 -DMIPS -DRISCos -c export.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c timers.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c ml_objects.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cfuns.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cstruct.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c signal.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c exncode.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -c malloc.c cc -g -signed -systype bsd43 -DMIPS -DRISCos -o run run.o run_ml.o callgc.o gc.o MIPS.dep.o prim.o export.o timers.o ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o allmo.o makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 4096 -r 20 -h 2048 IntMipsBig [Increasing heap to 2049k] [Loading mo/CoreFunc.mo] [Executing mo/CoreFunc.mo] [Loading mo/Math.mo] [Executing mo/Math.mo] [Loading mo/Initial.mo] [Executing mo/Initial.mo] makeml: 18680 Illegal instruction - core dumped ^ This number may be different for another run. Comments: On MIPS RC3240, makeml successfully made sml. runtime/run made on RC6280 works on RC3240 without problem. runtime/run made on either system dumps core on RC6280. 0.68 reproduced the same problem. I disabled FlushIcache, but could not get improvement. I shall report this to MIPS, too. [jgm] I assume this is the problem of using the branch delay slots for some non-standard reason? Status: fixed in 0.70; other RC6280 problems not quite fixed in 0.71. --------------------------------------------------------------------------- Number: 309 Title: NeXTstation exported image doesn't work Keywords: Submitter: oneill@cs.sfu.ca Keywords: Date: 3/28/91 Version: 0.68 System: NeXTstation Severity: Problem: boots and exports, but exported image bombs with SEGV when invoked Fix: Heres the changes I made to get as far as I got, (note, TRAP #2 on a NeXT flushes the 68040 code cache, which is necessary after a gc). Richard, (used to be {cmp7130,rmo}@sys.uea.ac.uk) my diffs (w.r.t 0.68)... diff -r -c runtime.orig/callgc.c runtime/callgc.c *** runtime.orig/callgc.c Wed Mar 6 11:50:57 1991 --- runtime/callgc.c Thu Mar 21 15:19:19 1991 *************** *** 86,95 **** --- 86,103 ---- int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; + #ifdef NeXT + extern void * get_edata(); + #else extern int edata; + #endif resettimers(); + #ifdef NeXT + lastbreak = (int)get_edata(); + #else lastbreak = (int)&edata; + #endif gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { *************** *** 330,335 **** --- 338,346 ---- arend = arenabase+arenasize; arstart = (((arend+old_high)/2)+3)&(~3); (*arptr) = arstart; + #ifdef NeXT + asm("trap #2"); + #endif } /* end of callgc */ diff -r -c runtime.orig/export.c runtime/export.c *** runtime.orig/export.c Wed Nov 21 11:34:06 1990 --- runtime/export.c Thu Mar 21 15:08:53 1991 *************** *** 87,93 **** --- 87,97 ---- * > set a_entry as address of start procedure */ + #ifdef NeXT + extern void * get_etext(); + #else extern int etext; /* &etext is just beyond the end of the text segment */ + #endif extern int old_high; static int textstart,datastart; *************** *** 425,432 **** int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC68030; ! E.cpusubtype = CPU_SUBTYPE_NeXT; E.filetype = MH_EXECUTE; E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) --- 429,436 ---- int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC680x0; ! E.cpusubtype = CPU_SUBTYPE_MC68040; E.filetype = MH_EXECUTE; E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) *************** *** 442,448 **** tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; --- 446,452 ---- tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; >From cs.cornell.edu!jhr Fri Mar 29 10:46:22 0500 1991 >Received: by coma; Fri Mar 29 10:46:27 EST 1991 >Received: by inet.att.com; Fri Mar 29 10:46 EST 1991 >Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N) > id AA21402; Fri, 29 Mar 91 10:46:22 -0500 >Date: Fri, 29 Mar 91 10:46:22 -0500 >From: jhr@cs.cornell.edu (John Reppy) >Message-Id: <9103291546.AA27105@maui.cs.cornell.edu> >Received: by maui.cs.cornell.edu (5.65/N-0.12) id AA27105; Fri, 29 Mar 91 10:46:20 -0500 >To: appel@princeton.edu, dbm@research.att.com >Subject: Re: NeXT 68040 attempt I have integrated Richard O'Neill's changes into my 0, in a style that is more consistant with the runtime system. Here are the diffs; maybe they can be included in 0.69. (BTW, there are probably still some other changes needed to make this work). - John diff -c ml_os.h ml_os.h.ORIG *** ml_os.h Fri Mar 29 10:40:07 1991 --- ml_os.h.ORIG Wed Nov 21 14:34:31 1990 *************** *** 111,122 **** (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0)) # endif #else ! #ifdef NeXT ! # define FlushICache(addr, size) asm ("trap #2") ! #else ! # define FlushICache(addr, size) #endif - #endif #if defined(MACH) && defined(MIPS) --- 111,118 ---- (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0)) # endif #else ! #define FlushICache(addr, size) #endif #if defined(MACH) && defined(MIPS) *************** *** 158,163 **** --- 154,160 ---- #define READDIR(fd,buf,sz) getdirentries((fd), (buf), (sz), &dummy) #endif + #if defined(BSD) || defined(RISCos) || defined(HPUX) || defined(SGI) #define HAS_WRITEV #include *************** *** 164,175 **** #define HAS_NONBLOCKING_IO #endif ! #ifdef NeXT ! extern void *get_edata(); ! # define EDATA ((int)get_edata()) ! #else ! extern int edata; ! # define EDATA ((int)(&edata)) ! #endif #endif !_ML_OS_ --- 161,167 ---- #define HAS_NONBLOCKING_IO #endif ! ! #endif !_ML_OS_ diff -c callgc.c callgc.c.ORIG *** callgc.c Fri Mar 29 10:41:06 1991 --- callgc.c.ORIG Wed Mar 6 14:50:57 1991 *************** *** 86,94 **** int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; resettimers(); ! lastbreak = EDATA; gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { --- 86,95 ---- int live_size = old_high - arenabase; int a = 0; ML_val_t x = gcmessages; + extern int edata; resettimers(); ! lastbreak = (int)&edata; gcmessages = INT_CtoML(0); new_size = compute_new_size(live_size); do { >From cs.sfu.ca!oneill Wed Apr 24 18:22:39 EDT 1991 >Received: by coma; Wed Apr 24 18:22:39 EDT 1991 >Received: by inet.att.com; Wed Apr 24 18:22 EDT 1991 >Received: by relay.CDNnet.CA (4.1/1.14) > id AA23566; Wed, 24 Apr 91 15:20:58 PDT >From: >Date: 24 Apr 91 15:13 -0700 >To: dbm@research.att.com >Cc: jhr@cs.cornell.edu >Message-Id: <9104242213.AA15593@phoenix.cs.sfu.ca> >Subject: Re: Getting Sml up and running on a NeXT running OS2.[01] Long long ago, you (dbm) wrote: > I think we should have SML of NJ running on the 68040 NeXTs soon, > since John Reppy has just bought one of them (to write his thesis > on). He is confident he can get SML running on it quite quickly. > I'll forward your message to him, since it looks like a useful start > on the problem. John Reppy also wrote: > It may be a while before I can fix this, since I still need to get a decent > sized disk. Well, after a month of messing about with other things, I finally got arround to getting sml working the NeXT (my NeXT arrived and so I could work on it at home). I'll tell you the problem and give my diffs. The problem was that, among the various load commands needed in the executable's header, one is needed to load the c shared library, and this was ommited (since previously programs weren't *forced* into using the shared libraries). Since the load command is always exactly the same, I did a ghastly hack and substituted the thing in as a constant (array stuffed with the right hex numbers). This isn't quite the cleanest thing to do, but I was only concerned with getting it to work for me. (Yeah, I know, I'm lazy...) Anyway, diffs follow, and it at least it works now... Richard, ---8<--cut-here--(and ruin your monitor)--cut-here--8<--- *** export.c.orig Wed Nov 21 11:34:06 1990 --- export.c Wed Apr 10 17:06:57 1991 *************** *** 87,93 **** --- 87,98 ---- * > set a_entry as address of start procedure */ + #ifndef NeXT extern int etext; /* &etext is just beyond the end of the text segment */ + #else + extern void *get_etext(); + #endif + extern int old_high; static int textstart,datastart; *************** *** 422,436 **** static unsigned long thcount; static struct NeXT_thread_state_regs ntregs; static unsigned int hdrsize; int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC68030; ! E.cpusubtype = CPU_SUBTYPE_NeXT; E.filetype = MH_EXECUTE; ! E.ncmds = 3; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) ! + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs); E.flags = MH_NOUNDEFS; --- 427,445 ---- static unsigned long thcount; static struct NeXT_thread_state_regs ntregs; static unsigned int hdrsize; + static unsigned int lcmd[] = {0x00000006, 0x00000030, 0x00000014, 0x0000002c, + 0x05000000, 0x2f757372, 0x2f73686c, 0x69622f6c, + 0x69627379, 0x735f732e, 0x422e7368, 0x6c696200}; + int datasize, bsssize; E.magic = MH_MAGIC; ! E.cputype = CPU_TYPE_MC680x0; ! E.cpusubtype = CPU_SUBTYPE_MC68040; E.filetype = MH_EXECUTE; ! E.ncmds = 4; E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn) ! + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(lcmd) + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs); E.flags = MH_NOUNDEFS; *************** *** 442,448 **** tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; --- 451,457 ---- tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn); strcpy(tcmd.segname,SEG_TEXT); tcmd.vmaddr = textstart; ! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart; tcmd.fileoff = 0; tcmd.filesize = tcmd.vmsize; tcmd.maxprot = VM_PROT_ALL; *************** *** 515,520 **** --- 524,530 ---- bulletproofWrite(filid,&dcmd,sizeof(dcmd)); bulletproofWrite(filid,&dsectn,sizeof(dsectn)); bulletproofWrite(filid,&bsectn,sizeof(bsectn)); + bulletproofWrite(filid,&lcmd,sizeof(lcmd)); bulletproofWrite(filid,&uthr,sizeof(uthr)); bulletproofWrite(filid,&thflavor,sizeof(thflavor)); bulletproofWrite(filid,&thcount,sizeof(thcount)); >From cs.cornell.edu!jhr Wed Apr 24 20:41:38 0400 1991 >Received: by coma; Wed Apr 24 20:42:39 EDT 1991 >Received: by coma; Wed Apr 24 20:42:39 EDT 1991 >Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N) id AA00996; Wed, 24 Apr 91 20:41:38 -0400 >Date: Wed, 24 Apr 91 20:41:38 -0400 >From: jhr@cs.cornell.edu (John Reppy) >Message-Id: <9104250041.AA16310@maui.cs.cornell.edu> >Received: by maui.cs.cornell.edu (5.65/N-0.12) > id AA16310; Wed, 24 Apr 91 20:41:37 -0400 >To: dbm@research.att.com, oneill@cs.sfu.ca >Subject: Re: Getting Sml up and running on a NeXT running OS2.[01] >Cc: appel@cs.cornell.edu, jhr@cs.cornell.edu > From oneill@cs.sfu.ca Wed Apr 24 18:22:04 1991 > > Long long ago, you (dbm) wrote: > > I think we should have SML of NJ running on the 68040 NeXTs soon, > > since John Reppy has just bought one of them (to write his thesis > > on). He is confident he can get SML running on it quite quickly. > > I'll forward your message to him, since it looks like a useful start > > on the problem. > > John Reppy also wrote: > > It may be a while before I can fix this, since I still need to get a decent > > sized disk. > > Well, after a month of messing about with other things, I finally got arround > to getting sml working the NeXT (my NeXT arrived and so I could work on it at > home). I'll tell you the problem and give my diffs. > > ... Thanks for the fix. I'll merge these diffs into 0.69, and it should part of 0.70 (whenever that is). - John [jgm] Rumor has it that jhr has 0.69 running on the NeXTstation? Status: fixed in 0.75 --------------------------------------------------------------------------- Number: 310 Title: HP Cache flush problem Keywords: Submitter: Nick Rothwell Date: 5/23/91 Version: 0.66 System: HP9000/380 (a /300 with go-faster 68040 option) Severity: Critical for this system; fairly major overall Problem: Bombs with random bus errors or other traps on 68040-based HP machines. The build sequence runs, but not much else. Maybe it's a problem with saved images or something Code: Transcript: (i) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; EMT instruction (core dumped) (ii) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; Segmentation fault (core dumped) (iii) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; val it = 3 : int (iv) Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - 3; exnCode: code was 0 Fix: From: Andy Norman A solution to your problem is to change the caching to 'writethrough' instead of 'copyback' on the data region of the dumped sml image. i.e. chatr -Cd sml This is documented in the file /etc/newconfig/ReleaseNotes and on the man page for chatr. Hope this helps... a bit... -- ange -- ange@hpl.hp.co.uk From: Andrew Appel Message-Id: <9105240134.AA10277@cs.Princeton.EDU> To: ange.hpl.hp.co.uk@cs.Princeton.EDU Cc: dbm@inet.att.com I'm intrigued by your mail about write-through. Perhaps we can still use write-back, if we flush the cache whenever the garbage collector (etc.) moves code around. There is a provision in the runtime system to do this for machines like the MIPS where the i-cache does not track updates to the data. Could this be the problem? (grep for FLUSH in the runtime) Status: fixed in 0.75 --------------------------------------------------------------------------- Number: 311 Title: abstype bug Keywords: types, abstypes Submitter: Russ Green (rjg@lfcs) Date: 2/6/91 Version: 0.66 Severity: minor Problem: doesn't compile the following abstype definition Code: abstype t = C1 | C2 with fun f (x:t,y:t) = x=y end Status: fixed in 0.69 (jmg) --------------------------------------------------------------------------- Number: 312 Title: non-printable characters cause exception Abort to be raised Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 2/6/91 Version: 0.69 Severity: minor Problem: I've noticed that if you type a non-printable character (such as a control character), then you get an uncaught exception Abort. Code: Transcript: - ^W std_in:1.1 Error: illegal token uncaught exception Abort Comment: in parse/parse.sml, the first token is extracted from the input stream in order to initialize the parse. Unfortunately, this is outside the scope of the appropriate exception handler. Status: fixed in 0.84 --------------------------------------------------------------------------- Number: 313 Title: poor error message Keywords: error messages Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6/20/91 Version: 0.69 System: Severity: minor Problem: I tripped across a poor error message last night. Assume we have a 7 line file "xxx.sml" with the following contents: (* 1 *) fun foo () = let (* 2 *) fun bar () = let (* 3 *) val z = 1 (* 4 *) in (* 5 *) z (* 6 *) end (* 7 *) val w = 1 The error being that we forgot the body of foo's let. The error message that SML/NJ gives is: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "xxx.sml"; [opening xxx.sml] xxx.sml:7.19 Error: syntax error found at EOF [closing xxx.sml] - Comments: When foo is in the middle of a 1000 line file, figuring out the source of the error becomes quite hard. If the error message had the line range, it would be a lot better. Fix: perhaps allow specification in mlyacc that a three-token insertion should be tried; in this case "in 0 end" Same approach could fix bug 206. Status: fixed in 1.03f --------------------------------------------------------------------------- Number: 314 Title: unbalanced brackets on error message Keywords: error messages Submitter: John Reppy (jhr@cs.cornell.edu) Date: 5/5/91 Version: 0.66-0.69 Severity: minor Problem: Minor bug in 0.66: if you use a non-existent file, the resulting diagnostic has unbalanced brackets: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "nonexistent"; [use failed: open_in "nonexistent": open failed, No such file or directory Status: fixed in 0.74 --------------------------------------------------------------------------- Number: 315 Title: bad weakness degree (too weak) Keywords: types, weak types, polymorphism Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/15/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: bad weakness degree (too weak); Code: Transcript: - fun f g x = g x; val f = fn : ('a -> 'b) -> 'a -> 'b - f ref; std_in:2.1-2.5 Error: nongeneric weak type variable it : '0Z -> '0Z ref std_in:2.1-2.5 Error: nongeneric weak type variable it : '0Z -> '0Z ref - Comments: f ref should have type: '1a -> '1a ref (DBM: but can't tell this without examining the definition of f) Status: not a bug ------------------------------------------------------------------------- Number: 316 Title: stronger than required equality-type inference Keywords: types, datatypes, equality Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/15/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: stronger than required equality-type inference Code: Transcript: - datatype 'a new = N of 'a ref; datatype 'a new con N : 'a ref -> 'a new - fun f (X as ref x) (Y as ref y) = N X = N Y; val f = fn : ''a ref -> ''a ref -> bool - Comments: Not really a bug, but confusing. I may understand the reason why, but type of f above is unnecessarily strong; type 'a ref -> 'a ref -> bool would be enough as equality property for type constructor "new" does not depend upon its type argument (due to the ref in "N of 'a ref"). It is surprising that references to functions would admit equality, while constructions from these by N (as built in function f) would not. e.g. - let val r = ref (fn x=>x) in r=r end; val it = true : bool - let val r = ref (fn x=>x) in N r = N r end; std_in:3.1-3.47 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: ('0Y -> '0Y) new * ('0Y -> '0Y) new in expression: = (N r,N r) - - datatype 'a new0 = N0; - fun g x = x=N0; val g = fn : ''a new0 -> bool - Comments: g should have type: 'a new0 -> bool (DBM: see TACS paper) Status: not a bug ------------------------------------------------------------------------- Number: 317 Title: eqtypes and abstype Keywords: types, abstypes, equality Submitter: Simon Finn (simon@abstract-hardware-ltd.co.uk) Date: 9/20/90 Version: 0.69 Severity: Problem: shouldn't allow since the datatype constructor "Y" doesn't respect equality in the final environment (since it maps the non-equality type "abs" to the equality type "rep"). Poly/ML [and SML/NJ] fail to detect this. Code: abstype abs = X of int with datatype rep = Y of abs; val foo = X 1 end; fun eq x y = Y x = Y y; eq foo foo; Transcript: type abs con Y : abs -> rep val foo = - : abs val eq = fn : abs -> abs -> bool val it = true : bool Owner: dbm Status: open --------------------------------------------------------------------------- Number: 318 Title: rebinding of type operator "*" Keywords: Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: One is allowed to rebind type operator "*", but the new "*" is not properly handled in types, and old product type operator still present. Code: Transcript: - datatype * = P; datatype * con P : * - P; val it = P : * - fun f (x : *) = P; std_in:5.12 Error: syntax error found at ASTERISK - fun f (x : 'a * 'b) = (1,2); val f = fn : 'a * 'b -> int * int Comments: Is it really safe to allow rebinding of product type ? This operator must be parsed as special case anyway, as product type operator does not obey the same syntax as user definable type operators. Further, function type operator may not be rebound. [jgm] see Dave Tarditi's comments -- (x: *) is a syntax error since *) is a close comment delimiter. Status: fixed in 0.75 ------------------------------------------------------------------------------ Number: 319 Title: bad weakness degree (not weak enough) Keywords: types, weak types, polymorphism Submitter: Thierry Le Sergent (lesergen@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: major Problem: bad weakness degree (not weak enough); may create toplevel polymorphic references; Code: Transcript: - fun f x = let fun g z = ref x in g 3 end; val f = fn : '2a -> '2a ref - f []; val it = ref [] : '1a list ref Comments: f above should have type '1a -> '1a ref; Fix: propagate weakness for free as well as bound type variables (function instantiateType in basics/typesutil.sml). Status: fixed in 0.72 ------------------------------------------------------------------------------ Number: 320 Title: bad weakness degree (too weak) Keywords: types, weak types, polymorphism Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: bad weakness degree (too weak); Code: Transcript: - fun f x = (ref x; fn x=>x) x; std_in:1.5-1.28 Error: nongeneric weak type variable f : '0Z -> '0Z std_in:1.5-1.28 Error: nongeneric weak type variable f : '0Z -> '0Z - fun g x y = (ref x; fn x=>x) x; val g = fn : '1a -> 'b -> '1a Comments: f above should have type '1a -> '1a g above should have type '2a -> 'b -> '2a some rator forms confuse the type checker; which generate higher weakness degrees than expected. Fix: added base field to type absp in typing/typecheck.sml (but see bug 539). Status: fixed in 0.67 ------------------------------------------------------------------------------ Number: 321 Title: top level polymorphic exceptions allowed Keywords: types, exceptions, polymorphism Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: top level polymorphic exceptions allowed Transcript: - exception X of '0a; exception X - fun f x = raise X x; val f = fn : '0aU -> 'a - fun g h x = h x handle X y => y; val g = fn : ('a -> '0aU) -> 'a -> '0aU Comments: This would be a bug if I could raise that exception, but I could not; so ? As a comment, I would prefer the compiler to infer automatically weakness degrees for arguments of polymorphic exceptions, rather than asking the user to (sometime unconsistently) apply a type constraint. Weakness degrees are neglected in types appearing in, e.g., datatype declarations; I think this is a good practice, that I would generalize to all types written by the user. Status: fixed in 0.74 ------------------------------------------------------------------------------ Number: 322 Title: unreachable constructors should not be printed Keywords: Submitter: Bernard Berthomieu (bernard@laas.laas.fr) Date: 11/13/90 Version: 0.66 System: SUN Sparstation 1+, SunOS 4.0.3c Severity: minor Problem: unreachable constructors should not be printed Code: Transcript: - fun f x = let exception X of '1a in raise X x end; val f = fn : '1a -> 'b - f 5; uncaught exception X - fun f x = let datatype new = N in N end; val f = fn : 'a -> ?.new - f 1; val it = N : ?.new Comments: Not a bug, but confusing, as X and N above are not reachable at toplevel; and some reachable values may be printed as these. Fix: Status: not a bug, but confusing ------------------------------------------------------------------------------ Number: 323 Title: blast_read/write should have types Keywords: Submitter: Jawahar (malhotra%metasoft.uucp@BBN.COM) Date: 5/8/91 Version: 0.69 Severity: minor Problem: I'm trying to use blast_read/write to dump some functors into a file in binary form and then reload them in another image. I tried a small experiment and found that it causes a segmentation fault. Is there something I'm doing wrong? I used: - val x = {a=34,b=78}; - System.Unsafe.blast_write (x, "x.bl"); and - System.Unsafe.blast_write ("x.bl", x); both of them failed. Code: (see above) Transcript: Comments: [jgm] The first argument of blast_write and the argument of blast_read should be of type outstream and instream respectively. In system.sig, they're given types 'outstream * 'a -> unit and 'instream -> 'a making them polymorphic. I'm sure there's a reason for this, but I don't know what it is. Status: fixed in 0.84 --------------------------------------------------------------------------- Number: 324 Title: bulletproofWrite dies in a bad way when out of disk space Keywords: Submitter: Larryf Paulson (Larry.Paulson@computer-lab.cambridge.ac.uk) Date: 11/27/90 Version: System: Severity: minor Problem: when out of disk space, an exportML dies in an ugly way. Code: Transcript: A New Jersey execution failed giving the following message. Do you know what it means? Out of memory perhaps? Larry [Major collection... 99% used (1915968/1921456), 4860 msec] bulletproofWrite, errno = 28 *** Error code 3 Comments: The bulletproofWrite error you got was probably from an exportML, no? It's not out of memory; you have no space left on your disk. However, we should provide a better error message, of course. Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 325 Title: import and symlinks Keywords: Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: 4/8/91 Version: Standard ML of New Jersey, Version 0.65, 10 September 1990 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Problem: if the source file is a symbolik link import checks the modification time of the link but not of the file. Fix: *** cfuns.c.new Tue Apr 9 12:11:46 1991 --- cfuns.c.org Wed Aug 22 15:28:17 1990 *************** *** 715,721 **** int sts; if (OBJ_isBOXED(f)) ! sts = stat((char *)PTR_MLtoC(f), buf); else sts = fstat(INT_MLtoC(f), buf); --- 715,721 ---- int sts; if (OBJ_isBOXED(f)) ! sts = lstat((char *)PTR_MLtoC(f), buf); else sts = fstat(INT_MLtoC(f), buf); Comments: I use symbolik-links to share the source-code but not the bin-files for architectures sun3 and sun4 Status: not a bug --- (defunct feature) ------------------------------------------------------------------------- Number: 326 Title: very big arrays Keywords: Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: 4/9/91 Version: 0.65 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Problem: creating very big arrays leads to the message: [Minor collection...bug: insufficient to_space Comments: [jgm] I tried fairly large arrays under 0.69 (10,000,000 integers) and everything worked fine. Status: fixed in 0.75 ------------------------------------------------------------------------- Number: 327 Title: large constants cause overflow in compilation Keywords: Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: 4/23/91 Version: 0.69, 3 April 1991 System: Sun4-370 / SunOS Release 4.1.1 Problem: Big integer constants leads to an uncaught exception Overflow in codegen. Script: Script started on Tue Apr 23 13:39:20 1991 jubu@flp jubu/ml_bugs 1) smlp69 Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - val x = 1024 * 1024 * 512; val x = 536870912 : int - val maxint = x + ( x - 1 ); val maxint = 1073741823 : int - System.Control.debugging := true; execution val it = () : unit - 1073741823; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen uncaught exception Overflow - 1; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen done about to boot code size =300 codegen uncaught exception Overflow - 1; parse semantics debug instrument translate convert cpsopt closure globalfix spill codegen done about to boot code size =188 codegen execution val it = 1 : int - jubu@flp jubu/ml_bugs 2) script done on Tue Apr 23 13:41:24 1991 Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 328 Title: callcc not tail recursive Keywords: callcc Submitter: John Reppy (jhr@cs.cornell.edu) Date: 1/14/91 Version: 0.69 System: Severity: minor Problem: callcc is not tail-recursive Code: Transcript: Comments: Fix: To make callcc tail-recursive, replace the "callcc" conversion code of cps/convert.sml (starting at line 201) with the following: of Lambda.APP(Lambda.PRIM P.callcc, f) => let val h = mkLvar() and k = mkLvar() and x = mkLvar() val k' = mkLvar() and x' = mkLvar() in (* k is the callcc return cont, k' is the argument cont. *) FIX([(k, [x], c (VAR x))], PRIMOP(P.gethdlr, [], [h], [FIX( [(k', [x'], PRIMOP(P.sethdlr, [VAR h], [], [APP(VAR k, [VAR x'])]))], conv (f, fn vf => APP(vf, [VAR k', VAR k])))])) end Status: fixed in 0.75 --------------------------------------------------------------------------- Number: 329 Title: checkopen broken Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 12/6/90 Version: 0.67 System: Severity: major Problem: Compiling Dave Berry's library produces a compiler bug in 0.67 Error: Compiler bug: EnvAccess.checkopen.test Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - use "nj-sml.load"; [opening nj-sml.load] ... [closing nj-sml.load] val it = () : unit - use "build.sml"; [opening build.sml] ... [closing ../signatures/InStreamType.sml] val it = () : unit structure Types : sig eqtype InStream end open Types Error: Compiler bug: EnvAccess.checkopen.test structure Types : sig end [opening outStream.sml] ... Comments: >From Lal George: The bug seems simple; checkopen.test was complaining if anything other than vals, exceptions, or structures were defined within a structure! The problem was only visible if this other thing (e.g., a type declaration) came before test had a chance to raise NotStale on something else. A revised version of test is as follows: Fix: let fun test (s:symbol) = case Env.look newenv s of VARbind(VALvar{access=PATH(v'::_),...}) => if v' = v then raise NotStale else () | CONbind(DATACON{rep=VARIABLE(PATH(v'::_)),...}) => if v' = v then raise NotStale else () | STRbind(STRvar{access=PATH(v'::_),...}) => if v' = v then raise NotStale else () | _ => () Status: fixed in 0.69 --- however, the fix in 0.69 adds another arm to the case after the CONbind: | CONbind(DATACON{rep=VARIABLEc(PATH(v'::_)),...}) => if v' = v then raise NotStale else () --------------------------------------------------------------------------- Number: 330 Title: comments bug Keywords: comments Submitter: David Tarditi (dtarditi@cs.cmu.edu) Date: 5/17/91 Version: 0.69 System: Severity: minor Problem: According to Appendix D of the Commentary on Standard ML, an unmatched right comment bracket should be detected by the compiler. Thus the expression (op *) is illegal. Version 0.69 does not detect unmatched right comment brackets, and parses (op *). Code: (op *)(1,2); Transcript: - (op *)(1,2); val it = 2 : int Comments: Fix: add the following line to the lexer: "*)" => (err(yypos,yypos+1) COMPLAIN "unmatched close comment"; continue()); Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 331 Title: type variable generalized wrongly Keywords: types, type variables, polymorphism Submitter: Mike Fourman (mikef@lfcs.edinburgh.ac.uk) Date: 4/16/91 Version: System: Severity: major? Problem: The following is not legal ML and is rejected by PolyML, Poplog ML and the Edinburgh Kit compiler. NJ-ML and the old Edinburgh ML (wrongly) accept it. fn x => let val y : 'a -> 'a = fn z => x in y end; Error message from the Kit compiler (the others are more obscure): The following type variables could not be bound, even though they are scoped at this declaration. 'a Code: fn x => let val y : 'a -> 'a = fn z => x in y end; Transcript: Comments: Comment from David Turner: Once the new parser has been properly integrated, the above error will also show the declaration where the type variable was scoped (as below). fn x => let val y : 'a -> 'a = fn z => x in y end; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following type variables could not be bound, even though they are scoped at this declaration. 'a Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 332 Title: Allows null datatype constructor to be matched as a unit -> type function. Keywords: types, modules, signatures, signature matching Submitter: stark@cs.sunysb.edu (Gene Stark) Date: 1/26/91 Version: 0.66 and 0.69 System: SparcStation SLC, SunOS 4.0.3c Severity: major Problem: Fails to type-check datatype constructors in functor body against specifications in signature. Mismatched types result in core dump when constructor is used incorrectly. Code: The compiler allows the following code: signature SIG = sig type value; val NIL: unit -> value end functor Foo(): SIG = struct datatype value = NIL end; After importing this code, executing the following causes a bus error: structure Str = Foo(); open Str; NIL(); Status: fixed in 0.73 --------------------------------------------------------------------------- Number: 333 Title: code generation bug Keywords: Submitter: David Turner Date: 31/10/90 Version: SML of NJ version 0.66 System: Mips, Sun3, Sun4, HP9000 Severity: ? Problem: Code generation problem causing ml to crash ? Code: (* This code has been distilled to narrow down the error! *) fun sine x = (if 1 mod 4 = 0 then exp(x) else exp(real 1 * x)) / sine x Transcript: uncaught exception Regbind (* Doesn't matter too much what you type here, the whole system seems to have been corrupted. *) - sin; Illegal instruction Comments: This happen on all the machines mentioned above (nearly always via an illegal instruction). This is clearly a problem with the new CPS stuff, but I'd like to again point out the other problem: code generation bugs, such as this one or the shift bug on the sparc, cause the system to get into some kind of corrupted state, which causes a core dump on the next top-level definition. I think that there needs to be a catch-all exception handler wrapped around code generation stuff, which will restore things to a reasonable state. - John The problem with System.Unsafe.Weak is that John forgot to make it an abstraction rather than a Structure. If this is fixed, haven no longer dumps core; I would hope shamash wouldn't get wedged either, though I don't intend to try the experiment! Andrew Trying to reproduce a bug that occurs on haven in 67, I typed open System.Unsafe.Weak; strong 1; This should give a typechecking error, but on haven, it causes a Bus Error. It looks like on shamash it wedges the machine! I'm investigating further on other machines. Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 334 Title: adjust_limit in M68.prim.s Keywords: Submitter: Andre Kramer akramer@ecrc.de Date: 5/2/91 Version: 0.66 System: m68 (sun3 sunos) Severity: major? Problem: adjust_limit in M68.prim.s trashes d0 with a comment that ml does not use it. It appears that ML does use d0 (e.g. floating point primitives in same file). Code: I had an alarm signal handler causing random crashes. Transcript: . Comments: Sparc is ok. Fix: adjust_limit: movw cc,d5 /* save condition codes */ movl _saved_pc,sp@- movw d5,sp@- /* push the saved condition codes */ clrl d5 /* generate a trap on the next limit check */ rtr /* return, restoring condition codes */ Status: fixed in 0.74 --------------------------------------------------------------------------- Number: 335 Title: Dave Berry's library won't compile Keywords: Submitter: Richard O'Neill (oneill@cs.sfu.ca) Date: 4/24/91 Version: 0.68-0.69 System: NeXTstation, OS2.1 Severity: Major Problem: The current 'working' version cannot compile Dave Berry's library (as in dblibrary.tar.Z in dist/ml on research.att.com). It chuggs away for a while but finally comes up with a Runbind exception. I can't say if it works for previous releases as 0.69 is the first version that runs on a NeXT under OS2.1, and thus the first release I have been able to run in a while. Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "nj-sml.load"; . . . - use "build_all.sml"; [opening build_all.sml] val loadEntry = fn : string -> unit val loadSig = fn : string -> unit val loadLocalSig = fn : string -> unit val setLoadPrefix = fn : string -> unit val setLoadSigPrefix = fn : string -> unit ... [opening Int.sml] [opening ../signatures/INT.sml] signature INT = sig eqtype T eqtype int ... val ~ : int -> int end [closing ../signatures/INT.sml] val it = () : unit [Major collection... 36% used (948744/2627428), 814 msec] [closing Int.sml] [closing build_all.sml] uncaught exception Runbind - Status: fixed in 0.74 --------------------------------------------------------------------------- Number: 336 Title: $$lookTycPath diagnostic message Keywords: Submitter: Andre Appel (appel@princeton.edu) Date: 3/6/91 Version: 0.69 System: Severity: minor? Problem: Reminder: for 0.70 SML/NJ remove the $$lookTycPath diagnostic message. Fix: Status: fixed in 0.73 --------------------------------------------------------------------------- Number: 337 Title: double error message Keywords: Submitter: John Ophel jlophel@watmsg.waterloo.edu Date: 4/1/91 Version: 0.66 System: Vax, Unix Severity: very minor Problem: repeated error message Transcript: - val g = (fn x => (fn y => (ref x, ref(x,y)))); val g = fn : '2a -> '2b -> '2a ref * ('2a * '2b) ref - val h = g(nil); val h = fn : '1a -> '1b list ref * ('1b list * '1a) ref - h true; std_in:4.1-4.6 Error: nongeneric weak type variable it : '0Z list ref * ('0Z list * bool) ref std_in:4.1-4.6 Error: nongeneric weak type variable it : '0Z list ref * ('0Z list * bool) ref Comments: I tried to generate the double error message with a simpler code but couldn't. John Status: fixed in 0.74 --------------------------------------------------------------------------- Number: 338 Title: local datatypes Keywords: types, datatypes, local Submitter: Bruce Duba (duba@rice.edu) Date: 11/8/90 Version: System: Severity: major Problem: Is the following a bug or am I confused? I didn't expect the application of f1 to a2 to type check. Code: fun new() = let datatype A = A in (A,fn A => ()) end val (a1,f1) = new() val (a2,f2) = new() val x = f1 a2 Status: not a bug --------------------------------------------------------------------------- Number: 339 Title: type = allowed Keywords: Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: 11/8/90 Version: System: Severity: minor Problem: SML/NJ allows the following code Code: signature S = sig type = end; Transcript: Comments: Here, "=" is clearly not standing for the equality predicate (even though it's not being rebound), so this is illegal. The status of something like signature S = sig structure T: sig ... end sharing type T.t = T.* end; is less clear. "*" is not allowed as a TyCon, but "T.*" presumably is (even though no matching signature for "T" would be syntactically possible to write). Sender: David.Tarditi@b.gp.cs.cmu.edu Here are some answers to the questions about parsing in SML/NJ raised by Nick Rothwell. First, the processing of infix operators is handled by an operator precedence parser after parsing is finished. The ML-Yacc grammar essentially allows allow any string of legal identifiers in certain places; the operator precedence parser sorts it out later. (As a side note, this make syntactic error correction much harder). Yes, this means that we don't have a "pure" LALR grammar, but I don't see any way anyone could have one with the precedence scheme used in ML. The parser deals with "=" and "*" by always regarding them as reserved words. To put it another way, the lexer always returns separate tokens for these values. This reduces our problem to deciding where exactly "=" and "*" should be permitted to be used in place of identifiers. The following rules sort this out: "*" can always be used in place of an identifier, except in the syntactic class "TyCon" "=" can only be used in place of an identifier in an expression. Since it cannot be rebound, it cannot be used as an identifier in pattern. As Nick Rothwell has pointed out, there are some mistakes in SML/NJ where these rules are violated. To summarize the problems found so far: (1) Allows * to be used as TyCon in type specifications. This is clearly illegal SML (see p. 13 of the Definition). Example: sig type * end (2) Allows = to be used as TyCon in type specifications. Since this isn't the equality predicate, this is wrong. Example: sig type = end (3) Doesn't allow "*" to be used as a record label. This is clearly allowed, since "*" is just an identifier. Example {* = 5} All of these can be fixed by some minor changes to the grammar using by SML/NJ, without making the grammar ambiguous. With regard to parsing examples: (1) This is complicated, but not ambiguous. val x = {A=B=C=D=E, B=((X=Y), {X=Y}, X=Y), X=Y}; binds x to a record with fields A,B, and X. Field A is set to the boolean value of ((B=C)=D)=E), Field B is a tuple of type bool * {X:bool} * bool, and Field X is set to the value of Y. Thus: val B=1 and C=1 and D=true and E=true and X=1 and Y=1 val x = {A=B=C=D=E,B=((X=Y), {X=Y}, X=Y), X=Y} gives: val x = {A=true,B=(true,{X=1},true),X=1) : {A:bool,B : bool * {X : int} * bool, X : int} (2) This is legal; the Definition says nothing about rebinding the precedence of =. It won't typecheck though, since function types are not equality types. nonfix = val x = = and y = {A= =(=, =), B = =} (3) This should be illegal, but isn't. It shows that SML is inherently ambiguous for any fixed lookahead k. nonfix = fun f x = = | f y = case y of 1 => = | 2 => = | f z = = The reason is best illustrated with this simpler case fun f x = case y of 1 => 1 | f z = 3 The "| f z = 3" phrase should go with "fun f x", not with the case statement clause. A parser cannot decide this, however, until it sees that the "=" is not an "=>". However, z can be an arbitrarily complex pattern, so for fixed lookahead k we can choose some pattern that requires lookahead of k+1 tokens. There isn't much you can do about this, short of changing the language definition. The following variant is legal, by the way: nonfix = fun f x = = |00 stlouis8913372 "" \r\d in:--in: nuucp word: nuucpNUUCP to the problem of infixes in signatures making separate parsing and typehcecking passes difficult, it is already impossible (I think) to separate the parsing and typechecking completely. The infix status of an identifier cannot be determined without the use of static semantics information. You could separate the passes as: (1) parsing (2) typechecking plus parsing of infix identifiers if you insist on this kind of division. Dave Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 340 Title: = specification allowed Keywords: modules, signatures Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: 11/8/90 Severity: minor Problem: The following (legal - I think) signature is accepted by SML/NJ and rejected by Poly/ML and Poplog/ML: Code: signature S = sig val = : 'a * 'a -> bool end also signature S = sig val = : int end Transcript: Comments: Is this legal? "val =" is only allowed if the "=" is standing for the equality predicate (Defn. p.4). Does its appearance in a spec. count? What about sig val = : int end where it can't possibly be the equality predicate. Status: not a bug --------------------------------------------------------------------------- Number: 341 Title: equality Keywords: datatypes, equality Submitter: Andrew Tolmach (apt@princeton.edu) Date: 4/17/91 Version: 0.68 Severity: major Problem: not consistent about allowing equality Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - datatype 'a A = A of 'a ref; datatype 'a A con A : 'a ref -> 'a A - val f = fn () => (); val f = fn : unit -> unit - val f1 = fn () => (); val f1 = fn : unit -> unit - f = f1; std_in:5.1-5.6 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: (unit -> unit) * (unit -> unit) in expression: Initial.General.Initial.= (f,f1) - ref f = ref f1; val it = false : bool - ref 2 = ref 2; val it = false : bool - A (ref f) = A (ref f1); std_in:3.1-3.22 Error: operator and operand don't agree (equality type required) operator domain: ''Z * ''Z operand: (unit -> unit) A * (unit -> unit) A in expression: Initial.General.Initial.= (A ( ),A ( )) - A (ref 2) = A (ref 2); val it = false : bool - Comments: If I can compare ref f with ref f1, why can't I compare A(ref f) with A(ref f1)? Is this a bug or a feature? Also, from Chet Murthy: I want to define a datatype, with constructors/destructors, for which the system can be forced to not provide an equality. I do not think this is possible. Here is the application: The Nuprl term-type is one for which constructors/destructors are crucial. But the term-type is defined in such a way that alpha-equal variants are not represented identically. So lambda(x.x) and lambda(y.y) are not the same structure. So structural equality will fail on them. So we define alpha-equality, which respects this equivalence. But the problem is that we do not want to discard structural equality completely. That is, if we were to add a new disjunct to the Nuprl term-type: datatype Term = .......... | Bogus of int -> int then Term would not be an eq-type, and structural equality would be inadmissible. But sometimes I DO want structural equality, like in hash-consing (and I'm not sure where else, but I don't want to rule that out). So I don't want to give it up right now. So it would be nice to define a structure which exported a datatype for the term-type, an equality function which happened to be defined as structural equality, but in which the term-type was NOT an eqtype. Is this possible? Here is my try - and the problem: signature ASIG = sig type t datatype DNE = D of int | Bogus of t val op == : DNE * DNE -> bool infix 4 == end; abstraction A:ASIG = struct type t = int datatype DNE = D of int | Bogus of t fun == (a,b) = (a = b) end; If I run (A.D 5)=(A.D 6) the system will happily run it. But I want the system to complain about DNE not being an eq-type. This isn't possible, is it? Status: not a bug (language problem, see Gunter,Gunter,MacQueen) --------------------------------------------------------------------------- Number: 342 Title: execute destroys the unix-environment Keywords: Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: 12/21/90 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun 4/60, 16Mbytes, SunOS Release 4.1 Problem: The function execute destroys the unix-environment Transcript: Script started on Fri Dec 21 16:07:27 1990 jubu@flp ml66/src 1) ./sml Standard ML of New Jersey, Version 0.66, 15 September 1990 - val (istr,ostr) = execute "/bin/sh"; - outputc ostr "echo '>'$DISPLAY'<'"; val it = () : unit - close_out ostr; val it = () : unit - inputc istr (can_input istr); val it = ">flp:0.0\220<\n" : string ^^^^ Comments: cfuns.c line 1100: The c-function exec has to add 0-bytes to the ml-strings. Fix: A simple fix can be done in perv.sml: perv.sml line 953: fun execute cmd = let fun add_0byte x = x^"\000\000 val (fdin, fdout) = exec (c_string cmd, [], List.map add_0byte(environ())) handle (SysError(_,msg)) => error("execute", cmd, msg) . . [jgm] Trying this on the SGI produces the following: Uncaught exception Io with "output "": write failed, Broken pipe" Status: fixed in 0.74 (JHR) --------------------------------------------------------------------------- Number: 343 Title: wrong error message in non-gen exc bindings Keywords: error messages Submitter: Ryan Stansifer ryan@cs.purdue.edu Date: 5/11/91 Version: 0.66 Severity: minor Problem: wrong error message in non-gen exc bindings Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - exception e; exception e - val e' = e - exception e'' = e; exception e'' = e - raise e''; uncaught exception e - e'; val it = exn : exn - e''; val it = exn : exn - exception f = e'; std_in:3.15-3.16 Error: unbound exn: e' - exception f = e''; exception f = e'' Status: not a bug; perhaps the error message could be improved to indicate that e' is just a value, not a constructor --------------------------------------------------------------------------- Number: 344 Title: explicit type variable problem Keywords: types, type variables, scoping Submitter: Dave MacQueen (dbm@research.att.com) Date: 3/30/91 Version: through 0.74 Code: structure C : sig val f : 'a -> 'a end = struct exception E fun foo(k:'a option -> 'a) : 'a = k(NONE) fun bar(x:'a option) (y: 'a) = raise E fun f (e) = (* using (e:'a) as argument works *) foo (fn l => let fun g (x : 'a) = bar l x in g e end) end Comments: The rule for "scoping" explicit type variables like the 'a that appears in the definition of g is purely syntactic (i.e. doesn't take type checking, and its associated unifications, into account). Each explicit type variable is associated with with a particular val/fun declaration, and it should be generalized at that declaration, if possible. In this case 'a is associated with the "fun g" declaration, and we might annotate the definition of f accordingly: fun f (e) = (* using (e:'a) as argument works *) foo (fn l => let fun{'a} g (x : 'a) = bar l x in g e end) This means that the only legal place to generalize 'a would be at the definition of g. However, in this case the expression "bar l x" forces the type of l to be 'a option, meaning that 'a occurs in the type of the outer lambda bound variable l. This prevents the generalization of 'a at "fun g", so there is a conflict. Thus the program is not legal, but there should have been an error message about not being able to generalize 'a at "fun g", where it is syntactically scoped. I'll put in a fix to detect this situation and generate such an error message. Status: fixed in 0.85 --------------------------------------------------------------------------- Number: 345 Title: export should return a code and have different type Keywords: Date: 11/8/90 Severity: minor Problem: How come exportFn is string * (string list * string list -> unit) -> unit instead of string * (string list * string list -> int) -> 'a ? I was actually suggesting two things: the function passed as argument to exportFn should return an exit status and exportFn itself should "return" 'a rather than unit because it doesn't return. Of course, making exportFn's argument return exit status might break existing programs that use it; I don't know whether that's important or not at this stage of the game. If you want to write unix commands in ML, it's important to be able to set a return code. Comments: there is, of course, an "exit" function available for this purpose. Status: not a bug suggestion --------------------------------------------------------------------------- Number: 346 Title: exportFn Keywords: exportFn Submitter: Juergen Buntrock, TU-Berlin, jubu@cs.tu-berlin.de Date: 4/8/91 Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 System: Sun3-260 / SunOS Release 4.0.3_Export Sun4-370 / SunOS Release 4.1.1 Messages: Warning: can't increase heap Ran out of memory Comments: After an exportFn two pointers in Core.Refs are invalid. The addresses of (!Core.Refs.getDebugf) and (!Core.Refs.debugInterface) are bigger then (arenabase+arenasize) ! After an increase_heapsize the gc will collect some random-object. Bug Fix : change the type of Core.Refs.getDebugf and Core.Refs.debugInterface to (unit->unit) ref. (in file boot/core.sml) := will the do an boxed-update! Status: fixed in 0.84 --------------------------------------------------------------------------- Number: 347 Title: dec function in fastlib wrong Keywords: Submitter: Andrew Appel (appel@princeton.edu) Date: 4/15/91 Version: 0.69 (and all previous) Severity: major Problem: In all versions up to and including 0.69, the "dec" function (decrement) in boot/fastlib.sml was wrong (it incremented). This will affect only those users who followed the hints for faster performance in the doc/ directory, which explained how to include Fastlib in one's programs. Unfortunately, I am such a user. What a waste of time. Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 348 Title: connect_inet bug Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 3/23/91 Version: 0.68 Severity: minor Fix: If you haven't already built 0.69, then please include the following bug fix for connect_inet in runtime/cfuns.c: line 258, which is: saddr.sin_port = atoi(port); should be replaced with saddr.sin_port = htons(atoi(port)); and line 266, which is: saddr.sin_addr.s_addr = s; should be replaced with saddr.sin_addr.s_addr = htonl(s); Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 349 Title: function names in FUN not checked for uniqueness Keywords: duplicate bingings Submitter: Andrzej Filinski Date: 6/5/91 Version: 0.67 System: All Severity: Minor Problem: Function names in FUN not checked for uniqueness Code: fun foo x = 3 and foo x = true Transcript: - fun foo x = 3 and foo x = true; val foo = fn : 'a -> int val foo = fn : 'a -> bool - Comments: The equivalent VAL REC declaration is correctly rejected. Also, from Olof Johansson (olof@cs.umu.se) Is this a bug? What is the point of the definition? Is it allowed to do this according to the definition of SML? Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - datatype F = C and F = D; datatype F con C : F datatype F con D : F - D; > val it = D : F - C; > val it = D : F Which one of the following response is the correct one. Should they not be the same? Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - val rec f = fn x => 1 and f = fn y => 2; std_in:2.9-2.39 Error: duplicate function name in val rec dec: f - fun f x = 1 and f y = 2; val f = fn : 'a -> int val f = fn : 'a -> int - f 0; val it = 2 : int Olof Johansson Fix: Add checkUniq of function names to makeFUNdec in parse/corelang.sml or to FUNdec in absyn/absyn.sml Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 350 Title: fvalbind rewrite rule Keywords: syntax, parsing Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk) Date: 2/12/91 Version: System: Severity: minor Problem: Referring to the definition of the `fun' derived form (defn. V4 p68): there's a rewriting rule for fvalbind's looking like var atpat.11 ... atpat.1n <: ty> = exp.1 var atpat.21 ... atpat.2n <: ty> = exp.2 var atpat.m1 ... atpat.mn <: ty> = exp.m This implicitly suggests that all the function result type constraints (whichever present) have to be the same. But, this is a *syntactic* constraint (we're dealing with derived forms, not elaboration rules). Certainly they have to elaborate to the same type, but surely they may be distinct syntactically? The above rule outlaws the following local type INT = int in fun f 0 : int = 0 | f 1 : INT = 1 end; Code: Transcript: Comments: Appel says: the Def'n should have subscripts on the ty's, and that's obviously what is meant here. Fix: Status: not a bug? --------------------------------------------------------------------------- Number: 351 Title: gc messages bug Keywords: garbage collection, messages Submitter: Andrew Tolmach (apt@princeton.edu) Date: 5/7/91 Version: 0.69 (and some earlier, 68 based versions) System: mipsb Severity: minor Problem: In version 69 (and some earlier, 68 based versions) on mipsb, the unsafe gc primitive interacts badly with gcmessages. Obviously this isn't a serious problem in itself, but maybe bears loking into...? Code: Transcript: - val gc = System.Unsafe.CInterface.gc; val gc = fn : int -> unit - (gc 0; gc 0); val it = () : unit - System.Control.Runtime.gcmessages := 3; val it = () : unit - (gc 0; gc 0); [Minor collection... 0% used (2224/765756), 10 msec] [Minor collection...bogus signal in ML: (5, 0x7) Comments: Fix: Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 352 Title: gc statistics bug Keywords: garbage collection, measurements Submitter: Greg Morrisett (jgmorris@cs.cmu.edu) Date: 5/25/91 Version: 0.69 System: All Severity: minor Problem: In callgc.c, there's a couple of places where you're trying to bump an ML_val_t int ref (e.g. majorcollections, collected, etc.) and using code like this: minorcollections += 2; But since ML_val_t is an unsigned int pointer, this bumps the value by 4 (i.e. ML 2). The safe way to add to an ML_val_t is to use INT_incr. Code: Transcript: Comments: Fix: change line 217 of callgc.c to read minorcollections = INT_incr(minorcollections,1); change lines 292-294 of callgc.c to read collected = INT_incr(collected, ((a+512)/1024)); collectedfrom = INT_incr(collectedfom, ((b+512)/1024)); majorcollections = INT_incr(majorcollections,1); Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 353 Title: getWD can't get above mount points on NeXT Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6/7/91 Version: 0.69 System: NeXT Severity: minor Problem: System.Directory.getWD doesn't seem to be able to get above mount points on the NeXT (works on the sun). E.g., Code: Transcript: pwd /usr/fsys/loki/b/jhr sml Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - System.Directory.cd ".."; val it = () : unit - System.Directory.getWD(); val it = "/" : string - System.Directory.cd ".."; val it = () : unit - System.Directory.getWD(); val it = "/usr/fsys/loki" : string Comment: See also 421. To be fixed by calling C version of getWD (after new gc allows malloc). Status: fixed in 107 --------------------------------------------------------------------------- Number: 354 Title: SIGILL bug on SPARC Keywords: signals, sparc Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6/18/91 Version: 0.69 System: SPARC Severity: major Problem: One of our alpha testers encountered a strange Overflow exception in eXene. Upon closer examination it turns out that the problem really is an illegal instruction exception (SIGILL), and that modifications made to support MACH on the SPARC caused SIGILL to be mapped to Overflow. Further examination demonstrates that the bug is neither an eXene bug or CML bug, but is a bug in SML/NJ. After a lot of testing I've managed to produce a small (<100 lines) example program, which will cause the bug on both the SPARC and DECstation 3100. The fact that this program uses the timer interrupts to do thread switching is key; if you turn the signals off, then the bug does not appear. I also note that the bug does not seem to appear in my version of 0.68 (0.67 + my changes for the unsafe callcc); thus I suspect that it was introduced by the changes made for supporting FP registers. The example program is included below; to produce the bug, run the function "go." It usually takes about 3-5 minutes to fail on a SPARCstation-1. For example, the following run took 2.5 min: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - use "sml-bug.sml"; [opening sml-bug.sml] val yield = fn : unit -> unit val spawn = fn : string * (unit -> unit) -> unit val doit = fn : (unit -> unit) -> unit val go = fn : unit -> unit [closing sml-bug.sml] val it = () : unit - go(); initial process proc1 proc2 proc1: uncaught exception Overflow initial process: uncaught exception Overflow val it = () : unit Code: (see John's CML code) Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 355 Title: incorrect line numbers with import Keywords: import Submitter: deutsch@poly.polytechnique.fr. Alain Deutsch, Laboratoire d'Informatique de l'Ecole Polytechnique (LIX) 91128 Palaiseau Cedex France. Date: 11/22/90 Version: Version 0.66 System: SUN3/60 Severity: minor Problem: Incorrect line/column numbers when compiling a module w. import, although the numbers are correct when compiling with use. Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - use "ExampleFunctor.sml"; [opening ExampleFunctor.sml] ExampleFunctor.sml:3.9-3.18 Warning: match not exhaustive x :: nil => ... functor F : [closing ExampleFunctor.sml] val it = () : unit - import "ExampleFunctor"; [reading ExampleFunctor.sml] ExampleFunctor.sml:0.0-0.0 Warning: match not exhaustive x :: nil => ... [writing ExampleFunctor.bin... done] [closing ExampleFunctor.sml] functor F - Status: not a bug (Defunct feature) --------------------------------------------------------------------------- Number: 356 Title: size of images generated by import too large Keywords: import Submitter: Jawahar Malhotra (malhotra%metasoft@bbn.com) Date: 1/29/91 Version: System: Severity: Problem: I recently redesigned a large system so that I could use separate compilation. I experienced an increase in heap size of close to 100%. This was a little disturbing and so I investigated a little. To explain the problem consider the following example: Say my system consists of 4 modules: A, B, C, D. Every functor is in a separate file as is every signature. To link, I execute 'use "link.sml"'. ++++++++++++++++++++++++++++++ (* link.sml *) import "a"; import "b"; import "c"; import "d"; structure A = A(); structure B = B(A); structure C = C(A); structure D = D(structure X = B structure Y = C); ++++++++++++++++++++++++++++++ The files are as follows: ++++++++++++++++++++++++++++++ (* a.sml *) import "a.sig"; functor A() = ... ++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ (* b.sml *) import "a.sig"; import "b.sig"; functor B (X:ASIG) : BSIG = ... ++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++ (* c.sml *) import "a.sig"; import "c.sig"; functor C (X:ASIG) : CSIG = ... ++++++++++++++++++++++++++++++ ... Building the system as shown above led to LARGE heap sizes (and images generated by exportML). I suspected that this was due to the duplicated imports of the same signature file by many sml files. For example, "a.sig" is imported by "a.sml", "b.sml", "c.sml". To verify this, I wrote a function called "smartImport" which uses "use" to load files. It maintains an environment of files already loaded and avoids duplicate loading of files (code appears at end of message). I then replaced "import" by "smartImport" in all my source files and rebuilt. I found that the resulting image size was much smaller. The following results were obtained using an actual system with approx. 40 modules. For both cases, exactly the same source code was loaded and an image exported using "exportML". ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ exportML file size (bytes) Without smartImport (regular sep. comp.) 5799968 With smartImport 3063840 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ This is quite a significant saving. I would eventually like to have an improved "import" command; one that can avoid duplicated loading of files. I'm not so sure the technique I have used (i.e. using file names to determine if a file has already been loaded) is a general error-free solution. A combination of file name and file modification time may be better. So whenever "import" loads a file, it records the file name and the file modification time. The next time it encounters this file, it compares the saved modification time with the file's actual modification time. If the file is newer, it reloads the file else it skips the file. Has anyone else had such experiences with separate compilation? Any other suggestions for how to keep the heap size down? Jawahar Comments: [jgm] Gene Rollin's sourcegroup stuff is being designed to take care of this problem. Status: not a bug --- (defunct feature) --------------------------------------------------------------------------- Number: 357 Title: import broken Keywords: import Submitter: Richard O'Neill (rmo@sys.uea.ac.uk) Date: 11/13/90 Version: 0.67 (not in 0.66) System: Sun4/SunOS 4.1 (probably irrelevant) Severity: Major Problem: Version 0.67 of Standard ML of New Jersey breaks 'import'. Import now seems to compile the file it is given but fails to introduce the declarations from that file into the environment. Transcript: unix% cat > example.sml signature Test = sig type foobar end unix% sml Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - import "example"; [reading example.sml] [writing example.bin... done] [closing example.sml] signature Test - signature CopyOfTest = Test; std_in:3.24-3.27 Error: unbound signature: Test - Comments: (guesses) Looking at differences between 0.66 & 0.67 I see that the way the environment is handled has changed. I suspect that this has something to do with it. Other information: The version I have built was made from the mo.sparc files and src from 'pub/ml/working' at princeton. Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 358 Title: import & pervasives Keywords: import Submitter: Elsa Gunter elsa@research.att.com Date: 3/27/91 Version: 0.68 System: mips Problem: import doesn't always get the pervasive types right Code: (* File: bug.sig.sml *) signature ASig = sig exception FOO of string end (* File: bug.sml *) import "bug.sig"; functor AFunc () = struct exception FOO of string end Transcript: Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - import "bug.sig"; [reading bug.sig.sml] [writing bug.sig.bin... done] [closing bug.sig.sml] signature ASig - import "bug"; [reading bug.sml] [reading bug.sig.bin... done] bug.sml:5.18-5.23 Error: unbound type constructor: string import: syntax or semantic error [closing bug.sml] IMPORT failed - Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - import "bug"; [reading bug.sml] [reading bug.sig.sml] [writing bug.sig.bin... done] [closing bug.sig.sml] [writing bug.bin... done] [closing bug.sml] signature ASig functor AFunc - import "bug"; [reading bug.bin... ] [import(s) of bug are out of date; recompiling] [closing bug.bin] [reading bug.sml] [reading bug.sig.bin... done] bug.sml:5.18-5.23 Error: unbound type constructor: string import: syntax or semantic error [closing bug.sml] IMPORT failed - Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 359 Title: indexing Keywords: Submitter: Gene Rollins Date: 3/11/91 Version: 0.67 Severity: minor Problem: Indexing code doesn't handle all abstract syntax trees Code: Anything with an import clause in it. Transcript: Error: Compiler bug: Index2 Comments: Only happens when (!System.Control.indexing) = true Fix: In file build/index.sml, add three clauses for printDec, and eliminate the final wildcard clause. diff {old,new}/build/index.sml 160a161,162 > | printDec(FIXdec _) = () > | printDec(OVLDdec _) = () 161a164 > | printDec(IMPORTdec _) = () 163d165 < | printDec _ = ErrorMsg.impossible "Index2" Comment: Import will soon go away. Then this will be "not a bug". Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 360 Title: bad error message when missing functor argument Keywords: modules, functors, error messages Submitter: Robert Harper (rwh@cs.cmu.edu) Date: 8/29/90 Version: System: Severity: minor Problem: Here's another bug report, this one relatively minor. The problem arises as follows. I have a build file which imports a bunch of files and then applies a bunch of functors to build the program. I changed one of the functors to take a parameter where it formerly had none. But I forgot to change the build file to plug in an argument. Here's what I get: /usr/rwh/courses/ic90/build.sml:56.5-56.10 Error: unmatched structure spec: Type Error: Compiler bug: inststr NULLstr [closing /usr/rwh/courses/ic90/build.sml] - It gives a reasonable message, then an unreasonable one. I've noticed versions of this where the "compiler bug" is "tyC" (or something close to that). My suspicion is that it has to do with the awful declaration-as-argument syntax for functor applications .... Code: Transcript: Comments: Fix: Status: fixed in 0.73, but can't tell (no source provided) --------------------------------------------------------------------------- Number: 361 Title: Error: Compiler bug: Functor.applyFunctor.insttyc Keywords: modules, functors Submitter: Elsa elsa@research.att.com Date: 3/8/91 Version: 0.66 & 0.67 System: mips mips and Sun3 with SunOS 4.0 Problem: Error: Compiler bug: Functor.applyFunctor.insttyc Code: signature AA = sig datatype s = a of s end (* signature AA *) signature BB = sig structure A : AA end (* signature BB *) signature CC = sig structure B : BB type v end (* signature CC *) functor F (structure B : BB) : CC = struct structure B = B structure A = B.A open A type u = s end (* functor F *) structure C : CC = F (structure B = B); Transcript: - use "bug2.sml"; [opening bug2.sml] bug2.sml:19.5-24.7 Error: unmatched type spec: v bug2.sml:26.37 Error: unbound structure name: B bug2.sml:26.20 Error: unmatched structure spec: A insttyc: NULLtyc Error: Compiler bug: Functor.applyFunctor.insttyc [closing bug2.sml] - Status: fixed in 0.73 --------------------------------------------------------------------------- Number: 362 Title: missing primop in interp Keywords: interpreter Submitter: John Reppy (jhr@cs.cornell.edu) Date: 1/17/91 Version: 0.67 System: Severity: Problem: Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - System.Control.interp := true; val it = () : unit - fun f x = Bits.notb x; Error: Compiler bug: bad primop in interp Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 363 Title: bug in 0.69 interpreter Keywords: interpreter Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6/17/91 Version: 0.69 System: Severity: Problem: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - app (fn x => x) ["abc", "def"]; val it = () : unit - System.Control.interp := true; val it = () : unit - app (fn x => x) ["abc", "def"]; uncaught exception Match - Comments: First fix the saving of lambda in interact.sml. Fix: Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 364 Title: bug in lexgen doc Keywords: ml-lex, documentation Submitter: John Reppy (jhr@cs.cornell.edu) Date: 6/5/91 Version: System: Severity: minor Problem: The example of how to build a lexer is wrong (line 348), because the input file gets opened multiple times. val lexer = Mlex.makeLexer (fn x => input(open_in "f",x)) should be val lexer = Mlex.makeLexer (inputc (open_in "f")) This has confused at least one naive user. Code: Transcript: Comments: [jgm] according to Dave Tarditi, this has been fixed in the latest copy of the documentation. Fix: Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 365 Title: fixed size of tuples causes bug Keywords: Submitter: Jawahar Malhotra Date: 5/29/91 Version: 0.62 System: SUN SPARC, SUN OS 4.1 Severity: major Problem: A labeled record can have no more than 100 fields Comments: I was browsing the typechecker code (typing/typecheck.sml) and I noticed a constant "val maxFieldNum = 100," which I assume limits the number of slots a tuple is allowed to have. It would be best to avoid such hard-coded limits, but, if they must exist, they probably should be localized into a single structure, to allow easy modifications. - John Version 0.69 of SML/NJ: When compiling the following code, an "uncaught exception Subscript" occurs. If the number of elements in the tuple is reduced to 100 from 110, the exception no longer occurs. From: wright@rice.edu (Andrew Wright) fun g(f) = ( f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f(), f() ); Fix: sort without an array Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 366 Title: lookahead Keywords: I/O, lookahead Submitter: Dave Berry Date: 1/26/91 Version: ? Severity: minor Problem: If I type the following simple program to either SML/NJ or Poly/ML, I get some interesting behaviour: (lookahead std_in; lookahead std_in); (I haven't tried this with Poplog ML or Edinburgh ML because they're only installed on our Suns, which have crashed.) If I give this program the input a it returns the string "a". This is the behaviour I expect - the first call looks at the next character but doesn't affect the state of the stream, so the next call finds the same character. (If you try this you'll have to type a semi-colon after the program finishes, because the compiler will read your input.) However, if I give the following input to the program a then it still returns "a". In other words the first call consumes the end-of-stream marker, changing the state of the stream. It's not at all clear to me that this is the desired behaviour. It's this behaviour that results in the problem with end_of_stream that I mentioned some weeks ago, because (end_of_stream i) is defined as (lookahead i = ""). I suggest that lookahead should never change the state of a stream, even when it finds an end-of-stream marker on an interactive stream. This may require some extra state information in the implementation of a stream, but that shouldn't be visible to the user. This would give more consistent behaviour, and would solve the problem with end_of_stream. It also means that I could get rid of the InStream and OutStream types in the Edinburgh library, making it quite a bit simpler to use (and maintain). Some interactive programs do have to consume end-of-stream markers on interactive streams. This can be done by calling read at the appropriate place, perhaps using a function like the following: fun consumeEOS i = if InStream.interactive i then if end_of_stream i then read i else "" else raise NotInteractive i; The only problem that I can see with this approach is that a program that tests for end_of_stream won't necessarily consume the end-of-stream marker with an explicit read, which means that the compiler will read it and exit. I can think of a couple of ways that an implementation could avoid this. The first is to consume an end-of-stream marker before reading a new program, thus requiring the user to type CTRL-D twice to exit (which might be safer anyway). The second is to require the user to call a specific exit function to exit the compiler. The third is to treat std_in specially, and to mark when an end-of-stream marker is encountered by a user calling lookahead as opposed to the compiler calling lookahead. I don't know how easy this would be to implement. To summarise, this gives a consistent behaviour to lookahead, and seems a far neater way of solving the end_of_stream problem than my previous suggestion. Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 367 Title: Decstation mach recompolation to m68 Keywords: decstation Submitter: Gene Rollins Date: 3/13/91 Version: 0.67 Batch Compiler System: Decstation mach (cross compiler to m68) Severity: major Problem: Cross compiler halts with Getscratch Code: The 0.67 compiler sources Transcript 1: I added vertical ellipses to omit part that worked correctly. Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler) [setreducemore()] [reducemore := 0] [setrounds()] [rounds := 10] [setbodysize()] [bodysize := 20] [mBoot()] . . . [Compiling boot/math.sml] signature MATH structure Math boot/math.sml:290.4 Warning: match not exhaustive 0 => ... 1 => ... [closing boot/math.sml] [Failed on "~mBoot" with Getscratch] Transcript 2: Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler) [globalhandle := false] [markabsyn := false] [mBoot()] . . . [Compiling env/env.sml] structure Env [closing env/env.sml] [Failed on "!env/env.sml" with Getscratch] uncaught exception (Loader): Getscratch Comments: The Sun3 Mach batch compiler for m68 works fine. Status: fixed in 0.69, Appel suspects. --------------------------------------------------------------------------- Number: 368 Title: missing exceptions Keywords: exceptions Submitter: Larry Paulson (larry.paulson@computer-lab.cambridge.ac.uk) Date: 11/16/90 Version: 0.69 System: Severity: minor Problem: You have most, but not all, of those silly arithmetic exceptions. Larry Code: Transcript: - Abs; std_in:7.1-7.3 Error: unbound variable Abs - Div; val it = exn : exn - Mod; val it = exn : exn - Quot; std_in:3.1-3.4 Error: unbound variable Quot - Prod; val it = exn : exn - Neg; val it = exn : exn - Sum; val it = exn : exn - Diff; val it = exn : exn - Floor; val it = exn : exn - Sqrt; val it = exn : exn - Exp; val it = exn : exn - Ln; val it = exn : exn Comments: Fix: edit perv.sml and perv.sig Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 369 Title: bug in MLYACC Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 5/29/91 Version: 0.69 System: Severity: major Problem: I was compiling mlyacc with 0.69 and noticed a couple of problems. In addition to the syntax error in yacc.sml (lines 350-351), there is also a funny message being generated: [opening yacc.sml] $$ lookTycPath 1: 2 2 tyconInContext: [2] Code: Transcript: Comments: [jgm] See bugs 307 and 336 -- this may not be MLYACC's fault. Fix: see 336. Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 370 Title: Wrong definition of div & mod in perv.sml Keywords: primitives, arithmetic Submitter: Andrzej Filinski Date: 3/16/91 Version: 0.67 System: All (verified on PMAX, Mach/4.3 BSD) Severity: major Problem: Wrong definition of div & mod in perv.sml Code: 0 div ~2 Transcript: - 0 div ~2; val it = ~1 : int - 0 mod ~2; val it = ~2 : int Comments: Definition (p.79) requires a result of 0 in both cases. Fix: In boot/perv.sml, "structure Integer = ...", replace < fun op div(a:int,b:int):int = < if a>=0 < then if b>=0 then InLine.div(a,b) < else InLine.div(a-1,b)-1 < else if b>=0 then InLine.div(a+1,b)-1 < else InLine.div(a,b) with > fun op div(a:int,b:int):int = > if b>=0 > then if a>=0 then InLine.div(a,b) > else InLine.div(a+1,b)-1 > else if a>0 then InLine.div(a-1,b)-1 > else InLine.div(a,b) Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 371 Title: intmap bug Keywords: Submitter: Chet Murthy (murthy@cs.cornell.edu) Date: 6/13/91 Version: System: Severity: Problem: I was using intmap to implement a hash table, and I found what appears to be a bug. Code: (* requires intmap.sig and intmap.sml to be loaded To see the bug, run "try 477 trace;" and "try 476 trace;" the variable longtrace is bound to an even longer trace. Each will, for each N in the list, add (N,CTR) to the intmap, and then increment CTR. Then each will dump the intmap with intMapToList, and compare the cardinality of the domain (computed by getting the first projection of each pair in the graph given by intMapToList and and uniquifying it) to the actual length of the list returned by intMapToList. The function repeated will print out all the pairs (N,V) such that N appears more than once in the graph. Try "repeated 476 trace" and observe that the output is empty, whereas "repeated 477 trace" produces "[(29,476),(29,316)]" meaning that both pairs showed up in the trace. *) (* splits a list into the first N elts and the tail *) fun chopList(0,l) = (nil,l) | chopList(n,h::t) = let val (m,l') = chopList(n-1,t) in (h::m,l') end fun member x nil = false | member x (h::t) = if x = h then true else member x t fun uniquize nil = nil | uniquize (h::t) = if member h t then uniquize t else h::(uniquize t) fun collect f l = fold List.@ (map f l) nil fun runTo n l = let val (pref,_) = chopList(n,l) val ctr = ref 0 val imap = Intmap.new(100,General.Match) fun go nil = () | go (h::t) = (Intmap.add imap (h,!ctr);inc ctr;go t) in (go pref;Intmap.intMapToList imap) end fun try n trace = uniquize(map #1 (runTo n trace)) = (map #1 (runTo n trace)) fun repeated n trace = let val graph = runTo n trace fun aux nil = nil | aux (h::t) = (if member h t then [h] else nil)@(aux t) fun find x nil = nil | find x ((a,b)::t) = (if x = a then [(a,b)] else nil)@(find x t) val repetitions = aux (map #1 graph) in collect (fn x => find x graph) repetitions end val trace = [26,98,96,64,32,52,62,91,23,53,41,30,58,67,29,16,37, 68,51,62,89,70,5,10,76,50,90,16,51,47,48,74,32,21, 68,33,55,58,19,12,19,81,60,31,38,15,45,69,32,19,38, 44,0,50,97,15,8,79,55,23,3,81,11,3,23,64,26,74,23, 57,93,69,41,66,19,96,20,63,25,90,8,44,98,98,82,40, 46,18,81,92,65,35,65,77,98,45,39,87,46,64,2,48,43, 2,79,83,25,41,42,98,71,39,44,65,40,77,54,32,12,15, 80,76,55,26,43,20,57,77,15,66,11,92,64,4,8,1,22,5, 66,39,48,17,72,41,76,28,56,41,6,69,89,31,38,44,51, 9,64,85,45,37,82,20,97,93,82,61,18,0,27,6,17,65,20, 23,0,23,39,98,66,75,54,23,19,77,96,57,78,22,50,30, 13,63,84,88,12,83,84,22,41,68,61,54,60,4,69,84,10, 21,50,35,28,89,11,62,12,75,69,80,95,6,98,94,2,84, 60,29,51,72,77,6,20,5,95,29,97,21,49,30,89,3,70,53, 28,74,37,59,96,22,52,65,6,98,91,22,95,8,7,65,60,61, 44,47,62,76,30,63,46,32,94,26,30,7,73,79,29,57,12, 15,14,57,9,25,72,89,36,87,57,66,87,59,26,26,26,16, 66,68,26,59,59,26,72,22,55,59,73,73,26,64,96,27,73, 96,96,26,15,43,29,96,48,48,26,71,8,84,48,68,68,26, 31,50,97,68,88,88,26,91,59,40,88,36,36,26,35,44,31, 36,16,16,26,39,49,88,16,48,48,26,67,99,21,48,26,27, 98,98,98,26,48,46,98,26,26,27,77,77,77,26,0,25,77, 26,27,15,92,92,26,61,71,92,26,27,81,81,81,26,48,19, 81,26,26,27,15,15,15,26,9,57,15,26,26,27,10,80,80,26, 25,48,80,26,26,27,24,24,24,26,23,76,24,26,26,27,99,76, 76,26,43,89,76,26,26,27,34,34,34,26,7,74,34,43,6,27, 45,26,91,91,26,91,64,91,26,26,27,31,31,31,26,31,54,31, 26,26,27,36,13,13,26,86,29] Transcript: Comments: Should fix intmap to not allow users to specify initial size. Fix: Don't use 100 as the initial size. Status: not a bug --------------------------------------------------------------------------- Number: 372 Title: open in signature causes compiler bug Keywords: modules, signature, open Submitter: Gene Rollins Date: 3/11/91 Version: 0.67 Severity: major Problem: open in signature results in compiler reporting a bug Code: signature ARITH = sig structure Term : TERM open Term ... Transcript: - use "src-use/arith.sig.sml"; [opening src-use/arith.sig.sml] Error: Compiler bug: EnvAccess.openStructureVar -- bad access value [closing src-use/arith.sig.sml] Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 373 Title: bug in printing fully qualified structure names Keywords: modules, printing Submitter: Andrew Tolmach (apt@princton.edu) Date: 4/16/91 Version: 0.69 System: Severity: minor Problem: prints qualified names in the wrong order on error. Looks like someone got the list backwards. Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - structure Fred = struct structure Bill = struct fun f x = x + 1 end end; structure Fred : sig structure Bill : sig...end end - open Fred.Bill; open Fred.Bill - f true; std_in:4.1-4.6 Error: operator and operand don't agree (tycon mismatch) operator domain: int operand: bool in expression: Bill.Fred.f true Comments: Appel says: these qualified names shouldn't be there anyway! The abstract syntax should in this case match the concrete syntax, so the message should say, "f true" not "Fred.Bill.f true". Fix: remove "qid@" from varApplied and strApplied in envaccess.sml Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 374 Title: mod overflows on some negative numbers Keywords: primitives, arithmetic Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: 5/01/91 Version: 0.66-0.69 System: Pmax, Vax, Sun4 Severity: major Problem: Code: Transcript: - val minint = ~1073741824; val minint = ~1073741824 : int - minint mod 10; uncaught exception Overflow Comments: The SML definition of div and mod is different than that typically provided by hardware, thus mod and div actually defined as fun op div(a:int,b:int):int = if a>=0 then if b>=0 then InLine.div(a,b) else InLine.div(a-1,b)-1 else if b>=0 then InLine.div(a+1,b)-1 else InLine.div(a,b) fun op mod(a:int,b:int):int = a-(a div b)*b (see boot/perv.sml). The "*" in mod is causing the overflow. You could use quot and rem, but they may not give you the answer you want: - ~1073741824 rem 10; val it = ~4 : int - John Fix: First, see the fix for bug 370. Second, use a separate case analysis for "mod", don't just call "div". Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 375 Title: overflow bugs Keywords: arithmetic, overflow Submitter: John Reppy (jhr@cs.cornell.edu) Date: 12/6/90 Version: 0.67 System: Severity: major? Problem: Dave Berry's library code trips over the following problem with large positive integers: Code: Transcript: Standard ML of New Jersey, Version 0.67, 21 November 1990 val it = () : unit - ~1073741822; val it = ~1073741822 : int - it+1; val it = ~1073741821 : int - ~it; val it = 1073741821 : int - 1073741821; uncaught exception Overflow Comments: dbm@research.att.com writes: > (2) I have had a runbind bug report for 0.69, but it may not be the > same bug you have seen. I would appreciate it very much if you could > send me formal bug reports on the Runbind and Overflow problems. We > can certainly cope with redundant bug reports! The easiest way to reproduce the Runbind exception is to try to load the portable version of the SML library into SML 0.69. I've also had it occur when I was doing something with returning options, but that code doesn't exist anymore (I changed the structure of the code and the problem went away). As far as the overflow is concerned: eXene -- version 0.2 (alpha) -- April 1, 1991 Concurrent ML, version 0.9.2, January 15, 1991 val it = () : unit - 1073741823; uncaught exception Overflow - 1024; uncaught exception Overflow <------ this shouldn't happen - Standard ML of New Jersey, Version 0.68, March 7, 1991 val it = () : unit - 1073741823; uncaught exception Overflow - 1024; uncaught exception Overflow <------ this shouldn't happen - Fix: Status: fixed in 0.69? ([jgm] works on SGI) --------------------------------------------------------------------------- Number: 376 Title: empty signatures and functors, parsing Keywords: modules, signatures, functors, parsing Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk) Date: 11/21/90 Version: 0.66? Severity: minor Problem: SML/NJ accepts the following (both of which are not legal SML): signature S = sig end functor F() = struct end; val x = "A" ^ if true then "B" else "C"; Comment: [dbm] The first problem is an intensional divergence, the second is fixed as of 0.69. Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 377 Title: prop.sml has bug Keywords: Submitter: Date: 12/25/90 Version: 0.66 System: Severity: minor Problem: ../66/doc/examples/prop.sml doesn't correctly change to conjunctive normal form. (* exercise *) Code: Transcript: Comments: Fix: Put comment at top of prop.sml saying that it has bugs. Status: fixed in 0.71 (comment put in!) --------------------------------------------------------------------------- Number: 378 Title: Error: Compiler bug: Functor.applyFunctor.redoTycs 1 Keywords: modules, functors Submitter: Elsa Gunter (elsa@research.att.com) Date: 3/8/91 Version: 0.66 & 0.67 System: mips mips and sun3 with SunOS 4.0 Severity: major Problem: Error: Compiler bug: Functor.applyFunctor.redoTycs 1 Code: (* File bug1.sml *) signature AA = sig datatype s = a of t * s and t = b of s end (* signature AA *) signature BB = sig structure A : AA end (* signature BB *) signature CC = sig structure B : BB type u end (* signature CC *) functor F (structure B : BB) : CC = struct structure B = B structure A = B.A open A type u = t * s end (* functor F *) structure C : CC = F (structure B = B); Transcript: - use "bug1.sml"; [opening bug1.sml] bug1.sml:27.37 Error: unbound structure name: B bug1.sml:27.20 Error: unmatched structure spec: A Error: Compiler bug: Functor.applyFunctor.redoTycs 1 [closing bug1.sml] - Comments: Fix: Cascade Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 379 Title: redundant patterns Keywords: Submitter: John Reppy (jhr@cs.cornell.edu) Date: 1/25/91 Problem: I would like to suggest that the compiler reject redundant patterns as errors (possibly with a flag to generate only warnings to preserve compatibility with "The Definition"). The reason for this change is that it will force the user to deal with potential errors (warning messages usually get buried in the output). Often, a redundant pattern is the result of a mis-spelled constructor name, and so is actually an error (there is an example of this in the 0.67 version of the debugger). Transcript: I noticed the following redundant pattern warnings while compiling 0.67. The debugger ones are definitely an error. - John translate/translate.sml:227.30 Warning: redundant patterns in match VALtrans (PATH p) => ... VALtrans (INLINE eql) => ... VALtrans (INLINE neq) => ... VALtrans (INLINE i) => ... THINtrans (PATH p,v,locs) => ... CONtrans (d as DATACON {const=true,...}) => ... CONtrans (d as DATACON {const=false,...}) => ... VALtrans a => ... THINtrans (a,_,_) => ... --> _ => ... build/process.sml:334.32 Warning: redundant patterns in match ({access=SLOT s1,name=name},{access=SLOT s2,name=_}) => ... ({access=SLOT _,...},_) => ... ({access=PATH (:: (,)),...},{access=PATH (:: (,)),...}) => ... ({access=PATH _,...},_) => ... ({access=INLINE i1,...},{access=INLINE i2,...}) => ... ({access=INLINE _,...},_) => ... --> _ => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... debug/historystore.sml:371.1 Warning: redundant patterns in match (a,weak_desc) => ... --> (_,tag) => ... Status: not a bug (a suggestion) --------------------------------------------------------------------------- Number: 380 Title: regbind compiler bug Keywords: Submitter: Eric Cooper, ecc@cs.cmu.edu Date: 12/5/90 Version: 0.66 System: VAX and SPARC running Mach 2.5 Severity: major Problem: compiler raises Regbind; top-level dumps core Code: (* This example causes the compiler to raise Regbind on SML/NJ 0.66 on Sparc SML/NJ 0.65 on VAX After the exception message is printed, typing () to the top level causes an illegal instruction trap. It doesn't fail if: functor is replaced by a structure (name ^ "\n") is replaced by name (n mod period = 0) is replaced by (n + period = 0) the tail recursive call to proc () is removed *) functor Broken (S : sig val perform : (unit -> 'a) -> 'a end) = struct val period = 0 val name = "foo" val n = 0 fun proc () = (if n mod period = 0 then S.perform (fn () => print (name ^ "\n")) else (); proc ()) end (* Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - [opening bug.sml] [closing bug.sml] uncaught exception Regbind - (); SIGILL code 0x2 Process Inferior sml exited abnormally with code 3 *) Status: fixed in 0.75 ([jgm] works on SGI) --------------------------------------------------------------------------- Number: 381 Title: saving registers for signal handler continuation Keywords: signals, registers Submitter: Andrew Tolmach (apt@princeton.edu) Date: 5/14/91 Version: 0.69 System: Severity: major Problem: Andrew Tolmach discovered an interesting bug, which he and I traced further. Summary: At a heap-limit check (typically an add-to-limit-causing-overflow), there are two kinds of general-purpose registers: 1. Live Pointers or Tagged Integers. These get a 1 in the register mask. 2. Dead Pointers, Live Untagged Integers, or anything else. These get a 0. Thus, a 0 in the mask does NOT indicate "dead." Registers with a 1 in the mask should be forwarded (if pointers) by the G.C., and registers with a 0 should be preserved unchanged. Unfortunately, the function "make_ml_sigh_arg" was not preserving the 0-in-the-mask registers, so that the string-creation function create_s was losing a register if a signal occurred. Code: Transcript: Comments: From: David.Tarditi@LAMBDA.ERGO.CS.CMU.EDU You write: > Thus, a 0 in the mask does NOT indicate "dead". Registers with a 1 > in the mask should be forwarded (if pointers) by the G.C., and > registers with a 0 should be preserved unchanged. > > Unfortunately, the function "make_ml_sigh_arg" was not preserving the > 0-in-the-mask registers, so that the string-creation function create_s > was losing a register if a signal occurred. Is having ml_sigh_arg preserve all registers the right thing to do ? Maybe we should enforce the invariant that a 0 in the mask indicates "dead" ? The argument for doing this is that it makes signal handling cheaper in both time and space. Right now, make_ml_sigh_arg only has to save the number of used registers. It scans each bit in the mask to determine which registers to save until the remainder of the mask is 0, so it takes less time also, if live registers tend to be the lower numbered registers (as they do with the current register allocator). The argument for not doing this is that is allows us to do "representation analysis", i.e. place untagged integers in registers across procedure boundaries. I don't know what the performance gain from this will be. Dave From: Andrew Appel John Reppy has found that signal-handling overhead isn't too bad (3% for 20-millisecond timer interrupts on a SPARC), and saving a few extra register shouldn't make a huge difference. I would certainly hate to rule out passing untagged integers across procedure boundaries. Fix: Status: not a bug (yet) --------------------------------------------------------------------------- Number: 382 Title: missing \n on infix echo Keywords: printing, top level Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: 6/11/91 Version: 0.69 System: Severity: minor Problem: First, a trivial one: the top-level omits the \n when echoing global infix declarations: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - infix operator; infix operator- (In 0.65, infix declarations weren't being printed at all.) Comments: Fix: insert newline() at end of printFixity function in print/printdec.sml Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 383 Title: open in nested structures fails with "Runbind" Keywords: modules, Runbind Submitter: Eric Cooper (ecc@cs.cmu.edu) Date: 6/11/91 Version: 0.69 System: Severity: major Problem: The "print x" below fails with exception "Runbind". Code: structure S = struct val x = 0 end; structure SS = struct structure S = S end open S; open SS; print x; (* fails with exception Runbind *) Transcript: Comments: This worked OK in 0.65. Among other things, Paulson's Isabelle examples now fail to compile, which is how I tripped over this. Fix: Appel partially diagnosed this, sent mail to MacQueen Status: fixed in 0.73 --------------------------------------------------------------------------- Number: 384 Title: signal handler never re-installed Keywords: signals Submitter: Manuel Fahndrich (mf39@andrew.cmu.edu) Date: 6/4/91 Version: 0.66 0.67 System: DECstation 3100 (Mach and BSD UNIX 4.3) Problem: The signal handlers only get called the first time they are installed. Once setHandler(signal, NONE) is executed and then setHandler(signal, SOME handler), the signal is ignored. Tested on signals (SIGIO, SIGINT, SIGALRM) Transcript: fun ioh (_, k) = (print "SIGIO\n"; k); System.Signals.setHandler (System.Signals.SIGIO, SOME ioh); System.Signals.setHandler (System.Signals.SIGIO, NONE); System.Signals.setHandler (System.Signals.SIGIO, SOME ioh); Comment: The inqHandler returns the correct handler function at the end. [jgm] The following code really exercises the bug: open System.Signals; setHandler(SIGINT, NONE); inqHandler(SIGINT); (* core dumps *) Code for setHandler and inqHandler is simple enough to figure that the bug is probably in the code generator -- it's broken on Mach and Irix, so the OS is not to blame. Also, ripping the signal handling code in perv.sml out and compiling it on top of the pervasives makes the bug go away. (1) Suppose we do : open System.Signals; open System.Timer; val setitimer = System.Unsafe.CInterface.setitimer; fun setTimer msec = (setitimer(0,TIME{sec=0,usec=1000*msec}, TIME{sec=0,usec=1000*msec})); setHandler(SIGALRM,SOME(fn (_,k) => (print "hi!\n";k))); setTimer 500; This will print hi! twice a second (on cs or elan) or (roughly speaking) when return is hit (on haven), more or less as expected. (2) Now suppose we do : setHandler(SIGALRM,NONE); setHandler(SIGALRM,SOME(fn (_,k) => (print "lo!\n";k))); On all machines, this has no visible effect; that is, lo! is not printed. (3) But if we then do: System.Unsafe.CInterface.c_function "enablesig" (3,true); we do start seeing lo! just as we saw hi! before. Finally, and most excitingly, if we do (1) followed by: setHandler(SIGALRM,NONE); inqHandler SIGALRM; we get the following results: on haven and k2 (both versions): Bus Error on elan: - Fixed up unaligned data access for pid 16679 (sml) at pc 0x417ed0 val it = SOME fn : (int * (unit) cont -> (unit) cont) option on cs: val it = SOME fn : (int * (unit) cont -> (unit) cont) option [jgm] See bug 397 for the probable cause... Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 385 Title: SIGHUP, SIGQUIT, SIGTERM ignored sometimes Keywords: signals Submitter: Mark Foster (mark@central.cis.upenn.edu) Date: 11/15/90 Version: 0.66 System: Severity: minor Problem: It appears that some signals get ignored when they shouldn't. In particular, SIGHUP SIGQUIT and SIGTERM don't get properly delivered when the parent process of sml exits in certain ways. As a result, the sml process remains, sometimes dormant, and sometimes in a spin loop (continuous select() calls, trying to output a message, but it can't because it's psuedo tty is "gone"). The easiest way we've found to demonstrate the problem is via telnet % telnet me Trying 127.0.0.1 ... Connected to LOCALHOST.UPENN.EDU. Escape character is '^]'. (login stuff deleted) % sml Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - now, escape back to telnet, then close the connection ^] telnet> c the sml process does not exit. WORKAROUNDS: We have two possible workarounds to this problem. Fundamentally, the output that's trying to happen probably needs to be fixed. Either to detect when it cannot successfully output or to just give up at some point. The following two approaches don't do fix the problem, they just bandaid around it. Both methods "cure" the problems we've been experiencing. Method 1: Change runtime/signal.c to disallow redefining of the signals used to shutdown a child process % diff signal.c.orig signal.c 210c210,214 < case ML_SIG_ENABLED: SETSIG (sig, sig_handler, SIGMASK); break; --- > case ML_SIG_ENABLED: if ((sig != SIGQUIT) && > (sig != SIGHUP) && (sig != SIGTERM)) { > SETSIG (sig, sig_handler, SIGMASK); > } > break; 234c238,241 < SETSIG (sig, sig_handler, SIGMASK); --- > if ((sig != SIGQUIT) && > (sig != SIGHUP) && (sig != SIGTERM)) { > SETSIG (sig, sig_handler, SIGMASK); > } Method 2: Change boot/perv.sml to not attempt to output a message on quit % diff perv.sml.orig perv.sml 1871,1873c1871 < fun quit s _ = ( < output(std_err, s); output(std_err, " (no coredump)\n"); < System.Unsafe.CleanUp.shutdown()) --- > fun quit s _ = (System.Unsafe.CleanUp.shutdown()) >Date: Sun, 18 Nov 90 09:58:41 -0500 >From: jhr@cs.cornell.edu (John Reppy) >Subject: Re: signal info from Mark Foster at Penn. I've seen this effect, but I never thought about it enough to realize what was going on. His first solution is an awkward way to say the ML can't handle SIGHUP, SIGQUIT and SIGTERM; I like to avoid that. His second solution is better; but there probably should be a warning somewhere abut the problems with SIGHUP. - John From: jhr@cs.cornell.edu (John Reppy) Subject: Re: signal info from Mark Foster at Penn. Cc: mark@central.cis.upenn.edu I think that this problem is a bug in the way select works. If you do a select on a closed file, it fails with EBADF; I think it should do the same if the ptty has gone away. But we live in an imperfect world, so I recommend the following fix: Replace the function quit (at the end of perv.sml) with the following code: fun quit s _ = let val msg = (s ^ " (no coredump)\n\000") in (* use write, since IO.output will block if we've lost the ptty *) System.Unsafe.SysIO.write(2, System.Unsafe.cast msg, size msg) handle _ => (); System.Unsafe.CleanUp.shutdown() end Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 386 Title: printing bug with abstype Keywords: types, abstypes, printing Submitter: *jhr$ Date: 11/8/90 Version: 0.69 System: Severity: minor Problem: Notice the misplaced white space: - abstype 'a foo = Foo of 'a with end; type'a foo Code: Transcript: Comments: Fix: search for "type" in print/printdec.sml (also "eqtype") Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 387 Title: arrays on Sparc Keywords: arrays, sparc Submitter: ark Date: 2/12/91 Version: 0.66 System: Sparcstation Severity: major Problem: dumps core when allocating large array Code: array(10000000,0) Transcript: Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 388 Title: * as label of record Keywords: Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk) Date: 11/8/90 Version: System: Severity: minor Problem: SML/NJ doesn't allow { * = "Hello" } as an expression. It should; after all, "*" is (chortle) just an ordinary identifier. Code: Transcript: Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 389 Title: stats Keywords: measurement Submitter: Andrew Appel (appel@princeton.edu) Date: 4/3/91 Version: 0.66-0.69 System: Severity: minor Problem: Bug report: versions 0.66-0.69 System.Stats.execution (as reported in "summary()") starts out negative. Caused by the following sequence in "interact.sml": t := current cpu usage; exportML; t' := current cpu usage; System.Stats.execution := t'-t But of course, t' is less than t IN THE NEW PROCESS. Code: Transcript: Comments: Fix: Appel has a fixt for this that will go into 0.70 Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 390 Title: Keywords: Submitter: bpwing@phoenix.princeton.edu Date: 3/19/91 Version: 0.65-0.69 System: SUN 4, v4.1? Severity: minor Problem: when reporting error positions, tabs are treated as single characters instead of being expanded Comments: [jgm -- this seems correct to me...] Status: not a bug --------------------------------------------------------------------------- Number: 391 Title: truncate Keywords: Submitter: David Taridti (dtarditi@cs.cmu.edu) Date: 4/10/91 Version: 0.69 System: Severity: major Problem: The function truncate does not work properly for large real numbers. For example, truncate of 4 billion yields a negative integer when it should raise the exception Overflow: Code: Transcript: Standard ML of New Jersey, Version 0.69, 3 April 1991 val it = () : unit - truncate(4000000000.0); val it = ~294967296 : int Comments: Status: fixed in 0.71 --------------------------------------------------------------------------- Number: 392 Title: two type constraints Keywords: types, syntax Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk) Date: 11/14/90 Version: 0.66 System: Severity: minor Problem: As I understand the Definition, Poly/ML is correct. Two type constraints might be handy if the program involves a lot of type synonyms. Comments? Code: Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 - 0 : int : int; std_in:2.9 Error: syntax error found at COLON Poly/ML v1.89 - Definition of SML Version 4 > 0 : int : int; val it = 0 : int Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 393 Title: type abbreviations not transparent Keywords: types, type abbreviations Submitter: Chris Okasaki (cokasaki@cs.cmu.edu) Date: 11/16/90 Version: 0.65 Severity: minor Problem: type abbreviations not transparent In particular, when the type abbreviation takes an argument which does not appear on the right hand side of the abbreviation, any type which appears in that position should be completely irrelevant. But in the current implementation this is not true. Code: type ('a,'b) bogus = 'a; val x = 0 : (int,int) bogus; (* really int *) val y = 1 : (int,int list) bogus; (* really int *) fun f (x:'a,y:'a) = (); (* force the types to unify *) f (x,y); (* unify (int,int) bogus and (int,int list) bogus *) (* should be equivalent to unifying int with int *) (* but it's not *) Transcript: Standard ML of New Jersey, Version 0.65, 10 September 1990 val it = () : unit - type ('a,'b) bogus = 'a; type ('a,'b) bogus = 'a - val x = 0 : (int,int) bogus; val x = 0 : (int,int) bogus - val y = 1 : (int,int list) bogus; val y = 1 : (int,int list) bogus - fun f (x:'a,y:'a) = (); val f = fn : 'a * 'a -> unit - f (x,y); std_in:3.1-3.7 Error: operator and operand don't agree (tycon mismatch) operator domain: (int,int) bogus * (int,int) bogus operand: (int,int) bogus * (int,int list) bogus in expression: f (x,y) - Comments: Interestingly enough, this doesn't seem to happen when you have a unary type abbreviation like type 'a bogus = int The problem seems to boil down to WHEN you project through abbreviations (i.e. when you do the "macro" expansion). There seems to be at least two possibilities, project through before a unification containing this type, or attempt to unify with this type and project through only if this fails. As long as every argument to the type abbreviation also appears in the expanded form, the two are equivalent. When an argument DOESN'T appear in expanded form, the second approach (which is the approach currently being used) causes problems. As is evident in the above example, it causes the typechecker to unify things which should not be unified. The following code from unify.sml (in unifyTy) is where the problem is: | (CONty(tycon1, args1), CONty(tycon2, args2)) => if eqTycon(tycon1, tycon2) -----> then unifyArgs(args1, args2) else (unifyTy(reduceType ty1, ty2) handle ReduceType => unifyTy(ty1, reduceType ty2) handle ReduceType => raise Unify("tycon mismatch")) The point marked is where the damage is done. If both types have the same abbreviation constructor, unification will blithely go ahead and try to unify ALL of the arguments, even though some of them might be irrelevant because they are unused. Fix: Three possibilities: 1. Decide that this is a "feature", that you really don't want (int,int) bogus to unify with (int,int list) bogus. However, I would argue that if this is what you want, you should be using the datatype facility, not the type facility. 2. Forbid type abbreviations which do not use all their arguments. This is somewhat unsatisfying since, although human programmers will probably not produce abbreviations like this, it is easy to imagine automatic programming utilities (like Lex or Yacc) that MIGHT produce such code. 3. Perform abbreviation expansion BEFORE unifying an abbreviated type with anything except a type variable (you would want to unify the type variable with the abbreviated type so that it can be printed correctly). The best way to do this is probably to define a new constructor for the type "ty" called something like ABBREVty of tycon * tylist * ty where the tycon is the abbreviation constructor tylist are the constructor's arguments and ty is the "macro expanded" type Then, in unifyTy, you could have (right after the two VARty clauses) | (ABBREVty(_,_,ty),_) => unifyTy(ty,ty2) | (_,ABBREVty(_,_,ty)) => unifyTy(ty1,ty) to project through the abbreviation appropriately. The catch to this is that you can then produce circular types so you would have to perform an occur check during type printing. For instance, consider the following: type ('a,'b) bogus; fun f (x:'b,y:('a,'b) bogus) = (); fun g x = f (x,x); What is the type of g? Really, it's 'a->unit but internally it's something like (pardon the abuse of notation): ABBREVty(bogus,['a,*],'a) --> unit where the * marks a circular reference back to the ABBREVty object. Obviously, a naive attempt to print this type will infinite loop-- hence the requirement for an occur check during type printing. Status: fixed in 0.74 (dbm) --------------------------------------------------------------------------- Number: 394 Title: strange message in 0.66 typechecker Keywords: types, type checking Submitter: John Reppy (jhr@cs.cornell.edu) Date: 11/6/90 Version: 0.66 Severity: minor Code: Transcript: Standard ML of New Jersey, Version 0.66, 15 September 1990 val it = () : unit - signature SAMPLER = = sig = type time sharing type time = System.Timer.time = val init : unit -> unit = val sample : (time * int * int) -> unit = end; signature SAMPLER = sig isEqTycon 1 UNDEF type time val init : unit -> unit val sample : time * int * int -> unit end - Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 395 Title: weakness constraint problem Keywords: types, weak types, modules, signatures, functors Submitter: John Reppy (jhr@cs.cornell.edu) Date: 3/18/91 Problem: I'm having trouble with a weakness constraint, and I don't understand it. I have a function at top-level of a module, which the typechecker gives the type val attach : 'aU CML.chan * widget_t * mbutton_t * 'aU menu_t -> widget_t My memory is that the 'aU is an internal type variable? Anyway, attach calls another function taht also has an 'aU in its type; by adding a type constraint to the other function, then things compile. Anyway, this seems like a bug (and I think I've run into it before). Code: Transcript: Comments: Here is a smaller example that triggers the bug. The offending line is marked by "(** THIS DOESN'T WORK **)" signature INTERNAL_CML = sig type 'a event val sync : 'a event -> 'a end functor ConcurML () : INTERNAL_CML = struct exception Never and Escape exception Sync (* for signature compatability *) datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK type 'a base_evt = { pollfn : unit -> evt_sts, dofn : unit -> 'a, blockfn : bool ref -> 'a } datatype 'a event = EVT of 'a base_evt list local datatype 'a ready_evts = NO_EVTS (* no ready events *) | ANY_EVTS of (int * (unit -> 'a) list) (* list of ready anyevents *) | RDY_EVTS of (int * (unit -> 'a) list) (* list of ready events *) fun extract _ = NO_EVTS (* Generate index numbers for "non-deterministic" selection. We use a * round-robin style policy. *) val cnt = ref 0 fun random i = let val j = !cnt in cnt := j+1; (j mod i) end fun selectEvt (_, [f]) = f() | selectEvt (n, l) = (nth(l, random n)) () in (* sync : 'a event -> 'a *) fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **) (*fun sync ((EVT []) : 'a event) = raise Never*) (** THIS WORKS **) | sync (EVT el) = ( case (extract el) of NO_EVTS => callcc (fn sync_k => let val evtflg = ref false fun log ({blockfn, ...} : 'a base_evt)= (throw sync_k (blockfn evtflg)) handle Escape => () in app log el; (*atomicDispatch()*) raise Sync end) | ANY_EVTS anyevts => selectEvt anyevts | RDY_EVTS evts => selectEvt evts) end (* local *) end (* functor ConcurML *) Comment: This is really the way that user-bound type variables are supposed to work! Status: not a bug --------------------------------------------------------------------------- Number: 396 Title: unbound variables should have type ERRORty Keywords: types, error recovery Submitter: Dave MacQueen (dbm@research.att.com) Date: 5/7/91 Version: 0.66? Severity: minor Problem: An unbound variable should have type ERRORty rather than UNDEFty so that spurious secondary errors can be avoided. E.g. foo 3; Error: unbound variable foo Error: operator is not a function operator: undef in expression foo 3 Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 397 Title: Unsafe.update with constant Keywords: Submitter: Andrew Tolmach (apt@princeton.edu) Date: 3/18/91 Version: 0.69 System: Mips Severity: critical Problem: from Appel: Andrew Tolmach discovered the following bug, and I've tracked it down. Unsafe.update is unreliable on the MIPS when the value stored is a constant. (The same temporary is used twice in mips.sml). I'll fix this for the next version; in the meantime, use Array.update. Code: Transcript: Comments: [jgm] This is probably causing the bug in the signal handling routines. See bug 384 Fix: Appel and Tolmach have the fix, will install in 0.70 Status: fixed in 0.70 --------------------------------------------------------------------------- Number: 398 Title: use and pathnames Keywords: use, pathnames Submitter: ark Date: 5/13/91 Version: 0.66 Severity: minor Problem: A reminder: SML still doesn't interpret pathnames in "use" calls relative to the correct directory. Comments: Should be taken over by sourcegroup mechanisms. Fix: make "use" accumulate filepaths (using filepaths.sig) Owner: Status: open --------------------------------------------------------------------------- Number: 399 Title: Vax dumps core Keywords: vax Submitter: David Tarditi (dtarditi@cs.cmu.edu) Date: 3/14/91 Version: 0.67 System: Vax Severity: critical Problem: The following piece of code causes version 0.67 of the compiler to dump core on Vaxes running Mach: - val s = "a"; - s; Segmentation fault (core dumped) Code: Transcript: Comments: Fix: Status: fixed in 0.69 --------------------------------------------------------------------------- Number: 400 Title: problem parsing weak types Keywords: types, weak types, parsing Submitter: John Ophel jlophel@watmsg.waterloo.edu Date: 9/11/90 Version: 0.66 System: Vax, Unix Severity: minor Problem: weak type variables incorrectly parsed Transcript: - fun f (x:'10000000a) = x; val f = fn : 'a -> 'a - fun f (x:'10000001a) = x; std_in:1.5-1.24 Error: pattern and constraint don't agree (weakness violation) pattern: 'Z constraint: '10000001aU in pattern: x : '10000001aU Fix: In mkUBOUND (basics/typesutil.sml), weakness of more than 900000 should be illegal. Also note that the type variable '10000000000000a will cause an uncaught Overflow, which should be caught in this function. Status: fixed in 0.71 ---------------------------------------------------------------------------