> However, LISP is ultimately dynamically typed, while GOAL is statically typed. This means the compiler can generate fast code ahead of time, LISP can't.

LISP (of 1958) can't, but Lisp can. Optimizing compilers for Lisp were invented decades ago.

Surprise: Common Lisp has types and type declarations since day one (1984). The type system is not what you would expect from, say, Haskell. But it allows the developer to define and specify types.

Additionally one can set optimization policies (debug, space, safety, ...), declare functions to be compiled inline or request to have data stack allocated. And so on...

Compilers which take advantage of type declarations and type inference to create optimized code exist also since that time.

See the Common Lisp Hyperspec chapter on types:

http://www.lispworks.com/documentation/HyperSpec/Body/04_.ht...

> GOAL also does not use runtime garbage collection in the same way a LISP system does.

There are several Lisp systems which do similar things (manual memory management) like GOAL.
Mostly they were/are used to develop certain types of applications - like GOAL.

Let's see how sbcl, ( http://sbcl.org ) handles types at compile time: it clearly identifies and describes where it has not enough information for best optimization.

(declaim (optimize (speed 3) (debug 0)))

; a TYPE declaration

(deftype somebyte ()
`(integer 0 255))

; an untyped function

(defun add1 (a b)
(+ a b))

; declararing the types of function ADD2
; but one argument remains of general type.
; arguments are of type SOMEBYTE and T.
; T is the most general type.
; Return value has type SOMEBYTE.

(declaim (ftype (function (somebyte t) somebyte)
add2))

(defun add2 (a b)
(+ a b))

; declararing the types of function ADD3

(declaim (ftype (function (somebyte somebyte) somebyte)
add3))

(defun add3 (a b)
(+ a b))

You can now see what the LISP (sic!) compiler says, when it can't optimize the code:

* (compile-file "/tmp/test.lisp")

; compiling file "/private/tmp/test.lisp" (written 13 JAN 2017 09:15:03 AM):
; compiling (DECLAIM (OPTIMIZE # ...))
; compiling (DEFTYPE SOMEBYTE ...)
; compiling (DEFUN ADD1 ...)
; file: /private/tmp/test.lisp
; in: DEFUN ADD1
; (+ A B)
;
; note: forced to do GENERIC-+ (cost 10)
; unable to do inline float arithmetic (cost 2) because:
; The first argument is a T, not a DOUBLE-FLOAT.
; The second argument is a T, not a DOUBLE-FLOAT.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES DOUBLE-FLOAT
; &REST T).
; unable to do inline float arithmetic (cost 2) because:
; The first argument is a T, not a SINGLE-FLOAT.
; The second argument is a T, not a SINGLE-FLOAT.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES SINGLE-FLOAT
; &REST T).
; etc.

; compiling (DECLAIM (FTYPE # ...))
; compiling (DEFUN ADD2 ...)
; file: /private/tmp/test.lisp
; in: DEFUN ADD2
; (+ A B)
;
; note: forced to do GENERIC-+ (cost 10)
; unable to do inline fixnum arithmetic (cost 2) because:
; The second argument is a T, not a FIXNUM.
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES FIXNUM &REST T).
; unable to do inline (signed-byte 64) arithmetic (cost 5) because:
; The second argument is a T, not a (SIGNED-BYTE 64).
; The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES (SIGNED-BYTE 64)
; &REST T).
; etc.

; compiling (DECLAIM (FTYPE # ...))
; compiling (DEFUN ADD3 ...);
; compilation unit finished
; printed 2 notes

; /tmp/test.fasl written
; compilation finished in 0:00:00.030
#P"/private/tmp/test.fasl"
NIL
NIL