shithub: femtolisp

Download patch

ref: 96e8c5d8f56998045411b0bead00a0d4f68a4212
parent: ba328f34850a8030652c105a2258599ab5847f0d
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Dec 23 14:22:24 EST 2024

introduce #<void>, not printing in repl when is the result of eval

References: https://todo.sr.ht/~ft/femtolisp/26

--- a/builtins.c
+++ b/builtins.c
@@ -318,7 +318,7 @@
 	v = alloc_vector(i, 0);
 	a = 1;
 	for(k = 0; k < i; k++){
-		f = a < nargs ? args[a] : FL_unspecified;
+		f = a < nargs ? args[a] : FL_void;
 		vector_elt(v, k) = f;
 		if((a = (a + 1) % nargs) < 1)
 			a = 1;
--- a/compiler.lsp
+++ b/compiler.lsp
@@ -482,7 +482,8 @@
                ((eq? x 1)   (emit g 'load1))
                ((eq? x #t)  (emit g 'loadt))
                ((eq? x #f)  (emit g 'loadf))
-               ((eq? x ())  (emit g 'loadnil))
+               ((eq? x nil) (emit g 'loadnil))
+               ((void? x)   (emit g 'loadvoid))
                ((fits-i8 x) (emit g 'loadi8 x))
                ((eof-object? x)
                 (compile-in g env tail? (list (top-level-value 'eof-object))))
@@ -586,13 +587,12 @@
 
 (define (expand-define x)
   ;; expand a single `define` expression to `set!`
-  (let ((form (cadr x))
-    (body (if (cons? (cddr x))
-              (cddr x)
-              (if (symbol? (cadr x))
-                  `(,(void))
-                  (error "compile error: invalid syntax "
-                         (print-to-string x))))))
+  (let* ((form (cadr x))
+         (body (if (cons? (cddr x))
+                   (cddr x)
+                   (if (symbol? form)
+                       `(,(void))
+                       (error "compile error: invalid syntax " (print-to-string x))))))
     (if (symbol? form)
         `(set! ,form ,(car body))
         `(set! ,(car form)
@@ -618,17 +618,17 @@
 (define (lower-define e)
   ;; convert lambda to one body expression and process internal defines
   (define (λ-body e)
-    (let ((B (if (cons? (cddr e))
-                 (if (cons? (cdddr e))
-                     (cons 'begin (cddr e))
-                     (caddr e))
-                 (void))))
-      (let ((V     (get-defined-vars B))
-            (new-B (lower-define B)))
-        (if (null? V)
-            new-B
-            (cons `(λ ,V ,new-B)
-                  (map (λ (x) (void)) V))))))
+    (let* ((B (if (cons? (cddr e))
+                  (if (cons? (cdddr e))
+                      (cons 'begin (cddr e))
+                      (caddr e))
+                  (void)))
+           (V (get-defined-vars B))
+           (new-B (lower-define B)))
+      (if (null? V)
+          new-B
+          (cons `(λ ,V ,new-B)
+                (map (λ (x) (void)) V)))))
   (cond ((or (atom? e) (quoted? e))
          e)
         ((eq? (car e) 'define)
--- a/cvalues.c
+++ b/cvalues.c
@@ -697,6 +697,8 @@
 			return FL(nullsym);
 		if(args[0] == FL_eof)
 			return FL_eof;
+		if(args[0] == FL_void)
+			return FL_void;
 		if(isbuiltin(args[0]))
 			return FL(builtinsym);
 		return FL(function);
--- a/flisp.boot
+++ b/flisp.boot
@@ -13,12 +13,12 @@
 	      #fn("8000z0700}2:" #(/)) #fn("8000z0700}2:" #(div0))
 	      #fn("6000n201l:" #()) #fn("6000n201m:" #()) 0 #fn("8000z0700}2:" #(vector))
 	      #fn("8000z0700}2:" #(aset!)) 0 0 0 0 0 0 0 0 0 0 0 #fn("9000n3012082>1|:" #(#fn("6000n1A061:" #())))
-	      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #fn("8000z0700}2:" #(aref)) 0)
+	      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #fn("8000z0700}2:" #(aref)) 0 0)
 	    *empty-string* "" *properties*
 	    #table(*funvars* #table(length= (lst n)  help (term))  *doc* #table(length= "Bounded length test.\n\nUse this instead of (= (length lst) n), since it avoids unnecessary\nwork and always terminates."  help "Display documentation for the specified term, if available."  *properties* "All properties of symbols recorded with putprop are recorded in this table."))
 	    *runestring-type* (array rune) *string-type* (array byte)
-	    *syntax-environment* #table(when #fn(";000z1200211POe4:" #(if begin))  help #fn(";000n170021527002252853\\0738551474504863B07450475086P51@30O474504D:73262705152474504O:" #(getprop
-  *doc* *funvars* princ newline print "no help for " #fn(string)))  with-output-to #fn("<000z12021e1220e2e1e12315163:" #(#fn(nconc)
+	    *syntax-environment* #table(when #fn(";000z1200211POe4:" #(if begin))  help #fn("<000n170021527002252853\\0738551474504863B07450475086P51@30O47450@B0732627051524745047860:" #(getprop
+  *doc* *funvars* princ newline print "no help for " #fn(string) void))  with-output-to #fn("<000z12021e1220e2e1e12315163:" #(#fn(nconc)
   with-bindings *output-stream* #fn(copy-list)))  catch #fn("@000n220502112286e123242586e2262786e22829e2e3262:86e20e3e42;86e22<86e2e4e3e3:" #(#fn(gensym)
   trycatch λ if and cons? eq? car quote thrown-value cadr caddr raise))  let* #fn("@000z10H3E02021e1qe12215153e1:2021e173051e1e1220=B3H02024e10=e12215153e1@301515375051e2:" #(#fn(nconc)
   λ #fn(copy-list) caar let* cadar))  with-input-from #fn("<000z12021e1220e2e1e12315163:" #(#fn(nconc)
@@ -25,10 +25,10 @@
   with-bindings *input-stream* #fn(copy-list)))  unless #fn("<000z1200O211Pe4:" #(if begin))  letrec #fn(">000z1202021e12273052e122240522515154e1222605262:" #(#fn(nconc)
   λ #fn(map) car #fn("8000n12021e12205162:" #(#fn(nconc) set! #fn(copy-list)))
   #fn(copy-list) #fn("5000n17060:" #(void))))  time #fn(">000n12050218522e1e2e123024252622e185e327e4e3e3:" #(#fn(gensym)
-  let time-now prog1 princ "Elapsed time: " - " seconds\n"))  cond #fn(":000z0D\x8a5852085>1_485<061:" #(#fn(">000n10H340O:0<85<20Q;I80485<DQ3C085=J6085<:2185=P:85=J@02285<A<0=51e3:85T23C\x98074758551513c07675855151278685<e2e12886217975855151PA<0=51e4e3:2:50278685<e2e1288675855186e2A<0=51e4e3:2885<2185=PA<0=51e4:" #(else
+  let time-now prog1 princ "Elapsed time: " - " seconds\n"))  cond #fn(":000z0\x8d\x8a5852085>1_485<061:" #(#fn(">000n10H340O:0<85<20Q;I80485<DQ3C085=J6085<:2185=P:85=J@02285<A<0=51e3:85T23C\x98074758551513c07675855151278685<e2e12886217975855151PA<0=51e4e3:2:50278685<e2e1288675855186e2A<0=51e4e3:2885<2185=PA<0=51e4:" #(else
   begin or => 1arg-lambda? caddr caadr let if cddr #fn(gensym)) cond-clauses->if)))  do #fn("J000z220501<2172052217305221240522587268927882829e12:1=51522829e12:82512887e18;52e153e4e3e2e12887e18:52e3:" #(#fn(gensym)
   #fn(map) car cadr #fn("6000n170051B38071061:0<:" #(cddr caddr)) letrec λ if #fn(nconc) begin #fn(copy-list)))  assert #fn(";000n1200D2122230e2e2e2e4:" #(if
-  raise quote assert-failed))  case #fn("A000z1D\x8a68620_4215022870e2e12324e125268687>215252e3:" #(#fn("8000n2120C5020:1J40O:1R3=021072151e3:1H3=023072151e3:1=J>0230721<51e3:74751523=0260271e2e3:280271e2e3:" #(else
+  raise quote assert-failed))  case #fn("A000z1\x8d\x8a68620_4215022870e2e12324e125268687>215252e3:" #(#fn("8000n2120C5020:1J40O:1R3=021072151e3:1H3=023072151e3:1=J>0230721<51e3:74751523=0260271e2e3:280271e2e3:" #(else
   eq? quote-value eqv? every symbol? memq quote memv) vals->cond)
   #fn(gensym) let #fn(nconc) cond #fn(map) #fn("7000n1A<F0<520=P:" #())))  let #fn(">000z1O0R3B00?641<?041=?1@30O42021e12223052e124151532225052863C0268687e2e186e3@408788P:" #(#fn(nconc)
   λ #fn(map) #fn("5000n10B3500<:0:" #()) #fn(copy-list)
@@ -45,13 +45,13 @@
   length=) 1arg-lambda?)
 	    <= #fn("6000n210L;IB0470051;380470151S:" #(nan?) <=) >
 	    #fn("6000n210L:" #() >) >= #fn("6000n201L;IB0470051;380470151S:" #(nan?) >=)
-	    Instructions #table(call.l 81  trycatch 75  largc 79  loadg.l 68  aref2 23  box 90  cadr 36  argc 62  setg 71  load0 21  vector? 45  fixnum? 41  loadc0 17  loada0 0  div0 59  keyargs 89  call 5  loada.l 69  brt.l 50  sub2 78  add2 29  loadc.l 70  loadc 9  builtin? 43  set-car! 47  brt 25  ret 10  loadi8 66  tapply 77  loada1 1  shift 46  boolean? 39  atom? 24  cdr 13  brne.l 83  / 58  loadf 31  equal? 52  apply 54  dup 11  loadt 20  jmp.l 48  null? 38  not 35  = 60  set-cdr! 30  eq? 33  * 57  load1 27  bound? 42  brf 3  function? 44  box.l 91  < 28  brnn.l 84  jmp 16  loadv 2  for 76  lvargc 80  dummy_eof 93  + 55  brne 19  compare 61  neg 37  loadv.l 67  number? 40  vargc 74  brn 85  brbound 88  vector 63  loadc1 22  setg.l 72  cons? 18  brf.l 49  aref 92  symbol? 34  aset! 64  car 12  cons 32  tcall.l 82  - 56  brn.l 86  optargs 87  closure 14  pop 4  eqv? 51  list 53  seta 15  seta.l 73  brnn 26  loadnil 65  loadg 7  loada 8  tcall 6)
+	    Instructions #table(call.l 81  trycatch 75  largc 79  loadg.l 68  aref2 23  box 90  cadr 36  argc 62  setg 71  load0 21  vector? 45  fixnum? 41  loadc0 17  loada0 0  div0 59  keyargs 89  call 5  loada.l 69  brt.l 50  sub2 78  add2 29  loadc.l 70  loadc 9  builtin? 43  set-car! 47  brt 25  ret 10  loadi8 66  tapply 77  loadvoid 93  loada1 1  shift 46  boolean? 39  atom? 24  cdr 13  brne.l 83  / 58  loadf 31  equal? 52  apply 54  dup 11  loadt 20  jmp.l 48  null? 38  not 35  = 60  set-cdr! 30  eq? 33  * 57  load1 27  bound? 42  brf 3  function? 44  box.l 91  < 28  brnn.l 84  jmp 16  loadv 2  for 76  lvargc 80  dummy_eof 94  + 55  brne 19  compare 61  neg 37  loadv.l 67  number? 40  vargc 74  brn 85  brbound 88  vector 63  loadc1 22  setg.l 72  cons? 18  brf.l 49  aref 92  symbol? 34  aset! 64  car 12  cons 32  tcall.l 82  - 56  brn.l 86  optargs 87  closure 14  pop 4  eqv? 51  list 53  seta 15  seta.l 73  brnn 26  loadnil 65  loadg 7  loada 8  tcall 6)
 	    __init_globals #fn("5000n020w1422w3474w5476w7478w9:" #("/" *directory-separator* "\n"
 								   *linefeed* *stdout*
 								   *output-stream* *stdin*
 								   *input-stream* *stderr*
 								   *error-stream*) __init_globals)
-	    __rcscript #fn(":000n0708421c37022@U08423c3A0242526512752@>0242528512952^12:84513907;8461:D:" #(*os-name*
+	    __rcscript #fn(":000n0708421c37022@U08423c3A0242526512752@>0242528512952^12:84513907;8461:\x8d:" #(*os-name*
   "unknown" "" "plan9" #fn(string) #fn(os-getenv) "home" "/lib/flisprc" "HOME" "/.flisprc" #fn(path-exists?)
   load) __rcscript)
 	    __script #fn("6000n1200>121{:" #(#fn("6000n070A61:" #(load))
@@ -76,7 +76,7 @@
   bcode:nconst #fn(has?) #fn(get) #fn(put!)) bcode:indexfor)
 	    bcode:nconst #fn("6000n10r2G:" #() bcode:nconst) bcode:sp
 	    #fn("6000n10r4G:" #() bcode:sp) bcode:stack #fn("8000n20r40r4G1Mp:" #() bcode:stack)
-	    box-vars #fn("9000n2D\x8a68620086>2_486<^1161:" #(#fn("9000n10B3Q00<T3B070A21720<5153@30D4F<0=61:D:" #(emit
+	    box-vars #fn("9000n2\x8d\x8a68620086>2_486<^1161:" #(#fn("9000n10B3Q00<T3B070A21720<5153@30\x8d4F<0=61:\x8d:" #(emit
   box caddr))) box-vars)
 	    bq-bracket #fn(";000n20H3=070710152e2:0<22CR01El380700=P:707324710=1K~52e3e2:0<25CS01El390260Te2:707027710T1K~52e3e2:0<28CO01El3500T:707029710T1K~52e3e2:70710152e2:" #(list
   bq-process unquote cons 'unquote unquote-splicing copy-list 'unquote-splicing unquote-nsplicing
@@ -83,7 +83,7 @@
   'unquote-nsplicing) bq-bracket)
 	    bq-bracket1 #fn(":000n20B3R00<20CK01El3500T:7122730=1K~52e3:730162:" #(unquote cons 'unquote
 										   bq-process) bq-bracket1)
-	    bq-process #fn("<000n20R380200e2:0]3T0717205115286<73C907486=P:757486e3:0H3400:0<26CB07327710T1KM52e3:0<28CU01El3?0790r2523500T:7:2;710=1K~52e3:7<7=052It07>0512?2@1>105286J807387P:87=JA07:87<7186152e3:2A7B87P7186152e162:D\x8a6862C186>2_486<^10q62:" #(quote
+	    bq-process #fn("<000n20R380200e2:0]3T0717205115286<73C907486=P:757486e3:0H3400:0<26CB07327710T1KM52e3:0<28CU01El3?0790r2523500T:7:2;710=1K~52e3:7<7=052It07>0512?2@1>105286J807387P:87=JA07:87<7186152e3:2A7B87P7186152e162:\x8d\x8a6862C186>2_486<^10q62:" #(quote
   bq-process vector->list list vector apply quasiquote 'quasiquote unquote length= cons 'unquote
   any splice-form? lastcdr #fn(map) #fn("7000n1700A62:" #(bq-bracket1))
   #fn(nconc) list* #fn("=000n20J;02071151P:0B3n00<22CW020731AEl3700=@C07425e2760=AK~52e252P:F<0=770<A521P62:2071760A521P51P:" #(nconc
@@ -109,7 +109,7 @@
 	    closure? #fn("6000n10\\;36040[S:" #() closure?) compile
 	    #fn("8000n170q7105162:" #(compile-f lower-define) compile) compile-and #fn("<000n570018283D218467:" #(compile-short-circuit
   brf) compile-and)
-	    compile-app #fn("E000n483<88R3U07088152IK088Z3E0218851[3;0218851@40887283=23523i07401O89544750K524760183=537508:U5247708237028@40298:63:89[;39047:8951892;Cf07089152I\\0212;517;d3P07<83r2523E07401O83T5447702;62:89B3P07=89<513F07>83513=07?01828364:8:IE07401O89544750K52@30D4760183=537508;U5248:I<0750r/52@30D48:3C07@018283898:8;67:770823702A@402B8;63:" #(in-env?
+	    compile-app #fn("E000n483<88R3U07088152IK088Z3E0218851[3;0218851@40887283=23523i07401O89544750K524760183=537508:U5247708237028@40298:63:89[;39047:8951892;Cf07089152I\\0212;517;d3P07<83r2523E07401O83T5447702;62:89B3P07=89<513F07>83513=07?01828364:8:IE07401O89544750K52@30\x8d4760183=537508;U5248:I<0750r/52@30\x8d48:3C07@018283898:8;67:770823702A@402B8;63:" #(in-env?
   #fn(top-level-value) length> 255 compile-in bcode:stack compile-arglist emit tcall.l call.l
   builtin->instruction cadr length= is-lambda? inlineable? compile-let compile-builtin-call tcall
   call) compile-app)
@@ -120,12 +120,12 @@
   compile-app aset! > aref list-head compile-arglist list-tail bcode:stack emit argc-error) compile-aset!)
 	    compile-begin #fn("9000n483H3?0700182715064:83=H3>070018283<64:7001O83<5447202352474018283=64:" #(compile-in
   void emit pop compile-begin) compile-begin)
-	    compile-builtin-call #fn("=000n7207185O538;3I07283=8;52I=073858;52@30D4858<24CK086El3:07502662:750858663:8<27C[086El3:07502862:86r2l3:07502962:750858663:8<2:Cj086El3:07385K62:86Kl3:07502;62:86r2l3:07502<62:750858663:8<2=CK086El3:07502>62:750858663:8<2?CK086El3:07385K62:750858663:8<2@CM086El3<07502A2B63:750858663:8<2CCW086r2L3;07385r262:750823702D@402C8663:8<2ECc086r2l3:07502F62:7G86r2523?07508586r3~63:7385r262:7508562:" #(#fn(get)
+	    compile-builtin-call #fn("=000n7207185O538;3I07283=8;52I=073858;52@30\x8d4858<24CK086El3:07502662:750858663:8<27C[086El3:07502862:86r2l3:07502962:750858663:8<2:Cj086El3:07385K62:86Kl3:07502;62:86r2l3:07502<62:750858663:8<2=CK086El3:07502>62:750858663:8<2?CK086El3:07385K62:750858663:8<2@CM086El3<07502A2B63:750858663:8<2CCW086r2L3;07385r262:750823702D@402C8663:8<2ECc086r2l3:07502F62:7G86r2523?07508586r3~63:7385r262:7508562:" #(#fn(get)
   arg-counts length= argc-error list emit loadnil + load0 add2 - neg sub2 * load1 / vector loadv #()
   apply tapply aref aref2 >) compile-builtin-call)
 	    compile-f #fn("8000n2702101>22262:" #(call-with-values #fn("7000n070AF62:" #(compile-f-))
 						  #fn("5000n20:" #())) compile-f)
-	    compile-f- #fn("O000n270501T711T517215173741T52711518;J7025@408;87H360E@802687518=268:51~73778:528:\x85\xa208?JL07886298>88J708=@508=U54@r07:867;2<7=2<7>8?527?268?5151535152478862@8>268?5188J708=@508=U5547A8608:898>55@30D47B8=2C523I0788688J702D@402E8=53@W088\x85?078862F8=53@E08:J?078862G8=53@30O47H0897I7J1518952537K868@<52486r4268951r4Mp47L868@D7J15154478862M5247N2O7P7Q8651517R86518<537S865162:" #(make-code-emitter
+	    compile-f- #fn("O000n270501T711T517215173741T52711518;J7025@408;87H360E@802687518=268:51~73778:528:\x85\xa208?JL07886298>88J708=@508=U54@r07:867;2<7=2<7>8?527?268?5151535152478862@8>268?5188J708=@508=U5547A8608:898>55@30\x8d47B8=2C523I0788688J702D@402E8=53@W088\x85?078862F8=53@E08:J?078862G8=53@30O47H0897I7J1518952537K868@<52486r4268951r4Mp47L868@D7J15154478862M5247N2O7P7Q8651517R86518<537S865162:" #(make-code-emitter
   lastcdr lambda:vars filter cons? λ #fn(length) keyword-arg? emit optargs bcode:indexfor
   make-perfect-hash-table #fn(map) cons car iota keyargs emit-optional-arg-inits > 255 largc lvargc
   vargc argc extend-env complex-bindings lambda:body box-vars compile-in ret values #fn(function)
@@ -132,27 +132,27 @@
   encode-byte-code bcode:code const-to-idx-vec bcode:cenv) compile-f-)
 	    compile-if #fn("A000n470051700517005183T718351728351B3;0738351@6074508;DC=07501828<64:8;OC=07501828=64:7501O8;895547602789534780885247501828<544823<07602952@;07602:8:534780895247501828=5447808:62:" #(make-label
   caddr cdddr cadddr void compile-in emit brf mark-label ret jmp) compile-if)
-	    compile-in #fn("B000\x8740005000\x884000I60O?4483R3<0700183D64:83H3\xaf083EC:07102262:83KC:07102362:83DC:07102462:83OC:07102562:83qC:07102662:7783513<0710288363:2983513C07:01822;2<51e164:7102=8363:83<2>C<07?0183=63:83<RS;ID0483<Z;I;047@83<1523=07A01828364:83<892BCS07C83T513>07:018283T64:7102=83T63:892DC=07E01828364:892FC>07G018283=64:892HC;07I018363:892JCD07K2L183>22M01>262:892NC@07O018283=8465:892PC>07Q018283=64:892RCE07S0183T2F7T8351P64:892UCE07:01D83T5447102V62:892WC\x93083T7T83517X8;518:R360O@807Y2Z5148<3`08;=?;47[8:8<8;<B;3G047\\8;<<51;3:047]8;<5153@30O47^018:8;<64:892_Cp07:01O2Jq83Te35447`7a835151360O@807Y2b5147:01O7a83515447102_62:7A01828364:" #(compile-sym
-  emit load0 load1 loadt loadf loadnil fits-i8 loadi8 #fn(eof-object?) compile-in #fn(top-level-value)
+	    compile-in #fn("B000\x8740005000\x884000I60O?4483R3<0700183D64:83H3\xc0083EC:07102262:83KC:07102362:83DC:07102462:83OC:07102562:83qC:07102662:7783513:07102862:7983513<07102:8363:2;83513C07<01822=2>51e164:7102?8363:83<2@C<07A0183=63:83<RS;ID0483<Z;I;047B83<1523=07C01828364:83<892DCS07E83T513>07<018283T64:7102?83T63:892FC=07G01828364:892HC>07I018283=64:892JC;07K018363:892LCD07M2N183>22O01>262:892PC@07Q018283=8465:892RC>07S018283=64:892TCE07U0183T2H7V8351P64:892WCE07<01D83T5447102X62:892YC\x93083T7V83517Z8;518:R360O@807[2\\5148<3`08;=?;47]8:8<8;<B;3G047^8;<<51;3:047_8;<5153@30O47`018:8;<64:892aCp07<01O2Lq83Te35447b7c835151360O@807[2d5147<01O7c83515447102a62:7C01828364:" #(compile-sym
+  emit load0 load1 loadt loadf loadnil void? loadvoid fits-i8 loadi8 #fn(eof-object?) compile-in #fn(top-level-value)
   eof-object loadv aset! compile-aset! in-env? compile-app quote self-evaluating? if compile-if
   begin compile-begin prog1 compile-prog1 λ call-with-values #fn("7000n070AF62:" #(compile-f-))
-  #fn("9000n270A2105341\x85K02223AF>2152470A242515163:D:" #(emit loadv #fn(for-each)
-							    #fn("9000n170AF0O64:" #(compile-sym))
-							    closure #fn(length))) and compile-and
-  or compile-or while compile-while cddr return ret set! value-get-doc error "set!: name must be a symbol"
+  #fn("9000n270A2105341\x85K02223AF>2152470A242515163:\x8d:" #(emit loadv #fn(for-each)
+							       #fn("9000n170AF0O64:" #(compile-sym))
+							       closure #fn(length))) and
+  compile-and or compile-or while compile-while cddr return ret set! value-get-doc error "set!: name must be a symbol"
   symbol-set-doc is-lambda? lambda:vars compile-set! trycatch 1arg-lambda? caddr "trycatch: second form must be a 1-argument lambda") compile-in)
-	    compile-let #fn("A000n483<83=7005188T71018953728;737488518;528:537508=524268=1<521=P7708>827488515447808<U524798<E523A082I<07:02;8<63:D:" #(bcode:sp
+	    compile-let #fn("A000n483<83=7005188T71018953728;737488518;528:537508=524268=1<521=P7708>827488515447808<U524798<E523A082I<07:02;8<63:\x8d:" #(bcode:sp
   compile-arglist vars-to-env complex-bindings caddr box-vars #fn(nconc) compile-in bcode:stack >
   emit shift) compile-let)
 	    compile-or #fn("<000n470018283O21O67:" #(compile-short-circuit brt) compile-or)
-	    compile-prog1 #fn(":000n37001O82T544718251B3W0720K5247301O71825154474025524720r/62:D:" #(compile-in
+	    compile-prog1 #fn(":000n37001O82T544718251B3W0720K5247301O71825154474025524720r/62:\x8d:" #(compile-in
   cddr bcode:stack compile-begin emit pop) compile-prog1)
-	    compile-set! #fn("?000n470821E538821CF07201O83544730248263:88<El88=T893<07588=51@9076082528:3g07308937027@40288;534790K5247201O83544790r/5247302:62:7201O8354489IA07;2<2=825251@30D47302>8;63:" #(lookup-sym
+	    compile-set! #fn("?000n470821E538821CF07201O83544730248263:88<El88=T893<07588=51@9076082528:3g07308937027@40288;534790K5247201O83544790r/5247302:62:7201O8354489IA07;2<2=825251@30\x8d47302>8;63:" #(lookup-sym
   global compile-in emit setg vinfo:index capture-var! loada loadc bcode:stack set-car! error #fn(string)
   "internal error: misallocated var " seta) compile-set!)
 	    compile-short-circuit #fn("?000n783H3?0700182848665:83=H3@070018283<8665:86;I804710517001O83<86554720K52486360O@9073024524730858;534720r/52486360O@907302552476018283=84858657486340O:7708;62:" #(compile-in
   make-label bcode:stack emit dup pop compile-short-circuit mark-label) compile-short-circuit)
-	    compile-sym #fn(";000n470821E538821C`02282513M073248251513@07502624825163:750278263:88<El3W0750287988=51534833A088=T3:07502:62:D:7502;7<08252534833A088=T3:07502:62:D:" #(lookup-sym
+	    compile-sym #fn(";000n470821E538821C`02282513M073248251513@07502624825163:750278263:88<El3W0750287988=51534833A088=T3:07502:62:\x8d:7502;7<08252534833A088=T3:07502:62:\x8d:" #(lookup-sym
   global #fn(constant?) printable? #fn(top-level-value) emit loadv loadg loada vinfo:index car
   loadc capture-var!) compile-sym)
 	    compile-thunk #fn(":000n170q21q72051e362:" #(compile-f λ lower-define) compile-thunk)
@@ -162,7 +162,7 @@
 										  complex-bindings-
 										  filter #fn("7000n120A062:" #(#fn(has?)))
 										  table-keys) complex-bindings)
-	    complex-bindings- #fn("=000n61J40O:0R3K0833D02001523;021840D63:D:0H;I80472051340O:0<23Co0200T1523Q021850TD534833>021840TD53@30D@30D474750511O83848566:760<513U074770517817905152O82S;I50483848566:740<17:051838485562;2<1838485>40=52P:" #(#fn(memq)
+	    complex-bindings- #fn("=000n61J40O:0R3K0833D02001523;021840D63:\x8d:0H;I80472051340O:0<23Co0200T1523Q021850TD534833>021840TD53@30\x8d@30\x8d474750511O83848566:760<513U074770517817905152O82S;I50483848566:740<17:051838485562;2<1838485>40=52P:" #(#fn(memq)
   #fn(put!) quoted? set! complex-bindings- caddr is-lambda? lambda:body diff lambda:vars
   inlineable? #fn(map) #fn(";000n1700AOF929366:" #(complex-bindings-))) complex-bindings-)
 	    const-to-idx-vec #fn("9000n1207105151222385>17405152485:" #(#fn(vector-alloc)
@@ -170,13 +170,13 @@
 									#fn("7000n2A10p:" #())
 									bcode:ctable) const-to-idx-vec)
 	    copy-tree #fn("7000n10H3400:700<51700=51P:" #(copy-tree) copy-tree) count
-	    #fn("9000n2D\x8a6862086>1_486<01E63:" #(#fn("9000n31J5082:A<01=01<5139082KM@408263:" #() count-)) count)
-	    delete-duplicates #fn(":000n1700rD523O02150D\x8a686228586>2_486<^10q62:0H3400:0<0=73858652390748661:85748651P:" #(length>
+	    #fn("9000n2\x8d\x8a6862086>1_486<01E63:" #(#fn("9000n31J5082:A<01=01<5139082KM@408263:" #() count-)) count)
+	    delete-duplicates #fn(":000n1700rD523O02150\x8d\x8a686228586>2_486<^10q62:0H3400:0<0=73858652390748661:85748651P:" #(length>
   #fn(table) #fn("8000n20H38070161:21A0<523:0F<0=162:22A0<D534F<0=0<1P62:" #(reverse! #fn(has?)
 									     #fn(put!))) member
   delete-duplicates) delete-duplicates)
 	    diff #fn("8000n20J40q:200<1523:0710=162:0<710=152P:" #(#fn(memq) diff) diff)
-	    disassemble #fn("U000\x871000.///\x881000I60O?14z282JD07001E53471504D:@30D482<2205123051DD2487>1?:425187>2?;4r4268851\x8a<D8<<8=L3\x93242728888<>2O79537:8<<r4523907150@30D4E87K~2;|48<8<<KM_48>2<8?2=523[08;8>8<<r45348:897>888<<52G5148<8<<r4M_@\x1f12<8?2?523V08;8>8<<K5348:89888<<GG5148<8<<KM_@\xf012<8?2@523e08;8>8<<K5347A2B888<<G8>2CC70r3@30EM515148<8<<KM_@\xb212<8?2D523\\08;8>8<<r45347A2B7>888<<52515148<8<<r4M_@}12<8?2E523\xb808;8>8<<r88>2FC70r4@30EM5347A2B7>888<<52512G5248<8<<r4M_47A2B7>888<<52515148<8<<r4M_48>2FCY07A2G5147A2B7>888<<52512G5248<8<<r4M_@30D@\xec08?2Hc3^08;8>8<<r45347A2B7>888<<52512G5248<8<<r4M_@\xb802<8?2I523e08;8>8<<r25347A2J7K8<<r,7L888<<52g3515248<8<<r2M_@z02<8?2M523e08;8>8<<r45347A2J7K8<<r,7>888<<52g3515248<8<<r4M_@<08;8>8<<E53^1^1@\xc8-:" #(disassemble
+	    disassemble #fn("U000\x871000.///\x881000I60O?14z282JD07001E53471504D:@30\x8d482<2205123051\x8d\x8d2487>1?:425187>2?;4r4268851\x8a<\x8d8<<8=L3\x93242728888<>2O79537:8<<r4523907150@30\x8d4E87K~2;|48<8<<KM_48>2<8?2=523[08;8>8<<r45348:897>888<<52G5148<8<<r4M_@\x1f12<8?2?523V08;8>8<<K5348:89888<<GG5148<8<<KM_@\xf012<8?2@523e08;8>8<<K5347A2B888<<G8>2CC70r3@30EM515148<8<<KM_@\xb212<8?2D523\\08;8>8<<r45347A2B7>888<<52515148<8<<r4M_@}12<8?2E523\xb808;8>8<<r88>2FC70r4@30EM5347A2B7>888<<52512G5248<8<<r4M_47A2B7>888<<52515148<8<<r4M_48>2FCY07A2G5147A2B7>888<<52512G5248<8<<r4M_@30\x8d@\xec08?2Hc3^08;8>8<<r45347A2B7>888<<52512G5248<8<<r4M_@\xb802<8?2I523e08;8>8<<r25347A2J7K8<<r,7L888<<52g3515248<8<<r2M_@z02<8?2M523e08;8>8<<r45347A2J7K8<<r,7>888<<52g3515248<8<<r4M_@<08;8>8<<E53^1^1@\xc8-:" #(disassemble
   newline #fn(function:code) #fn(function:vals) #fn("9000n10\\3H00[IC07021514720OAKM63:73061:" #(princ
   "\n" disassemble print) print-val) #fn(";000n370A3S0FEl3M071A72151523@0A182ML37023@4024751r5~512602765:" #(princ
   >= 1- " >" "  " hex5 ":  " " ") print-inst) #fn(length)
@@ -187,15 +187,15 @@
   (optargs keyargs) keyargs " " brbound (jmp brf brt brne brnn brn) "@" hex5 ref-int16-LE (jmp.l
   brf.l brt.l brne.l brnn.l brn.l)) disassemble)
 	    div #fn("7000n201k0EL;3C041EL;3404K;I504r/;I404EM:" #() div) emit
-	    #fn("O000z20EG82JR0120CB087<21C:08722_@900E187Pp@\x9e123124523A075082<52e1?2@30D42612752883F07882<29523:088T?1@30D^142612:52883F07882<29523:088T?1@30D^1412;C\\0822<d3=02=?14q?2@F0822>d3=02??14q?2@30O@30D412@C\\0822<d3=02A?14q?2@F0822>d3=02B?14q?2@30O@30D487<12CQ;3\x9b04882DCM087T2ECE00E82<2F7G8751PPp@x0882DCB00E82<2H87=PPp@a0882ICB00E82<2J87=PPp@J0882ECB00E82<2K87=PPp@30O;I]0412HCI0882ECB00E82<2F87=PPp@?00E7L182P8752p^140:" #(car
+	    #fn("O000z20EG82JR0120CB087<21C:08722_@900E187Pp@\x9e123124523A075082<52e1?2@30\x8d42612752883F07882<29523:088T?1@30\x8d^142612:52883F07882<29523:088T?1@30\x8d^1412;C\\0822<d3=02=?14q?2@F0822>d3=02??14q?2@30O@30\x8d412@C\\0822<d3=02A?14q?2@F0822>d3=02B?14q?2@30O@30\x8d487<12CQ;3\x9b04882DCM087T2ECE00E82<2F7G8751PPp@x0882DCB00E82<2H87=PPp@a0882ICB00E82<2J87=PPp@J0882ECB00E82<2K87=PPp@30O;I]0412HCI0882ECB00E82<2F87=PPp@?00E7L182P8752p^140:" #(car
   cdr cadr #fn(memq) (loadv loadg setg) bcode:indexfor #fn(assq)
   ((loadv loadv.l) (loadg loadg.l) (setg setg.l) (loada loada.l) (seta seta.l) (box box.l)) > 255
   ((loadc loadc.l)) loada (0) loada0 (1) loada1 loadc loadc0 loadc1 brf not null? brn cddr brt eq?
   brne brnn nreconc) emit)
-	    emit-optional-arg-inits #fn("<000n582B3\x900700517102284534710238953474075176838452q53O7782515447102884534710295247:0895247;0182=8384KM65:D:" #(make-label
+	    emit-optional-arg-inits #fn("<000n582B3\x900700517102284534710238953474075176838452q53O7782515447102884534710295247:0895247;0182=8384KM65:\x8d:" #(make-label
   emit brbound brt compile-in extend-env list-head cadar seta pop mark-label
   emit-optional-arg-inits) emit-optional-arg-inits)
-	    encode-byte-code #fn("S000n17005171855172238651r3238651r2ki2M2452238651E255025502650OO278<28524D8988L3\xd9148689G?=48=29CP02:8:8689KMG2;8<5153489r2M?9@\xa81278<2<2=7>873\x8308=8D2?C702@@p08D2AC702B@d08D2CC702D@X08D2EC702F@L08D2GC702H@@08D2IC702J@408=^1@408=525152489KM?948988L3:08689G@30O?>42K8=2L523`02:8;2;8<518>534278<873707M@407NE5152489KM?9@\xeb08=2OCH0278<2P8>5152489KM?9@\xce08>X3\xc708=2K8?2Q523H0278<2P8>5152489KM?9@\x9f02K8?2R523\x810278<2P8>5152489KM?94278<2P8689G5152489KM?948=2SCK0278<2P8689G5152489KM?9@30D@E0278<2T8>5152489KM?9^1@30O@\x83.42U2V8<878:>38;5242W8<61:" #(reverse!
+	    encode-byte-code #fn("S000n17005171855172238651r3238651r2ki2M2452238651E255025502650OO278<28524\x8d8988L3\xd9148689G?=48=29CP02:8:8689KMG2;8<5153489r2M?9@\xa81278<2<2=7>873\x8308=8D2?C702@@p08D2AC702B@d08D2CC702D@X08D2EC702F@L08D2GC702H@@08D2IC702J@408=^1@408=525152489KM?948988L3:08689G@30O?>42K8=2L523`02:8;2;8<518>534278<873707M@407NE5152489KM?9@\xeb08=2OCH0278<2P8>5152489KM?9@\xce08>X3\xc708=2K8?2Q523H0278<2P8>5152489KM?9@\x9f02K8?2R523\x810278<2P8>5152489KM?94278<2P8689G5152489KM?948=2SCK0278<2P8689G5152489KM?9@30\x8d@E0278<2T8>5152489KM?9^1@30O@\x83.42U2V8<878:>38;5242W8<61:" #(reverse!
   list->vector >= #fn(length) 65536 #fn(table) #fn(buffer)
   #fn(io-write) #int32(0) label #fn(put!) #fn(sizeof)
   #fn(byte) #fn(get) Instructions jmp jmp.l brt brt.l brf brf.l brne brne.l brnn brnn.l brn brn.l
@@ -210,10 +210,10 @@
 	    #fn("9000z020210P61:" #(#fn(raise) error) error) eval #fn("7000n170710515160:" #(compile-thunk
   expand) eval)
 	    even? #fn("7000n1200K52El:" #(#fn(logand)) even?) every
-	    #fn("7000n21H;ID0401<51;3:047001=62:" #(every) every) expand #fn("F000n1DDDDDDDDDDD\x8a5\x8a6\x8a7\x8a8\x8a9\x8a:\x8a;\x8a<\x8a=\x8a>\x8a?8520_4862186>1_48722e1_4882385868?87>4_489248?89>2_48:258:>1_48;268:8988>3_48<278?8:8988>4_48=28888?>2_48>29_48?2:8?8>8;8<8=>5_48?<0q62:" #(#fn("7000n20Z;I904200152S:" #(#fn(assq)) top?)
+	    #fn("7000n21H;ID0401<51;3:047001=62:" #(every) every) expand #fn("F000n1\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8d\x8a5\x8a6\x8a7\x8a8\x8a9\x8a:\x8a;\x8a<\x8a=\x8a>\x8a?8520_4862186>1_48722e1_4882385868?87>4_489248?89>2_48:258:>1_48;268:8988>3_48<278?8:8988>4_48=28888?>2_48>29_48?2:8?8>8;8<8=>5_48?<0q62:" #(#fn("7000n20Z;I904200152S:" #(#fn(assq)) top?)
   #fn("8000n10H3400:020d3400:0<B3P07105122CF023A<7405151A<0=5162:0<A<0=51P:" #(((begin)) caar begin
 									       #fn(append) cdar) splice-begin)
-  *expanded* #fn("A000n20H3400:A<201523:0F<051@300A<21152873;0728651@30q2324758852152\x8a987IA024269289>28662:D\x8a:8:278:928993>4_48:<^186518:D8;B3c0493<788;51QIC08;92<8;<89<52_@;08;798;51_48;=?;@\xfb/48::" #(begin
+  *expanded* #fn("A000n20H3400:A<201523:0F<051@300A<21152873;0728651@30q2324758852152\x8a987IA024269289>28662:\x8d\x8a:8:278:928993>4_48:<^186518:\x8d8;B3c0493<788;51QIC08;92<8;<89<52_@;08;798;51_48;=?;@\xfb/48::" #(begin
   define get-defined-vars #fn(nconc) #fn(map) list #fn("7000n1A<0F<62:" #())
   #fn(";000n10H3400:0<B3F02071051C<00<A<0=51P:F<0<92<52922223747585515292<52_493<85PA<0=51P:" #(define
   caar #fn(nconc) #fn(map) list get-defined-vars)) caar cdar) expand-body)
@@ -227,12 +227,12 @@
 									       #fn(map)
 									       #fn("9000n10<70A<0TF525150Fe3:" #(compile-thunk))) expand-let-syntax)
   #fn("5000n20:" #() local-expansion-env) #fn("<000n20H3400:0<208615221A10>3873P087=B3I0A<87T0=f2F<72875115262:87;I?0486RS;I60486Z3708860:73051893>0A<890=f2162:8624C400:8625C:092<0162:8625C:092<0162:8626C:093<0162:8627C:094<0162:8860:" #(#fn(assq)
-  #fn(":000n0D\x8a48420AF84>3_484<^19261:" #(#fn("8000n10H3400:0<H3700<@90A<0<F5292<0=51P:" #())))
+  #fn(":000n0\x8d\x8a48420AF84>3_484<^19261:" #(#fn("8000n10H3400:0<H3700<@90A<0<F5292<0=51P:" #())))
   caddr macrocall? quote λ define let-syntax) expand-in)) expand)
-	    expand-define #fn("?000n10T70051B3:070051@L00TR3;07150e1@=07223740515285R3<0258586<e3:2585<2627e185=e128865185<54e3:" #(cddr
+	    expand-define #fn("?000n10T70051B3:070051@L085R3;07150e1@=07223740515285R3<0258586<e3:2585<2627e185=e128865185<54e3:" #(cddr
   void error "compile error: invalid syntax " print-to-string set! #fn(nconc) λ #fn(copy-list)) expand-define)
 	    extend-env #fn("8000n370182E530P:" #(vars-to-env) extend-env) filter
-	    #fn("9000n2D200>1?648601qe163:" #(#fn("8000n382D1B3Q04A1<513?0821<qPN=?2@30O41=?1@\x0e/4=:" #() filter-)) filter)
+	    #fn("9000n2\x8d200>1?648601qe163:" #(#fn("8000n382\x8d1B3Q04A1<513?0821<qPN=?2@30O41=?1@\x0e/4=:" #() filter-)) filter)
 	    fits-i8 #fn("7000n10Y;3F04700r\xb052;3:04710r\xaf62:" #(>= <=) fits-i8) foldl
 	    #fn("9000n382J401:700082<15282=63:" #(foldl) foldl) foldr #fn(":000n382J401:082<700182=5362:" #(foldr) foldr)
 	    get-defined-vars #fn("7000n170A<05161:" #(delete-duplicates) #(#0=(#fn("8000n10H340q:0<20Cj00=B3d00TR;37040Te1;IS040TB;3E0471051R;3:0471051e1;I404q:0<22C?07324A<0=52}2:q:" #(define
@@ -259,13 +259,13 @@
 										  #fn(string-sub)
 										  1- #fn(string-length)) keyword->symbol)
 	    keyword-arg? #fn("6000n10B;3904200<61:" #(#fn(keyword?)) keyword-arg?) lambda-vars
-	    #fn(":000n1D\x8a5852085>1_485<00OO54421227305162:" #(#fn(":000n40V;I5040R340D:0B3Z00<R3T082;I504833<0702112263:A<0=1828364:0B3\x8d00<B3\x870730<r2523?074051R360O@=070250<2615442774051513=0A<0=182D64:833<0702112863:A<0=1D8364:0B3>070290<26164:01C:07021162:7029026164:" #(error
+	    #fn(":000n1\x8d\x8a5852085>1_485<00OO54421227305162:" #(#fn(":000n40V;I5040R340D:0B3Z00<R3T082;I504833<0702112263:A<0=1828364:0B3\x8d00<B3\x870730<r2523?074051R360O@=070250<2615442774051513=0A<0=182D64:833<0702112863:A<0=1D8364:0B3>070290<26164:01C:07021162:7029026164:" #(error
   "compile error: invalid argument list " ". optional arguments must come after required." length=
   caar "compile error: invalid optional argument " " in list " #fn(keyword?)
   ". keyword arguments must come last." "compile error: invalid formal argument ") check-formals)
-								 #fn(map)
-								 #fn("6000n10B390700<61:0:" #(keyword->symbol))
-								 to-proper) lambda-vars)
+								    #fn(map)
+								    #fn("6000n10B390700<61:0:" #(keyword->symbol))
+								    to-proper) lambda-vars)
 	    lambda:body #fn("6000n170061:" #(caddr) lambda:body) lambda:vars
 	    #fn("6000n1700T61:" #(lambda-vars) lambda:vars) last-pair #fn("6000n10=H3400:700=61:" #(last-pair) last-pair)
 	    lastcdr #fn("6000n10H3400:70051=:" #(last-pair) lastcdr) length=
@@ -274,12 +274,12 @@
 	    #fn("9000n2701E52340q:0<710=1K~52P:" #(<= list-head) list-head) list-ref #fn("7000n2700152<:" #(list-tail) list-ref)
 	    list-tail #fn("8000n2701E523400:710=1K~62:" #(<= list-tail) list-tail) list?
 	    #fn("6000n10V;I@040B;3904700=61:" #(list?) list?) load #fn("9000n120021522285>123850>2{:" #(#fn(file)
-  :read #fn("9000n0D\x8a48420A84>2_484<^1DDD63:" #(#fn("9000n320A51IB0F<21A5107215163:23A51472161:" #(#fn(io-eof?)
+  :read #fn("9000n0\x8d\x8a48420A84>2_484<^1\x8d\x8d\x8d63:" #(#fn("9000n320A51IB0F<21A5107215163:23A51472161:" #(#fn(io-eof?)
   #fn(read) load-process #fn(io-close))))) #fn("8000n120A5142122F0e361:" #(#fn(io-close)
 									   #fn(raise) load-error))) load)
 	    load-process #fn("6000n170061:" #(eval) load-process) lookup-sym
 	    #fn(";000n31J5020:1<2108752883808288P:7201=82KM63:" #(global #fn(assq) lookup-sym) lookup-sym)
-	    lower-define #fn(";000n1D20?540H;I804710513400:0<22C<0737405161:750<513K02627e10Te185051e17805164:2973062:" #(#fn("=000n170051B3N071051B3=02270051P@7073051@60745075855176855186J5087:278687e328298652P:" #(cddr
+	    lower-define #fn(";000n1\x8d20?540H;I804710513400:0<22C<0737405161:750<513K02627e10Te185051e17805164:2973062:" #(#fn("=000n170051B3N071051B3=02270051P@7073051@60745075855176855186J5087:278687e328298652P:" #(cddr
   cdddr begin caddr void get-defined-vars lower-define λ #fn(map)
   #fn("5000n17060:" #(void))) λ-body) quoted? define lower-define expand-define is-lambda? #fn(nconc)
   λ lastcdr #fn(map)) lower-define)
@@ -286,10 +286,10 @@
 	    macrocall? #fn("6000n10<R;3904700<61:" #(symbol-syntax) macrocall?) macroexpand-1
 	    #fn("7000n10H3400:7005185390850=}2:0:" #(macrocall?) macroexpand-1) make-code-emitter
 	    #fn("9000n0q2050EqEo5:" #(#fn(table)) make-code-emitter) make-label #fn("5000n12060:" #(#fn(gensym)) make-label)
-	    make-perfect-hash-table #fn(";000n1D\x8a58520_4D\x8a6862185860>3_486<^12205161:" #(#fn("8000n270712205151162:" #(mod0
-  abs #fn(hash)) $hash-keyword) #fn("=000n120r20i2O52D\x8a68621A085F86>5_486<^19261:" #(#fn(vector-alloc)
-											#fn(":000n10B3p070051r2A<85F52i29286G3;093<FKM61:928685p49286KM71051p494<0=61:92:" #(caar
-  cdar)))) #fn(length)) make-perfect-hash-table)
+	    make-perfect-hash-table #fn(";000n1\x8d\x8a58520_4\x8d\x8a6862185860>3_486<^12205161:" #(#fn("8000n270712205151162:" #(mod0
+  abs #fn(hash)) $hash-keyword) #fn("=000n120r20i2O52\x8d\x8a68621A085F86>5_486<^19261:" #(#fn(vector-alloc)
+  #fn(":000n10B3p070051r2A<85F52i29286G3;093<FKM61:928685p49286KM71051p494<0=61:92:" #(caar cdar))))
+  #fn(length)) make-perfect-hash-table)
 	    make-system-image #fn("<000n120021222354247576Dw54Dw64278788>2288685>22989>1{89504:" #(#fn(file)
   :write :create :truncate (*linefeed* *directory-separator* *argv* that *print-pretty*
 				       *print-width* *print-readably* *print-level* *print-length*
@@ -299,7 +299,7 @@
   #fn(top-level-value) #fn(string) #fn(memq) #fn(iostream?))) simple-sort #fn(environment)
   #fn(write) nconc #fn(map) list top-level-value #fn(io-write) *linefeed* #fn(io-close)))
   #fn("6000n1A50420061:" #(#fn(raise)))) make-system-image)
-	    map! #fn("8000n21D1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
+	    map! #fn("8000n21\x8d1B3B04101<51_41=?1@\x1d/4:" #() map!) map-int
 	    #fn(";000n2701E52340q:0E51qPq\x8a78786_4K7115122870>2|486:" #(<= 1- #fn("7000n1A<F051qPN4AA<=_:" #())) map-int)
 	    mark-label #fn("8000n270021163:" #(emit label) mark-label) max
 	    #fn(";000z11J400:70210163:" #(foldl #fn("6000n201L3401:0:" #())) max) member #fn("7000n21H340O:1<0d3401:7001=62:" #(member) member)
@@ -311,7 +311,7 @@
 	    #fn("8000\x8700001000\x880000I7070?0421072524D:" #(*output-stream* #fn(io-write)
 							       *linefeed*) newline)
 	    nreconc #fn("7000n2701062:" #(reverse!-) nreconc) odd?
-	    #fn("6000n170051S:" #(even?) odd?) partition #fn(":000n2D20?648601qe1qe164:" #(#fn("9000n48283PD1B3Z0401<513?0821<qPN=?2@<0831<qPN=?341=?1@\x05/47088<=88==62:" #(values) partition-)) partition)
+	    #fn("6000n170051S:" #(even?) odd?) partition #fn(":000n2\x8d20?648601qe1qe164:" #(#fn("9000n48283P\x8d1B3Z0401<513?0821<qPN=?2@<0831<qPN=?341=?1@\x05/47088<=88==62:" #(values) partition-)) partition)
 	    positive? #fn("7000n1700E62:" #(>) positive?) princ
 	    #fn(";000z070Ow042185>1220>12386>1{86504:" #(*print-readably* #fn("5000n0Aw0:" #(*print-readably*))
 							 #fn("7000n02071A62:" #(#fn(for-each) write))
@@ -321,9 +321,9 @@
   length= princ "type error: expected " ", got " #fn(typeof) caddr ": " print bounds-error "index "
   " out of bounds for " unbound-error "eval: variable " " has no value" error "error: " load-error
   print-exception "in file " list? #fn(string?) "*** Unhandled exception: " *linefeed*) print-exception)
-	    print-stack-trace #fn("@000n1DD\x8a5\x8a6852085>1_4862185>1_472730r3523F074075370r5@40r452@30051767728292:505252E\x8a92;2<868889>38762:" #(#fn("=000n32005182P2105121151C?022232487e361:25051E76278851512888A187>4|:" #(#fn(function:name)
+	    print-stack-trace #fn("@000n1\x8d\x8d\x8a5\x8a6852085>1_4862185>1_472730r3523F074075370r5@40r452@30051767728292:505252E\x8a92;2<868889>38762:" #(#fn("=000n32005182P2105121151C?022232487e361:25051E76278851512888A187>4|:" #(#fn(function:name)
   #fn(function:code) #fn(raise) thrown-value ffound #fn(function:vals) 1- #fn(length)
-  #fn("8000n170A0G513>0F<A0G929363:D:" #(closure?))) find-in-f)
+  #fn("8000n170A0G513>0F<A0G929363:\x8d:" #(closure?))) find-in-f)
   #fn(";000n220A01>321{863I02273247576865152275261:28:" #(#fn("8000n02021AF>292524O:" #(#fn(for-each)
 											#fn("8000n1A<0Fq63:" #())))
 							  #fn("6000n10B3F00<20C?00T21C8072061:23061:" #(thrown-value
@@ -345,7 +345,7 @@
 	    #fn("6000n10<20Q:" #(quote) quoted?) random #fn("7000n1200513<0712250062:23500i2:" #(#fn(integer?)
   mod #fn(rand) #fn(rand-double)) random)
 	    read-all #fn("7000n17071062:" #(read-all-of read) read-all) read-all-of
-	    #fn(":000n2D\x8a686201860>3_486<^1q015162:" #(#fn("8000n220A5138071061:F<10P92A5162:" #(#fn(io-eof?)
+	    #fn(":000n2\x8d\x8a686201860>3_486<^1q015162:" #(#fn("8000n220A5138071061:F<10P92A5162:" #(#fn(io-eof?)
   reverse!))) read-all-of)
 	    ref-int16-LE #fn(":000n2202101EMGE522101KMGr852M61:" #(#fn(int16)
 								   #fn(ash)) ref-int16-LE)
@@ -353,15 +353,15 @@
   #fn(ash)) ref-int32-LE)
 	    remprop #fn("8000n220711O5386;3F042286052;3:042386062:" #(#fn(get) *properties* #fn(has?)
 								      #fn(del!)) remprop)
-	    repl #fn(":000n0DD\x8a4\x8a58420_485218485>2_485<5047260:" #(#fn("8000n0702151422735142425{267751S;3F04788451798551485w:4D:" #(princ
+	    repl #fn(":000n0\x8d\x8d\x8a4\x8a58420_485218485>2_485<5047260:" #(#fn("9000n0702151422735142425{267751S;3[04788451798551360O@=07:855147;50485w<47=60:" #(princ
   "> " #fn(io-flush) *output-stream* #fn("5000n02060:" #(#fn(read)))
   #fn("6000n1207151422061:" #(#fn(io-discardbuffer) *input-stream* #fn(raise)))
-  #fn(io-eof?) *input-stream* load-process print that) prompt)
-									 #fn("6000n020A>121{3<072504F<60:O:" #(#fn("6000n0A<50;37047060:" #(newline))
-  #fn("6000n1700514D:" #(top-level-exception-handler)) newline) reploop) newline) repl)
+  #fn(io-eof?) *input-stream* load-process void? print newline that void) prompt)
+									       #fn("6000n020A>121{370F<60:O:" #(#fn("5000n0A<60:" #())
+  #fn("6000n1700514D:" #(top-level-exception-handler))) reploop) newline) repl)
 	    revappend #fn("7000n2701062:" #(reverse-) revappend) reverse
 	    #fn("7000n170q062:" #(reverse-) reverse) reverse! #fn("7000n170q062:" #(reverse!-) reverse!)
-	    reverse!- #fn("8000n2D1B3B041=101?04N4?1@\x1d/40:" #() reverse!-) reverse-
+	    reverse!- #fn("8000n2\x8d1B3B041=101?04N4?1@\x1d/40:" #() reverse!-) reverse-
 	    #fn("7000n21J400:701<0P1=62:" #(reverse-) reverse-) self-evaluating? #fn("7000n10H;36040RS;IK0420051;3A040R;3:04021051Q:" #(#fn(constant?)
   #fn(top-level-value)) self-evaluating?)
 	    set-syntax! #fn("8000n220710163:" #(#fn(put!)
@@ -376,17 +376,17 @@
 										#fn("7000n120AF52420A062:" #(#fn(io-write)))
 										#fn(iostream->string)) string-join)
 	    string-lpad #fn(":000n3207182122051~52062:" #(#fn(string) string-rep #fn(string-length)) string-lpad)
-	    string-map #fn("=000n2205021151ED8887L3O0422860231885251524748851?8@\r/^14258661:" #(#fn(buffer)
+	    string-map #fn("=000n2205021151E\x8d8887L3O0422860231885251524748851?8@\x0d/^14258661:" #(#fn(buffer)
   #fn(string-length) #fn(io-putc) #fn(string-char) 1+ #fn(iostream->string)) string-map)
 	    string-rep #fn(":000n21r4L3`0701E5235021:1Kl38022061:1r2l390220062:2200063:731513@02207401K~5262:742200521r2j262:" #(<=
   "" #fn(string) odd? string-rep) string-rep)
 	    string-rpad #fn(";000n32007182122051~5262:" #(#fn(string) string-rep #fn(string-length)) string-rpad)
 	    string-tail #fn("7000n2200162:" #(#fn(string-sub)) string-tail) string-trim
-	    #fn(">000n3DD\x8a7\x8a8872087>1_4882188>1_42205123087<01E895488<082895363:" #(#fn("9000n48283L3P02012108252523A0A<017282518364:82:" #(#fn(string-find)
+	    #fn(">000n3\x8d\x8d\x8a7\x8a8872087>1_4882188>1_42205123087<01E895488<082895363:" #(#fn("9000n48283L3P02012108252523A0A<017282518364:82:" #(#fn(string-find)
   #fn(string-char) 1+) trim-start) #fn(":000n37082E523R021122073825152523?0A<0173825163:82:" #(> #fn(string-find)
   #fn(string-char) 1-) trim-end) #fn(string-length)
   #fn(string-sub)) string-trim)
-	    symbol-set-doc #fn("9000\x8720003000\x882000I60O?24700211534823<0700228263:D:" #(putprop
+	    symbol-set-doc #fn("9000\x8720003000\x882000I60O?24700211534823<0700228263:\x8d:" #(putprop
   *doc* *funvars*) symbol-set-doc)
 	    symbol-syntax #fn("8000n120710O63:" #(#fn(get)
 						  *syntax-environment*) symbol-syntax)
@@ -409,12 +409,13 @@
 											print-stack-trace
 											#fn(stacktrace)))
 							  #fn("6000n1A50420061:" #(#fn(raise)))) top-level-exception-handler)
-	    trace #fn("A000n1200512150728551Ig0230742586262728290e286e3e22:e12;2985e286e3e4e35152@30D^1^142<:" #(#fn(top-level-value)
+	    trace #fn("A000n1200512150728551Ig0230742586262728290e286e3e22:e12;2985e286e3e4e35152@30\x8d^1^142<:" #(#fn(top-level-value)
   #fn(gensym) traced? #fn(set-top-level-value!) eval λ begin write cons quote newline apply ok) trace)
 	    traced? #fn("7000n170051;3?042105121A<51d:" #(closure? #fn(function:code)) #((#fn("9000z020210P51472504230}2:" #(#fn(write)
   x newline #.apply)))))
-	    untrace #fn("9000n1200517185513A0220238551r2G62:D:" #(#fn(top-level-value) traced? #fn(set-top-level-value!)
-								  #fn(function:vals)) untrace)
+	    untrace #fn("9000n1200517185513A0220238551r2G62:\x8d:" #(#fn(top-level-value) traced?
+								     #fn(set-top-level-value!)
+								     #fn(function:vals)) untrace)
 	    value-get-doc #fn("8000n10<0=208551;3=0486B;350485:" #(#fn(string?)) value-get-doc)
 	    values #fn("8000z00B3:00=J500<:A0P:" #() #(#1#)) vars-to-env
 	    #fn(":000n32021182>2072230515163:" #(#fn(map)
@@ -427,4 +428,5 @@
 								   #fn("9000n1A0F920G51p:" #())) vector-map)
 	    vinfo #fn("7000n30182e3:" #() vinfo) vinfo:heap? #.cadr vinfo:index
 	    #2# vinfo:sym #.car void
-	    #fn("5000n0D:" #() void) zero? #fn("6000n10El:" #() zero?))
+	    #fn("7000z0\x8d:" #() void) void? #fn("6000n10\x8dQ:" #() void?) zero?
+	    #fn("6000n10El:" #() zero?))
--- a/flisp.c
+++ b/flisp.c
@@ -313,7 +313,7 @@
 	if(init){
 		unsigned int i;
 		for(i = 0; i < n; i++)
-			vector_elt(v, i) = FL_unspecified;
+			vector_elt(v, i) = FL_void;
 	}
 	return v;
 }
@@ -992,6 +992,7 @@
 		GOTO_OP_OFFSET(OP_BOX),
 		GOTO_OP_OFFSET(OP_BOXL),
 		GOTO_OP_OFFSET(OP_SHIFT),
+		GOTO_OP_OFFSET(OP_LOADVOID),
 	};
 	NEXT_OP;
 #else
@@ -1246,6 +1247,10 @@
 			PUSH(FL_t);
 			NEXT_OP;
 
+		OP(OP_LOADVOID)
+			PUSH(FL_void);
+			NEXT_OP;
+
 		OP(OP_LOAD0)
 			PUSH(fixnum(0));
 			NEXT_OP;
@@ -1722,7 +1727,7 @@
 			FL(stack)[ipd] = (uintptr_t)ip;
 			s  = tofixnum(FL(stack)[FL(sp)-3]);
 			hi = tofixnum(FL(stack)[FL(sp)-2]);
-			v = FL_unspecified;
+			v = FL_void;
 			FL(sp) += 2;
 			n = FL(sp);
 			for(; s <= hi; s++){
@@ -1938,8 +1943,8 @@
 		for(uint32_t i = 1; i < sz; i++){
 			value_t si = FL(stack)[bp+i];
 			// if there's an error evaluating argument defaults some slots
-			// might be left set to UNBOUND (issue #22)
-			vector_elt(v, i+1) = si == UNBOUND ? FL_unspecified : si;
+			// might be left set to UNBOUND
+			vector_elt(v, i+1) = si == UNBOUND ? FL_void : si;
 		}
 		lst = fl_cons(v, lst);
 		top = FL(stack)[top-3];
--- a/flisp.h
+++ b/flisp.h
@@ -331,8 +331,8 @@
 	FL_nil = builtin(OP_LOADNIL),
 	FL_t = builtin(OP_LOADT),
 	FL_f = builtin(OP_LOADF),
+	FL_void = builtin(OP_LOADVOID),
 	FL_eof = builtin(OP_EOF_OBJECT),
-	FL_unspecified = FL_t,
 };
 
 #define N_GC_HANDLES 1024
--- a/gen.lsp
+++ b/gen.lsp
@@ -1,99 +1,100 @@
 (define opcodes '(
   ; C opcode, lisp compiler opcode, arg count, builtin lambda
-    OP_LOADA0         loada0    #f      0
-    OP_LOADA1         loada1    #f      0
-    OP_LOADV          loadv     #f      0
-    OP_BRF            brf       #f      0
-    OP_POP            pop       #f      0
-    OP_CALL           call      #f      0
-    OP_TCALL          tcall     #f      0
-    OP_LOADG          loadg     #f      0
-    OP_LOADA          loada     #f      0
-    OP_LOADC          loadc     #f      0
-    OP_RET            ret       #f      0
-    OP_DUP            dup       #f      0
-    OP_CAR            car       1       (λ (x) (car x))
-    OP_CDR            cdr       1       (λ (x) (cdr x))
-    OP_CLOSURE        closure   #f      0
-    OP_SETA           seta      #f      0
-    OP_JMP            jmp       #f      0
-    OP_LOADC0         loadc0    #f      0
-    OP_CONSP          cons?     1       (λ (x) (cons? x))
-    OP_BRNE           brne      #f      0
-    OP_LOADT          loadt     #f      0
-    OP_LOAD0          load0     #f      0
-    OP_LOADC1         loadc1    #f      0
-    OP_AREF2          aref2     #f      0
-    OP_ATOMP          atom?     1       (λ (x) (atom? x))
-    OP_BRT            brt       #f      0
-    OP_BRNN           brnn      #f      0
-    OP_LOAD1          load1     #f      0
-    OP_LT             <         2       (λ (x y) (< x y))
-    OP_ADD2           add2      #f      0
-    OP_SETCDR         set-cdr!  2       (λ (x y) (set-cdr! x y))
-    OP_LOADF          loadf     #f      0
-    OP_CONS           cons      2       (λ (x y) (cons x y))
-    OP_EQ             eq?       2       (λ (x y) (eq? x y))
-    OP_SYMBOLP        symbol?   1       (λ (x) (symbol? x))
-    OP_NOT            not       1       (λ (x) (not x))
-    OP_CADR           cadr      1       (λ (x) (cadr x))
-    OP_NEG            neg       #f      0
-    OP_NULLP          null?     1       (λ (x) (null? x))
-    OP_BOOLEANP       boolean?  1       (λ (x) (boolean? x))
-    OP_NUMBERP        number?   1       (λ (x) (number? x))
-    OP_FIXNUMP        fixnum?   1       (λ (x) (fixnum? x))
-    OP_BOUNDP         bound?    1       (λ (x) (bound? x))
-    OP_BUILTINP       builtin?  1       (λ (x) (builtin? x))
-    OP_FUNCTIONP      function? 1       (λ (x) (function? x))
-    OP_VECTORP        vector?   1       (λ (x) (vector? x))
-    OP_SHIFT          shift     #f      0
-    OP_SETCAR         set-car!  2       (λ (x y) (set-car! x y))
-    OP_JMPL           jmp.l     #f      0
-    OP_BRFL           brf.l     #f      0
-    OP_BRTL           brt.l     #f      0
-    OP_EQV            eqv?      2       (λ (x y) (eqv? x y))
-    OP_EQUAL          equal?    2       (λ (x y) (equal? x y))
-    OP_LIST           list      ANYARGS (λ rest rest)
-    OP_APPLY          apply     -2      (λ rest (apply apply rest))
-    OP_ADD            +         ANYARGS (λ rest (apply + rest))
-    OP_SUB            -         -1      (λ rest (apply - rest))
-    OP_MUL            *         ANYARGS (λ rest (apply * rest))
-    OP_DIV            /         -1      (λ rest (apply / rest))
-    OP_IDIV           div0      2       (λ rest (apply div0 rest))
-    OP_NUMEQ          =         2       (λ (x y) (= x y))
-    OP_COMPARE        compare   2       (λ (x y) (compare x y))
-    OP_ARGC           argc      #f      0
-    OP_VECTOR         vector    ANYARGS (λ rest (apply vector rest))
-    OP_ASET           aset!     -3      (λ rest (apply aset! rest))
-    OP_LOADNIL        loadnil   #f      0
-    OP_LOADI8         loadi8    #f      0
-    OP_LOADVL         loadv.l   #f      0
-    OP_LOADGL         loadg.l   #f      0
-    OP_LOADAL         loada.l   #f      0
-    OP_LOADCL         loadc.l   #f      0
-    OP_SETG           setg      #f      0
-    OP_SETGL          setg.l    #f      0
-    OP_SETAL          seta.l    #f      0
-    OP_VARGC          vargc     #f      0
-    OP_TRYCATCH       trycatch  #f      0
-    OP_FOR            for       3       (λ (a b f) (for a b (λ (x) (f x))))
-    OP_TAPPLY         tapply    #f      0
-    OP_SUB2           sub2      #f      0
-    OP_LARGC          largc     #f      0
-    OP_LVARGC         lvargc    #f      0
-    OP_CALLL          call.l    #f      0
-    OP_TCALLL         tcall.l   #f      0
-    OP_BRNEL          brne.l    #f      0
-    OP_BRNNL          brnn.l    #f      0
-    OP_BRN            brn       #f      0
-    OP_BRNL           brn.l     #f      0
-    OP_OPTARGS        optargs   #f      0
-    OP_BRBOUND        brbound   #f      0
-    OP_KEYARGS        keyargs   #f      0
-    OP_BOX            box       #f      0
-    OP_BOXL           box.l     #f      0
-    OP_AREF           aref      -2      (λ rest (apply aref rest))
-    OP_EOF_OBJECT     dummy_eof #f      0
+    OP_LOADA0         loada0     #f      0
+    OP_LOADA1         loada1     #f      0
+    OP_LOADV          loadv      #f      0
+    OP_BRF            brf        #f      0
+    OP_POP            pop        #f      0
+    OP_CALL           call       #f      0
+    OP_TCALL          tcall      #f      0
+    OP_LOADG          loadg      #f      0
+    OP_LOADA          loada      #f      0
+    OP_LOADC          loadc      #f      0
+    OP_RET            ret        #f      0
+    OP_DUP            dup        #f      0
+    OP_CAR            car        1       (λ (x) (car x))
+    OP_CDR            cdr        1       (λ (x) (cdr x))
+    OP_CLOSURE        closure    #f      0
+    OP_SETA           seta       #f      0
+    OP_JMP            jmp        #f      0
+    OP_LOADC0         loadc0     #f      0
+    OP_CONSP          cons?      1       (λ (x) (cons? x))
+    OP_BRNE           brne       #f      0
+    OP_LOADT          loadt      #f      0
+    OP_LOAD0          load0      #f      0
+    OP_LOADC1         loadc1     #f      0
+    OP_AREF2          aref2      #f      0
+    OP_ATOMP          atom?      1       (λ (x) (atom? x))
+    OP_BRT            brt        #f      0
+    OP_BRNN           brnn       #f      0
+    OP_LOAD1          load1      #f      0
+    OP_LT             <          2       (λ (x y) (< x y))
+    OP_ADD2           add2       #f      0
+    OP_SETCDR         set-cdr!   2       (λ (x y) (set-cdr! x y))
+    OP_LOADF          loadf      #f      0
+    OP_CONS           cons       2       (λ (x y) (cons x y))
+    OP_EQ             eq?        2       (λ (x y) (eq? x y))
+    OP_SYMBOLP        symbol?    1       (λ (x) (symbol? x))
+    OP_NOT            not        1       (λ (x) (not x))
+    OP_CADR           cadr       1       (λ (x) (cadr x))
+    OP_NEG            neg        #f      0
+    OP_NULLP          null?      1       (λ (x) (null? x))
+    OP_BOOLEANP       boolean?   1       (λ (x) (boolean? x))
+    OP_NUMBERP        number?    1       (λ (x) (number? x))
+    OP_FIXNUMP        fixnum?    1       (λ (x) (fixnum? x))
+    OP_BOUNDP         bound?     1       (λ (x) (bound? x))
+    OP_BUILTINP       builtin?   1       (λ (x) (builtin? x))
+    OP_FUNCTIONP      function?  1       (λ (x) (function? x))
+    OP_VECTORP        vector?    1       (λ (x) (vector? x))
+    OP_SHIFT          shift      #f      0
+    OP_SETCAR         set-car!   2       (λ (x y) (set-car! x y))
+    OP_JMPL           jmp.l      #f      0
+    OP_BRFL           brf.l      #f      0
+    OP_BRTL           brt.l      #f      0
+    OP_EQV            eqv?       2       (λ (x y) (eqv? x y))
+    OP_EQUAL          equal?     2       (λ (x y) (equal? x y))
+    OP_LIST           list       ANYARGS (λ rest rest)
+    OP_APPLY          apply      -2      (λ rest (apply apply rest))
+    OP_ADD            +          ANYARGS (λ rest (apply + rest))
+    OP_SUB            -          -1      (λ rest (apply - rest))
+    OP_MUL            *          ANYARGS (λ rest (apply * rest))
+    OP_DIV            /          -1      (λ rest (apply / rest))
+    OP_IDIV           div0       2       (λ rest (apply div0 rest))
+    OP_NUMEQ          =          2       (λ (x y) (= x y))
+    OP_COMPARE        compare    2       (λ (x y) (compare x y))
+    OP_ARGC           argc       #f      0
+    OP_VECTOR         vector     ANYARGS (λ rest (apply vector rest))
+    OP_ASET           aset!      -3      (λ rest (apply aset! rest))
+    OP_LOADNIL        loadnil    #f      0
+    OP_LOADI8         loadi8     #f      0
+    OP_LOADVL         loadv.l    #f      0
+    OP_LOADGL         loadg.l    #f      0
+    OP_LOADAL         loada.l    #f      0
+    OP_LOADCL         loadc.l    #f      0
+    OP_SETG           setg       #f      0
+    OP_SETGL          setg.l     #f      0
+    OP_SETAL          seta.l     #f      0
+    OP_VARGC          vargc      #f      0
+    OP_TRYCATCH       trycatch   #f      0
+    OP_FOR            for        3       (λ (a b f) (for a b (λ (x) (f x))))
+    OP_TAPPLY         tapply     #f      0
+    OP_SUB2           sub2       #f      0
+    OP_LARGC          largc      #f      0
+    OP_LVARGC         lvargc     #f      0
+    OP_CALLL          call.l     #f      0
+    OP_TCALLL         tcall.l    #f      0
+    OP_BRNEL          brne.l     #f      0
+    OP_BRNNL          brnn.l     #f      0
+    OP_BRN            brn        #f      0
+    OP_BRNL           brn.l      #f      0
+    OP_OPTARGS        optargs    #f      0
+    OP_BRBOUND        brbound    #f      0
+    OP_KEYARGS        keyargs    #f      0
+    OP_BOX            box        #f      0
+    OP_BOXL           box.l      #f      0
+    OP_AREF           aref       -2      (λ rest (apply aref rest))
+    OP_LOADVOID       loadvoid   #f      0
+    OP_EOF_OBJECT     dummy_eof  #f      0
 ))
 
 (define (for-each-n f lst n)
--- a/maxstack.inc
+++ b/maxstack.inc
@@ -13,7 +13,7 @@
 		case OP_LOADA: case OP_LOADI8: case OP_LOADV: case OP_LOADG:
 			ip++; // fallthrough
 		case OP_LOADA0: case OP_LOADA1:
-		case OP_DUP: case OP_LOADT: case OP_LOADF: case OP_LOADNIL:
+		case OP_DUP: case OP_LOADT: case OP_LOADF: case OP_LOADNIL: case OP_LOADVOID:
 		case OP_LOAD0:
 		case OP_LOAD1: case OP_LOADC0:
 		case OP_LOADC1:
--- a/opcodes.h
+++ b/opcodes.h
@@ -92,6 +92,7 @@
 	OP_BOX,
 	OP_BOXL,
 	OP_AREF,
+	OP_LOADVOID,
 	OP_EOF_OBJECT,
 	N_OPCODES
 };
--- a/print.c
+++ b/print.c
@@ -174,7 +174,7 @@
 	return (
 		isfixnum(v) || isbuiltin(v) || iscprim(v) ||
 		v == FL_f || v == FL_t ||
-		v == FL_nil || v == FL_eof
+		v == FL_nil || v == FL_eof || v == FL_void
 	);
 }
 
@@ -420,7 +420,9 @@
 			outsn("nil", f, 3);
 		else if(v == FL_eof)
 			outsn("#<eof>", f, 6);
-		else if(isbuiltin(v)){
+		else if(v == FL_void){
+			outsn("#<void>", f, 7);
+		}else if(isbuiltin(v)){
 			if(!FL(print_princ))
 				outsn("#.", f, 2);
 			outs(builtins[uintval(v)].name, f);
@@ -873,6 +875,6 @@
 		memset(FL(consflags), 0, 4*bitvector_nwords(FL(heapsize)/sizeof(cons_t)));
 
 	if((iscons(v) || isvector(v) || isfunction(v) || iscvalue(v)) &&
-		!fl_isstring(v) && v != FL_t && v != FL_f && v != FL_nil)
+		!fl_isstring(v) && v != FL_t && v != FL_f && v != FL_nil && v != FL_void)
 		htable_reset(&FL(printconses), 32);
 }
--- a/read.c
+++ b/read.c
@@ -698,7 +698,7 @@
 	case TOK_DOT:
 		parse_error(&ctx->loc, "unexpected '.'");
 	}
-	return FL_unspecified;
+	return FL_void;
 }
 
 value_t
--- a/system.lsp
+++ b/system.lsp
@@ -11,7 +11,8 @@
 ;; so it makes more sense to reduce the number of subtables for the *properties* table.
 (define *properties* (table))
 
-(define (void) #t)  ; the unspecified value
+(define (void . rest) #.(void))
+(define (void? x) (eq? x #.(void)))
 
 (unless (bound? '*syntax-environment*)
   (define *syntax-environment* (table)))
@@ -750,12 +751,11 @@
       (when funvars
         (newline)
         (print (cons term funvars)))
-      (newline)
-      #t)
+      (newline))
     (begin
       (princ "no help for " (string term))
-      (newline)
-      #f))))
+      (newline)))
+  (void)))
 
 ; toplevel --------------------------------------------------------------------
 
@@ -930,20 +930,19 @@
   (define (prompt)
     (princ "> ") (io-flush *output-stream*)
     (let ((v (trycatch (read)
-                       (λ (e) (begin (io-discardbuffer *input-stream*)
-                                          (raise e))))))
+                       (λ (e) (io-discardbuffer *input-stream*)
+                              (raise e)))))
       (and (not (io-eof? *input-stream*))
            (let ((V (load-process v)))
-             (print V)
+             (unless (void? V) (print V) (newline))
              (set! that V)
-             #t))))
+             (void)))))
   (define (reploop)
-    (when (trycatch (and (prompt) (newline))
+    (when (trycatch (prompt)
                     (λ (e)
                       (top-level-exception-handler e)
                       #t))
-          (begin (newline)
-                 (reploop))))
+          (reploop)))
   (reploop)
   (newline))