Re: fields for methods?




On Fri, 13 Oct 2006, Jon Slaughter wrote:

Ok, I thought about it a little and I think I was making up stuff before. I
wasn't to clear what I actually wanted or how to achieve it(or I ended up
getting confused on two different things). Since functions can be part of
classes and classes themselfs are objects with data one one needs the
functions's "fields" to be local to that object. Hence static fields won't
work. i.e., what I said about state stuff is a good interpretation but
ofcourse you would wan't want the same function in different objects to
share the same state(maybe in some cases but not in general).

<snip>
Later you ask for an example:

I was overriding a method in C# that was to draw some graphics. This was to
be called fairly often(basically a Paint handler) and in that function I was
creating some brushes to be used. Now the brushes were pretty basic and
probably would never be changed. But I did have to create them from scratch
each time(and each call would create allocate them on the heal and then
release them(well, eventually by the GC). I could have created them "global"
to the function but "local" to the class and initalized them in the
constructor but these brushes "belonged" to that function and not to the
class in the sense that the class probably would never change them. But if
they were fields of the function then I could initalize them in the function
for the first time and not have the declarations "muddy" up the class's
fields. i.e., it seperates the declarations of things that do not go
together. But, now what if I eventually want to change the brushes?

Then you have more than one thing that handles brushes --- i.e., more
than one method on a "Brush" object:

class Brush {
private:
int color, width, shape;
public:
Brush(int, int, int);
void change_color(int color);
void change_width(int width);
void change_shape(int width);
};

struct Painter {
Brush brush;
void init_brush() {
/* This could also go in a constructor for Painter. */
brush = new Brush(0,0,0);
}
void paint_callback() {
do_something_with(brush);
}
void other_method();
};

Painter p;

Here, you can call 'p.paint_callback()' to paint the scene, and also,
at any time, you can call 'p.brush.change_color()' to make it a new
color. (Read on for objections and counterarguments...)

Say the brush represents the background color. This color is obviously not
changed often if at all. But if I can access tha field of the method
outside(say later I figure that I need to change it) then I could just use
method.field = value to change it and then the functions "state" has
changed. Again, this can be completely done in the current langauge of
C++/C# but I feel the way that does it does not allow "code isolation" by
which I mean grouping of similar code into similar blocks... basically
"visual isolation". i.e., the field, if declared w.r.t to the scope of the
class is not really where it belongs. Its suppose to represent the state
that the method deals with and not really something that is directly part of
the class(or that is as important to other fields of the class).

So you don't like that 'brush' is declared far away from the
implementation of 'paint_callback', which uses it. Well, that's really
no different from the way any old field is defined far from its uses.
But if you wanted to make it more syntactically obvious, you could
always throw 'brush' and 'paint_callback' into their own little
sub-struct, like this:

struct Painter {
struct {
Brush brush;
void operator() {
do_something_with(brush);
}
} paint_callback;
void init_brush() {
this->paint_callback.brush = new Brush(0,0,0);
}
void other_method();
};

so that the object formerly known as 'p.brush' must be referred to as
'p.paint_callback.brush'.


I think basically I'm trying to form some hierarchy out of classes. Instead
just having a linear collection of common data and methods you have a
hierarchy of things that are related. If, say, you create a function where
you need to call another function, say, that is used for recursion then you
shoudn't delcare that function outside of the first functions scope...
unless it is used in the larger scope... but if you need occasional access
to it then you still should have the ability to do it(if you were given
access to it).

If you need occasional access to it, it's not really local, and
therefore you shouldn't try to declare it locally.

[...]
Now you might say that I should simply just create a "functor" to do this or
a class. To me though a class is a more powerful beast and what I'm talking
about is more in between a function and a class. If I do it in a class I have to write much more code and redundant information.

Actually, except for the words 'struct' and 'operator' and couple of
extra curly braces, in my example above there's no extra baggage for
doing it in a class --- you just write some of the keywords in a
different order. :)

Instead I'd rather
use the original syntax of a function with a slight change to allow for what
I'm talking about. Besides this one also gets encapsulation at the function
level

Mmm... that word, I do not think it means what you think it means.
Sure, "encapsulation" is a buzzword with many competing definitions,
but since what you're asking for is a way to refer to local variables
/outside/ of their "normal" scope, I think it's only fair to call it
the /opposite/ of encapsulation.

which is slightly different than just using local variables and not
the same as static local variables because static local variables are like
class local variables. So I guess you were right about the static_instance
thing.

Yes, I think so too. :)

My "idea" is really just a notational/programming convience... but thats all
a programming language is. Encapsuation has nothing to do with the
computers themself but is used for humans. So I don't see why one shouldn't
take it a step farther. Obviously one cannot have a field of a field, or a
method of a field(well, which is essentially a property I suppose) but one
can have a field of a method.

Um... typically, you /can/ have "fields of fields" (if the field is
itself of class type), and also "methods of fields" (ditto). The idea
of "field of a method" is the one that nobody's ever done before.
(Since methods aren't of class type, and just plain don't behave like
class instances, they can't have "fields" in the normal sense... as I
think you're discovering.)

And now that we've clarified the semantics of what you want, I hope
you agree that it would totally break separate compilation, which is
a darn good reason it'll never make it into a C-like language.[1]

Anyways, maybe now we are on the right track?

Getting there. :)

-Arthur

[1] - Templates in C++ also kinda break separate compilation, but not
as much --- you just need a special linker, AFAIK, to compact the
multiple definitions of templated functions into single definitions.
But "static_instance" would break things farther upstream than the
linker --- it would break the 'sizeof' operator!
.



Relevant Pages

  • Re: fields for methods?
    ... than one method on a "Brush" object: ... void change_color; ... "Properties are syntactic shorthand for accessor and mutator methods." ... Sure, "encapsulation" is a buzzword with many competing definitions, ...
    (comp.programming)
  • Re: fields for methods?
    ... than one method on a "Brush" object: ... void change_color; ... would require a new language and also a new model for compilation. ... get {[Code Block]}; ...
    (comp.programming)
  • Re: C99: Suggestions for style(9)
    ... at the start clearly points that there're no local variables used. ... non-scalar declarations in a function, then a compiler can coalesce them ... void f; ... struct Foo a; ...
    (freebsd-hackers)
  • Re: C99: Suggestions for style(9)
    ... There's no need to add more redundant parentheses. ... Last, but definitely not least, I added this paragraph about the use of local variables. ... Even considereing the extremly rare case of multiple non-scalar declarations in a function, then a compiler can coalesce them if their life ranges are disjoint. ... void f; ...
    (freebsd-hackers)
  • Re: My local variable addresses are changing
    ... Look for use of alloca or longjmp, to name a couple of suspects. ... Rudy Ray Moore wrote: ... > The address of local variables change when they are passed to another ... > void f ...
    (microsoft.public.dotnet.languages.vc)