Translate, compile, evaluate, interpret

In documentation and text books the words 'translate', 'compile', 'evaluate' and 'interpret' are abundant, but they have subtly distinct meanings. Is there somewhere an article describing the subtle differences?

I'm not aware of one. Here's how I used the terms, I'd love to be educated.

  • Translate : I'm not aware of a programming-specific definition of this term.
  • Evaluate / Interpret : In the context of a programming languages course, I use these interchangeably. To "interpret" or "evaluate" a program or expression is to map that program or expression to its meaning. Put differently, to "run" the program. If I "interpret" the racket expression (+ 3 4) I get the result 7.
  • Compile : In the context of programming, I use the term "compile" to refer to the process of translating a program or expression in one language into an equivalent program in another, typically lower-level language. If I compile the program
#lang racket
(+ 3 4)

using raco make and then take a look at the output using raco decompile, I get this on my Arm64 machine:

(module foo ....
  (require (lib "racket/main.rkt"))
  (provide)
  (define /tmp/foo.rkt:3:0
    (lambda ()
      "/tmp/compiled/foo.rkt:3:1"
      (#%assembly-code
       "       0: ff0200f1                       (subs xzr x23 #x0)"
       "       4: 81000054                       (b.ne (+ pc #x10)) ; => 14"
       "       8: 170780d2                       (movz x23 #x38)"
       "       c: 8a0240f8                       (ldur x10 (mem+ x20))"
       "      10: 40011fd6                       (br x10)"
       "      14: 0a668bd2                       (movz x10 #x5b30) ; #<code doargerr> ; <="
       "      18: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
       "      1c: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
       "      20: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
       "      24: 40011fd6                       (br x10)"
       "")))
  (define ....
    (lambda ()
      (#%assembly-code
       "       0: d60600f1                       (subs x22 x22 #x1)"
       "       4: a0020054                       (b.eq (+ pc #x54)) ; => 58"
       "       8: ff0200f1                       (subs xzr x23 #x0)"
       "       c: c1010054                       (b.ne (+ pc #x38)) ; => 44"
       "      10: a0ad8dd2                       (movz x0 #x6d6d) ; #<procedure:/tmp/foo.rkt:3:0>"
       "      14: e0b4a1f2                       (movk x0 (lsl #xda7 #x10))"
       "      18: 2000c0f2                       (movk x0 (lsl #x1 #x20))"
       "      1c: 0000e0f2                       (movk x0 (lsl #x0 #x30))"
       "      20: 41b340f8                       (ldur x1 (mem+ x26 #xb))"
       "      24: 78b396d2                       (movz x24 #xb59b) ; '#%call-with-values"
       "      28: b820a1f2                       (movk x24 (lsl #x905 #x10))"
       "      2c: 3800c0f2                       (movk x24 (lsl #x1 #x20))"
       "      30: 1800e0f2                       (movk x24 (lsl #x0 #x30))"
       "      34: 1a5340f8                       (ldur x26 (mem+ x24 #x5))"
       "      38: 570080d2                       (movz x23 #x2)"
       "      3c: 0ad340f8                       (ldur x10 (mem+ x24 #xd))"
       "      40: 40011fd6                       (br x10)"
       "      44: 0a668bd2                       (movz x10 #x5b30) ; #<code doargerr> ; <="
       "      48: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
       "      4c: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
       "      50: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
       "      54: 40011fd6                       (br x10)"
       "      58: 0a7690d2                       (movz x10 #x83b0) ; #<code event-detour> ; <="
       "      5c: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
       "      60: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
       "      64: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
       "      68: 40011fd6                       (br x10)"
       "")))
  (#%assembly-code
   "       0: d60600f1                       (subs x22 x22 #x1)"
   "       4: e0060054                       (b.eq (+ pc #xdc)) ; => e0"
   "       8: ff1200f1                       (subs xzr x23 #x4)"
   "       c: 01060054                       (b.ne (+ pc #xc0)) ; => cc"
   "      10: 8f0640f9                       (ldr x15 (mem+ x20 (lsl #x1 #x3)))"
   "      14: 7e4a40f9                       (ldr x30 (mem+ x19 (lsl #x12 #x3)))"
   "      18: 9f021eeb                       (subs xzr x20 x30)"
   "      1c: c2040054                       (b.cs (+ pc #x98)) ; => b4"
   "      20: b80e00d1                       (sub x24 x21 #x3) ; <="
   "      24: b5420091                       (add x21 x21 #x10)"
   "      28: 7e5240f9                       (ldr x30 (mem+ x19 (lsl #x14 #x3)))"
   "      2c: df0315eb                       (subs xzr x30 x21)"
   "      30: 63030054                       (b.cc (+ pc #x6c)) ; => 9c"
   "      34: e00318aa                       (orr x0 xzr x24) ; <="
   "      38: 1e6a8fd2                       (movz x30 #x7b50) ; #<code>"
   "      3c: 3ec0a1f2                       (movk x30 (lsl #xe01 #x10))"
   "      40: 3e00c0f2                       (movk x30 (lsl #x1 #x20))"
   "      44: 1e00e0f2                       (movk x30 (lsl #x0 #x30))"
   "      48: 1e3000f8                       (stur x30 (mem+ x0 #x3))"
   "      4c: 0fb000f8                       (stur x15 (mem+ x0 #xb))"
   "      50: 94220091                       (add x20 x20 #x8)"
   "      54: 78eb84d2                       (movz x24 #x275b) ; 'call-with-module-prompt"
   "      58: 3821a1f2                       (movk x24 (lsl #x909 #x10))"
   "      5c: 3800c0f2                       (movk x24 (lsl #x1 #x20))"
   "      60: 1800e0f2                       (movk x24 (lsl #x0 #x30))"
   "      64: 1a5340f8                       (ldur x26 (mem+ x24 #x5))"
   "      68: 3e010010                       (adr x30 (+ pc #x24)) ; => 8c"
   "      6c: 9e0200f9                       (str x30 (mem+ x20 (lsl #x0 #x3)))"
   "      70: 370080d2                       (movz x23 #x1)"
   "      74: 0ad340f8                       (ldur x10 (mem+ x24 #xd))"
   "      78: 40011fd6                       (br x10)"
   "      7c: bd00000000000000               (data)"
   "      84: 0500000000000000               (data)"
   "      8c: 942200d1                       (sub x20 x20 #x8) ; <="
   "      90: d70580d2                       (movz x23 #x2e)"
   "      94: 8a0240f8                       (ldur x10 (mem+ x20))"
   "      98: 40011fd6                       (br x10)"
   "      9c: 0a7889d2                       (movz x10 #x4bc0) ; #<code get-room> ; <="
   "      a0: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
   "      a4: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
   "      a8: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
   "      ac: 40013fd6                       (blr x10)"
   "      b0: e1ffff17                       (b (+ pc #x-7c)) ; => 34"
   "      b4: 0a188ad2                       (movz x10 #x50c0) ; #<code dooverflow> ; <="
   "      b8: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
   "      bc: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
   "      c0: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
   "      c4: 40013fd6                       (blr x10)"
   "      c8: d6ffff17                       (b (+ pc #x-a8)) ; => 20"
   "      cc: 0a668bd2                       (movz x10 #x5b30) ; #<code doargerr> ; <="
   "      d0: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
   "      d4: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
   "      d8: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
   "      dc: 40011fd6                       (br x10)"
   "      e0: 0a7690d2                       (movz x10 #x83b0) ; #<code event-detour> ; <="
   "      e4: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
   "      e8: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
   "      ec: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
   "      f0: 40011fd6                       (br x10)"
   "")
  (module (foo configure-runtime) ....
    (require '#%kernel (lib "racket/runtime-config.rkt"))
    (provide)
    (#%assembly-code
     "       0: d60600f1                       (subs x22 x22 #x1)"
     "       4: a0040054                       (b.eq (+ pc #x94)) ; => 98"
     "       8: ff1200f1                       (subs xzr x23 #x4)"
     "       c: c1030054                       (b.ne (+ pc #x78)) ; => 84"
     "      10: 7e4a40f9                       (ldr x30 (mem+ x19 (lsl #x12 #x3)))"
     "      14: 9f021eeb                       (subs xzr x20 x30)"
     "      18: a2020054                       (b.cs (+ pc #x54)) ; => 6c"
     "      1c: c00180d2                       (movz x0 #xe) ; <="
     "      20: 94220091                       (add x20 x20 #x8)"
     "      24: 78d98fd2                       (movz x24 #x7ecb) ; '1/print-as-expression"
     "      28: 3820a1f2                       (movk x24 (lsl #x901 #x10))"
     "      2c: 3800c0f2                       (movk x24 (lsl #x1 #x20))"
     "      30: 1800e0f2                       (movk x24 (lsl #x0 #x30))"
     "      34: 1a5340f8                       (ldur x26 (mem+ x24 #x5))"
     "      38: 3e010010                       (adr x30 (+ pc #x24)) ; => 5c"
     "      3c: 9e0200f9                       (str x30 (mem+ x20 (lsl #x0 #x3)))"
     "      40: 370080d2                       (movz x23 #x1)"
     "      44: 0ad340f8                       (ldur x10 (mem+ x24 #xd))"
     "      48: 40011fd6                       (br x10)"
     "      4c: 8d00000000000000               (data)"
     "      54: 0500000000000000               (data)"
     "      5c: 942200d1                       (sub x20 x20 #x8) ; <="
     "      60: d70580d2                       (movz x23 #x2e)"
     "      64: 8a0240f8                       (ldur x10 (mem+ x20))"
     "      68: 40011fd6                       (br x10)"
     "      6c: 0a188ad2                       (movz x10 #x50c0) ; #<code dooverflow> ; <="
     "      70: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
     "      74: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
     "      78: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
     "      7c: 40013fd6                       (blr x10)"
     "      80: e7ffff17                       (b (+ pc #x-64)) ; => 1c"
     "      84: 0a668bd2                       (movz x10 #x5b30) ; #<code doargerr> ; <="
     "      88: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
     "      8c: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
     "      90: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
     "      94: 40011fd6                       (br x10)"
     "      98: 0a7690d2                       (movz x10 #x83b0) ; #<code event-detour> ; <="
     "      9c: ea02a1f2                       (movk x10 (lsl #x817 #x10))"
     "      a0: 2a00c0f2                       (movk x10 (lsl #x1 #x20))"
     "      a4: 0a00e0f2                       (movk x10 (lsl #x0 #x30))"
     "      a8: 40011fd6                       (br x10)"
     "")))

Is any of this surprising or controversial to you? Probably not?

No, it does not surprise me. Thanks for your contribution. The decompilation in your example shows binary code (rather hexonal) along with assembler code. Should we call it 'disassemble'? :wink: I tend to use the word 'evaluator' for a program that reduces an expression without side side effects to an irreducible term and the word 'interpreter' for a program that does what is implied by the expressions, side effects included. NB, in common life an interpreter translates only and certainly is not allowed to do what may be implied by the translated sentences.

To add:

Compilers and assemblers translate only without execution of the program being compiled or assembled. A peculiar thing is that an assembler may produce information about its doing. For example, long ago, I made an assembler code that made the assembler produce the solution of finding the shortest way of moving a tower of Hanoi. It gave the solution without actually running the assembled program. (I used the powerful COMPASS of a CDC6000 machine.) Question: using the assembler this way, was it an assembler or an evaluator?

I found the explanations ‘Evaluators’ on page 15 of Programming Languages: Application and Interpretation (version 3.2.0) to be helpful;

image| ‘Evaluators’ on page 15 of Programming Languages: Application and Interpretation (version 3.2.0)
https://www.plai.org/3/2/PLAI%20Version%203.2.0%20electronic.pdf#page15

Best regards

Stephen

Thanks, I saw it. Shriram Krishnamurthi states that there is no bright line.
I think I agree with him.

1 Like