Thanks, Rob.  I've applied your patch.
David

On 09/01/2016 15:27, Rob Arthan wrote:
PolyML.addPrettyPrinter checks its printArgTypes parameter carefully
when you are installing a pretty-printer for a polymorphic type.
As far as I can see it guarantees type security for polymorphic types.

However, when you install a pretty-printer for a monomorphic type,
the parameter isn't checked at all. E.g., the following code doesn't
result in any error messages and ends by crashing poly.

datatype MONO = Mono of int;

fun pp_mono1 _ (i : int) (Mono j) = (
        PolyML.PrettyString (Int.toString (i + j))
);

PolyML.addPrettyPrinter pp_mono1;

Mono 42; (* Prints "val it = 42: MONO" - apparently i was 0 *)

fun pp_mono2 _ (r : int ref) (Mono _) = (
        PolyML.PrettyString (Int.toString (!r))
);

PolyML.addPrettyPrinter pp_mono2;

Mono 42; (* Crashes *)

Shouldn't processArgTypes be required to have type unit when
defining a pretty-printer for a monotype? The patch below
implements this check and tries to improve the error message
(which is already a bit misleading if you get something wrong
for a type with more than one parameter).

Regards,

Rob.

diff --git a/mlsource/MLCompiler/VALUE_OPS.ML b/mlsource/MLCompiler/VALUE_OPS.ML
index 1535d4f..9e00f0d 100644
--- a/mlsource/MLCompiler/VALUE_OPS.ML
+++ b/mlsource/MLCompiler/VALUE_OPS.ML
@@ -958,8 +958,8 @@ struct
                          val typeVars = List.tabulate(arity, fn _ => mkTypeVar 
(0, false, true, false))
                          val tupleType =
                              case typeVars of
-                                [] => (* No arg so we can have anything here. 
*)
-                                    mkTypeVar (generalisable, false, false, 
false)
+                                [] => (* No arg so must have unit. *)
+                                   unitType
                              |   [arg] => mkFn arg (* Just a single function. 
*)
                              |   args => mkProductType(List.map mkFn args)
                          val addPPType = mkFunctionType(argPrints, 
mkFunctionType(installType, pretty))
@@ -970,7 +970,7 @@ struct
                      in
                          checkPPType(addPPType, testType, "addPrettyPrint", 
lex, loc,
                              fn () =>
-                                PrettyString "addPrettyPrint element functions must 
have type 'a * int -> pretty")
+                                PrettyString "addPrettyPrint element functions must have 
type 'a * int -> pretty, 'b * int -> pretty, ... with one function for each type 
parameter")
                      end;

              (* Only report the error when the function is run.  Because 
addPrettyPrint is


_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to