Forth Quines

On some of the differences between Forth and other languages

Here, I list some Forth quines, starting with the shortest ones, then eliminating various features of Forth, and see how the quines become longer. The elimination features are the section headings.

Full Forth

First, the empty program is a quine in Forth and some (but not all) other languages; however, apart from pointing out languages that require some overhead for doing even nothing, this is not a very interesting quine. So, the next Forth quine is:

source type

Eliminate interpretation

Some other languages do not allow directly interpreting code, but require that code is wrapped in a function. The corresponding restriction in Forth would be to define a Forth word that outputs its own definition. Here it is:

: quine [ source ] sliteral type ;

Eliminate SOURCE

: QUINE S" SEE QUINE" EVALUATE ;

: quine S" see quine" EVALUATE ;

: quine s\" see quine" evaluate ;

Eliminate SEE

s" 2dup cr 115 emit 34 emit space type 34 emit space type cr" 2dup cr 115 emit 34 emit space type 34 emit space type cr

As word

s" 2constant s : quine 115 emit 34 emit space [ s ] sliteral 2dup type 34 emit type ;"2constant s : quine 115 emit 34 emit space [ s ] sliteral 2dup type 34 emit type ;

[ s ] sliteral

s

Only colon definitions

: s s" ; : quine [ char ' parse : s s' ] sliteral type 34 emit space s type 34 emit s type ;"; : quine [ char ' parse : s s' ] sliteral type 34 emit space s type 34 emit s type ;

Eliminate interpretation

: s s" ; : quine 58 emit space 115 emit space 115 emit 34 emit space s type 34 emit s type ;"; : quine 58 emit space 115 emit space 115 emit 34 emit space s type 34 emit s type ;

Only one colon definition

: quine s" 2dup 32 34 115 32 101 110 105 117 113 32 58 11 0 do emit loop type 34 emit 32 emit type 32 101 110 105 117 113 32 59 32 9 0 do emit loop" 2dup 32 34 115 32 101 110 105 117 113 32 58 11 0 do emit loop type 34 emit 32 emit type 32 101 110 105 117 113 32 59 32 9 0 do emit loop ; quine

: quine s" 2dup 32 34 115 32 101 110 105 117 113 32 58 11 0 do emit loop type 34 emit type ;"2dup 32 34 115 32 101 110 105 117 113 32 58 11 0 do emit loop type 34 emit type ;

: q s" 2dup 32 34 115 32 113 32 58 7 0 do emit loop type 34 emit type ;"2dup 32 34 115 32 113 32 58 7 0 do emit loop type 34 emit type ;

Eliminating S"

36 base ! create d 1M c, W c, 35 c, W c, 1A c, Y c, W c, 1F c, 1I c, W c, 2Q c, 2P c, 37 c, 2T c, W c, X c, W c, 2R c, 36 c, 2T c, 2P c, 38 c, 2T c, W c, 2S c, W c, Y c, W c, 2S c, W c, 1E c, 1U c, W c, 1C c, W c, 2S c, 33 c, W c, 2S c, 39 c, 34 c, W c, 2X c, W c, 2R c, 2W c, 2P c, 36 c, 37 c, W c, 17 c, W c, 2R c, 1S c, W c, 1A c, W c, 1A c, Y c, W c, 2R c, 18 c, W c, Y c, W c, 30 c, 33 c, 33 c, 34 c, W c, 2S c, W c, 1E c, 1U c, W c, 38 c, 3D c, 34 c, 2T c, W c, 1N c, W c, 35 c, : q ." 36 base ! create d " d 2B 0 do dup i chars + c@ . ." c, " loop d 2B type ; q

Eliminating BASE

Other ways of dealing with quotes

: quiche s" : quiche % 2dup bounds ?DO I c@ 37 = IF 's emit 34 emit space type 34 emit ELSE I c@ emit THEN LOOP ; quiche" 2dup bounds ?DO I c@ 37 = IF 's emit 34 emit space type 34 emit ELSE I c@ emit THEN LOOP ; quiche

: quine s" : quine s% 2dup over + swap DO I c@ 37 = IF 34 emit space type 34 emit ELSE I c@ emit THEN LOOP ;" 2dup over + swap DO I c@ 37 = IF 34 emit space type 34 emit ELSE I c@ emit THEN LOOP ;

: quine s" : quine over 8 type 115 emit 34 emit space 2dup type 34 emit 8 /string type ;" over 8 type 115 emit 34 emit space 2dup type 34 emit 8 /string type ;

: quine s" : quine s over 9 type 34 emit space 2dup type 34 emit 9 /string type ;" over 9 type 34 emit space 2dup type 34 emit 9 /string type ;

: x 83 emit 34 emit space type 34 emit ; : quine S" : x 83 emit 34 emit space type 34 emit ; : quine "S" 2swap 2dup type x 2dup x type ;"2swap 2dup type x 2dup x type ;

: x 83 emit 34 emit space type 34 emit ; : quine S" 2dup type 2over x x type ;"S" : x 83 emit 34 emit space type 34 emit ; : quine "2dup type 2over x x type ;

: s s\" : quine .\\\" : s s\\\\\\\" \" 0 xpos ! s c-\\type .\\\" \\\" ; \" s type ;" ; : quine .\" : s s\\\" " 0 xpos ! s c-\type .\" \" ; " s type ;