I got your drift. What you are proposing is that the primitive 'set'
be revised to be tighter even if it is slow, but the backend can be
optimised because 90% of the time we know at compile time that the
global is not a boolean etc. and hence those slow 'set's can be
optimised to be fast because we can compile them out to fast code.
I'd agree there is merit in this but
1. There are some dynamically generated 'sets' e.g. (set (hd X) (tl
X)) which cannot be optimised.
2. W.O. type checking, the info on the type is not there to make any
optimisation.
3. We end up with a primitive that is inherently so inefficient that
porters must avoid it and compile around it whenever they can.
4. If we are aiming at weak portability then we don't have to rise to
this challenge. If we want strong portability we have to deal with
other challenges - like Ramil's concatenating '+' sign. Actually it
would be good to hear him on this.
You put down some good arguments though. Let's put this one down as
open for now.
Mark
On Apr 4, 4:57 am, Greg Spurrier <
greg.spurr...@gmail.com> wrote:
> I was not clear enough in my wording and it is possible that the point that
> I was trying to make was not clear. By 'compiler', I have been referring to
> the KLambda-to-host compiler, not the Shen-to-KLambda compiler. I will use
> the term KLHC below to avoid confusion.
>
> Please allow me one more attempt at arguing in favor of requiring the first
> arugment to 'set' to be a symbol and explaining how I think this can be
> implemented at an acceptable cost. If you still disagree, then I will have
> given it my best shot and will fully embrace your decision.
>
> In the KLambda sources for Shen 9.2, there are 66 uses of 'set'. 62 of
> these have symbol literals as their first argument. For those, the KLHC can
> emit the most efficient 'set' code possible because it knows that no
> run-time check is necessary. In the other 4 cases (one of which is a
> lexically-scoped variable reference; the others are function applications),
> the KLHC can emit a run-time check to validate that the first argument has
> evaluated to a symbol, followed by the actual set code.
>
> To put this in more concrete terms, I am suggesting that the CLisp
> implementation of KLambda transform (set X Y) to either:
>
> `(SET ,X ,Y)
>
> or something along the lines of:
>
> `(LET ((*C* ,X))
> (IF (OR (EQ *C* 'true) (EQ *C* 'false))
> (ERROR "~A is not a symbol" *C*)
> (SET *C* ,Y)))))
>
> depending on whether X is a known symbol literal. The run-time check
> maximizes performance by taking advantage of the fact that SET already
> raises an error if its argument is not a Common Lisp symbol (see NOTE
> below). It just needs to reject the Common Lisp symbols 'true and 'false.
> An added check with SYMBOLP could of course be added to unify the error
> messages.
>
> We should, of course, question how often these run-time checks will be
> encountered in practice. I instrumented the ShenRuby compiler and run-time
> environment to gather this data. During the loading of the KL sources for
> Shen, 'set' is invoked 1,646 times. Zero run-time checks occur. During the
> loading and execution of the Shen test suite, 'set' is invoked 203,602
> times. Only 10 of these invocations required run-time checks. (Note, there
> is one test that does not run to completion because of stack overflow, so
> other's numbers may vary slightly if this experiment is repeated).
>
> Given these statistics, the additional overhead for a run-time check in the
> targeted cases that require them will have a negligible impact on the
> overall performance of the system. Therefore, I am of the opinion that the
> benefits for portability outweigh the performance impact.
>
> NOTE: the run-time check in my example code above is slightly more
> permissive than I would like. It will accept any Common Lisp symbol other
> than 'true and 'false. Given that 'intern' is allowed to produce
> non-boolean values that will return false for 'symbol?' there are other
> valid Common Lisp symbols that should be rejected. This could be fixed with
> a more expensive run-time check (it is perhaps this check that you are
> referring to as being 50X slower than SET), or by tightenening the spec for
> 'intern' so that it raises an error if given a string that would produce a
> value that satisfies neither 'boolean?' nor 'symbol?'. I prefer the latter
> because it also enhances portability, but IMHO, the former is also
> acceptable given the infrequency of it coming into play.
>
> Regards,
> Greg