With a little bit of complexity we could improve efficiency (e.g. using VList instead of singly-linked list.) But I want to tackle efficiency by compilation, and write the compiler(s) in Prolog. I think that avoids complexity compared to intricating the guts of the interpreter by hand, and moves the unavoidable complexity into formal statements of logic that can be evaulated by machine (aka Prolog.) --------------------------------------- So how do we want to handle definitions? Read a defs.txt file at compile time? Build defs.c from defs.txt? void defname(JoyListPtr stack, JoyListPtr expression) { def_node = some C initializer? def_node = text_to_expression("dup mul"); push_quote(def_node, expression); } ...? I think the easiest thing to do at the mo' would be to hardcode the defs as an array of strings and then read them and convert at start time? /*mpz_t pi;*/ /*char *text = (char *)TEXT;*/ /*mpz_init_set_str(pi, "3141592653589793238462643383279502884", 10);*/ /*mpz_init_set_str(pi, "25d0c79fe247f31777d922627a74624", 16);*/ /*GC_register_finalizer(pi, my_callback, NULL, NULL, NULL);*/ /*el = push_integer_from_str("3141592653589793238462643383279502884", 0);*/ /*el->tail = text_to_expression(text);*/ /*el = text_to_expression(text);*/ /*print_list(el);*/ /*printf("\n");*/ concat cons dip dup first loop pop rest stack swaack swap pop_any(), pop_int(), and add With cmp (provided by the GMP lib) we can implement the rest of the comparison functions as definitions: G E L eq [false] [true] [false] cmp gt [true] [false] [false] cmp lt [false] [false] [true] cmp neq [true] [false] [true] cmp le [false] [true] [true] cmp ge [true] [true] [false] cmp