[fpc-pascal] Question about interfaces

ml at brainwashers.org ml at brainwashers.org
Mon Mar 21 04:00:55 CET 2005


Quoting Marco van de Voort <marcov at stack.nl>:

> > Seems a bit sad to me that, I didn't get answer to "what I really asked"
> > but a lot of flaming posts about one btw. in my question, even subject
> > says "Question about interfaces" and not "Question about operators". 
> > 
> > 1. Couldn't interfaces support blind properties (specifying only read
> > write capability)? Without having to specify function and procedure for
> > writing. Property access varies from one interface inheritor to another
> > and interface cares only about read write ability of property. Blind
> > properties could be applied without any loosing of compatibility. And
> > demands a whole lot more code in the way as it is applied now.
> > 
> > What you would get from blind interface properties?
> > - Lot less code.
> > - Smaller more readable interfaces
> > - freedom of property implementation in classes
> 
> This doesn't sound bad, but there is an implementation problem I think. The
> idea itself is sound, an interface is a contract only and how a property
> is implemented is a implementation detail.
> 
> However the problem is that one must be able to access the property give
> only the interface definition. Keep in mind that a property can be both a
> field and calls to getter/setter functions, and also that a property is only
> a language construction. In the final code, a direct reference to the field
> or getter/setter is done.
> 
> In this light, decoupling a property poses a problem; if the compiler has
> 
> var x : ISomeinterface; // has a  blind property someproperty
> 
> begin
>   x:=getintfromsomewhere;
>   writeln(x.someproperty);  
> end; 
> 
> how do I know what code to generate for the property?
> 


Shouldn't direct access to object and resolving object property be involved here
when dealing with interface property and not pointing to interface functions and
procedures? 
You have the pointer to object, so you have the pointer to its vmt.
Shouldn't property be accessed like that in the real world?

> > 2. Question about operators was about YES: "existing" and YES: "pascal
> > standard" "is" operator and interfaces. Instead of needing to write
> >  
> >   if Supports(obj, ISomeInterface) then
> > 
> > wouldn't it be nicer to be able to write
> > 
> >   if (obj is ISomeInterface) then
> >   if (obj is [ISomeInterface, ISomeOtherInterface]) then
> 
> I have no idea, but I fail to see the point a bit (this isn't a much
> used construct), but it could. 
> 

It can't be if it is not present

> Being a compiler developer is not sitting on a table and thinking up all
> kinds of interesting new extensions. I know some of the perl/python freaks
> seem to do it like that, but they seem to be engaged into some who can
> write the shortest and most unreadable code contest.
>

Not that I try to lower your status or status of fpc, I repect everybody that is
able to maintain project as large as this, but

Not always, if competing who will do more then yes. But then there could be a
lot of good new things suggested. Users can have good ideas, look at inkscape
for example.
Every suggested idea (people in mailing lists suggest different variantions or )
goes to discussion and they discuss if feature should be included and how it
should be included.

I don't believe that living under borland shell is the way to go. This said is
just like you would said that there's no world beside borland and all features
not implemented in borland are not good.

No invention, no progress. Maybe that's why Phyton has so many people.   Because
people expect new approaches

> In seven years of FPC work, I pretty much came up with one extension
> (properties at the procedural level, and while useful, not the most
> interesting or timesaving one.)
> 
> > Which is completely what you all said. I just noted that standard pascal
> > operator "is" does not exist for interfaces.
> 
> There is no such thing "is" is a Delphi extension. A later one even.
> 
> > Array checking would be
> > nice if one uses fine grained interfaces and therefore usually needs
> > more than one interface for one function
> 
> It's a set.

Ok

>   
> > 3. Interface multiple inheritance. Asking just for a reason why not, for
> > sole curiosity.
> 
> Interfaces to my knowledge are contracts about sets of calls. More or less
> function X is at offset y*4 or something like that.
> 
> If you create a new interface by multiple inheritance from both X and Y each
> with 4 methods, you get a new interface Z with 8 methods.
> 
> However Z can only be compatible with one interface, namely the one that
> gets the first 4 methods. So if I create Z with first the 4 methods of X
> and then those of Y, Z will be compatible with X (same 4 methods on the same
> offsets), but not with Y.
> 

Care to explain offsets here:
IA = interface
function A: integer;
end;
IB=interface(IA)
function B: integer;
end;
IC=interface(IB)
procedure C;
end;

Don't take it so literaly. It's just that interface usage goes beyond simple
logic. You have two possible implementation

- monolithic structure where interfaces express most of the object reflection
- non-monolithic fine grained, which can be implemented in two ways

1. Real, interfaces that have multiple inheritors can be inherited
2. Posibility of setting sets of combinations

Version 1 would be best, but as I saw version 2 is not so bad. When you use fine
grained interfaces, you try to avoid interface inheriting completely (it would
not make sense anyway). And use those sets in classes inheritance and
functionality checking only.

On of my previous e-mails had simple macro solution which is more than
satisfiable for version 2, except that its a hack and no solution

> > I solved that for my self with macros.
> 
> Macro's are no solution, but a hack. 

Yeah, but comparing working hacked solution to no solution...

> 
> >  Just as I implemented foreach(). 
> 
> Eeeuw :_)

I thought that at first too, yes. But after a while I started loving them.
Working with 20-30 threads does that to you.

If foreach is carefuly designed then it can be threadsafe and balanced. Which
you can't say for "for i := 0  to (Count - 1) do" if you code threaded environment. 
Balanced enumerators reflect on changes in list. When my list deletes items in
one thread all enumerators reflect to change and reposition them self accordingly.

and foreach was nothing but a beauty hack
{$define foreach := while MACRO_FOR_EACH} 

but I can't afford instability. I can afford slowness, but instability no.

>  
> > What are benefits of interface multiple inheritance:
> > - No monolithic structure
> > - Fine grained interfaces (smaller, easier to read)
> > - Lot less code duplication
> 
> All a bit vague. Could you back these up with real examples?
> 

ok, here it one in c#, the only problem here could be that you would try to look
at this from monolithic perspective. And notice how many times one could reuse
those simple interfaces. 
As soon as interface goes complex,... well there's no difference if you would
use class.

interface ICountable{
	int Count { get; put; }
}

interface IAccessible{
	int Get(int aIdx; ref object aObject);
}

interface IRemovable{
	int RemoveAt(int aIdx);
}

interface IModifiable{
	int Add(string aStr);
	int Modify(int aIdx, object aObject);
}

interface IExportable{
	int Export(int aIdx, object aObject);
}

....

interface IMyList(ICountable, IRemovable, IModifiable, IAccessible) {}

interface IMyExportable(ICountable, IAccesible, IExportable) {}

class MyList(IMyList) { ..... }
class MyExportable(IMyExportable) { ..... }

.....
int GetCountOf(object aObject) { // nothing special here isn't it. But then
again this function will be usable for everything I throw at it not just the code 
	if (aObject != null) 
		if (aObject is ICountable)
			return (aObject as ICountable).Count;
	return 0;
}

.... // somewhere else where my needs depend on bigger compatibility
int AddStr(str aStr, object aObject) {
	if (aObject is IMyList)
		(aObject as IMyList).Add(aStr);
}

Here is a simple example of having fine grained interfaces. Both object
completely non-interferring one with the other (not the same hierarchy). 
But still I can detect wheter passed object supports counting or accessing items
inside of my code.
If passed object supports ICountable then, ... well access trough
ICountable(passedobject).Count and so on. But the problem with fine grained
interfaces 
is that you almost always need more than one interface, you can land with bunch
of interfaces in declaration and supporting checks. That's why multiple
interfaces are usable.
In my case I only needed to specify IMyList and IMyExportable.

Coding with fine grained Interfaces is slower than coding with objects, but it
is less dependent and probably bulletproof. Difference between one and the other
type of coding is
how much planning you need to do in the begining.

Its just like glade or delphi interface designer. Glade is harder to figure out
but its bulletproof, while delphi is simple but at the same time almost
unqualified for its existance. 
I just change font size and almost all delphi windows go broken (change the
language, well how many labels gets too long and get covered up with controls).
Glade does not 
suffer from this effects, form is always as it should be. But it had to be
planned much more than delphi form was.

IMyList simplified my task, and this couldn't be done in monolithic interface. I
would have to inherit ICountable in IAccessible, IAccessible in IRemovable. 
Which would lead that instead of having simple IModifiable, IModifiable would
contain bunch of declarations which mostly wouldn't be needed. While in multiple
inheritance
having separate IModifiable is possible. And reuse same IRemovable in lists,
windows,... whatever. And when I need complete IMyList functionality I don't
need to check for every interface just IMyList

Hope this was enough extensive

> (p.s. Interfaces have no code. That is pretty much their definition :_)


???? And the reason for my asking about blind properties would be probably
because I don't know that

ml


And by the way, about chess example that was here

One guy didn't succed and this is the reason why no one should try something new
ever again??? Shouldn't everybody make suicide too, just because one guy didn't
succed in his life, nobody will?


> 
> 
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
> 



----------------------------------------------------------------------
This mail sent through Horde-Toaster (http://qmailtoaster.clikka.com/)




More information about the fpc-pascal mailing list