(* A modern optimizing compiler for a dynamically typed programming language: Standard ML of New Jersey (preliminary report) Ian Zerny http://www.zerny.dk/dynamic-ml.html SIGBOVIK, CMU, Pittsburgh April 1, 2012 The proceedings paper presents Dynamic ML and shows how it outperforms existing dynamic languages. In this presentation we will look at what Dynamic ML gives us. The subtitle for the talk is: Program based Semantic Synthesis: write the desired program---derive the needed semantics Note to reader: This file contains the final result from the SIGBOVIK 2012 talk and does not detail the development. The "desired program"s are at the end of the file. They guided the derivation of the "needed semantics" in the MySem module below. So, skip to the end of the file to see where things start. To compile this file requires an installation of Dynamic ML found on the project website: http://www.zerny.dk/dynamic-ml.html **************************************************************** *) (* MySem is the derived "needed semantics" for Dynamic ML. *) structure MySem = struct (* helper to decompose a string to a number and its context *) fun decomp s = let fun return (ds, pre, post) = (case Num.fromString (implode (rev ds)) of NONE => NONE | SOME n => SOME (n, fn m => implode (rev pre) ^ Num.toString m ^ implode post)) fun indig ([], ds, str) = return (ds, str, []) | indig (c :: cs, ds, str) = if Char.isDigit c then indig (cs, c :: ds, str) else return (ds, str, c::cs) fun instr ([], str) = NONE | instr (c :: cs, str) = if Char.isDigit c then indig (cs, [c], str) else instr (cs, c :: str) in instr (explode s, []) end (* runtime type coercion to a number *) fun asNUM d = (case d of NUM n => n | STR s => (case decomp s of NONE => DML.asNUM d | SOME (n, _) => n) | _ => DML.asNUM d) (* runtime type coercion to a string *) fun asSTR d = (case d of NUM n => Num.toString n | STR s => s | _ => DML.asSTR d) (* generalized equality *) fun x == y = (case (x, y) of (NUM n, _) => BOOL (n = asNUM y) | (_, NUM n) => BOOL (n = asNUM x) | (STR s, _) => BOOL (s = asSTR y) | (_, STR s) => BOOL (s = asSTR x) | p => DML.== p) (* generalized concatenation *) fun concat (x, y) = STR (asSTR x ^ " " ^ asSTR y) (* generalized subtraction *) fun x - y = (case (x, y) of p as (NUM n, STR s) => (case decomp s of NONE => raise TYPE_CAST_ERROR | SOME (m, k) => STR (k (Num.- (n, m)))) | p as (STR s, NUM n) => (case decomp s of NONE => raise TYPE_CAST_ERROR | SOME (m, k) => STR (k (Num.- (m, n)))) | p => raise TYPE_CAST_ERROR) (* generalized addition *) fun x + y = (case (x, y) of p as (NUM x, NUM y) => DML.+ p | p as (STR s, NUM n) => (case decomp s of NONE => concat p | SOME (m, k) => STR (k (Num.+ (m, n)))) | p as (NUM n, STR s) => (case decomp s of NONE => concat p | SOME (m, k) => STR (k (Num.+ (n, m)))) | p as (STR s1, STR s2) => (case (decomp s1, decomp s2) of (SOME (n1, k1), SOME (n2, k2)) => STR (k1 (Num.+ (n1, n2))) | _ => concat p) | p => concat p) end (* ************************************************************** *) local open MySem in (* Our motivating programs: The intended results should be self explanatory *) val s1 = STR "I've got" val s2 = STR "trombones" val s3 = s1 + s2 val s4 = s1 + NUM 10 val s5 = s4 + NUM 1 val s6 = STR "10" + NUM 1 val s7 = STR "I've got 10 trombones" + NUM 1 val s8 = STR "I've got 10 trombones" + NUM ~1 val s9 = STR "I've got 10 trombones" + STR "I've got 1 trombone" (* The Fibonacci function from the paper *) FUN fib[x] = IF x == NUM 0 THEN x ELSE IF x == NUM 1 THEN x ELSE fib$[x - NUM 1] + fib$[x - NUM 2] NUF (* Our semantics does indeed make sense! *) val profit = fib$[STR "I've got 10 trombones"] end