Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-28 Thread David . Leeper


 so please note that destruction is not collection and they are and can
 be separately controlled. you have to stop thinking c++ (which will
 probably NOT be directly supported by parrot) and think perlish (or
 as other dynamic langs) more. perl doesn't have a delete thing and
 doesn't need one. it can detect DoD on its own and then let parrot GC
 them later. memory usage and objects are not the same.

Well, I'm not really interested in Perl at all. If all Parrot can do is
allow me to write a languge that is basically Perl, then I'm not interested
in Parrot either.

I think it may be a good idea to wait until the Parrot folks have their
product and web site a little better documented and aren't under such
stress.

Dave




   

Uri Guttman

uri@stemsyste   To: [EMAIL PROTECTED]

ms.com  cc: [EMAIL PROTECTED], [EMAIL PROTECTED], 
[EMAIL PROTECTED]  
 Subject: Re: How Powerful Is Parrot? (A 
Few More Questions)   
01/25/02 11:49 

PM 

Please respond 

to Uri Guttman 

   

   





 DL == David Leeper [EMAIL PROTECTED] writes:

  DL If I know what I want to destroy and when, can I just turn off
Parrot's
  DL automatic garbage collector/memory compactor and send it instructons
on
  DL what I want deleted?

i have to jump in here because i am seeing the classic discussion of A
and B and they are not the same things. in parrot, GC is separated from
DoD. you seem to always conflate the two. in general destruction is not
related to GC, it is used to clean up stuff like file handles, complex
objects, deal with persistance etc. a destroyed object may have its
space reclaimed at some future time. destruction is more of a language
feature and GC is more of a VM feature. they are not the same thing and
you shouldn't keep talking about them as if they are con-joined
twins. you can cause object destruction when you want in most langs that
parrot will support. and you can probably initiate a GC pass from most
langs if they have an API to get into parrot's GC. but you don't have to
do one to do the other. many heap allocated things won't be objects
(buffers, strings, etc.) and will be purely GC'ed as needed. some
objects can be destroyed simply when their context exits (e.g. leaving a
block and destroying any my'ed objects which are dead). those will then
be marked for later GC.

so please note that destruction is not collection and they are and can
be separately controlled. you have to stop thinking c++ (which will
probably NOT be directly supported by parrot) and think perlish (or
as other dynamic langs) more. perl doesn't have a delete thing and
doesn't need one. it can detect DoD on its own and then let parrot GC
them later. memory usage and objects are not the same.

uri

--
Uri Guttman  --  [EMAIL PROTECTED]  
http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite
-
- Stem and Perl Development, Systems Architecture, Design and Coding

Search or Offer Perl Jobs  
http://jobs.perl.org






Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-28 Thread Simon Cozens

On Mon, Jan 28, 2002 at 10:03:53AM -0500, [EMAIL PROTECTED] wrote:
 Well, I'm not really interested in Perl at all. If all Parrot can do is
 allow me to write a languge that is basically Perl, then I'm not interested
 in Parrot either.

To be fair, Uri did say and other dynamic languages. And I have no
problems with a C or C++ style language implemented on top of Parrot. 
C would obviously be relatively easy; I'd positively like to have someone
thinking about the likes of C# on Parrot.

-- 
Wouldn't it be wonderful if real life supported control-Z?



Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-28 Thread Melvin Smith



Well, I'm not really interested in Perl at all. If all Parrot can do is
allow me to write a languge that is basically Perl, then I'm not
interested
in Parrot either.

I think it may be a good idea to wait until the Parrot folks have their
product and web site a little better documented and aren't under such
stress.

Dave

Or you could become a Parrot folk and wade in and help out. ;)

-Melvin Smith

IBM :: Atlanta Innovation Center
[EMAIL PROTECTED] :: 770-835-6984










Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper


Thanks to everyone for their information on Parrot. A couple more questions
have come to mind.

1) Does Parrot support multiple inheritance?
2) Does Parrot support stack variables or is everything allocated on the
heap?

Thanks again.

Dave




Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Simon Cozens

On Fri, Jan 25, 2002 at 10:18:56AM -0500, [EMAIL PROTECTED] wrote:
 1) Does Parrot support multiple inheritance?
 2) Does Parrot support stack variables or is everything allocated on the
 heap?

There's an easy way to answer these questions for yourself.
Does Parrot support X? == Does any language which we hope to run
on Parrot support X?

Perl has multiple inheritance. It would be a shame if the interpreter we
wrote to run Perl on didn't have multiple inheritance.
Perl, and many other languages, have stack variables. Parrot has to support
them.

-- 
You are in a maze of little twisting passages, all different.



Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Melvin Smith


From what I've seen, supporting both garbage collection and true stack
variables is a difficult task.

Why is that?

-Melvin Smith

IBM :: Atlanta Innovation Center
[EMAIL PROTECTED] :: 770-835-6984





Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper


 From what I've seen, supporting both garbage collection and true stack
 variables is a difficult task.

 Why is that?

Because stack variables can refer to heap variables and heap variables can
refer to stack variables. The garbage collector needs to be smart enough to
handle all cases correctly. For example, let's say we have the following
two classes...

class A
{
 public B b_member;
}

class B
{
 public A a_member;
}

and the following declarations and function...

B global_b;  // Creates an instance of B with an A member, both
on the stack.
B global_b2;// Creates an instance of B with an A member, both on
the stack.

void f()
{
 A a;   // Creates an instance of A with a B member, both on
the stack.
 B b = new B(); // Creates an instance of B with an A member, both on
the heap.

 // 4 objects have now been created in this function, an A and B on the
stack, and an A and B on the heap.

 a.b_member = b; // Stack variable a now references heap variable
b.
 b.a_member = a; // Heap variable b now references stack variable
a.
 global_b.a_member = a;   // Stack variable global_b now references
stack variable a.
 global_b2 = b; // Stack variable global_b2 now references heap
variable b.

 // What happens to the six objects we've created when we leave the
scope of f()?
}

This implies several things.

1) Garbage collection is optional because stack variables are not garbage
collected.
2) Garbage collection knows every object created, how every object was
created (stack or heap), and how every object is referenced by other
objects.
3) The stack interacts seemlessly with garbage collection. When we leave f
() in the above example, referencing global_b.a_member needs to produce an
error or exception.
4) Garbage collection interacts seemlessly with the stack. In the above
example, b can never be garbage collected for the life of the program
because the stack variable global_b2 references it and global_b2 never goes
out of scope.

It's not impossible to write a garbage collector that can handle this, I've
done it myself. This is why I've been asking these questions about Parrot.
I want to know if I can use Parrot as a VM for a language I've designed.
I'm currently generating C++ code. I'd like to use Parot, but I need true
stack variables and 100% deterministic garbage collection.

I don't know of any language that has these features. Java doesn't. C++
doesn't (unless you roll your own and restrict what programmers can do), C#
doesn't.

Dave



   

Melvin Smith 

[EMAIL PROTECTED]   To: [EMAIL PROTECTED]

m.com   cc: [EMAIL PROTECTED], Simon 
Cozens [EMAIL PROTECTED] 
 Subject: Re: How Powerful Is Parrot? (A 
Few More Questions)   
01/25/02 12:00 

PM 

   

   






From what I've seen, supporting both garbage collection and true stack
variables is a difficult task.

Why is that?

-Melvin Smith

IBM :: Atlanta Innovation Center
[EMAIL PROTECTED] :: 770-835-6984








Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Melvin Smith

Thanks for the nice example, except I understand the issue you
are speaking of, I was basically asking what parts of it do you think
are more difficult to implement than any other major construct?

There are several ways to address the example you just gave (my computer
science is getting rusty here) but let me think...

 a.b_member = b; // Stack variable a now references heap variable
b.

I see no problem here.

 b.a_member = a; // Heap variable b now references stack variable
a.
 global_b.a_member = a;   // Stack variable global_b now references
stack variable a.
 global_b2 = b; // Stack variable global_b2 now references heap
variable b.

 // What happens to the six objects we've created when we leave the
scope of f()?

One approach is

stack = stack (reference)
stack = heap (reference)
heap = heap (reference)
heap = stack (copy)


-Melvin Smith

IBM :: Atlanta Innovation Center
[EMAIL PROTECTED] :: 770-835-6984


   
   
  David.Leeper@bisy
   
  s.comTo:   Melvin 
Smith/ATLANTA/Contr/IBM@IBMUS 
   cc:   [EMAIL PROTECTED], 
Simon Cozens [EMAIL PROTECTED]
  01/25/2002 12:45 Subject:  Re: How Powerful Is Parrot? 
(A Few More Questions)   
  PM   
   
   
   
   
   




 From what I've seen, supporting both garbage collection and true stack
 variables is a difficult task.

 Why is that?

Because stack variables can refer to heap variables and heap variables can
refer to stack variables. The garbage collector needs to be smart enough to
handle all cases correctly. For example, let's say we have the following
two classes...

class A
{
 public B b_member;
}

class B
{
 public A a_member;
}

.and the following declarations and function...

B global_b;  // Creates an instance of B with an A member, both
on the stack.
B global_b2;// Creates an instance of B with an A member, both on
the stack.

void f()
{
 A a;   // Creates an instance of A with a B member, both on
the stack.
 B b = new B(); // Creates an instance of B with an A member, both on
the heap.

 // 4 objects have now been created in this function, an A and B on the
stack, and an A and B on the heap.

 a.b_member = b; // Stack variable a now references heap variable
b.
 b.a_member = a; // Heap variable b now references stack variable
a.
 global_b.a_member = a;   // Stack variable global_b now references
stack variable a.
 global_b2 = b; // Stack variable global_b2 now references heap
variable b.

 // What happens to the six objects we've created when we leave the
scope of f()?
}

This implies several things.

1) Garbage collection is optional because stack variables are not garbage
collected.
2) Garbage collection knows every object created, how every object was
created (stack or heap), and how every object is referenced by other
objects.
3) The stack interacts seemlessly with garbage collection. When we leave f
() in the above example, referencing global_b.a_member needs to produce an
error or exception.
4) Garbage collection interacts seemlessly with the stack. In the above
example, b can never be garbage collected for the life of the program
because the stack variable global_b2 references it and global_b2 never goes
out of scope.

It's not impossible to write a garbage collector that can handle this, I've
done it myself. This is why I've been asking these questions about Parrot.
I want to know if I can use Parrot as a VM for a language I've designed.
I'm currently generating C++ code. I'd like to use Parot, but I need true
stack variables and 100% deterministic garbage collection.

I don't know of any language that has these features. Java doesn't. C++
doesn't (unless you roll your own and restrict what programmers can do), C#
doesn't.

Dave




Melvin Smith

[EMAIL PROTECTED]   To: [EMAIL PROTECTED]
m.com   cc: [EMAIL PROTECTED],
Simon Cozens [EMAIL PROTECTED]
 Subject: Re: How Powerful Is
Parrot? (A Few More Questions)
01/25/02 12:00

PM








From what I've seen

Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper


 Thanks for the nice example, except I understand the issue you
 are speaking of, I was basically asking what parts of it do you think
 are more difficult to implement than any other major construct?

I believe the main difficulty comes from heading into uncharted waters. For
example, once you've decided to make garbage collection optional, what does
the following line of code mean?

 delete x;

Does it mean anything at all? Is it even a legal statement? Is garbage
collection optional for all variables, or simply not used for stack
variables, but always used for heap variables?

Or, for example, are the side effects of the following two functions
different?

void f1()
{
 // On the stack
 MyClass o;
}

void f2()
{
 // On the heap
 MyClass o = new MyClass();
}

If garbage collection is not 100% deterministic, these two functions could
produce very different results because we do not know when or if the
destructor for MyClass will execute in the case of f2(). The same would be
true when exceptions are thrown from a function. If garbage collection is
not 100% deterministic (and Mark and Sweep is not), we need extra language
features, such as Java's finally block, to ensure things can be cleaned
up, and extra training to ensure programmers are smart enough to know how
to use finally blocks correctly.

So, as I see it, the choice of garbage collections schemes ripples
throughout the entire language. It effects what statements are legal and
the semantics of even the simplest pieces of code.

The point to all my questions is this: I'm thinking about basing my
language on the Parrot VM. If I do that, what does the call to f2() mean?

What happens to my language when I use the Parrot VM?

Dave




   

Melvin Smith 

[EMAIL PROTECTED]   To: [EMAIL PROTECTED]

m.com   cc: [EMAIL PROTECTED], Simon 
Cozens [EMAIL PROTECTED] 
 Subject: Re: How Powerful Is Parrot? (A 
Few More Questions)   
01/25/02 01:13 

PM 

   

   





Thanks for the nice example, except I understand the issue you
are speaking of, I was basically asking what parts of it do you think
are more difficult to implement than any other major construct?

There are several ways to address the example you just gave (my computer
science is getting rusty here) but let me think...

 a.b_member = b; // Stack variable a now references heap variable
b.

I see no problem here.

 b.a_member = a; // Heap variable b now references stack variable
a.
 global_b.a_member = a;   // Stack variable global_b now references
stack variable a.
 global_b2 = b; // Stack variable global_b2 now references heap
variable b.

 // What happens to the six objects we've created when we leave the
scope of f()?

One approach is

stack = stack (reference)
stack = heap (reference)
heap = heap (reference)
heap = stack (copy)


-Melvin Smith

IBM :: Atlanta Innovation Center
[EMAIL PROTECTED] :: 770-835-6984



  David.Leeper@bisy
  s.comTo:   Melvin
Smith/ATLANTA/Contr/IBM@IBMUS
   cc:
[EMAIL PROTECTED], Simon Cozens [EMAIL PROTECTED]
  01/25/2002 12:45 Subject:  Re: How Powerful
Is Parrot? (A Few More Questions)
  PM






 From what I've seen, supporting both garbage collection and true stack
 variables is a difficult task.

 Why is that?

Because stack variables can refer to heap variables and heap variables can
refer to stack variables. The garbage collector needs to be smart enough to
handle all cases correctly. For example, let's say we have the following
two classes...

class A
{
 public B b_member;
}

class B
{
 public A a_member;
}

.and the following declarations and function...

B global_b;  // Creates an instance of B with an A member, both
on the stack.
B global_b2;// Creates an instance of B with an A member, both on
the stack.

void f()
{
 A a;   // Creates an instance of A with a B member, both on
the stack.
 B b = new B(); // Creates an instance of B with an A member, both on
the heap.

 // 4 objects have now been created

Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Bryan C. Warnock

On Friday 25 January 2002 13:50, [EMAIL PROTECTED] wrote:
  Thanks for the nice example, except I understand the issue you
  are speaking of, I was basically asking what parts of it do you think
  are more difficult to implement than any other major construct?

 I believe the main difficulty comes from heading into uncharted waters.
 For example, once you've decided to make garbage collection optional, what
 does the following line of code mean?

  delete x;

 Does it mean anything at all? Is it even a legal statement? Is garbage
 collection optional for all variables, or simply not used for stack
 variables, but always used for heap variables?

 Or, for example, are the side effects of the following two functions
 different?

 void f1()
 {
  // On the stack
  MyClass o;
 }

 void f2()
 {
  // On the heap
  MyClass o = new MyClass();
 }

 If garbage collection is not 100% deterministic, these two functions could
 produce very different results because we do not know when or if the
 destructor for MyClass will execute in the case of f2(). The same would be
 true when exceptions are thrown from a function. If garbage collection is
 not 100% deterministic (and Mark and Sweep is not), we need extra language
 features, such as Java's finally block, to ensure things can be cleaned
 up, and extra training to ensure programmers are smart enough to know how
 to use finally blocks correctly.

 So, as I see it, the choice of garbage collections schemes ripples
 throughout the entire language. It effects what statements are legal and
 the semantics of even the simplest pieces of code.

 The point to all my questions is this: I'm thinking about basing my
 language on the Parrot VM. If I do that, what does the call to f2() mean?

 What happens to my language when I use the Parrot VM?

GC (at the Parrot level) isn't finalization (at the language level).   In 
your last several posts, it hasn't been clear at what level you're trying to 
address.

Parrot supports deterministic destruction at the language level.  If your 
language wants 'o' to be destroyed at the exit from f2(), then 'o' will be 
destroyed in whatever manner MyClass destruction means to your language.
Resources allocated strictly by the internal representation responsible for 
MyClass (e.g. Leeper_Object) may not be collected at that point, but that's 
mostly independent of the language.  (You could also trigger a GC run 
yourself.)

Consider, for a moment, a C++ object that is dependent on some kernel 
resource.  C++ makes the determination of when and how that object is 
destroyed and finalized, releasing both program memory, user-space 
resources, and the attached kernel resources.  It shouldn't then matter to 
the program if, when, or how the kernel goes about collecting those 
resources.  (Overcommitting memory is a good example of how some modern 
kernels lie to their programs for exactly that reason.)

-- 
Bryan C. Warnock
[EMAIL PROTECTED]



Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper


 Parrot supports deterministic destruction at the language level.  If your
 language wants 'o' to be destroyed at the exit from f2(), then 'o' will
be
 destroyed in whatever manner MyClass destruction means to your language.
 Resources allocated strictly by the internal representation responsible
for
 MyClass (e.g. Leeper_Object) may not be collected at that point, but
that's
 mostly independent of the language.  (You could also trigger a GC run
 yourself.)

I believe I understand now. I think that what this means to me is that if I
want 100% deterministic destruction, I will have to implement my own
garbage collector. This garbage collector will call object destructors and
free all language-specific resources of the object. Once I've finished
using the object, the Parrot garbage collector will free Parrot resources
associated with the object at some undetermined time in the future.

I think that's acceptable.

Thanks Bryan.

Dave



   

Bryan C.  

Warnock To: [EMAIL PROTECTED]

bwarnock@capi   cc: [EMAIL PROTECTED]  

ta.com  Subject: Re: How Powerful Is Parrot? (A 
Few More Questions)   
   

01/25/02 02:10 

PM 

Please respond 

to bwarnock

   

   





On Friday 25 January 2002 13:50, [EMAIL PROTECTED] wrote:
  Thanks for the nice example, except I understand the issue you
  are speaking of, I was basically asking what parts of it do you think
  are more difficult to implement than any other major construct?

 I believe the main difficulty comes from heading into uncharted waters.
 For example, once you've decided to make garbage collection optional,
what
 does the following line of code mean?

  delete x;

 Does it mean anything at all? Is it even a legal statement? Is garbage
 collection optional for all variables, or simply not used for stack
 variables, but always used for heap variables?

 Or, for example, are the side effects of the following two functions
 different?

 void f1()
 {
  // On the stack
  MyClass o;
 }

 void f2()
 {
  // On the heap
  MyClass o = new MyClass();
 }

 If garbage collection is not 100% deterministic, these two functions
could
 produce very different results because we do not know when or if the
 destructor for MyClass will execute in the case of f2(). The same would
be
 true when exceptions are thrown from a function. If garbage collection is
 not 100% deterministic (and Mark and Sweep is not), we need extra
language
 features, such as Java's finally block, to ensure things can be cleaned
 up, and extra training to ensure programmers are smart enough to know how
 to use finally blocks correctly.

 So, as I see it, the choice of garbage collections schemes ripples
 throughout the entire language. It effects what statements are legal and
 the semantics of even the simplest pieces of code.

 The point to all my questions is this: I'm thinking about basing my
 language on the Parrot VM. If I do that, what does the call to f2() mean?

 What happens to my language when I use the Parrot VM?

GC (at the Parrot level) isn't finalization (at the language level).   In
your last several posts, it hasn't been clear at what level you're trying
to
address.

Parrot supports deterministic destruction at the language level.  If your
language wants 'o' to be destroyed at the exit from f2(), then 'o' will be
destroyed in whatever manner MyClass destruction means to your language.
Resources allocated strictly by the internal representation responsible for
MyClass (e.g. Leeper_Object) may not be collected at that point, but that's
mostly independent of the language.  (You could also trigger a GC run
yourself.)

Consider, for a moment, a C++ object that is dependent on some kernel
resource.  C++ makes the determination of when and how that object is
destroyed and finalized, releasing both program memory, user-space
resources

RE: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Hong Zhang

 I believe the main difficulty comes from heading into uncharted waters.
For
 example, once you've decided to make garbage collection optional, what
does
 the following line of code mean?
 
  delete x;

If the above code is compiled to Parrot, it probably equivalent to

  x-~Destructor();

i.e., the destructor is called, but the memory is left to GC, which most
likely
handle free at a later time.

 Or, for example, are the side effects of the following two functions
 different?
 
 void f1()
 {
  // On the stack
  MyClass o;
 }
 
 void f2()
 {
  // On the heap
  MyClass o = new MyClass();
 }
 
 If garbage collection is not 100% deterministic, these two functions could
 produce very different results because we do not know when or if the
 destructor for MyClass will execute in the case of f2().

This is exactly the same case for C++. When you compile f2 with gcc, how
can you tell when the destructor is called. Even the following code does
not work.

  void f3()
  {
MyClass o = new MyClass();
...
delete o;
  }

If there is an exception happens within (...), the destructor will not be
called.

 If garbage collection is
 not 100% deterministic (and Mark and Sweep is not), we need extra language
 features, such as Java's finally block, to ensure things can be cleaned
 up, and extra training to ensure programmers are smart enough to know how
 to use finally blocks correctly.

That is exactly the case for C++. In your above code f1(), the C++ compiler
already (behind the scene) inserts finally block for o destructor. That
is why the destructor of stack allocated objects is called even when
exception 
happens. The only difference is that the memory deallocation is
dis-associated
with object destruction.

Summary: the object destruction with GC is as deterministic as C++ heap 
allocated object, i.e. you have to call delete x (in C++), x.close() (in
Java), x.dispose (in C#), otherwise is 0% deterministic, period.

Hong



RE: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper


 That is exactly the case for C++. In your above code f1(), the C++
compiler
 already (behind the scene) inserts finally block for o destructor. That
 is why the destructor of stack allocated objects is called even when
 exception
 happens. The only difference is that the memory deallocation is
 dis-associated
 with object destruction.

 Summary: the object destruction with GC is as deterministic as C++ heap
 allocated object, i.e. you have to call delete x (in C++), x.close()
(in
 Java), x.dispose (in C#), otherwise is 0% deterministic, period.

No, there is a difference. The difference is you do not know when the Java
garbage collector will call an object's finalize() method, and in fact Java
does not even guarentee it will be called at all. C#'s garbage collector is
nondeterministic as well. The garbage collector in these languages are
usually implemented to run on a low priority thread. This thread gets
processor time based on system load, which means objects are collected and
finalized based on thread scheduling, the number of active threads, and
other factors that have nothing to do with a function going out of scope
and which cannot be predicted prior to run time.

In C++, when operator delete is called, the object's destructor is invoked
as part of the call right away, not at some point in the future, by some
other thread, maybe as with Java.

This changes the way a programmer writes code. A C++ class and function
that uses the class looks like this:

class A
{
public:
 A(){...grab some resources...}
 ~A(){...release the resources...}
}

void f()
{
 A a;
 ... use a's resources ...
}

looks like this in Java...

class A
{
public:
 A(){...grab some resources...}
}

void f()
{
 try
 {
  A a;
  ... use a's resources ...
 }
 finally
 {
  ...release the resources...
 }
}

because we do not know when or if Java will finalize the a object. And
everywhere the programmer uses the class A he must write the finally block
as well. Also note that both examples behave correctly in the face of
exceptions thrown during the execution of f().

Dave



   
  
Hong Zhang 
  
Hong.Zhang@corp   To: 
  
.palm.com cc: [EMAIL PROTECTED]
  
   Subject: RE: How Powerful Is Parrot? (A 
Few More Questions)   
01/25/02 03:05 
  
PM 
  
   
  
   
  




 I believe the main difficulty comes from heading into uncharted waters.
For
 example, once you've decided to make garbage collection optional, what
does
 the following line of code mean?

  delete x;

If the above code is compiled to Parrot, it probably equivalent to

  x-~Destructor();

i.e., the destructor is called, but the memory is left to GC, which most
likely
handle free at a later time.

 Or, for example, are the side effects of the following two functions
 different?

 void f1()
 {
  // On the stack
  MyClass o;
 }

 void f2()
 {
  // On the heap
  MyClass o = new MyClass();
 }

 If garbage collection is not 100% deterministic, these two functions
could
 produce very different results because we do not know when or if the
 destructor for MyClass will execute in the case of f2().

This is exactly the same case for C++. When you compile f2 with gcc, how
can you tell when the destructor is called. Even the following code does
not work.

  void f3()
  {
MyClass o = new MyClass();
...
delete o;
  }

If there is an exception happens within (...), the destructor will not be
called.

 If garbage collection is
 not 100% deterministic (and Mark and Sweep is not), we need extra
language
 features, such as Java's finally block, to ensure things can be cleaned
 up, and extra training to ensure programmers are smart enough to know how
 to use finally blocks correctly.

That is exactly the case for C++. In your above code f1(), the C++ compiler
already (behind the scene) inserts finally block for o destructor. That
is why the destructor of stack allocated objects is called even when
exception
happens. The only difference is that the memory deallocation is
dis-associated
with object destruction.

Summary: the object

Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Dan Sugalski

At 2:46 PM -0500 1/25/02, [EMAIL PROTECTED] wrote:
   Parrot supports deterministic destruction at the language level.  If your
  language wants 'o' to be destroyed at the exit from f2(), then 'o' will
be
  destroyed in whatever manner MyClass destruction means to your language.
  Resources allocated strictly by the internal representation responsible
for
  MyClass (e.g. Leeper_Object) may not be collected at that point, but
that's
  mostly independent of the language.  (You could also trigger a GC run
  yourself.)

I believe I understand now. I think that what this means to me is that if I
want 100% deterministic destruction, I will have to implement my own
garbage collector. This garbage collector will call object destructors and
free all language-specific resources of the object. Once I've finished
using the object, the Parrot garbage collector will free Parrot resources
associated with the object at some undetermined time in the future.

I think you're getting confused a bit here--I apologize for not 
jumping in earlier.

As far as Parrot's concerned, Garbage Collection is just the 
reclamation of unused memory and unused interpreter structures. This 
will happen when the interpreter deems it necessary, and you can 
force or block a GC run if you need to. The heap may be compacted 
when this happens, but variables can be marked as non-moveable if 
this is necessary. (for those cases when absolute memory addresses 
are referenced outside of the interpreter as well)

Dead Object Detection is the phase where the interpreter determines 
which objects are reachable from the root set, and which aren't. Any 
objects that aren't reachable *and* are marked as having an active 
destructor (and most won't, there's no need in 90% of the cases) will 
have their destructor called and the objects can clean up as need be. 
Once again this happens when the interpreter deems it necessary and 
you may also force or block a DOD run.

In neither case do you have any control over the order that memory is 
compacted, or dead objects with destructors have their destructors 
called. If you must force some sort of order you need to do so within 
the objects destructor. Alternately if your program knows what order 
objects should be destroyed in your may explicitly call objects 
destructors. This is outside the GC/DOD system however as it happens 
from within your mainline code. (When the DOD later runs it won't do 
anything with those objects as you've already destroyed them and thus 
left nothing for the DOD sweep to do)

 Bryan 
C.
 
 Warnock To: 
[EMAIL PROTECTED]   
 bwarnock@capi   cc: 
[EMAIL PROTECTED] 
 ta.com  Subject: Re: How 
Powerful Is Parrot? (A Few More Questions)  
 
  
   
 01/25/02 
02:10
 
PM

 Please 
respond   
 
 to 
bwarnock  
 
 
  
   
 
  
   




On Friday 25 January 2002 13:50, [EMAIL PROTECTED] wrote:
   Thanks for the nice example, except I understand the issue you
are speaking of, I was basically asking what parts of it do you think
   are more difficult to implement than any other major construct?

  I believe the main difficulty comes from heading into uncharted waters.
  For example, once you've decided to make garbage collection optional,
what
  does the following line of code mean?

   delete x;

  Does it mean anything at all? Is it even a legal statement? Is garbage
  collection optional for all variables, or simply not used for stack
  variables, but always used for heap variables?

  Or, for example, are the side effects of the following two functions
  different?

  void f1()
  {
   // On the stack
   MyClass o;
  }

  void f2()
  {
   // On the heap
   MyClass o = new MyClass();
  }

  If garbage collection is not 100% deterministic, these two functions
could
  produce very different results because we do not know when or if the
  destructor for MyClass will execute in the case of f2(). The same would
be
  true when exceptions are thrown from a function. If garbage collection

Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread David . Leeper



 In neither case do you have any control over the order that memory is
 compacted, or dead objects with destructors have their destructors
 called. If you must force some sort of order you need to do so within
 the objects destructor. Alternately if your program knows what order
 objects should be destroyed in your may explicitly call objects
 destructors. This is outside the GC/DOD system however as it happens
 from within your mainline code. (When the DOD later runs it won't do
 anything with those objects as you've already destroyed them and thus
 left nothing for the DOD sweep to do)

If I know what I want to destroy and when, can I just turn off Parrot's
automatic garbage collector/memory compactor and send it instructons on
what I want deleted?

Dave



   

Dan Sugalski   

[EMAIL PROTECTED]   To: [EMAIL PROTECTED], 
[EMAIL PROTECTED]   
cc: [EMAIL PROTECTED]  

 Subject: Re: How Powerful Is Parrot? (A 
Few More Questions)   
01/25/02 03:43 

PM 

   

   





At 2:46 PM -0500 1/25/02, [EMAIL PROTECTED] wrote:
   Parrot supports deterministic destruction at the language level.  If
your
  language wants 'o' to be destroyed at the exit from f2(), then 'o' will
be
  destroyed in whatever manner MyClass destruction means to your
language.
  Resources allocated strictly by the internal representation responsible
for
  MyClass (e.g. Leeper_Object) may not be collected at that point, but
that's
  mostly independent of the language.  (You could also trigger a GC run
  yourself.)

I believe I understand now. I think that what this means to me is that if
I
want 100% deterministic destruction, I will have to implement my own
garbage collector. This garbage collector will call object destructors and
free all language-specific resources of the object. Once I've finished
using the object, the Parrot garbage collector will free Parrot resources
associated with the object at some undetermined time in the future.

I think you're getting confused a bit here--I apologize for not
jumping in earlier.

As far as Parrot's concerned, Garbage Collection is just the
reclamation of unused memory and unused interpreter structures. This
will happen when the interpreter deems it necessary, and you can
force or block a GC run if you need to. The heap may be compacted
when this happens, but variables can be marked as non-moveable if
this is necessary. (for those cases when absolute memory addresses
are referenced outside of the interpreter as well)

Dead Object Detection is the phase where the interpreter determines
which objects are reachable from the root set, and which aren't. Any
objects that aren't reachable *and* are marked as having an active
destructor (and most won't, there's no need in 90% of the cases) will
have their destructor called and the objects can clean up as need be.
Once again this happens when the interpreter deems it necessary and
you may also force or block a DOD run.

In neither case do you have any control over the order that memory is
compacted, or dead objects with destructors have their destructors
called. If you must force some sort of order you need to do so within
the objects destructor. Alternately if your program knows what order
objects should be destroyed in your may explicitly call objects
destructors. This is outside the GC/DOD system however as it happens
from within your mainline code. (When the DOD later runs it won't do
anything with those objects as you've already destroyed them and thus
left nothing for the DOD sweep to do)

 Bryan
C.
 Warnock To:
[EMAIL PROTECTED]
 bwarnock@capi   cc:
[EMAIL PROTECTED]
 ta.com  Subject: Re: How
Powerful Is Parrot? (A Few More Questions)


 01/25/02
02:10

PM
 Please
respond
 to
bwarnock








On Friday 25 January 2002 13:50, [EMAIL PROTECTED] wrote:
   Thanks for the nice example, except I understand the issue you
are speaking of, I was basically asking what parts of it do you
think
   are more difficult to implement than any other major construct?

  I

RE: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Hong Zhang

 This changes the way a programmer writes code. A C++ class 
 and function that uses the class looks like this:
 
 class A
 {
 public:
  A(){...grab some resources...}
  ~A(){...release the resources...}
 }
 
 void f()
 {
  A a;
  ... use a's resources ...
 }
 
 ...looks like this in Java...
 
 class A
 {
 public:
  A(){...grab some resources...}
 }
 
 void f()
 {
  try
  {
   A a;
   ... use a's resources ...
  }
  finally
  {
   ...release the resources...
  }
 }

This is exactly the right way to do things in Java. In Java, you
can open hundreds of files, and never trigger any gc, since each
file object is very small. Unless you explicit close file, you
will be dead very quickly.

The difference between C++ and Java is C++ provides you stack allocated
object, and compiler does the dirty job to make sure the dtors are
called at the right time. In Java, you have to do it yourself.
In case you make some mistakes, the finalizer will kick in. But you
should not rely on it. From the runtime poit of view, the above C++
and Java are almost the same, except the memory deallocation.

This is one of the reason Java is so sloppy. Everyone relies on language
feature to do their job, but it is impossible for JVM to know there
are several file objects in thousands of dead object, which need to
be finalized in order to free enough file descriptor.

All you need to do is to treat Java object as C++ heap object, period.

Hong



Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Dan Sugalski

At 3:48 PM -0500 1/25/02, [EMAIL PROTECTED] wrote:
   In neither case do you have any control over the order that memory is
  compacted, or dead objects with destructors have their destructors
  called. If you must force some sort of order you need to do so within
  the objects destructor. Alternately if your program knows what order
  objects should be destroyed in your may explicitly call objects
  destructors. This is outside the GC/DOD system however as it happens
  from within your mainline code. (When the DOD later runs it won't do
  anything with those objects as you've already destroyed them and thus
  left nothing for the DOD sweep to do)

If I know what I want to destroy and when, can I just turn off Parrot's
automatic garbage collector/memory compactor and send it instructons on
what I want deleted?

You don't even have to go that far. Just explicitly call the object's 
destruction code and you're fine. (You do *not* want to turn off 
Parrot's GC, though, or you'll leak like a sieve)

Something like:

 destroy P4

or whatever. You'll need to make sure your cleanup code properly sets 
the PMC internals to make itself undef so Bad Things don't happen, 
but that's about it.

 
  
   
 Dan 
Sugalski  

 [EMAIL PROTECTED]   To: 
[EMAIL PROTECTED], [EMAIL PROTECTED]  
 cc: 
[EMAIL PROTECTED] 
  Subject: Re: How 
Powerful Is Parrot? (A Few More Questions)  
 01/25/02 
03:43
 
PM

 
  
   
 
  
   




At 2:46 PM -0500 1/25/02, [EMAIL PROTECTED] wrote:
Parrot supports deterministic destruction at the language level.  If
your
   language wants 'o' to be destroyed at the exit from f2(), then 'o' will
be
   destroyed in whatever manner MyClass destruction means to your
language.
   Resources allocated strictly by the internal representation responsible
for
   MyClass (e.g. Leeper_Object) may not be collected at that point, but
that's
   mostly independent of the language.  (You could also trigger a GC run
   yourself.)

I believe I understand now. I think that what this means to me is that if
I
want 100% deterministic destruction, I will have to implement my own
garbage collector. This garbage collector will call object destructors and
free all language-specific resources of the object. Once I've finished
using the object, the Parrot garbage collector will free Parrot resources
associated with the object at some undetermined time in the future.

I think you're getting confused a bit here--I apologize for not
jumping in earlier.

As far as Parrot's concerned, Garbage Collection is just the
reclamation of unused memory and unused interpreter structures. This
will happen when the interpreter deems it necessary, and you can
force or block a GC run if you need to. The heap may be compacted
when this happens, but variables can be marked as non-moveable if
this is necessary. (for those cases when absolute memory addresses
are referenced outside of the interpreter as well)

Dead Object Detection is the phase where the interpreter determines
which objects are reachable from the root set, and which aren't. Any
objects that aren't reachable *and* are marked as having an active
destructor (and most won't, there's no need in 90% of the cases) will
have their destructor called and the objects can clean up as need be.
Once again this happens when the interpreter deems it necessary and
you may also force or block a DOD run.

In neither case do you have any control over the order that memory is
compacted, or dead objects with destructors have their destructors
called. If you must force some sort of order you need to do so within
the objects destructor. Alternately if your program knows what order
objects should be destroyed in your may explicitly call objects
destructors. This is outside the GC/DOD system however as it happens
from within your mainline code. (When the DOD later runs it won't do
anything with those objects as you've already destroyed them and thus
left nothing for the DOD sweep to do)

  Bryan
C.
  Warnock To:
[EMAIL PROTECTED]
  bwarnock@capi   cc:
[EMAIL PROTECTED]
  ta.com  Subject: Re: How
Powerful

RE: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Melvin Smith


This is exactly the right way to do things in Java. In Java, you
can open hundreds of files, and never trigger any gc, since each
file object is very small. Unless you explicit close file, you
will be dead very quickly.

Although your point is taken, I think in this case it is the programmer
who is at fault. Any programmer who opens hundreds of files hoping
for GC to take over is asking for it, in any language.

This is one of the reason Java is so sloppy. Everyone relies on language
feature to do their job, but it is impossible for JVM to know there

I think it is the programmer who is sloppy. Java just encourages it, IMO.

-Melvin




Re: How Powerful Is Parrot? (A Few More Questions)

2002-01-25 Thread Uri Guttman

 DL == David Leeper [EMAIL PROTECTED] writes:

  DL If I know what I want to destroy and when, can I just turn off Parrot's
  DL automatic garbage collector/memory compactor and send it instructons on
  DL what I want deleted?

i have to jump in here because i am seeing the classic discussion of A
and B and they are not the same things. in parrot, GC is separated from
DoD. you seem to always conflate the two. in general destruction is not
related to GC, it is used to clean up stuff like file handles, complex
objects, deal with persistance etc. a destroyed object may have its
space reclaimed at some future time. destruction is more of a language
feature and GC is more of a VM feature. they are not the same thing and
you shouldn't keep talking about them as if they are con-joined
twins. you can cause object destruction when you want in most langs that
parrot will support. and you can probably initiate a GC pass from most
langs if they have an API to get into parrot's GC. but you don't have to
do one to do the other. many heap allocated things won't be objects
(buffers, strings, etc.) and will be purely GC'ed as needed. some
objects can be destroyed simply when their context exits (e.g. leaving a
block and destroying any my'ed objects which are dead). those will then
be marked for later GC.

so please note that destruction is not collection and they are and can
be separately controlled. you have to stop thinking c++ (which will
probably NOT be directly supported by parrot) and think perlish (or
as other dynamic langs) more. perl doesn't have a delete thing and
doesn't need one. it can detect DoD on its own and then let parrot GC
them later. memory usage and objects are not the same.

uri

-- 
Uri Guttman  --  [EMAIL PROTECTED]   http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite -
- Stem and Perl Development, Systems Architecture, Design and Coding 
Search or Offer Perl Jobs    http://jobs.perl.org