Discussion:
unknown
1970-01-01 00:00:00 UTC
Permalink
Cheers,
Chris

_______________________________________________
PDL-porters mailing list
PDL-***@jach.hawaii.edu
http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters





--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." -- Brian Kernighan
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." -- Brian Kernighan



--------------------------------------------------------------------------------
_______________________________________________
PDL-porters mailing list
PDL-***@jach.hawaii.edu
http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters

------=_NextPart_000_071F_01CF852D.1E2111E0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<HTML><HEAD></HEAD>
<BODY dir=ltr>
<DIV dir=ltr>
<DIV style="FONT-FAMILY: 'Calibri'; COLOR: #000000; FONT-SIZE: 12pt">
<DIV>David is quite right that roles are problematic in OO C.</DIV>
<DIV>&nbsp;</DIV>
<DIV>I think Glib / Vala is a working system that is quite good. I also believe
that if you can accept “interfaces” rather than full, formal “roles”, that Glib
can do that. How important is it to have “proper” roles?</DIV>
<DIV
style="FONT-STYLE: normal; DISPLAY: inline; FONT-FAMILY: 'Calibri'; COLOR: #000000; FONT-SIZE: small; FONT-WEIGHT: normal; TEXT-DECORATION: none">
<DIV style="FONT: 10pt tahoma">
<DIV>&nbsp;</DIV>
<DIV style="BACKGROUND: #f5f5f5">
<DIV style="font-color: black"><B>From:</B> <A title=***@gmail.com
href="mailto:***@gmail.com">David Mertens</A> </DIV>
<DIV><B>Sent:</B> Wednesday, June 11, 2014 12:54 AM</DIV>
<DIV><B>To:</B> <A title=***@gmail.com
href="mailto:***@gmail.com">Chris Marshall</A> </DIV>
<DIV><B>Cc:</B> <A title=***@karasik.eu.org
href="mailto:***@karasik.eu.org">Dmitry Karasik</A> ; <A
title=PDL-***@jach.hawaii.edu
href="mailto:PDL-***@jach.hawaii.edu">pdl-porters</A> </DIV>
<DIV><B>Subject:</B> Re: [Pdl-porters] PDL OO thoughts and Prima
OO</DIV></DIV></DIV>
<DIV>&nbsp;</DIV></DIV>
<DIV
style="FONT-STYLE: normal; DISPLAY: inline; FONT-FAMILY: 'Calibri'; COLOR: #000000; FONT-SIZE: small; FONT-WEIGHT: normal; TEXT-DECORATION: none">
<DIV dir=ltr>
<DIV>Hey everyone,</DIV>
<DIV>&nbsp;</DIV>
<DIV>If we just wanted a C object system that supported inheritance, I would say
we should take Prima's object system as a starting point and build new classes
based on Prima's Object class. I spent a weekend on this a while ago, but it'll
take quite a bit more work: Prima's purpose as a GUI toolkit is pretty deeply
embedded.</DIV>
<DIV>&nbsp;</DIV>
<DIV>However, if you want roles as well, that's a different beast, and the bulk
of my thoughts lie there. I think we can do it, but it'll be tricky. My concerns
and ideas, in brief:</DIV>
<DIV>&nbsp;</DIV>
<DIV>In C, object method invocation is efficient because the compiler
knows</DIV>
<DIV>exactly where to find your function pointers. As a result, in C an object
can</DIV>
<DIV>be cast into another class if it has the same binary layout. The problem
with</DIV>
<DIV>roles in C is that there is no promise of binary layout. If two
different</DIV>
<DIV>classes implement the same role, you don't know where in the vtable to
find</DIV>
<DIV>the same method. This can be solved in a handful of ways. The most
efficient</DIV>
<DIV>way I can think of is to make role methods a different kind of method than
a</DIV>
<DIV>class method.</DIV>
<DIV>&nbsp;</DIV>
<DIV>Thoughts?</DIV>
<DIV>David</DIV>
<DIV>&nbsp;</DIV>
<DIV>---</DIV>
<DIV>&nbsp;</DIV>
<DIV>In C, object method invocation is efficient because the compiler
knows</DIV>
<DIV>exactly where to find your function pointers. Typically, the first
element</DIV>
<DIV>of a struct definin a class is a vtable pointer, and the rest of the
items</DIV>
<DIV>are the data elements.</DIV>
<DIV>&nbsp;</DIV>
<DIV>struct my_string_vtable;</DIV>
<DIV>&nbsp;</DIV>
<DIV>struct my_string {</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>struct my_string_vtable *
methods;</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>char * string;</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>STRLEN allocated_length;</DIV>
<DIV>}</DIV>
<DIV>&nbsp;</DIV>
<DIV>struct my_string_vtable {</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>struct my_string * copy(struct
my_string *);</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>struct my_string * delete(sruct
my_string *);</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>STRLEN get_length (struct my_string
*);</DIV>
<DIV><SPAN style="WHITE-SPACE: pre"></SPAN>char * get_string(struct
my_string*);</DIV>
<DIV>}</DIV>
<DIV>&nbsp;</DIV>
<DIV>You then invoke the methods by calling the function pointers directly
from</DIV> <DIV>the vtable. To get this string's length, I would say:</DIV> <DIV>&nbsp;</DIV> <DIV>STRLEN the_len = the_string-&gt;methods-&gt;get_length(the_string);</DIV>
<DIV>&nbsp;</DIV>
<DIV>(Presumably it might iterate through the characters byte-by-byte until
it</DIV>
<DIV>found the null byte. We might consider storing this offset in the
object</DIV>
<DIV>itself, but I use it this way for illustrative purposes.) The C
compiler</DIV>
<DIV>knows that the first element of the_string is a pointer to the vtable. The
C</DIV>
<DIV>compiler also knows where the get_length method resides in this vtable, so
it</DIV>
<DIV>can locate the function to call with two pointer dereferences.</DIV>
<DIV>&nbsp;</DIV>
<DIV>As a result, in C an object can be cast into another class if it has the
same</DIV>
<DIV>binary layout. Suppose, for example, that the length method is supposed
to</DIV>
<DIV>return the number of printable characters. If I had a different (i.e.
Unicode)</DIV>
<DIV>implementation of a string, then it would need its own length method.
We</DIV>
<DIV>might want to add a few additional methods, but as long as the first
four</DIV>
<DIV>elements in our my_unicode_string_vtable are a copy, delete, get_length,
and</DIV>
<DIV>get_string function, we can cast our unicode object pointer to be a
string</DIV>
<DIV>object pointer. Any functions that operate on the string through
provided</DIV>
<DIV>methods will Just Work. This is how C inheritance works.
(Introspection</DIV>
<DIV>requires an additonal wrinkle, but it's not important here.)</DIV>
<DIV>&nbsp;</DIV>
<DIV>The problem with roles in C is that there is no promise of binary layout.
If</DIV>
<DIV>two different classes implement the same role, you don't know where in
the</DIV>
<DIV>vtable to find the same method. Suppose I have a role, does_logger.
Obviously,</DIV>
<DIV>if I compose the role into the class, then the class knows where
those</DIV>
<DIV>methods live and can call them out of the vtable without trouble. But
what</DIV>
<DIV>if I write a function that can take *anything* that does_logger? (So long
as</DIV>
<DIV>it sticks just to the logger role's functions, it should just work.) If
I</DIV>
<DIV>have a widget class and I create a derived widget class that
does_logger,</DIV>
<DIV>where in the vtable are the logger methods? The derived widget must be
binary</DIV>
<DIV>compatible with the base widget, so the logger methods must go at the end
of</DIV>
<DIV>the vtable. The binary location of these methods will certainly be
different</DIV>
<DIV>from the binary location of the logger methods composed into a derivative
of</DIV>
<DIV>my_string because that class only has four methods. We are left with
a</DIV>
<DIV>conundrum: the function cannot invoke logger commands as if they were
normal</DIV>
<DIV>object methods because the role does_logger makes no promises about
binary</DIV>
<DIV>layout. The compiler does not know where to look for them.</DIV>
<DIV>&nbsp;</DIV>
<DIV>This can be solved in a handful of ways. One way is to fetch role methods
via</DIV>
<DIV>a string hash or other index lookup. This method lookup could return a
void</DIV>
<DIV>pointer that is the function pointer, and it would have to be cast to
the</DIV>
<DIV>appropriate function type. Another mechanism which I think would be
more</DIV>
<DIV>efficient at the cost of an extra argument, would involve looking up a
role</DIV>
<DIV>vtable (once) and including that as a separate argument to role
methods.</DIV> <DIV>&nbsp;</DIV> <DIV>For comparison, here is a normal object method invocation:</DIV> <DIV>&nbsp;</DIV> <DIV>object-&gt;vtable-&gt;method(object, arg1, arg2, ...)</DIV>
<DIV>&nbsp;</DIV>
<DIV>Here is an index lookup, which relies upon a previously defined typedef
and</DIV>
<DIV>global index "does_logger_log_something_idx":</DIV>
<DIV>&nbsp;</DIV>
<DIV>typedef does_logger_log_something(void * objec);</DIV>
<DIV>does_logger_log_something log_func</DIV>
<DIV>&nbsp;&nbsp;&nbsp; =
object-&gt;vtable-&gt;lookup_role_method(does_logger_log_something_idx);</DIV>
<DIV>log_func(object, arg1, arg2, ...);</DIV>
<DIV>&nbsp;</DIV>
<DIV>And here is the role vtable lookup, which relies upon a global index for
the</DIV> <DIV>role, not the methods:</DIV> <DIV>&nbsp;</DIV> <DIV>struct * does_logger_vtable logger_vtable;</DIV> <DIV>logger_vtable = object-&gt;vtable-&gt;get_role_vtable(object,
does_logger_role_idx)</DIV> <DIV>logger_vtable-&gt;log_something(logger_vtable, object, arg1, arg2,
...);</DIV>
<DIV>&nbsp;</DIV>
<DIV>The advantage of this third approach is that you perform the vtable
lookup</DIV>
<DIV>once. Any role-based function calls within log_something have the vtable
on</DIV>
<DIV>hand and can perform role method lookups with a simple struct member
lookup.</DIV>
<DIV>&nbsp;</DIV>
<DIV>One more thing about role vtables: they don't need to be separate
vtables.</DIV>
<DIV>They can simply be offsets into the class's vtable. You could
implement</DIV>
<DIV>roles so that if the passed role vtable is null, the first thing the
role</DIV>
<DIV>method does is lookup the role vtable. In this way, if you know the class
of</DIV> <DIV>your object, you could simply invoke the logger method as</DIV> <DIV>&nbsp;</DIV> <DIV>object-&gt;vtable-&gt;log_something(0, object, arg1, arg2, ...)</DIV>
<DIV>&nbsp;</DIV></DIV>
<DIV class=gmail_extra><BR><BR>
<DIV class=gmail_quote>On Tue, Jun 10, 2014 at 2:52 PM, David Mertens <SPAN
dir=ltr>&lt;<A href="mailto:***@gmail.com"
target=_blank>***@gmail.com</A>&gt;</SPAN> wrote:<BR>
<BLOCKQUOTE
style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex"
class=gmail_quote>
<DIV dir=ltr>
<DIV>
<DIV>Hey everyone,<BR><BR>I know I originally started rumblings along these
lines (at least on the PDL end) a couple of years back, so obviously I've
thought about it. In an effort to not spam the list with a lengthy,
disorganized response, I'm going to try to collect my thoughts and be a bit
more systematic about it.<BR><BR></DIV>Didn't want my silence to indicate
indifference. :-)<BR><BR></DIV>David<BR></DIV>
<DIV class=gmail_extra>
<DIV>
<DIV class=h5><BR><BR>
<DIV class=gmail_quote>On Wed, Jun 4, 2014 at 10:59 AM, Chris Marshall <SPAN
dir=ltr>&lt;<A href="mailto:***@gmail.com"
target=_blank>***@gmail.com</A>&gt;</SPAN> wrote:<BR>
<BLOCKQUOTE
style="BORDER-LEFT: #ccc 1px solid; MARGIN: 0px 0px 0px 0.8ex; PADDING-LEFT: 1ex"
class=gmail_quote>Hi Dmitry-<BR><BR>I wanted to bring your attention to a
number of items tied<BR>into PDL3 development/plans (at least mine) that
could be<BR>of interest to you and might be an opportunity for
some<BR>synergy with Prima.<BR><BR>* David has been working on TinyCC based
JIT compiling<BR>&nbsp; with his C::Blocks development.&nbsp; This would
allow for<BR>&nbsp; runtime compilation of PDL+C code.<BR><BR>* My current
thoughts for the PDL3 kernel is that it would<BR>&nbsp; be lightweight,
support modern perl OO similar to Moose<BR>&nbsp; and perl5-mop ideas, *and*
be symmetrically usable from<BR>&nbsp; C and from Perl (this is where the
JIT really helps!).<BR><BR>* I think it is important that the PDL3 kernel be
C-based<BR>&nbsp; for portability and compatibility across platforms,
libraries,<BR>&nbsp; compilers...&nbsp; With C++ you lose that.<BR><BR>*
Going with C I've come across a number of techniques<BR>&nbsp; for
implementation:<BR><BR>&nbsp;&nbsp;&nbsp; <A
href="http://www.cs.rit.edu/~ats/books/ooc.pdf"
target=_blank>http://www.cs.rit.edu/~ats/books/ooc.pdf</A> (uses a
custom<BR>&nbsp;&nbsp;&nbsp; code generator from a specification
language)<BR><BR>&nbsp;&nbsp;&nbsp; <A
href="https://wiki.gnome.org/Projects/Vala"
target=_blank>https://wiki.gnome.org/Projects/Vala</A> (the Vala
OOC-to-C<BR>&nbsp;&nbsp;&nbsp; compiler based on the Gnome Object
system)<BR><BR>&nbsp;&nbsp;&nbsp; Prima (I finally was able to work through
the internals<BR>&nbsp;&nbsp;&nbsp; API and saw that it is very similar to
the above and it<BR>&nbsp;&nbsp;&nbsp; support symmetrically access to
methods from either<BR>&nbsp;&nbsp;&nbsp; C or perl layers)<BR><BR>* From
the Modern OO Perl point of view, and because the<BR>&nbsp; use of concepts
like Roles and method modifiers offer some<BR>&nbsp; elegant ways to
implement the PDL3 OO kernel interfaces.<BR>&nbsp; Given that the PDL3 work
would seem to be (essentially) a<BR>&nbsp; refactoring of the Prima OO
engine, I would be interested in<BR>&nbsp; discussing how PDL3 and Prima
could both benefit from<BR>&nbsp; this effort.&nbsp; Have you thought about
anything along these<BR>&nbsp;
lines?<BR><BR>Cheers,<BR>Chris<BR><BR>_______________________________________________<BR>PDL-porters
mailing list<BR><A href="mailto:PDL-***@jach.hawaii.edu"
target=_blank>PDL-***@jach.hawaii.edu</A><BR><A
href="http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters"
target=_blank>http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters</A><BR></BLOCKQUOTE></DIV><BR><BR
clear=all><BR></DIV></DIV><SPAN class=HOEnZb><FONT color=#888888>--
<BR>"Debugging is twice as hard as writing the code in the first
place.<BR>&nbsp; Therefore, if you write the code as cleverly as possible, you
are,<BR>&nbsp; by definition, not smart enough to debug it." -- Brian
Kernighan<BR></FONT></SPAN></DIV></BLOCKQUOTE></DIV><BR><BR clear=all>
<DIV>&nbsp;</DIV>-- <BR>"Debugging is twice as hard as writing the code in the
first place.<BR>&nbsp; Therefore, if you write the code as cleverly as possible,
you are,<BR>&nbsp; by definition, not smart enough to debug it." -- Brian
Kernighan<BR></DIV>
<P>
<HR>
_______________________________________________<BR>PDL-porters mailing
list<BR>PDL-***@jach.hawaii.edu<BR>http://mailman.jach.hawaii.edu/mailman/listinfo/pdl-porters<BR></DIV></DIV></DIV></BODY></HTML>

------=_NextPart_000_071F_01CF852D.1E2111E0--
Loading...