logoalt Hacker News

lispm10/12/20241 replyview on HN

> So I think the compiler may not be able to compile calls to arbitrary functions?

A Lisp compiler will by default compile a call to ANY function as a "jump subroutine" (or as a non-returning jump in the case of a tail call) machine code call. The function then has to be present at runtime (in the runtime) and the code will call it at runtime. Lisp code by default also calls a global function through its symbol's cell -> late binding.

"supported by the compiler" here probably means that the compiler can generate inline code for these functions in various cases. Thus if the call is to the function 1+ and it knows that the argument is an integer number (and, possibly, the result also has to be an integer number), then it will not use a subroutine call via the global function, but will inline the call to an integer addition machine instruction. Obviously this then defeats late binding.

If a Lisp (for a tiny machine) only has fixnum integers as its single numeric data type, then the thing is simple -> every 1+ will get an integer argument and thus one can inline it. Inlining makes for tiny computers (which uLisp was developed for) only sense if the inlined function code isn't too long and doesn't use to much of the precious memory for the machine code. Inlining OTOH like will have a positive effect in reducing execution time and a negative effect by increasing compilation time.

In languages like Common Lisp or Scheme, which have several numeric types (fixnums, bignums, floats, ratios, complex, ...) this gets more complicated. Common Lisp compilers typically use optional type declarations and type inference to determine what inlined code to generate.


Replies

kragen10/12/2024

What you say about Lisp compilers in general is correct; probably the uLisp author would learn some things from it.

With respect to uLisp itself, however, maybe you should read the code too.