ocaml to python

Jon Harrop jon at ffconsultancy.com
Mon Feb 19 14:27:40 EST 2007


Gigs_ wrote:
> Is there any way to convert ocaml code to python? but not manually

Translating between dissimilar high-level languages is very difficult, so
difficult that it is hard to do such a task justice by hand, let alone
automating the procedure.

If you must do it then write a compiler that converts OCaml's intermediate
representation into Python (after pattern match compilation), or write an
OCaml bytecode interpreter in Python.

For example, the following simple OCaml code is difficult to write in
Python:

let rec ( +: ) f g = match f, g with
  | `Q n, `Q m -> `Q (n +/ m)
  | `Q (Int 0), e | e, `Q (Int 0) -> e
  | f, `Add(g, h) -> f +: g +: h
  | f, g -> `Add(f, g)

let rec ( *: ) f g = match f, g with
  | `Q n, `Q m -> `Q (n */ m)
  | `Q (Int 0), e | e, `Q (Int 0) -> `Q (Int 0)
  | `Q (Int 1), e | e, `Q (Int 1) -> e
  | f, `Mul(g, h) -> f *: g *: h
  | f, g -> `Mul(f, g)

let rec simplify = function
  | `Q _ | `Var _ as e -> e
  | `Add(f, g) -> simplify f +: simplify g
  | `Mul(f, g) -> simplify f *: simplify g;;

OCaml compiles the pattern matches first, which gives an intermediate
representation much closer to something Python/Lisp can handle:

(seq
  (letrec
    (+:/71
       (function f/72 g/73
         (catch
           (catch
             (if (isint f/72) (exit 3)
               (if (!= (field 0 f/72) 81) (exit 3)
                 (let (n/74 (field 1 f/72))
                   (catch
                     (if (isint g/73) (exit 4)
                       (if (!= (field 0 g/73) 81) (exit 4)
                         (makeblock 0 81
                           (apply (field 0 (global Num!)) n/74
                             (field 1 g/73)))))
                    with (4)
                     (switch n/74
                      case tag 0: (if (!= (field 0 n/74) 0) (exit 3) g/73)
                      default: (exit 3))))))
            with (3)
             (if (isint g/73) (exit 2)
               (let (variant/113 (field 0 g/73))
                 (if (!= variant/113 81)
                   (if (!= variant/113 3254785) (exit 2)
                     (let (match/112 (field 1 g/73))
                       (apply +:/71 (apply +:/71 f/72 (field 0 match/112))
                         (field 1 match/112))))
                   (let (match/110 (field 1 g/73))
                     (switch match/110
                      case tag 0:
                       (if (!= (field 0 match/110) 0) (exit 2) f/72)
                      default: (exit 2)))))))
          with (2) (makeblock 0 3254785 (makeblock 0 f/72 g/73)))))
    (apply (field 1 (global Toploop!)) "+:" +:/71))
  (letrec
    (*:/83
       (function f/84 g/85
         (catch
           (catch
             (catch
               (catch
                 (catch
                   (if (isint f/84) (exit 10)
                     (if (!= (field 0 f/84) 81) (exit 10)
                       (let (n/86 (field 1 f/84))
                         (catch
                           (if (isint g/85) (exit 11)
                             (if (!= (field 0 g/85) 81) (exit 11)
                               (makeblock 0 81
                                 (apply (field 5 (global Num!)) n/86
                                   (field 1 g/85)))))
                          with (11)
                           (switch n/86
                            case tag 0:
                             (if (!= (field 0 n/86) 0) (exit 10) (exit 5))
                            default: (exit 10))))))
                  with (10)
                   (if (isint g/85) (exit 9)
                     (if (!= (field 0 g/85) 81) (exit 9)
                       (let (match/121 (field 1 g/85))
                         (switch match/121
                          case tag 0:
                           (if (!= (field 0 match/121) 0) (exit 9) (exit 5))
                          default: (exit 9))))))
                with (9)
                 (if (isint f/84) (exit 8)
                   (if (!= (field 0 f/84) 81) (exit 8)
                     (let (match/124 (field 1 f/84))
                       (switch match/124
                        case tag 0:
                         (if (!= (field 0 match/124) 1) (exit 8) g/85)
                        default: (exit 8))))))
              with (8)
               (if (isint g/85) (exit 7)
                 (let (variant/130 (field 0 g/85))
                   (if (!= variant/130 81)
                     (if (!= variant/130 3855332) (exit 7)
                       (let (match/129 (field 1 g/85))
                         (apply *:/83 (apply *:/83 f/84 (field 0 match/129))
                           (field 1 match/129))))
                     (let (match/127 (field 1 g/85))
                       (switch match/127
                        case tag 0:
                         (if (!= (field 0 match/127) 1) (exit 7) f/84)
                        default: (exit 7)))))))
            with (7) (makeblock 0 3855332 (makeblock 0 f/84 g/85)))
          with (5) [0: 81 [0: 0]])))
    (apply (field 1 (global Toploop!)) "*:" *:/83))
  (let
    (*:/83 (apply (field 0 (global Toploop!)) "*:")
     +:/71 (apply (field 0 (global Toploop!)) "+:"))
    (letrec
      (simplify/97
         (function e/98
           (let (variant/135 (field 0 e/98))
             (if (!= variant/135 3254785)
               (if (!= variant/135 3855332) e/98
                 (let (match/132 (field 1 e/98))
                   (apply *:/83 (apply simplify/97 (field 0 match/132))
                     (apply simplify/97 (field 1 match/132)))))
               (let (match/131 (field 1 e/98))
                 (apply +:/71 (apply simplify/97 (field 0 match/131))
                   (apply simplify/97 (field 1 match/131))))))))
      (apply (field 1 (global Toploop!)) "simplify" simplify/97))))

I suspect your best bet is to write an interface between the two (e.g.
XMLRPC) and keep the OCaml as OCaml.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists/index.html?usenet



More information about the Python-list mailing list