+
+: if? ( obj -- obj bool )
+ if-symbol tagged-list? ;
+
+: if-predicate ( ifobj -- pred )
+ cdr car ;
+
+: if-consequent ( ifobj -- conseq )
+ cdr cdr car ;
+
+: if-alternative ( ifobj -- alt|false )
+ cdr cdr cdr
+ 2dup nil objeq? if
+ 2drop false
+ else
+ car
+ then ;
+
+: false? ( boolobj -- boolean )
+ boolean-type istype? if
+ false boolean-type objeq?
+ else
+ 2drop false
+ then
+;
+
+: true? ( boolobj -- bool )
+ false? invert ;
+
+: lambda? ( obj -- obj bool )
+ lambda-symbol tagged-list? ;
+
+: lambda-parameters ( obj -- params )
+ cdr car ;
+
+: lambda-body ( obj -- body )
+ cdr cdr ;
+
+: make-procedure ( params body env -- proc )
+ nil
+ cons cons cons
+ drop compound-proc-type
+;
+
+: application? ( obj -- obj bool)
+ pair-type istype? ;
+
+: operator ( obj -- operator )
+ car ;
+
+: operands ( obj -- operands )
+ cdr ;
+
+: nooperands? ( operands -- bool )
+ nil objeq? ;
+
+: first-operand ( operands -- operand )
+ car ;
+
+: rest-operands ( operands -- other-operands )
+ cdr ;
+
+: list-of-vals ( args env -- vals )
+ 2swap
+
+ 2dup nooperands? if
+ 2swap 2drop
+ else
+ 2over 2over first-operand 2swap eval
+ -2rot rest-operands 2swap recurse
+ cons
+ then
+;
+
+: apply ( proc args )
+ 2swap dup case
+ primitive-proc-type of
+ drop execute
+ endof
+
+ compound-proc-type of
+ ." Compound procedures not yet implemented."
+ endof
+
+ bold fg red ." Object not applicable. Aboring." reset-term cr
+ abort
+ endcase
+;
+
+:noname ( obj env -- result )