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.
Luke