[Prev][Next][Index][Thread]

Re: Issues with GD



In article <87wvmtcu6i.fsf@ethereal.dyndns.org>, Nolan Darilek
<nolan@ethereal.dhis.org> wrote:

> Ah, great! This clarifies things a bit, but:
> 
> define functional class . . .
> 
> What exactly is the functional keyword?

"functional" is a Gwydion hack to tell the compiler that:
  - once an object is created, you will never change any of its fields
  - it should judge object equality by comparing the fields, not by
    comparing the addresses.

Together this allows the compiler to freely make copies of an object
without worrying that the progam will think the copy is a different
object.  This allows things such as allocating the objects on the stack,
using call-by-value, storing objects directly into data structures (e.g.
arrays) instead of storing pointers to them.

These things are true of some built-in classes such as <integer> and
<float>.  Ideally the compiler should be able to work out for itself that
a certain class has these properties, but for now just be happy that you
can tell it and that it  then knows how to do the right thing.


> define method content-size( cls == <Point> )
> =>( result :: <integer> )
>     4;
> end method content-size;
> 
> 
> What is the point of that? Is it intended to give the size of the
> structure? If so, how is that determined? Do you just add up the byte
> requirements of all items within it?

This is so that Dylan knows how many bytes to copy around.  Yes, you have
to work it out manually.  You *could* probably do something like ...

   c-expr(int: "sizeof(Point)")

... instead of the "4".  This *might* limit d2c's ability to do smart
things.  (hmm -- can it inline things using c-expr?)


> Also, what is initialize? It looks like it may be a constructor, but
> from what I've read in the "First Look at Dylan" article, those aren't
> present. So, what's that?

See:

   <http://www.gwydiondylan.org/drm/drm_98.htm>

Yes, initialize is very similar to a C++ constructor.  Mostly you don't
ned one, because the things you can say in the class declaration are
enough, but it's there if you want it.

You can think of "make()" as being like C++'s "operator new".  Usually you
don't implement your own make(), just letting the system get the memory
your object needs and then automatically call your initialize() instead,
but you can also implement your own make, which is a bit like using C++'s
"placement new".

See, for example, in the d2c runtime system source code...
  
<http://www.ccc.de/cgi-bin/cvsweb/gd/src/d2c/runtime/dylan/vector.dylan?rev=1.2>

... where a call to make(<vector>) (which is an abstract class) actuallys
creates a <simple-object-vector> instead:

define open abstract class <vector> (<array>)
end;

define inline sealed method make (class == <vector>, #key size = 0, fill)
    => res :: <simple-object-vector>;
  make(<simple-object-vector>, size: size, fill: fill);
end;



> What is call-out? Does that create a call to an external function? As a
> tangent, if a call-out is made, how is the other library linked in?
> For example, say I write a SDL interface library in Dylan. If I
> call-out to SDL functions, how do I inform the compiler that, not only
> does it need to link to the Dylan SDL library, but that it should also
> link to the real library in which the code lives?

d2c works by compiling Dylan into C, which is then compiled and linked as
usual.  call-out and friends (c-expr) pretty much just let you directly
specify some C code to generate. It's much like "inline assembler" in a
lot of C compilers.  You *do* need to know what you're doing at a fairly
low level.

If you call extermal C functions, then you'll need to add that C code (or
libraries) into your makefile in the usual way.

-- Bruce



Follow-Ups: References: