Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

automagic type-check optimization?

6 views
Skip to first unread message

luser- -droog

unread,
Jan 18, 2011, 11:24:26 PM1/18/11
to
IIRC, Crispin Goswell's interpreter used an elegant method
of dispatching polymorphic operators by using a dictionary
of type->type-specific-operator pairs. While I haven't fully
explored how to do this yet, it seems like you could use
this 'type-map' to give 'bind' the superpower to omit
typechecks for operators who "know" what should be
on the stack.

eg.
/inch {72 mul} bind def

'bind' receives a 2-element executable array
containing the integer 72 and the name mul.
it notes the type of 72 (pushing /integer to it's internal stack)
it looks up the name mul and finds a polymorphic operator
that can accept an integer or a real on top of the stack
and notices that the stack image consists of an integer,
and replaces the name object with a polymorphic operator
that already "knows" that the top is an integer and needs
only to dispatch on the second element (or stackunderflow
if it's at the bottom of stack).
'bind' then returns the (optimized) procedure.

Do any existing interpreters go this far?
Is there further to go?

SaGS

unread,
Jan 19, 2011, 1:39:03 AM1/19/11
to
On Jan 19, 6:24 am, luser- -droog <mijo...@yahoo.com> wrote:
> ...

> /inch {72 mul} bind def
>
> 'bind' receives a 2-element executable array
> containing the integer 72 and the name mul.
> it notes the type of 72 (pushing /integer to it's internal stack)
> it looks up the name mul and finds a polymorphic operator
> that can accept an integer or a real on top of the stack
> and notices that the stack image consists of an integer,
> and replaces the name object with a polymorphic operator
> that already "knows" that the top is an integer and needs
> only to dispatch on the second element (or stackunderflow
> if it's at the bottom of stack).
> 'bind' then returns the (optimized) procedure.
> ...

Not a good idea.
The following won’t beheave as prescribed in the PLRM:

/will-work { 1 1 mul } bind def
/will-fail { 1.0 1.0 //will-work 2 get exec } bind def

will-work = % OK
will-fail = % KO
quit

ThomasW

unread,
Jan 19, 2011, 1:47:24 AM1/19/11
to

This code would fail:

/addSomething {
1 add
} bind def

/addSomething load 0 .5 put

2 addSomething

luser- -droog

unread,
Jan 19, 2011, 1:49:57 AM1/19/11
to

Yeah. ok. Even worse: it would try to interpret raw bits for
any object as though it were an integer. What's the result
of multiplying two names?!

Helmar

unread,
Jan 19, 2011, 4:09:37 AM1/19/11
to

Well, the idea to make it inside the accessible parts of an object is
bad.
But I could imagine it's possible to write a JIT-compiler that works
without that you notice it (except the higher execution speed).
That would be a lot of work to get it correct.

Regards,
-Helmar

luser- -droog

unread,
Jan 22, 2011, 3:27:15 AM1/22/11
to
On Jan 19, 12:39 am, SaGS <sags5...@gmail.com> wrote:

What if I give it a different name, like bindfast?

And does anyone actually do what the example here shows?
Pull an operator out of a bound procedure and execute it?
While I accept the counterexample as valid, it does seem
a little artificial.

ThomasW

unread,
Jan 22, 2011, 4:25:10 PM1/22/11
to
On 22 Jan., 09:27, luser- -droog <mijo...@yahoo.com> wrote:
>
> And does anyone actually do what the example here shows?
> Pull an operator out of a bound procedure and execute it?
> While I accept the counterexample as valid, it does seem
> a little artificial.

Yes, I do things like this sometimes (not only pull something from a
bound procedure, but also put something into it). One example where I
remember having done this: I wrote a PS program that reads binary
files that are used by a specific application to store symbols. The
symbols are polygons/polylines (unclosed polygons) with filled and/or
stroked parts. Each vertex is represented by three values: x/y
coordinates and a "z" value (ranging from 0 to 3) that says what kind
of vertex it is. I put the action that is associated with the z value
into an array like this:

/z_action
{
%Line (z = 0)
lineto
{%Jump (z = 1) %paint_proc x y
3 -1 roll exec %x y
moveto %-empty-
{stroke} %paint_proc'
}
{%Fill (z = 2) %paint_proc x y
3 -1 roll exec
moveto
{gsave eofill grestore stroke}
}
%JmpFil (z = 3)
moveto
} bind cvlit def


Later, when I read the z value from the file, I execute the associated
command like this:


//z_action exch get exec


I don't think it's a good idea to speculate about what programmers
will or won't do.

Thomas W.

0 new messages