On 9/12/05, Yuval Kogman <[EMAIL PROTECTED]> wrote:
> Hi,

Hi.  These are superficial thoughts, before I've had time to really
think about the Big Picture.

> 2.      each block of code has a cryptographic digest, which is the hash
>         of it's body with the digests of all the functions it calls.
>         This digest is stable regardless of optimization semantics, and
>         is applied to the PIL structure.

Okay, a little clarification needed here.  Is the digest of the code
itself a collection of digests, one for the lexical body, and one for
each funciton it calls (1)?  Or is it a hash that combines all of
those somehow?

How do you deal with recursive/mutually recursive functions?  (I'm
pretty sure there's a way, I just can't think of it)

What about "temp &foo = sub {...}" ?

> 5.      Functions have a notion of equivelence. This is managed based on
>         the digest. For example
>                 my &c_int_mul = BEGIN { Code::Foreign.new(:language<C>, 
> :body("
>                         int foo (int x, int y) { return x * y }
>                 ") };
>                 multi &infix:<*> (int $x, int $y --> int) {
>                         [+] $x xx $y;
>                 }
>                 my $str = &infix:<*><int, int --> int>.digest; # must specify 
> the variant

You mean:

    my $str = &infix:<*>:(int, int --> int).digest;

Also, you said that the digest contains the digests of all called
functions.  How do you deal with multis there, which may depend on the
runtime types?

>                 &c_int_mul.set_equiv($str); # could be in another file
>                 # or, if they are maintained together
>                 &c_int_mul.set_equiv(&infix:<*><int, int --> int>);
>         This equivelence is with respect to the semantics of the input
>         and output. The test suite supposedly can assure that these are
>         really equivelent by running the same tests against either
>         version.

Okay, good.  So you have a way of marking that two functions do the
same thing, without having the program try to figure that out (which
is impossible).  That's something that Haskell didn't figure out :-)

I suppose it would be nice to have subtype semantics, in that
"function A does the same thing as function B for all arguments that
are valid for function B (but function A may have additional
functionality for arguments that are not valid for B)".  Then you
specify equivalence by specifying subtype equivalence in both
directions (with a shortcut, of course).

> 9.      static analysis may be leveraged to compile direct calls to
>         native functions when compile time resolution is possible. In
>         the example graph, for example, no eval or symbol table
>         assignments are made, so there is no way the code will ever
>         change. Hence the entire program can be pre-resolved. This
>         should be controlled via the 'optimize' pragma.

Rather than having the compiler try to infer for itself, which would
come up negative 99% of the time and just waste compile time.

> Since FFIs are going to be a core feature of perl 6, they can be
> used to bootstrap the whole compilation process. In effect, the
> "primitive" operations are now just FFI calls to the runtime we
> happen to be executing on.

And if you have a circular reference implementation, the implementors
can decide to implement whatever generating subset is easiest and get
a working Perl.  I like this.

Hmm, could we pull the idea of a generating subset out to
roles/theories?  That is, have a role specify that "a" and "b" are
implemented in terms of each other, so if you provide one, you fulfill
the role contract.  In Haskell, if you don't fulfill a class contract
that's mutually recursive, you get infinite loops.  It be nice to
catch that.

Then I guess we would have "theory PerlCore".  Neat.

> To make things modular, the paring of FFI and pure perl functions is
> orthogonal to their location of definition based on the hashing
> scheme.

So as we're hashing PIL, we'd leave out line number information and whatnot.

> WRT MMD, you can set the entire MM equivalent to
> a certain foreign function, and you can also set any variant
> individually. You can even set a single variant to be equivalent to
> a multimethod to make the FFI implementation simpler. The compiler
> simply presents the runtime with all the possible MMD choices, and
> lets the runtime choose between conflicting ones.

Like a nice "wrapping" MMD scheme ought to.

All in all, I like the idea.  I hope there are no major technical
hurdles.  The hashing scheme scares me a little, because it's easy to
create equivalent code that does not look the same from PIL, but it
seems like you covered that base.


Reply via email to