Re: PDD 2, vtables

2001-02-06 Thread Alan Burlison

Branden wrote:

> Where can I find how Perl5's stack works (specially about parameter passing
> and returning from subs)?

Oh boy.  What a masochist.

;-)

Alan Burlison



Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 05:41 PM 2/6/2001 -0200, Branden wrote:

>Sorry, I promess it's the last reply for today! Please don't rant on me!

I have not yet begun to rant. :) And I won't start, either. (And you 
certainly don't have to stop arguing your point. I don't claim to hold some 
sort of divine inspiration on interpreter or vtable design. And I can be 
rather dense sometimes...)

>Dan Sugalski wrote:
> > At 04:23 PM 2/6/2001 -0200, Branden wrote:
> > >Dan Sugalski wrote:
> > > > Don't forget we have an opcode machine here--we are *not* emitting C
>code
> > > > to be compiled. That means we're going to be storing temps in a
>register
> > > > file of some sort. (Or pushing them on a stack, or whatever) That
>means
> > > > that if we generate intermediaries that aren't PMCs then we need extra
> > >temp
> > > > space for them. Your way will mean an int, num, and string stack (or
> > > > register file, or whatever) in addition to a PMC stack/register
> > > > file/whatever. That's more stuff to track. (Which isn't to say we
>won't,
> > > > mind. We will if we have to)
> > > >
> > >
> > >I know that (althought I don't have the exact definition of opcode yet).
>I
> > >wrote C code only to illustrate my point.
> > >
> > >If a opcode is what I'm thinking, in the fact that the interpreter
>executes
> > >a opcode kind of atomically, like a machine instruction in assembly, then
>I
> > >would like to say that the entries you are proposing to the vtables are
> > >probably much better as opcodes than mine. But I'm actually not saying
>that
> > >one vtable function call should be a opcode. I mean, an `add' instruction
> > >could be built above that that would do all that at once, and that could
>be
> > >the opcode...
> >
> > If I was feeling crankier, I'd rant here for a moment. I'm not, though, so
> > I won't. (And please, everyone, lets also be a touch restrained)
> >
> > Perl is an interpreter, one that executes a stream of opcodes. That fact
> > *must* be kept in mind, as it places constraints that must be heeded for
> > speed. Your scheme may be a bit faster (certainly conceptually simpler)
> > than the one I'm proposing for a direct-to-C translator, but we're not
> > writing that--we're writing an interpreter. Different beasts.
> >
> > Think of the perl interpreter as a big CPU, with none of the neato-keen
> > tricks available to it that modern designers have. You'll find that the
> > design will tend towards a more CISC-like architecture than a RISC-like
>one.
> >
> > >I actually don't see a reason why the vtable entries should be the
>opcodes.
> > >Is there?
> >
> > Speed.
> >
>
>
>Actually, I don't see the problem of defining a C function that would do:
>
> void add(SVAR *result, SVAR *lop, SVAR *rop, SVAL *tmp1, SVAL *tmp2) {
> /* tmp comes from the temporary file */
> lop->vtable->FETCH(tmp1, lop);
> rop->vtable->FETCH(tmp2, rop);
> lop->vtable->ADD(tmp1, tmp1, tmp2);
> result->vtable->STORE(result, tmp1, tmp2);
> }
>
>And have it be my opcode. Passing the indexes wouldn't be a problem either.
>Is there any problem here?

Well, no, but what's the point? If you're calling lop's ADD vtable entry, 
why not have that entry deal with the rest of it, rather than stick things 
into, and later remove them, from temp slots?

>(Calm down, I'll also stop with the UNIX thing...)

That one's up to you. Doesn't bother me (despite my rep as "that damn VMS 
guy"... :) but the point I was (probably badly) making was important. There 
are a number of ways to do things, and the way that X does it (where X 
could be Unix, or VMS, or Windows, or even X) isn't necessarily the best 
way overall. It's usually a good way given other design constraints (well, 
except perhaps for signals, but we won't go there), but good is always 
relative to other things. In all engineering efforts there are tradeoffs, 
and things that seem really good taken alone end up being less good than 
other alternatives given the design choices already made.

Of course, I could be wrong here. Wouldn't be the first time, and not the 
last I'm sure.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Magic [Slightly Off-Topic... please point me to documentation]

2001-02-06 Thread Branden

Garrett Goebel wrote:
> > > package bar;
> > > @ISA = qw(foo);
> > > sub new {  bless \my $key; \$key }
> >

It appears you're blessing one reference and returning another... like

sub new {
my $key;
my $a = \$key;
my $b = \$key;
bless $a;
return $b;
}

I think the problem is not with the overloading magic, but with the code
snippet...

- Branden




Re: Magic [Slightly Off-Topic... please point me to documentation ]

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 01:38:56PM -0600, Garrett Goebel wrote:
> I'm sorry... I didn't mean to start an off-topic thread. 

This is currently being discussed on p5p, so you might want to take it over
there.

> Is there really no substantial documentation anywhere on magic?

Not yet. This looks like something that we can fix. What I'll try and do,
although I make no promises, is make sure that either Tim or I [1] finds out
all about magic, writes up some documentation and pushes some of it back to
perlguts.pod, since it looks like there is definitely a crying need for people
to understand this.

> I suppose that is why it is called magic, eh?

Yup!

[1] Tim Jenness has written a section about magic in a book we're writing on
Perl and C interaction. However, what we've got at the moment isn't much more
than what's in perlguts.
-- 
"Darkly hinting of head hitting desk" 
-- Megahal (trained on asr), 1998-11-05



Re: PDD 2, vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 05:21:03PM -0200, Branden wrote:
> Where can I find how Perl5's stack works (specially about parameter passing
> and returning from subs)?

4 steps:

1) Read the things I just mentioned.
2) Compile Perl with -DDEBUGGING, and run a very simple program with perl -Dts
3) Exchange the program with a slightly more complex one.
4) goto 2;

-- 
Doubt is a pain too lonely to know that faith is his twin brother.
- Kahlil Gibran



Re: Another approach to vtables

2001-02-06 Thread Branden


Sorry, I promess it's the last reply for today! Please don't rant on me!


Dan Sugalski wrote:
> At 04:23 PM 2/6/2001 -0200, Branden wrote:
> >Dan Sugalski wrote:
> > > Don't forget we have an opcode machine here--we are *not* emitting C
code
> > > to be compiled. That means we're going to be storing temps in a
register
> > > file of some sort. (Or pushing them on a stack, or whatever) That
means
> > > that if we generate intermediaries that aren't PMCs then we need extra
> >temp
> > > space for them. Your way will mean an int, num, and string stack (or
> > > register file, or whatever) in addition to a PMC stack/register
> > > file/whatever. That's more stuff to track. (Which isn't to say we
won't,
> > > mind. We will if we have to)
> > >
> >
> >I know that (althought I don't have the exact definition of opcode yet).
I
> >wrote C code only to illustrate my point.
> >
> >If a opcode is what I'm thinking, in the fact that the interpreter
executes
> >a opcode kind of atomically, like a machine instruction in assembly, then
I
> >would like to say that the entries you are proposing to the vtables are
> >probably much better as opcodes than mine. But I'm actually not saying
that
> >one vtable function call should be a opcode. I mean, an `add' instruction
> >could be built above that that would do all that at once, and that could
be
> >the opcode...
>
> If I was feeling crankier, I'd rant here for a moment. I'm not, though, so
> I won't. (And please, everyone, lets also be a touch restrained)
>
> Perl is an interpreter, one that executes a stream of opcodes. That fact
> *must* be kept in mind, as it places constraints that must be heeded for
> speed. Your scheme may be a bit faster (certainly conceptually simpler)
> than the one I'm proposing for a direct-to-C translator, but we're not
> writing that--we're writing an interpreter. Different beasts.
>
> Think of the perl interpreter as a big CPU, with none of the neato-keen
> tricks available to it that modern designers have. You'll find that the
> design will tend towards a more CISC-like architecture than a RISC-like
one.
>
> >I actually don't see a reason why the vtable entries should be the
opcodes.
> >Is there?
>
> Speed.
>


Actually, I don't see the problem of defining a C function that would do:

void add(SVAR *result, SVAR *lop, SVAR *rop, SVAL *tmp1, SVAL *tmp2) {
/* tmp comes from the temporary file */
lop->vtable->FETCH(tmp1, lop);
rop->vtable->FETCH(tmp2, rop);
lop->vtable->ADD(tmp1, tmp1, tmp2);
result->vtable->STORE(result, tmp1, tmp2);
}

And have it be my opcode. Passing the indexes wouldn't be a problem either.
Is there any problem here?




(Calm down, I'll also stop with the UNIX thing...)

- Branden




RE: Magic [Slightly Off-Topic... please point me to documentation]

2001-02-06 Thread Garrett Goebel

From: Branden [mailto:[EMAIL PROTECTED]]
> 
> try to define a method in package bar and try to call it
> from $bar, like $bar->foo. Won't work either, you have
> to ${$bar}->foo. Overloading should loose the magic
> in the same sense that the method should not be called.

No, $bar->asString and $baz->asString both work. They produce:

Hello World


> > package bar;
> > @ISA = qw(foo);
> > sub new {  bless \my $key; \$key }
> 
> You return a reference to the object...

No, it returns an object reference... Try it.

 
> Try printing $$bar, it will work...

No, it doesn't. $$bar is an undefined scalar.


sub new { my $ref = \ my $key; bless $ref; $ref }
  and
sub new { bless \ my $key; \$key; }
 
Both return an object reference. The former has magic, the latter does not.

I'm sorry... I didn't mean to start an off-topic thread. Unless someone can
find a way to shoe-horn in a discussion of language or internals magic
handling for Perl6?  Is there really no substantial documentation anywhere
on magic? I suppose that is why it is called magic, eh?


package foo;
use overload '""' => 'asString';
sub asString { 'Hello World' }

package bar;
@ISA = qw(foo);
sub new {  bless \my $key; \$key }

package baz;
@ISA = qw(foo);
sub new { my $ref = \ my $key; bless $ref; $ref }

package main;
my ($bar, $baz);
$bar = bar::->new();
$baz = baz::->new();

print "\$bar$bar\n";
print "\$baz$baz\n";
print "\$bar->asString  ", $bar->asString, "\n";
print "\$baz->asString  ", $baz->asString, "\n";
print "\$\$bar  ", $$bar, "\n";

Results In:
$barbar=SCALAR(0x1bbfc9c)
$bazHello World
$bar->asString  Hello World
$baz->asString  Hello World
$$bar



Re: Another approach to vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 04:23:06PM -0200, Branden wrote:
> What's exactly a op dispatch? I _really_ don't know that. Please tell me so
> that I can answer this...
> ...
> I know that (althought I don't have the exact definition of opcode yet).

Oh boy. Look, Dan's been Good Cop, now it's my turn. And even I'm going to be
a bit more restrained than usual. That ought to impress you. :)

These are fundamental principles when we're dealing with interpreters. If you
wish to be a useful help to people implementing an interpreter, it helps *us*
if you know something about the fundamentals of the subject. Now, this isn't a
"bugger off until you know what you're talking about" because I've spent many
hours of my life writing documentation for people *just like you* to find out
all about how the Perl interpreter works. It saddens me when I've made these
things available to people who need to know them, and they don't use them.

Can I suggest, then, that you (and everyone else out there who needs to know
how Perl works - and if you don't know, then you need to) at least have a look
at

http://simon-cozens.org/writings/perlhacktut.html

and, if possible, perlhack.pod and perlguts.pod in the perl 5.7.0 distribution?
(perlguts.pod used to be just about data structures, but in 5.7.0 and above
it's been grealy expanded.)

Because I'm feeling *extra nice* today, I've HTML-ified the latest versions of
perlhack.pod and perlguts.pod, so you don't have to download the whole
distribution, and you can find those at
http://simon-cozens.org/writings/perlhack.html
http://simon-cozens.org/writings/perlguts.html

These should really be required reading for Perl 6 hackers. 

-- 
If they can put a man on the moon, why can't they put them all there?



Re: PDD 2, vtables

2001-02-06 Thread Branden

Simon Cozens wrote:
> On Tue, Feb 06, 2001 at 05:01:38PM -0200, Branden wrote:
> > How is a list currently (Perl5) implemented?
>
> It's a bunch of SVs sitting on the stack, followed by a mark.
>

Where can I find how Perl5's stack works (specially about parameter passing
and returning from subs)?

- Branden




Re: PDD 2, vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 05:01:38PM -0200, Branden wrote:
> How is a list currently (Perl5) implemented? 

It's a bunch of SVs sitting on the stack, followed by a mark.

> Which operations does it support?

None.

-- 
Rule the Empire through force.
-- Shogun Tokugawa



Re: Another approach to vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> >In a certain way, overloading is a way to attach magic to a value, in
Perl5.
> >I don't know how it's implemented, but if $a contains an object that has
> >overloaded behaviour, and I do $b = $a, $b will contain a pointer to the
> >same object, with the same overloaded behaviour.
>
> It shouldn't. What $b should have is a *copy* of the data in $a, with the
> same overloading magic. Otherwise altering $a would alter $b, which isn't
> what you want.
>

That's why I propose separating add/subtract/multiply/... magic from
store/fetch magic. The former should be passed with the value (because it is
what gives meaning to the value), while the latter is really a thing of tied
variables.



> >I think in Perl5, it's not
> >possible to attach magic behaviour to an individual object, but only to a
> >class of them, so it wouldn't be possible to attach magic to the string
> >"foo", for instance...
>
> Magic can only be attached to individual [SAHG]Vs. It can't be attached to
> whole classes of things.

Sorry, wrong terminology. I was talking about overloading, which is kind of
magic in the sense that it does something special too...



> Now, all things of the same type have the same set
> of magic routines, but that's not the same thing. (And you can attach
magic
> to the string "foo", though attaching magic to string constants requires
> doing some evil things...)
>

Indeed I can attach it, but it gets away as soon as I try to store it in a
variable, so it's useless, in this sense. And the kind of magic I was
wanting to attach to a string was the overloading kind, so that I can have a
string "foo" stored in a variable $x and overload its + operation so that it
concatenates (I know this example sucks, but you get the idea).

- Branden




Re: PDD 2, vtables

2001-02-06 Thread Dan Sugalski

At 05:01 PM 2/6/2001 -0200, Branden wrote:
>Dan Sugalski wrote:
> > At 11:26 AM 2/6/2001 +, Tim Bunce wrote:
> > >Arrays and hashes should probably be at least mentioned here.
> >
> > And lists, yes. Or they need their own PDD with details.
> >
>
>What's the difference between array and list? How is a list currently
>(Perl5) implemented? Which operations does it support?

I'll leave this as an exercise for the reader. (Which is a polite way to 
say "go find out, grasshopper" :)

> > > > =item UTF-32 string
> > > > =item Native string
> > > > =item Foreign string
> > >
> > >I'm a little surprised not to see UTF-8 there, but since I'm also
> > >confused about what Native string and Foreign string are I'll skip it.
> > >Except to say that some clarification here may help, and explicitly
> > >mentioning UTF-8 (even to say it won't be a core type and provide a
> > >reference to why) would be good.
> >
> > I didn't put UTF-8 in on purpose, because I'd just as soon not deal with
>it
> > internally. Variable length character data's a pain in the butt, and if we
> > can avoid having the internals deal with it except as a source that gets
> > converted to UTF-32, that's fine with me.
> >
>
>I would bother a lot, having my strings occupying 4x more memory than they
>do now... For me, at least, UTF32 can be set aside, while UTF8 is a need
>nowadays (damn XML!).

It's a speed/space tradeoff. Dealing with the middle of a string with 
variable-length characters either requires an offset array (in which case 
you've just used more memory and time than a fixed-width representation) or 
scanning from the beginning of the array, which can be costly if you need 
to go too far in. (How costly depends on the architecture. Dealing with 
arrays of 8-bit ints is actually slower on the Alpha than the same size 
(element count, not bytecount) array of 32-bit ints. YMMV, though)

> > > > =item match
> > > >
> > > >void   match(PMC1, PMC2, REGEX[, key]);
> > > >
> > > > Performs a regular expression match on C against the expression
> > > > C, placing the results in C.
> > >
> > >Results, plural => container => array or hash. Needs clarifying.
> >
> > Yep, especially since I'd considered tossing the match destination
> > entirely. (Though that means special variables, and I'm not sure I want to
> > go there) It'll likely just return true or false. I'll rethink it.
> >
>
>Will Perl 6 still be based on a stack, to pass a list of parameters and
>return a list of results to the subs? Or is there any other approach
>discussed for it? Is it still undefined? Will it work the same as in Perl 5
>or will it take changes? Too soon to talk about it?

We'll probably pass lists in and out, but it'll have a stack of 
sorts--that's pretty much a requirement for Algol-based languages.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 04:23 PM 2/6/2001 -0200, Branden wrote:
>Dan Sugalski wrote:
> > At 01:50 PM 2/6/2001 -0200, Branden wrote:
> > >In the approach using the vtables I propose, it would be:
> > >
> > >
> > >  // get the PMC's that correspond to each variable...
> > >  HVAR *foo  = get_hvar("foo");
> > >  SVAR *baz  = get_svar("baz");
> > >  AVAR *xyz  = get_avar("xyzzy");
> >
> > This likely won't be done this way. Variables looked up by name (package
> > and named lexicals (if we even let you look up lexicals by name)) will be
> > handled like this (though we'll probably do a bunch of optimization) but
> > lexicals will not be. The compiler will pre-compute what it needs so we'll
> > have a PMC already, or find them with an array lookup in the appropriate
> > place in the lexical stack.
>
>Sorry 'bout that, it was only to illustrate having the PMC's in C without
>having to mention the compiler, or anything else...

Not generally unreasonable, as the behaviour of the compiler's not been set 
down in stone yet.

> > Well, the code *inside* foo's add would do:
> >
> >IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
> >IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
> >IV sum = lside + rside;
> >
> >db_store(foo->data->db_handle, KEYSTRING(key[0]), IV_TO_UTF8(sum));
> >
> > And yes, using the KEYSTRING and IV_TO_UTF8 macros to do the conversions
>is
> > a bit of a punt, but that's OK at this point.
> >
>
>I actually don't see anything related to foo here, besides the last line of
>it, which is actually the same as the set_string entry of the same vtable.

That's OK, since my example was wrong. (D'oh! Chalk it up to remnants of 
the martian death flu, along with too much blood in my caffeine stream) The 
example

  $foo{bar} = $baz + $xyzzy[42];

turns into

   baz->vtable->add[NATIVE](foo, baz, xyzzy, key);

with the add routine doing

 IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
 IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
 IV sum;
 bigstr *bigsum;
 CHECK_OVERFLOW(bigstr, (sum = lside + rside));

 if (OVERFLOW) {
   foo->vtable->set_integer[BIGINT](foo, bigsum, key[0]);
 } else {
   foo->vtable->set_integer[NATIVE](foo, sum, key[0]);
 }

and foo's set_integer storing the passed data in the database as appropriate.

>And if we replace that line for the correspondent set_string operation, I
>don't see the need to have add in a vtable, because I cannot understand how
>it could be implemented differently for another variable aside from foo.

Now, as to this...

What happens if you have an overloaded array on the left side? Or a complex 
number? Or a bigint? The point of having add in the vtable (along with a 
lot of the other stuff that's in there) is so we can have a lot of 
special-purpose code rather than a hunk of general-purpose code. The idea 
is to reduce the number of tests and branches and shrink the size of the 
code we actually execute so we don't blow processor cache or have to clear 
out execution pipelines.

>And the line that sums the two values doesn't take into account the fact
>that baz has + overloaded to make some test if the values are strings, to
>concatenate instead of sum. How would foo's vtable have to deal with that?

Well, in the updated (and actually correct... :) version it does, since 
it's baz's add code that gets called. If xyzzy is overloaded things get 
dicier. How that gets handled (when the right operand in an expression is 
overloaded, or both) is a language issue, and one that someone else (read: 
Larry) has to decide.

> > There's nothing wrong with a vtable's function from using the vtable
> > functions of its arguments. It's actually a requirement if the arguments
> > aren't all of the same class.
> >
>
>But the more one vtable has to deal with other vtables, the less code
>re-using and extensibility we have.

Really? Why? There's no reason that multiple classes can't share routines. 
Vtables are just big arrays of function pointers--if multiple classes share 
underlying implementations, there's no reason they can't share the 
functions as well.

[I snipped the next bit, since it was based on a bad example]

> > >In the approach I'm proposing, xyz->vtable->FETCH(xyz_val, xyz, xyz_idx)
> > >would ask for the element indexed 42 of the array. As the vtable used is
>the
> > >one of the array itself, it knows it should fetch it from the directory
> > >listing, and does it. In baz_val->vtable->ADD(foo_val, baz_val, xyz_val),
> > >the ADD method is called from the $baz vtable, so it knows about $baz
>being
> > >overloaded. (Of course overloading this way only applies to the left
> > >operand, I don't know if there's a workaround for this). The ADD method
>gets
> > >the right operand by calling STRING/INT/NUMBER on the last argument. And
> > >foo->vtable->STORE(foo, foo_key, foo_val) is responsible for storing the
> > >value on %foo, using foo_key as the key. STORE is in %foo's vtable, so it
> > >knows it

Re: PDD 2, vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> At 11:26 AM 2/6/2001 +, Tim Bunce wrote:
> >Arrays and hashes should probably be at least mentioned here.
>
> And lists, yes. Or they need their own PDD with details.
>

What's the difference between array and list? How is a list currently
(Perl5) implemented? Which operations does it support?



> > > =item UTF-32 string
> > > =item Native string
> > > =item Foreign string
> >
> >I'm a little surprised not to see UTF-8 there, but since I'm also
> >confused about what Native string and Foreign string are I'll skip it.
> >Except to say that some clarification here may help, and explicitly
> >mentioning UTF-8 (even to say it won't be a core type and provide a
> >reference to why) would be good.
>
> I didn't put UTF-8 in on purpose, because I'd just as soon not deal with
it
> internally. Variable length character data's a pain in the butt, and if we
> can avoid having the internals deal with it except as a source that gets
> converted to UTF-32, that's fine with me.
>

I would bother a lot, having my strings occupying 4x more memory than they
do now... For me, at least, UTF32 can be set aside, while UTF8 is a need
nowadays (damn XML!).



> > > =item match
> > >
> > >void   match(PMC1, PMC2, REGEX[, key]);
> > >
> > > Performs a regular expression match on C against the expression
> > > C, placing the results in C.
> >
> >Results, plural => container => array or hash. Needs clarifying.
>
> Yep, especially since I'd considered tossing the match destination
> entirely. (Though that means special variables, and I'm not sure I want to
> go there) It'll likely just return true or false. I'll rethink it.
>

Will Perl 6 still be based on a stack, to pass a list of parameters and
return a list of results to the subs? Or is there any other approach
discussed for it? Is it still undefined? Will it work the same as in Perl 5
or will it take changes? Too soon to talk about it?

- Branden




Re: Magic [Slightly Off-Topic... please point me to documentation]

2001-02-06 Thread Branden

Magic [Slightly Off-Topic... please point me to documentation]Garrett Goebel
wrote:
> I was recently bit by overloading magic in the Class::Context
> generic constructor which the following code illustrates. If
> you return "another" reference to a scalar which was blessed,
> instead of the blessed reference, then you loose your magic.
> I'm trying to keep Class::Contract (which I'm maintaining for
> Damian) overload friendly... But Perl magic on my map is
> labelled "there be dragons".
>

Only blessed objects can be overloaded, not references. Only a class can
have overloading behaviour, and a plain reference belongs to no class, so it
should have no overloading behaviour. Contrast this use of \$key with having
[1,2,3]. Do you think this array reference should have any overloading
behaviour? Or else, try to define a method in package bar and try to call it
from $bar, like $bar->foo. Won't work either, you have to ${$bar}->foo.
Overloading should loose the magic in the same sense that the method should
not be called.

> package bar;
> @ISA = qw(foo);
> sub new {  bless \my $key; \$key }

You return a reference to the object...

> package main;
> my ($bar, $baz);
> $bar = bar::->new();
> $baz = baz::->new();
>
> print "bar  $bar\n";
> print "baz  $baz\n";

Try printing $$bar, it will work...

- Branden




Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 04:32 PM 2/6/2001 -0200, Branden wrote:
>Dan Sugalski wrote:
> > At 02:32 PM 2/6/2001 -0200, Branden wrote:
> > >I noticed I couldn't get it to work. The thing is that $x = ... makes a
> > >sv_setsv, what copies the value of the other SV (ST(0) in this case), but
> > >not its magic, and other stuff. Here is the difference between `variable'
> > >and `value'. In Perl5, at least, I could attach magic to a variable, but
>not
> > >to a value (AFAIK).
> >
> > No, you attach the magic to a value. Perl just doesn't copy magic when it
> > copies data. Whether this is a good thing or not is up in the air. (Half
> > the time I want it to, the other half I don't...)
>
>My interpretation is that the `value' is what gets copied, so... But that's
>ok...
>
>In a certain way, overloading is a way to attach magic to a value, in Perl5.
>I don't know how it's implemented, but if $a contains an object that has
>overloaded behaviour, and I do $b = $a, $b will contain a pointer to the
>same object, with the same overloaded behaviour.

It shouldn't. What $b should have is a *copy* of the data in $a, with the 
same overloading magic. Otherwise altering $a would alter $b, which isn't 
what you want.

>I think in Perl5, it's not
>possible to attach magic behaviour to an individual object, but only to a
>class of them, so it wouldn't be possible to attach magic to the string
>"foo", for instance...

Magic can only be attached to individual [SAHG]Vs. It can't be attached to 
whole classes of things. Now, all things of the same type have the same set 
of magic routines, but that's not the same thing. (And you can attach magic 
to the string "foo", though attaching magic to string constants requires 
doing some evil things...)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Another approach to vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> At 02:32 PM 2/6/2001 -0200, Branden wrote:
> >I noticed I couldn't get it to work. The thing is that $x = ... makes a
> >sv_setsv, what copies the value of the other SV (ST(0) in this case), but
> >not its magic, and other stuff. Here is the difference between `variable'
> >and `value'. In Perl5, at least, I could attach magic to a variable, but
not
> >to a value (AFAIK).
>
> No, you attach the magic to a value. Perl just doesn't copy magic when it
> copies data. Whether this is a good thing or not is up in the air. (Half
> the time I want it to, the other half I don't...)

My interpretation is that the `value' is what gets copied, so... But that's
ok...

In a certain way, overloading is a way to attach magic to a value, in Perl5.
I don't know how it's implemented, but if $a contains an object that has
overloaded behaviour, and I do $b = $a, $b will contain a pointer to the
same object, with the same overloaded behaviour. I think in Perl5, it's not
possible to attach magic behaviour to an individual object, but only to a
class of them, so it wouldn't be possible to attach magic to the string
"foo", for instance...

- Branden




Re: Another approach to vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> At 01:50 PM 2/6/2001 -0200, Branden wrote:
> >In the approach using the vtables I propose, it would be:
> >
> >
> >  // get the PMC's that correspond to each variable...
> >  HVAR *foo  = get_hvar("foo");
> >  SVAR *baz  = get_svar("baz");
> >  AVAR *xyz  = get_avar("xyzzy");
>
> This likely won't be done this way. Variables looked up by name (package
> and named lexicals (if we even let you look up lexicals by name)) will be
> handled like this (though we'll probably do a bunch of optimization) but
> lexicals will not be. The compiler will pre-compute what it needs so we'll
> have a PMC already, or find them with an array lookup in the appropriate
> place in the lexical stack.

Sorry 'bout that, it was only to illustrate having the PMC's in C without
having to mention the compiler, or anything else...



> Well, the code *inside* foo's add would do:
>
>IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
>IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
>IV sum = lside + rside;
>
>db_store(foo->data->db_handle, KEYSTRING(key[0]), IV_TO_UTF8(sum));
>
> And yes, using the KEYSTRING and IV_TO_UTF8 macros to do the conversions
is
> a bit of a punt, but that's OK at this point.
>

I actually don't see anything related to foo here, besides the last line of
it, which is actually the same as the set_string entry of the same vtable.
And if we replace that line for the correspondent set_string operation, I
don't see the need to have add in a vtable, because I cannot understand how
it could be implemented differently for another variable aside from foo.

And the line that sums the two values doesn't take into account the fact
that baz has + overloaded to make some test if the values are strings, to
concatenate instead of sum. How would foo's vtable have to deal with that?



> There's nothing wrong with a vtable's function from using the vtable
> functions of its arguments. It's actually a requirement if the arguments
> aren't all of the same class.
>

But the more one vtable has to deal with other vtables, the less code
re-using and extensibility we have.

For example, if we replace + for - in the expression, as
$foo{bar} = $baz - $xyzzy[42];
that would be implemented as
:  struct key keys[] = {
:   { KEY_TYPE_HASH, (struct hash_key *) "bar" },
:   { KEY_NONE, NULL }, // scalar
:   { KEY_TYPE_ARRAY, (IV) 42 },
:   { 0, 0 } };
:
:  foo->vtable->subtract(foo, baz, xyz, keys);
and then subtract would have to do
:IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
:IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
:IV sum = lside - rside;
:
:db_store(foo->data->db_handle, KEYSTRING(key[0]), IV_TO_UTF8(sum));

Why would we make subtract deal with getting the int's from baz, and xyzzy,
and storing the data in the database, if it could only make the subtraction?
At least it what its name says it's meant to do...



> >In the approach I'm proposing, xyz->vtable->FETCH(xyz_val, xyz, xyz_idx)
> >would ask for the element indexed 42 of the array. As the vtable used is
the
> >one of the array itself, it knows it should fetch it from the directory
> >listing, and does it. In baz_val->vtable->ADD(foo_val, baz_val, xyz_val),
> >the ADD method is called from the $baz vtable, so it knows about $baz
being
> >overloaded. (Of course overloading this way only applies to the left
> >operand, I don't know if there's a workaround for this). The ADD method
gets
> >the right operand by calling STRING/INT/NUMBER on the last argument. And
> >foo->vtable->STORE(foo, foo_key, foo_val) is responsible for storing the
> >value on %foo, using foo_key as the key. STORE is in %foo's vtable, so it
> >knows it should actually write the data in the DBM.
>
> Nothing wrong with that, but there are more op dispatches that way. While
> that's not a horrible thing, if we can avoid them that's better.
>

What's exactly a op dispatch? I _really_ don't know that. Please tell me so
that I can answer this...



> Don't forget we have an opcode machine here--we are *not* emitting C code
> to be compiled. That means we're going to be storing temps in a register
> file of some sort. (Or pushing them on a stack, or whatever) That means
> that if we generate intermediaries that aren't PMCs then we need extra
temp
> space for them. Your way will mean an int, num, and string stack (or
> register file, or whatever) in addition to a PMC stack/register
> file/whatever. That's more stuff to track. (Which isn't to say we won't,
> mind. We will if we have to)
>

I know that (althought I don't have the exact definition of opcode yet). I
wrote C code only to illustrate my point.

If a opcode is what I'm thinking, in the fact that the interpreter executes
a opcode kind of atomically, like a machine instruction in assembly, then I
would like to say that the entries you are proposing to the vtables are
probably much better as opcodes than mine. But I'm actually not saying that
one vtable function call shoul

Re: Magic [Slightly Off-Topic... please point me to documentation]

2001-02-06 Thread Dan Sugalski

At 11:46 AM 2/6/2001 -0600, Garrett Goebel wrote:
>From: Dan Sugalski [mailto:[EMAIL PROTECTED]]
> >
> > No, you attach the magic to a value. Perl just doesn't copy
> > magic when it copies data. Whether this is a good thing or
> > not is up in the air. (Half the time I want it to, the other
> > half I don't...)
>
>Is there a good discussion of magic, copying magic etc. in the core perl
>documentation? Or elsewhere for that matter? Any documentation, pointers,
>general tips, etc. would be greatly appreciated.

Nope.

>I was recently bit by overloading magic in the Class::Context generic
>constructor which the following code illustrates. If you return "another"
>reference to a scalar which was blessed, instead of the blessed reference,
>then you loose your magic.  I'm trying to keep Class::Contract (which I'm
>maintaining for Damian) overload friendly... But Perl magic on my map is
>labelled "there be dragons".

Dragons is right. It's a dicey area, and past that most extensions handle 
magic values flat-out wrong. (Including most of mine, so I've no room to 
talk...)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Magic [Slightly Off-Topic... please point me to documentation]

2001-02-06 Thread Garrett Goebel

From: Dan Sugalski [mailto:[EMAIL PROTECTED]]
> 
> No, you attach the magic to a value. Perl just doesn't copy 
> magic when it copies data. Whether this is a good thing or
> not is up in the air. (Half the time I want it to, the other
> half I don't...)

Is there a good discussion of magic, copying magic etc. in the core perl
documentation? Or elsewhere for that matter? Any documentation, pointers,
general tips, etc. would be greatly appreciated.

I was recently bit by overloading magic in the Class::Context generic
constructor which the following code illustrates. If you return "another"
reference to a scalar which was blessed, instead of the blessed reference,
then you loose your magic.  I'm trying to keep Class::Contract (which I'm
maintaining for Damian) overload friendly... But Perl magic on my map is
labelled "there be dragons". 

package foo;
use overload '""' => 'asString';
sub asString { 'Hello World' }

package bar;
@ISA = qw(foo);
sub new {  bless \my $key; \$key }

package baz;
@ISA = qw(foo);
sub new { my $ref = \ my $key; bless $ref; $ref }

package main;
my ($bar, $baz);
$bar = bar::->new();
$baz = baz::->new();

print "bar  $bar\n";
print "baz  $baz\n";

Results In:
bar  bar=SCALAR(0x1bbfc9c)
baz  Hello World



Re: PDD 2, vtables

2001-02-06 Thread Dan Sugalski

At 11:26 AM 2/6/2001 +, Tim Bunce wrote:
>[First off: I've not really been paying attention so forgive me if I'm
>being dumb here.  And many thanks for helping to drive this forwards.]
>
>On Mon, Feb 05, 2001 at 05:14:44PM -0500, Dan Sugalski wrote:
> >
> > =head2 Core datatypes
> >
> > For ease of use, we define the following semi-abstract data types
>
>Probably worth stating upfront that it'll be easy to add new types
>to avoid people argusing for their favorite type to be added here.

I'm not sure it should be--that'd mean extending the vtables in ways they 
have little room to grow. Adding new perl datatypes is easy, adding new 
low-level types is harder.

> > =item INT
> > =item NUM
> > =item STR
> > =item BOOL
>
>What about references?

Special type of scalar, not dealt with here.

>Arrays and hashes should probably be at least mentioned here.

And lists, yes. Or they need their own PDD with details.

> > =head3 String data types
> >
> > =item binary buffer
>
>'Binary string'

I avoided that on purpose. Label it a string and people think of its 
contents as characters, and they're probably not going to be a good chunk 
of the time. Might not outweigh the consistency issue, though.

> > =item UTF-32 string
> > =item Native string
> > =item Foreign string
>
>I'm a little surprised not to see UTF-8 there, but since I'm also
>confused about what Native string and Foreign string are I'll skip it.
>Except to say that some clarification here may help, and explicitly
>mentioning UTF-8 (even to say it won't be a core type and provide a
>reference to why) would be good.

I didn't put UTF-8 in on purpose, because I'd just as soon not deal with it 
internally. Variable length character data's a pain in the butt, and if we 
can avoid having the internals deal with it except as a source that gets 
converted to UTF-32, that's fine with me.

The native and foreign string data types were an attempt to accommodate 
UTF-8, as well as ASCII and EBCDIC character data. One of the three will 
likely be the native type, and the rest will be foreign strings. I'm not 
sure if perl should have only one foreign string type, or if we should have 
a type tag along with the other bits for strings.

> > The functions are divided into two broad categories, those that perl
> > will use the value of internally (for example the type functions) and
> > those that produce or modify a PMC, such as the add function.
>
>So possibly a good idea to explicitly group them that way.

They were, but I see I lost that.

> > =head2 Functions in detail
> >
> > =item type
> >
> > =item name
> >
> >STRname(PMC[, key]);
> >
> > Returns the name of the class the PMC belongs to.
>
>So I'd call it type_name (or maybe class_name as you seem to be useing
>the words interchangably. If type != class then clarify somewhere.).

The interchange is due to sloppy thinking. I'll redo it so that class == 
perl data type, while type == (NUM|STR|BOOL|INT).

> > =item move_to
> >
> >BOOL   move_to(void *, PMC);
> >
> > Tells the PMC to move its contents to a block of memory starting at
> > the passed address. Used by the garbage collector to compact memory,
> > this call can return a false value if the move can't be done for some
> > reason. The pointer is guaranteed to point to a chunk of memory at
> > least as large as that returned by the C vtable function.
>
>Shouldn't the PMC be the first arg for consistency?

First arg of the PMC is the destination PMC. We don't have one here.

> > =item real_size
> >
> >IV real_size(PMC[, key]);
> >
> > Returns an integer value that represents the real size of the data
> > portion, excluding the vtable, of the PMC.
>
>Contiguous? Sum of parts (allowing for allignment) if it contains
>multiple chunks of data?

Size we'd need to allocate if we were going to move the data. Though 
knowing how much space is currently taken would also be useful, assuming 
they're not the same. (They probably would be within a few bytes, though)

> > =item destroy
> >
> >void   destroy(PMC[, key]);
> >
> > Destroys the variable the PMC represents, leaving it undef.
>
>Using the word 'variable' here probably isn't a good idea.
>Maybe "Destroys the contents of the PMC leaving it undef."

Better. Thanks.

> > =item is_same
> >
> >BOOL   is_same(PMC1, PMC2[, key]);
> >
> > Returns TRUE if C and C refer to the same value, and FALSE
> > otherwise.
>
>I think that needs more clarification, especially where they are of
>different types. Contrast with is_equal() below.

If they're different types they can't be the same. This would be used to 
check if two references have the same referent, or if two magic variables 
(database handles, say) pointed to the same thing.

> > =item concatenate
> >
> >void   concatenate(PMC1, PMC2, PMC3[, key]); ##
> >
> > Concatenates the strings in C and C, storing the result in
> > C.
>
>and insert (ala sv_insert)  etc?

Hadn't co

Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 02:32 PM 2/6/2001 -0200, Branden wrote:
>I noticed I couldn't get it to work. The thing is that $x = ... makes a
>sv_setsv, what copies the value of the other SV (ST(0) in this case), but
>not its magic, and other stuff. Here is the difference between `variable'
>and `value'. In Perl5, at least, I could attach magic to a variable, but not
>to a value (AFAIK).

No, you attach the magic to a value. Perl just doesn't copy magic when it 
copies data. Whether this is a good thing or not is up in the air. (Half 
the time I want it to, the other half I don't...)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Another approach to vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 02:32:16PM -0200, Branden wrote:
> I noticed I couldn't get it to work. The thing is that $x = ... makes a
> sv_setsv, what copies the value of the other SV (ST(0) in this case), but
> not its magic, and other stuff. Here is the difference between `variable'
> and `value'. In Perl5, at least, I could attach magic to a variable, but not
> to a value (AFAIK).

That's not quite right. I can do
%untied = %tied;

If Perl 5 worked the way you wanted, you could do
%tied2  = %tied;
%untied = (%tied); 

But if "%foo = %bar" should make %foo magical or not is a language issue, so
I'm allowed to duck the question. :)

-- 
dd.c:   sbrk(64);   /* For good measure */
- plan9 has a bad day



Re: Another approach to vtables

2001-02-06 Thread Branden

Simon Cozens wrote:
> Well, hmm. That's true and it's not true. Consider how
> $a = $b
> works in Perl 5: the gvsv operations produce two SVs, one for the value of
$a
> and for the value of $b. Then the value of $b is assigned to the value of
$a,
> and $a is changed. No difference between lvalue SVs (variables) and rvalue
SVs
> (values).


This thing has bitten me the first time I wrote XS code. I was embedding
some C++ objects in a Perl object. I didn't want the Perl object to contain
the address of the C++ object, because not careful use of it in Perl could
cause problems with memory addresses. So I chose to `hide' the C++ object
address in a magic table. I set up a scalar, called sv_magic with the '~'
slot (user-defined magic), and returned the scalar, like this:

sv_setmagic(ST(0), '~', NULL, address_of_cpp_object);
/* Is this right? I think I can't do XS anymore... */

but when I did

$x = my_sub_that_returns_a_sv_with_magic();

I noticed I couldn't get it to work. The thing is that $x = ... makes a
sv_setsv, what copies the value of the other SV (ST(0) in this case), but
not its magic, and other stuff. Here is the difference between `variable'
and `value'. In Perl5, at least, I could attach magic to a variable, but not
to a value (AFAIK).

Of course I found a workaround. I set up the magic scalar, and returned (a
value!) a reference to it. When I deref it, I have the original magical
thing. But from that day I actually saw that SV is a variable, definitely
*not* a value.

- Branden




Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 01:50 PM 2/6/2001 -0200, Branden wrote:
>Simon Cozens wrote:
> > On Tue, Feb 06, 2001 at 11:30:12AM -0200, Branden wrote:
> > > I actually have some more on it, but I'm saving it for the next
>postings.
> > > I'll wait for your opinions first. I really hope to see critics about
>this.
> >
> > I don't understand what you think this gives us that the PDD doesn't.

There are a few conceptual issues here. I can't speak for yours, but I'll 
correct the bits I can.

>To explain the difference, I'll show how the Perl statement
>  $foo{bar} = $baz + $xyzzy[42];
>would be traduced in both approaches.\

>In the approach using the vtables I propose, it would be:
>
>
>  // get the PMC's that correspond to each variable...
>  HVAR *foo  = get_hvar("foo");
>  SVAR *baz  = get_svar("baz");
>  AVAR *xyz  = get_avar("xyzzy");

This likely won't be done this way. Variables looked up by name (package 
and named lexicals (if we even let you look up lexicals by name)) will be 
handled like this (though we'll probably do a bunch of optimization) but 
lexicals will not be. The compiler will pre-compute what it needs so we'll 
have a PMC already, or find them with an array lookup in the appropriate 
place in the lexical stack.

>  // temporary...
>  SVAL *foo_val  = new_sval_temp();
>  SVAL *baz_val  = new_sval_temp();
>  SVAL *xyz_val  = new_sval_temp();

We're going to have a bunch of temps handy so this won't need to be done.

>  // this ones actually come from compiler...
>  SVAL *foo_key  = new_sval_pv("bar");
>  SVAL *xyz_idx  = new_sval_iv(42);

Yep--constants will be precomputed.

>  // fetch $bar and $xyzzy[42] values
>  baz->vtable->FETCH(baz_val, baz);
>  xyz->vtable->FETCH(xyz_val, xyz, xyz_idx);
>  // add them into a temporary
>  baz_val->vtable->ADD(foo_val, baz_val, xyz_val);
>   // probably xyz_val->vtable->INTEGER(xyz_val)
>   // and/or xyz_val->vtable->NUMBER(xyz_val) would
>   // get called by the ADD implementation, to
>   // inspect the right operand's value.
>  // store this value on $foo{bar}
>  foo->vtable->STORE(foo, foo_key, foo_val);
>
>
>Using the vtable approach proposed in the PDD:
>
>
>  // get the PMC's that correspond to each variable...
>  struct key keys[] = {
>   { KEY_TYPE_HASH, (struct hash_key *) "bar" },
>   { KEY_NONE, NULL }, // scalar
>   { KEY_TYPE_ARRAY, (IV) 42 },
>   { 0, 0 } };
>
>  foo->vtable->add(foo, baz, xyz, keys);
>
>
>Right? (Maybe I got it wrong, but for what I've read, that's it...).

I shipped out the code that's irrelevant (as the compiler will probably 
also chop it out, 'specially if it's all accessing lexicals.

>Well, when %foo, $baz and @xyzzy are plain hashes, scalars and arrays, it's
>ok. But now suppose %foo is a hash tied to a database through DB_File or
>AnyDBM, @xyzzy is attached to a directory so that $xyzzy[42] would actually
>return the name of the 43rd file in that directory, and the string stored in
>the $baz variable has overloaded + so that it will check if the other
>argument is a string or a number, and concatenate in case it's a string and
>sum only if both are numbers. How would foo->vtable->add(foo, baz, xyz,
>keys) deal with that? As it is %foo's vtable, I agree that it should know
>about %foo being tied to a DBM, but how would it know anything about the
>others?

Well, the code *inside* foo's add would do:

   IV lside = baz->vtable->get_int[NATIVE](baz, key+1);
   IV rside = xyzzy->vtable->get_int[NATIVE](xyzzy, key+2);
   IV sum = lside + rside;

   db_store(foo->data->db_handle, KEYSTRING(key[0]), IV_TO_UTF8(sum));

And yes, using the KEYSTRING and IV_TO_UTF8 macros to do the conversions is 
a bit of a punt, but that's OK at this point.

There's nothing wrong with a vtable's function from using the vtable 
functions of its arguments. It's actually a requirement if the arguments 
aren't all of the same class.

>In the approach I'm proposing, xyz->vtable->FETCH(xyz_val, xyz, xyz_idx)
>would ask for the element indexed 42 of the array. As the vtable used is the
>one of the array itself, it knows it should fetch it from the directory
>listing, and does it. In baz_val->vtable->ADD(foo_val, baz_val, xyz_val),
>the ADD method is called from the $baz vtable, so it knows about $baz being
>overloaded. (Of course overloading this way only applies to the left
>operand, I don't know if there's a workaround for this). The ADD method gets
>the right operand by calling STRING/INT/NUMBER on the last argument. And
>foo->vtable->STORE(foo, foo_key, foo_val) is responsible for storing the
>value on %foo, using foo_key as the key. STORE is in %foo's vtable, so it
>knows it should actually write the data in the DBM.

Nothing wrong with that, but there are more op dispatches that way. While 
that's not a horrible thing, if we can avoid them that's better.

Don't forget we have an opcode machine here--we are *not* emitting C code 
to be compiled. That means we're going to be storing temps in a register 
file of some sort. (Or pushing them on a stack, or whatever)

Re: Another approach to vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> At 03:53 PM 2/6/2001 +, David Mitchell wrote:
> > > 2. Perl 5 doesn't separate well a `variable' from a `value', and this
> > should
> > > be done to achieve a more clear design.
> >
> >Perl5 does in fact make a clear separation. 'values' are SV structures
> >(and AVs and HVs etc). Variables are names in stashes, PADs etc
> >that have a pointer to an SV or whatever.
> >
> >I think you may have mis-understood the emphasis of the vtable PDD doc -
> >it discusses how to store *values*, and says nothing whatsoever about
> >variables.
>
> This is important. (And a point I missed reading through the alternate
> vtable proposal) I don't care a bit about names, scratchpads, references,
> or whatnot at this level. This is pure "I have a PMC, what can I do with
> it?" stuff.
>
> Dealing with names and scratchpads and real perl variables is important,
> but covered elsewhere. (The compiler takes care of lexicals, FWIW, and
> we'll probably be treating the stash as a hash the way it is now for
globals)


Now I understand you!!! What I am calling a variable and what you are
calling a variable are different things. You are calling a variable what is
called a variable inside of perl, such as $x or @y. What I'm calling a
variable is a storage space for a value, something I can set the value. This
is exactly SV* in Perl 5, with its sv_setsv function. Of course, SV* can be
used for _perl_variables_, scratchpads, references, ... . But as in all
these cases it has the property of being able to change its value, it's a
variable.

The name->PMC translation really has nothing to do with this subject. It's a
thing with the compiler...

- Branden




Re: Another approach to vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 03:53:09PM +, David Mitchell wrote:
> Perl5 does in fact make a clear separation. 'values' are SV structures
> (and AVs and HVs etc). Variables are names in stashes, PADs etc
> that have a pointer to an SV or whatever.

Well, hmm. That's true and it's not true. Consider how 
$a = $b
works in Perl 5: the gvsv operations produce two SVs, one for the value of $a 
and for the value of $b. Then the value of $b is assigned to the value of $a,
and $a is changed. No difference between lvalue SVs (variables) and rvalue SVs
(values).

-- 
If you give a man a fire, he'll be warm for a day. If you set a man on fire, 
he'll be warm for the rest of his life.



Re: Another approach to vtables

2001-02-06 Thread Dan Sugalski

At 03:53 PM 2/6/2001 +, David Mitchell wrote:
> > 2. Perl 5 doesn't separate well a `variable' from a `value', and this 
> should
> > be done to achieve a more clear design.
>
>Perl5 does in fact make a clear separation. 'values' are SV structures
>(and AVs and HVs etc). Variables are names in stashes, PADs etc
>that have a pointer to an SV or whatever.
>
>I think you may have mis-understood the emphasis of the vtable PDD doc -
>it discusses how to store *values*, and says nothing whatsoever about
>variables.

This is important. (And a point I missed reading through the alternate 
vtable proposal) I don't care a bit about names, scratchpads, references, 
or whatnot at this level. This is pure "I have a PMC, what can I do with 
it?" stuff.

Dealing with names and scratchpads and real perl variables is important, 
but covered elsewhere. (The compiler takes care of lexicals, FWIW, and 
we'll probably be treating the stash as a hash the way it is now for globals)

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Another approach to vtables

2001-02-06 Thread Branden

David Mitchell wrote:
> > 2. Perl 5 doesn't separate well a `variable' from a `value', and this
should
> > be done to achieve a more clear design.
>
> Perl5 does in fact make a clear separation. 'values' are SV structures
> (and AVs and HVs etc). Variables are names in stashes, PADs etc
> that have a pointer to an SV or whatever.
>

Actually SV is a variable. That's a sv_setsv function that changes the value
of a SV. A thing that can change value is a variable, at least to me. Of
course, it's used as temporary variables also, in which case there's no name
for the variable in Perl, but it is a variable anyway...



> I think you may have mis-understood the emphasis of the vtable PDD doc -
> it discusses how to store *values*, and says nothing whatsoever about
> variables.
>
>

1. As I said before, a value shouldn't change its value, a variable does
that.
2. Array is not a value, at least not in Perl. Array references are, but
arrays themselves not. The same applies to hashes. And in my opinion, the
PDD talks about arrays and hashes (well, at least it talks about indexes and
keys). Arrays and hashes are actually collections of values, so as a scalar
is a `holder' for a value. Store and fetch methods should be in the variable
side, and operations on the value side.

Sorry if I can't make myself well understood...

- Branden




Re: Another approach to vtables

2001-02-06 Thread David Mitchell

> 2. Perl 5 doesn't separate well a `variable' from a `value', and this should
> be done to achieve a more clear design.

Perl5 does in fact make a clear separation. 'values' are SV structures
(and AVs and HVs etc). Variables are names in stashes, PADs etc
that have a pointer to an SV or whatever.

I think you may have mis-understood the emphasis of the vtable PDD doc -
it discusses how to store *values*, and says nothing whatsoever about
variables.




Re: Another approach to vtables

2001-02-06 Thread Branden

Simon Cozens wrote:
> On Tue, Feb 06, 2001 at 11:30:12AM -0200, Branden wrote:
> > I actually have some more on it, but I'm saving it for the next
postings.
> > I'll wait for your opinions first. I really hope to see critics about
this.
>
> I don't understand what you think this gives us that the PDD doesn't.




To explain the difference, I'll show how the Perl statement
 $foo{bar} = $baz + $xyzzy[42];
would be traduced in both approaches.

In the approach using the vtables I propose, it would be:


 // get the PMC's that correspond to each variable...
 HVAR *foo  = get_hvar("foo");
 SVAR *baz  = get_svar("baz");
 AVAR *xyz  = get_avar("xyzzy");
 // temporary...
 SVAL *foo_val  = new_sval_temp();
 SVAL *baz_val  = new_sval_temp();
 SVAL *xyz_val  = new_sval_temp();
 // this ones actually come from compiler...
 SVAL *foo_key  = new_sval_pv("bar");
 SVAL *xyz_idx  = new_sval_iv(42);
 // fetch $bar and $xyzzy[42] values
 baz->vtable->FETCH(baz_val, baz);
 xyz->vtable->FETCH(xyz_val, xyz, xyz_idx);
 // add them into a temporary
 baz_val->vtable->ADD(foo_val, baz_val, xyz_val);
  // probably xyz_val->vtable->INTEGER(xyz_val)
  // and/or xyz_val->vtable->NUMBER(xyz_val) would
  // get called by the ADD implementation, to
  // inspect the right operand's value.
 // store this value on $foo{bar}
 foo->vtable->STORE(foo, foo_key, foo_val);


Using the vtable approach proposed in the PDD:


 // get the PMC's that correspond to each variable...
 PMC *foo = hv_get("foo");
 PMC *baz = sv_get("baz");
 PMC *xyz = av_get("xyzzy");
 struct key keys[] = {
  { KEY_TYPE_HASH, (struct hash_key *) "bar" },
  { KEY_NONE, NULL }, // scalar
  { KEY_TYPE_ARRAY, (IV) 42 },
  { 0, 0 } };

 foo->vtable->add(foo, baz, xyz, keys);


Right? (Maybe I got it wrong, but for what I've read, that's it...).

Well, when %foo, $baz and @xyzzy are plain hashes, scalars and arrays, it's
ok. But now suppose %foo is a hash tied to a database through DB_File or
AnyDBM, @xyzzy is attached to a directory so that $xyzzy[42] would actually
return the name of the 43rd file in that directory, and the string stored in
the $baz variable has overloaded + so that it will check if the other
argument is a string or a number, and concatenate in case it's a string and
sum only if both are numbers. How would foo->vtable->add(foo, baz, xyz,
keys) deal with that? As it is %foo's vtable, I agree that it should know
about %foo being tied to a DBM, but how would it know anything about the
others?

In the approach I'm proposing, xyz->vtable->FETCH(xyz_val, xyz, xyz_idx)
would ask for the element indexed 42 of the array. As the vtable used is the
one of the array itself, it knows it should fetch it from the directory
listing, and does it. In baz_val->vtable->ADD(foo_val, baz_val, xyz_val),
the ADD method is called from the $baz vtable, so it knows about $baz being
overloaded. (Of course overloading this way only applies to the left
operand, I don't know if there's a workaround for this). The ADD method gets
the right operand by calling STRING/INT/NUMBER on the last argument. And
foo->vtable->STORE(foo, foo_key, foo_val) is responsible for storing the
value on %foo, using foo_key as the key. STORE is in %foo's vtable, so it
knows it should actually write the data in the DBM.

I really can't see how this would be implemented in the PDD proposed
approach, unless foo->vtable->add(foo, baz, xyz, keys) makes the calls in
the other vtables. And if it makes all these calls in the other vtables, I
don't see the point, because every `add' function would have to explicitly
do 2 fetches and 1 store, yet taking care of the keys, when it could
actually only do the addition...

Perhaps I didn't understood it quite well, but that's what I thought about
it...






>
> --
> For me, UNIX is a way of being. -Armando P. Stettner
>

For me too.

- Branden




Re: PDD 2, vtables

2001-02-06 Thread Dan Sugalski

At 11:32 AM 2/6/2001 -0200, Branden wrote:
>Simon Cozens wrote:
> > > > =item logical_or
> > > > =item logical_and
> > > > =item logical_not
> > >
> > > Er, why not just use get_bool?
> >
> > Overloading.
> >
>
>Please see my previous post on the subject. As I pointed there, implementing
>|| and && like that breaks short-circuits.

No, it doesn't. Just because you pass in two PMCs doesn't mean that they 
both need to be evaluated. Though the PDD does need to be clearer about how 
that happens.

Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk




Re: Another approach to vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 11:30:12AM -0200, Branden wrote:
> I actually have some more on it, but I'm saving it for the next postings.
> I'll wait for your opinions first. I really hope to see critics about this.

I don't understand what you think this gives us that the PDD doesn't.

-- 
For me, UNIX is a way of being. -Armando P. Stettner



Re: PDD 2, vtables

2001-02-06 Thread Branden

Simon Cozens wrote:
> > > =item logical_or
> > > =item logical_and
> > > =item logical_not
> >
> > Er, why not just use get_bool?
>
> Overloading.
>

Please see my previous post on the subject. As I pointed there, implementing
|| and && like that breaks short-circuits.

- Branden




Another approach to vtables

2001-02-06 Thread Branden


I have some thoughts on vtables and I actually think they should be pretty
different from what was proposed. Well, I'll tell you my ideas on vtables.
Please note that I'm not doing this as an intent to confront the other
proposal, or to create discordance and divergence. I'm presenting this
because I think the other presented approach has some weak points, and I
think this proposal here could solve them someway.



I'm writing it under these assumptions:

1. There should be different vtables for scalars, arrays and hashes. In
every use of a variable in the language, it's always perfectly clear what
the variable type is, only by the syntax, so that I don't see a reason for
having one vtable that should be used for all kinds of variable.

2. Perl 5 doesn't separate well a `variable' from a `value', and this should
be done to achieve a more clear design. For example, a _variable_ should
know how to _store_ or _fetch_ a _value_, but the _value_ should know how to
be _added_ to another _value_. (Sorry for the underlines...). Arrays and
hashes are actually like this, but I'm seeing the other proposal that for
scalars it's not.

3. We should have an interface that resembles current `tie' interface for
variable-vtables, and an interface that resembles current `overload'
interface for value-vtables. This is enough low-level for implementing basic
operations on variables/values, and is enough high-level to implement `tie'
and `overload' directly above it.


Under this decisions, I'll expose my proposal. It's all in pseudo-C (and a
tiny bit of C++). I've changed the current Perl5 names a bit, to make the
separation between variable/value more clear. I'm probably missing much
here, and I may be very wrong about it, consider this only a preliminary
draft.


   template
   struct PMC {
  vtable_t   *vtable;
  void   *data;
  int flags;
  void   *gc_data;
  void   *thr_data;
   };

   struct SVAR_PMC : public PMC;
   struct AVAR_PMC : public PMC;
   struct HVAR_PMC : public PMC;
   struct HNDL_PMC : public PMC;

   struct SVAL_PMC : public PMC;


Just couldn't resist... :-)
They are essentially the same, only each one carries its own type of vtable.
And I think strong typing should be ensured here, so that a AVAR cannot be
passed where a SVAR is expected, at least not without an explicit cast. (I
actually regard an explicit cast as signing the contract that says that you
know what you're doing...).

SVAR_PMC, AVAR_PMC, HVAR_PMC correspond to Perl5's SV, AV, HV. HNDL_PMC is
for file handles, and SVAL_PMC is for scalar values. The next session, on
variable vtables, is mainly taken from perltie. Arrays and hashes are
`crippled', they're here only to illustrate. The this argument is always the
one that has the vtable. Where return values are needed, they are the first
argument of the function. I included a `TYPE' slot to indicate the type of
the vtable (svar_vtable, avar_vtable, ...), althought I didn't find a use
for it. It can be used to identify if a variable is a scalar or an array,
but I really don't see much use for that, unless for sanity checking.


   struct svar_vtable {
  int TYPE;
  void  (*FETCH)   (SVAL *result,  SVAR *this);
  void  (*STORE)   (SVAR *this,SVAL *value);
  void  (*DESTROY) (SVAR *this);
   };

   struct avar_vtable {
  int TYPE;
  void  (*FETCH)   (SVAL *result,  AVAR *this,  int index);
  void  (*STORE)   (AVAR *this,int index,   SVAL *value);
  int   (*LENGTH)  (AVAR *this);
  void  (*DESTROY) (AVAR *this);
   };

   struct hvar_vtable {
  int TYPE;
  void  (*FETCH)   (SVAL *result,  HVAR *this,  SVAL *key);
  void  (*STORE)   (HVAR *this,SVAL *key,   SVAL *value);
  void  (*NEXTKEY) (SVAL *result,  HVAR *this,  SVAL *lastkey);
  void  (*DESTROY) (HVAR *this);
   };


Filehandles also follow the perltie model:


   struct hndl_vtable {
  int TYPE;
  void  (*GETLINE) (SVAL *result,  HNDL *this);
  void  (*PRINT)   (HNDL *this,SVAL **value);
  void  (*DESTROY) (HNDL *this);
   };


Please note that I cut most the things off here. SPLICE for arrays, EXISTS
and DELETE for hashes, READ and WRITE for handles, ... This is only meant to
be a draft.

Values are the new thing here. I think they correspond to Perl5's XIV, XPV,
..., but I'm not sure (I don't know the internals of Perl5 that well, I only
wrote some XS extensions... Well, actually some heavy ones...). Below are
the things I believe should be together with the value. I mostly borrowed
(and shortened) the names from Dan's vtable PDD.


   struct sval_vtable {
  int TYPE;
  // type conversion
  STR   (*STRING)  (SVAL *this);
  int   (*INTEGER) (SVAL *this);
  NUM   (*NUMBER)  (SVAL *this);
  int   (*BOOL)(SVAL *this);
  // operations (from overload.pm)
  void  (*ADD) (SVAL *result,  SVAL *this,  SVAL *value);
  void  (*SUB) (SVAL *result,  SVAL *thi

Re: PDD 2, vtables

2001-02-06 Thread Simon Cozens

On Tue, Feb 06, 2001 at 11:26:57AM +, Tim Bunce wrote:
> > =item UTF-32 string
> > =item Native string
> > =item Foreign string
> 
> I'm a little surprised not to see UTF-8 there, but since I'm also
> confused about what Native string and Foreign string are I'll skip it.

"Native string encoding" is an abstraction that allows us to say "some
encoding that Perl knows how to deal with, but you don't need to care about".
The idea, if I understand it correctly, is that strings can be treated as
arrays of numbers, and you don't need to know how they're *really* stored.
They might be stored as UTF8 internally; I hope so.

"Foreign string" is the same, but with the implication that some external code
will be needed to tell Perl how it should convert between an array of numbers
and this encoding.

> Using the word 'variable' here probably isn't a good idea.
> Maybe "Destroys the contents of the PMC leaving it undef."

Agreed.

> > =item logical_or
> > =item logical_and
> > =item logical_not
> 
> Er, why not just use get_bool?

Overloading.

> > =item repeat (x)
> > 
> >void repeat(PMC1, PMC2, PMC3[, key]); ##
> > 
> > Performs the following sequence of operations: finds the string value
> > from C; finds an integer value I from C; replicates the
> > string I times; stores the resulting string in C.
> 
> So call it replicate?

Well, the Perl-space operator is called "repeat", and the Perl 5 operator
is OP_REPEAT, so...

> Before that I think a section on containers need to be added.

This is basically what the whole "key" thing is about. I'm not sure that
*that* much more needs to be described, (well, something needs to be
described, but not in great detail) other than the fact that operating on a
container PMC-key pair is equivalent to operating on a scalar PMC.

Hence, I can say:
(on a hash)   get_number(hash, "key")
(on an array) get_number(array, elem)
(on a scalar) get_number(scalar)
and not worry about what's going on underneath. 

There ought to be special functions for containers though, yeah.

-- 
"I find that anthropomorphism really doesn't help me with a place full 
of bugs." -- Megahal (trained on asr), 1998-11-06



Re: PDD 2, vtables

2001-02-06 Thread Branden

Tim Bunce wrote:
> > =item move_to
> >
> >BOOL move_to(void *, PMC);
> >
> > Tells the PMC to move its contents to a block of memory starting at
> > the passed address. Used by the garbage collector to compact memory,
> > this call can return a false value if the move can't be done for some
> > reason. The pointer is guaranteed to point to a chunk of memory at
> > least as large as that returned by the C vtable function.
>
> Shouldn't the PMC be the first arg for consistency?
>

I believe the first arg is the result, when this is needed...



> > =item logical_or
> > =item logical_and
> > =item logical_not
>
> Er, why not just use get_bool? The only reason I can think of is to
> support three-value-logic but that would probably be better handled
> via a higher-level overloading kind of mechanism. Either way, clarify.
>

Having logical_* here is an error. This way, perl would have to evaluate
both left and right argument to apply them to this functions, but that would
break short-circuit, where the right hand function is only evaluated if it
should be. This also applies to the ?: operator.

See $f && close $f; now suppose $f is undef, close $f should not be called.
But if this should be passed to a logical_and function, $f and the value
returned by close $f would be evaluated, and then passed to logical_and. So
close $f would be evaluated, what is wrong...

What should be here is bitwise_*, that are different for strings and ints,
for example.

- Branden




Re: PDD 2, vtables

2001-02-06 Thread Tim Bunce

[First off: I've not really been paying attention so forgive me if I'm
being dumb here.  And many thanks for helping to drive this forwards.]

On Mon, Feb 05, 2001 at 05:14:44PM -0500, Dan Sugalski wrote:
> 
> =head2 Core datatypes
> 
> For ease of use, we define the following semi-abstract data types

Probably worth stating upfront that it'll be easy to add new types
to avoid people argusing for their favorite type to be added here.

> =item INT
> =item NUM
> =item STR
> =item BOOL

What about references?

Arrays and hashes should probably be at least mentioned here.

> =head3 String data types
> 
> =item binary buffer

'Binary string'

> =item UTF-32 string
> =item Native string
> =item Foreign string

I'm a little surprised not to see UTF-8 there, but since I'm also
confused about what Native string and Foreign string are I'll skip it.
Except to say that some clarification here may help, and explicitly
mentioning UTF-8 (even to say it won't be a core type and provide a
reference to why) would be good.


> The functions are divided into two broad categories, those that perl
> will use the value of internally (for example the type functions) and
> those that produce or modify a PMC, such as the add function.

So possibly a good idea to explicitly group them that way.

> =head2 Functions in detail
> 
> =item type
> 
> =item name
> 
>STRname(PMC[, key]);
> 
> Returns the name of the class the PMC belongs to.

So I'd call it type_name (or maybe class_name as you seem to be useing
the words interchangably. If type != class then clarify somewhere.).

> =item move_to
> 
>BOOL   move_to(void *, PMC);
> 
> Tells the PMC to move its contents to a block of memory starting at
> the passed address. Used by the garbage collector to compact memory,
> this call can return a false value if the move can't be done for some
> reason. The pointer is guaranteed to point to a chunk of memory at
> least as large as that returned by the C vtable function.

Shouldn't the PMC be the first arg for consistency?

> =item real_size
> 
>IV real_size(PMC[, key]);
> 
> Returns an integer value that represents the real size of the data
> portion, excluding the vtable, of the PMC.

Contiguous? Sum of parts (allowing for allignment) if it contains
multiple chunks of data?

> =item destroy
> 
>void   destroy(PMC[, key]);
> 
> Destroys the variable the PMC represents, leaving it undef.

Using the word 'variable' here probably isn't a good idea.
Maybe "Destroys the contents of the PMC leaving it undef."

> =item is_same
> 
>BOOL   is_same(PMC1, PMC2[, key]);
> 
> Returns TRUE if C and C refer to the same value, and FALSE
> otherwise.

I think that needs more clarification, especially where they are of
different types. Contrast with is_equal() below.

> =item concatenate
> 
>void   concatenate(PMC1, PMC2, PMC3[, key]); ##
> 
> Concatenates the strings in C and C, storing the result in
> C.

and insert (ala sv_insert)  etc?

> =item is_equal

Contrast with is_same() above.

> =item logical_or
> =item logical_and
> =item logical_not

Er, why not just use get_bool? The only reason I can think of is to
support three-value-logic but that would probably be better handled
via a higher-level overloading kind of mechanism. Either way, clarify.

> =item match
> 
>void   match(PMC1, PMC2, REGEX[, key]);
> 
> Performs a regular expression match on C against the expression
> C, placing the results in C.

Results, plural => container => array or hash. Needs clarifying.

> =item repeat (x)
> 
>void   repeat(PMC1, PMC2, PMC3[, key]); ##
> 
> Performs the following sequence of operations: finds the string value
> from C; finds an integer value I from C; replicates the
> string I times; stores the resulting string in C.

So call it replicate? Could also work for arrays.

> =item nextkey (x)
> 
>void   nextkey(PMC1, PMC2, start_key[, key]);
> 
> Looks up the key C in C and then stores the key after
> it in C. If start_key is C, the first key is returned,
> and C is set to undef if there is no next key.

Containers again.  And I'd call it key_next()

> =item exists (x)

Likewise, key_exists()

> =head1 TODO
> 
> The effects of each function on scalar, array, hash, list, and IO
> PMCs needs to be hashed out.

Before that I think a section on containers need to be added.

> =head1 REFERENCES
> 
> PDD 3: Perl's Internal Data Types.

Some references to any other vtable based languages would be good.
(I presume people have looked at some and learnt lessons.)

Tim.



Re: PDD 2, vtables

2001-02-06 Thread Branden

Dan Sugalski wrote:
> Okay, here's the VTABLE PDD. Comments, please. (As if there's any worry
> about not having any :)

Hi, Dan.

I have a _very_ different view of yours on the vtable area. I read your PDD,
but I really couldn't figure out how the operations would be carried. For
instance, on the add function, I have to sum PMC2 and PMC3 and store it in
PMC1. I should use the vtable of PMC1, PMC2 or PMC3? If I use the one of
PMC1, it wouldn't (shouldn't) know about the internal structure of PMC2 and
PMC3, and if I use the vtable of PMC2 or PMC3, it wouldn't know what how to
store the value on PMC1 (say if PMC1 is tied and the value should actually
be written to a database?).

I have a thought of making vtables very near to the current (Perl 5.6)
interface for ties and overload. Of course that interface could be designed
a little better if we dive into it, but I think it's ok to start with...

Anyway, I see if I'll write something about my ideas, and I send it to the
list later.

Thanks,

- Branden