1. SS

Having seen some of the misunderstandings, I would like to
re-present my SS proposal in different words. Perhaps I can be clearer.

StructureS
-- Define a structure
   structure Point is
      atom x, y
   end structure

A piece of data named Point is created.
It has 2 elements which can only be accessed by name
The values of the elements are always initialized, to 0 if not
otherwise specified.
?Point.x   --> "0.0"
   ?Point.y   --> "0.0"
   Point.x += 3.0
   Point.y = Point.x + 1.0
   ?Point.x    --> "3.0"
   ?Point.y    --> "4.0"

The ids used for the members ( x and y) are available only in 
the Point namespace, not globally so:
?Point.x   --> "3.0"
   ?x         -- ERROR not defined
   integer x
   x = 1
   ?x    --> "1"
   ?Point.x  --> "3.0"


In addition to holding some data, Point may be used as a prototype to
create new data. It provides both the structure and the data to the new
item.
Point p1
    ?p1.x    --> "3.0" 
    ?p1.y    --> "4.0"

The newly created structure has all the attributes of a structure
and can be used to create further structures
p1.x = 2.0
    p1 p2
    ?p2.x -> "2.0"



-- extends
A structure may be declared as being an extension of another, in which
case it has all the elements of the structure being extended and any new
items it declares
structure Point3d extends Point
       atom z
    end structure
    ?Point3d.z  --> "0.0"
    ?Point3d.x  --> "2.0" --Point.x was set above, and copied into Point3d


The not-notation is fully nestable so:
structure color is
      integer r, g, b
    end structure
    structure ColorPoint extends Point
       color mycol
    end structure
    ?ColorPoint.color  --> "<0,0,0>"
    ?ColorPoint.color.r  --> "0"


Note how ColorPoint.color is printed.
A structure is NOT a sequence!

KtB

new topic     » topic index » view message » categorize

2. Re: SS

Karl Bochert wrote:
> 
> A structure is NOT a sequence!

I have not investigated this to any great extent. What I'd like to do is
review some of the code I've written and see how structures would make it
better. Having said that, I like Karl's definition of structures a lot.
And here's the rationale that justifies adding it to official Euphoria:

1. Adds useful functionality that cannot be otherwise
    added with an include file.
2. Backward compatible. All current Euphoria code will
    work without change.
3. Makes Euphoria even more flexible and powerful.

Now, how much of a performance hit would current Euphoria programs take if
using an interpreter that included structure functionality? Matt has
added something very similar (even more advanced) to OOEU, and he says that
performance has not decreased significantly ("should be very similar" in
speed).

I suspect that native structures would improve performance of current
Euphoria code that used some kind of work-around to emulate structures.
Who wants to prove that? Karl? :)

Regardless, structures should get the go-ahead on more investigation. :)

-=ck
"Programming in a state of Euphoria."
http://www.cklester.com/euphoria/

new topic     » goto parent     » topic index » view message » categorize

3. Re: SS

I think this is good. One addition, though:

Although we've now distinguished the structure as its own type,
there should exist a standard method of translating between
sequence and structure. The rationale I have is that if you want
to serialize data in a file or a stream the sequence is a more
natural type to use, but without the interpreter's help you will
have to write a custom translation function 
for each different structure:

-- we have defined a 2d Point p that we wish to translate to
-- a sequence, and then back again

function PointToSeq(Point p)
    sequence s
    s = {p.x,p.y}
    return s
end function

function SeqToPoint(sequence s)
    Point p
    p.x = s[1]
    p.y = s[2]
    return p
end function

Point p
sequence s

s = PointToSeq(p)
p = SeqToPoint(s)


In a large program this code is going to be a lot of additional
work to maintain. We could implement a generic version to do the
same job instead:

-- same Point and sequence types, but no need for new functions

Point p
sequence s

s = toseq(p)    -- output is currently undefined

p = tostruct(s) -- tostruct takes the type of p (so it knows to use
                -- a Point)


This doesn't cover the order of the resulting sequence, but it is
presumably self-consistent. Remember, the point is to be able to
serialize all our data. It's still the user's job to maintain a 
method of identifying structures within the resulting sequence.

new topic     » goto parent     » topic index » view message » categorize

4. Re: SS

Karl Bochert wrote:
> 
> Having seen some of the misunderstandings, I would like to
> re-present my SS proposal in different words. Perhaps I can be clearer.
> 
> StructureS
> }}}
<eucode>
>    -- Define a structure
>    structure Point is
>       atom x, y
>    end structure
> </eucode>
{{{

> A piece of data named Point is created.
> It has 2 elements which can only be accessed by name
> The values of the elements are always initialized, to 0 if not
> otherwise specified.
> }}}
<eucode>
>    ?Point.x   --> "0.0"
>    ?Point.y   --> "0.0"
>    Point.x += 3.0
>    Point.y = Point.x + 1.0
>    ?Point.x    --> "3.0"
>    ?Point.y    --> "4.0"
> </eucode>
{{{

> The ids used for the members ( x and y) are available only in 
> the Point namespace, not globally so:
> }}}
<eucode>
>    ?Point.x   --> "3.0"
>    ?x         -- ERROR not defined
>    integer x
>    x = 1
>    ?x    --> "1"
>    ?Point.x  --> "3.0"
> </eucode>
{{{

> 
> In addition to holding some data, Point may be used as a prototype to
> create new data. It provides both the structure and the data to the new
> item.
> }}}
<eucode>
>     Point p1
>     ?p1.x    --> "3.0" 
>     ?p1.y    --> "4.0"
> </eucode>
{{{

> The newly created structure has all the attributes of a structure
> and can be used to create further structures
> }}}
<eucode>
>     p1.x = 2.0
>     p1 p2
>     ?p2.x -> "2.0"
> </eucode>
{{{

> 
> 
> -- extends
> A structure may be declared as being an extension of another, in which
> case it has all the elements of the structure being extended and any new
> items it declares
> }}}
<eucode>
>     structure Point3d extends Point
>        atom z
>     end structure
>     ?Point3d.z  --> "0.0"
>     ?Point3d.x  --> "2.0" --Point.x was set above, and copied into Point3d
> </eucode>
{{{

> 
> The not-notation is fully nestable so:
> }}}
<eucode>
>     structure color is
>       integer r, g, b
>     end structure
>     structure ColorPoint extends Point
>        color mycol
>     end structure
>     ?ColorPoint.color  --> "<0,0,0>"
>     ?ColorPoint.color.r  --> "0"
> </eucode>
{{{

> 
> Note how ColorPoint.color is printed.
> A structure is NOT a sequence!
> 
> KtB

I actually quite like this idea too.

I see you could have structures within structures.

Under this definition, could you have a sequence contain structures?
eg
-- Define a structure
   structure Point is
      atom x, y
   end structure

sequence my_sequence
my_sequence = repeat(Point, 10)

my_sequence[5].x = 4


ie, arrays

Chris


http://euallegro.wikispaces.com
http://members.aol.com/chriscrylex/euphoria.htm
http://uboard.proboards32.com/
http://members.aol.com/chriscrylex/EUSQLite/eusql.html

new topic     » goto parent     » topic index » view message » categorize

5. Re: SS

Chris Burch wrote:

> I actually quite like this idea too.
> 
> I see you could have structures within structures.
> 
> Under this definition, could you have a sequence contain structures?
> eg
> }}}
<eucode>
>    -- Define a structure
>    structure Point is
>       atom x, y
>    end structure
> 
> sequence my_sequence
> my_sequence = repeat(Point, 10)
> 
> my_sequence[5].x = 4
>
Yes, sequences of structures are possible and important but...

 my_sequence[5].x = 4

How is Eu to know that the object in [5] is a Point structure?
One solution would be run-time lookup. The object stored in [5] is tagged
as a Point. Eu then knows it must store 4 in one of a Point's members,
but which one?? At compile time Eu knows where x is only if it knows
what structure is in [5] (Other structures may have a member named 'x')
I don't know if I've explained that well, but the upshot is that it is
a can of worms, and very slow if possible at all.

The best possibility that I can see is for the programmer to tell Eu
what kind of structure to expect.
 For instance:
   <Point>my_sequence[5].x = 4
or
    Point:my_sequence[5].x = 4
or
    Point = my_sequence[5]
    Point.x = 4
or
   ???

With this information, Eu can generate the appropriate code, including
run-time verification that the object in [5] really is a Point.

KtB

new topic     » goto parent     » topic index » view message » categorize

6. Re: SS

Karl Bochert wrote:
>  my_sequence[5].x = 4
> 
> How is Eu to know that the object in [5] is a Point structure?
Oh my, yep.
A long time ago now, I figured it would not be completely impractical to have a
"last verified as udt" field on every sequence, tho obviously you cannot on a
short int and it would just not be worth it on a float.

Problem is that eg:
for i=1 to length(list) do
    ?list[i].phone
end for

Effectively ".phone" might be [15] for customers, [17] for suppliers, and
invalid subscript on anything else. Nasty.

Possibilities still exist with "sequence of customer" etc, but the problems and
limitations are mounting up now I feel. Fun while it lasted, though.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

7. Re: SS

Chris Burch wrote:
> 
> I actually quite like this idea too.
> 
> I see you could have structures within structures.
> 
> Under this definition, could you have a sequence contain structures?
> eg
> }}}
<eucode>
>    -- Define a structure
>    structure Point is
>       atom x, y
>    end structure
> 
> sequence my_sequence
> my_sequence = repeat(Point, 10)
> 
> my_sequence[5].x = 4
> 
> </eucode>
{{{

> 
> ie, arrays
> 
Yes, I think this is important, and I put this feature (still a bit 
buggy, I think) into ooeu, although you have to declare:
sequence of Point points

Of course, one difference is that my class objects are really just 
sequences (or possibly atoms), and there is no way for the backend
to know that it's dealing with a specific class unless it's declared.

I'm still not on board with the idea that "structures aren't sequences."
Partly for implementation issues, partly because I think it de-simplifies
the language needlessly.

Matt

new topic     » goto parent     » topic index » view message » categorize

8. Re: SS

Pete Lomax wrote:
> 
> Problem is that eg:
> }}}
<eucode>
> for i=1 to length(list) do
>     ?list[i].phone
> end for
> </eucode>
{{{

> Effectively ".phone" might be [15] for customers, [17] for suppliers, and
> invalid
> subscript on anything else. Nasty.

Proper OO design would put the 'phone' member into a super class of both, so
that they would be inheriting the same thing, and the indices would be the 
same.

In a related vein, for 'true' OOP, you really need late binding, which 
basically means virtual functions.  I think this is very doable for ooeu.
My idea is that, as soon as the user declares a routine as virtual, a
data member vtbl is automatically added (if it hasn't already).  Or maybe
it's just something that's invisible to the coder, which might make 
initialization easier...but I'm getting off topic.  The basic idea would
allow something like the following:
euclass person( sequence p )
    sequence name
    virtual procedure print_name()
    end procedure
end euclass person

euclass customer( person c )
    virtual procedure print_name()
        printf(1,"Customer: %s\n", {this.name})
    end procedure
end euclass

euclass supplier( person s )
    virtual procedure print_name()
        printf(1,"Supplier: %s\n", {this.name})
    end procedure
end euclass

customer cust = {"Matt"}
supplier supp = {"Pete"}

sequence of person people
people = {cust, supp}
for i = 1 to length(people) do
    people[i].print_name()
end for
--  Output:
--          Customer: Matt
--          Supplier: Pete


 
> Possibilities still exist with "sequence of customer" etc, but the problems
> and limitations are mounting up now I feel. Fun while it lasted, though.

I agree with you if we are still talking about the types of structures that
Karl had proposed (and basically agree with Rob, especially about the
backend issues).  However, I don't see a problem with the sort of thing
I've done with ooeu.

My approach, I suppose, is to allow the user to have extra tools for dealing
with data.  It allows a different way to organize and use the data, but 
doesn't preclude using it in a normal way, or in a halfway mode that uses
more dots, but doesn't use the same OOP-style syntax:
? cust[customer.name]
customer.print_name( cust )


Matt

new topic     » goto parent     » topic index » view message » categorize

9. Re: SS

Matt Lewis wrote:
> In a related vein, for 'true' OOP, you really need late binding, which 
> basically means virtual functions.  I think this is very doable for ooeu.
I'm pretty sure you are talking about precisely the stuff I "don't get".
Erm...
> }}}
<eucode>
> euclass person( sequence p )
>     sequence name
>     virtual procedure print_name()
>     end procedure
> end euclass person
umm...
> for i = 1 to length(people) do
>     people[i].print_name()
> end for
Youch! That kinda means that an integer has to have a virtual function of the
same name... ??

> backend issues).  However, I don't see a problem with the sort of thing
> I've done with ooeu.
Speaking of which, do you have any sort of design doc about ooeu's pbr?

Pete
PS is that what "virtual" actually means, ie "late binding"?

new topic     » goto parent     » topic index » view message » categorize

10. Re: SS

Pete Lomax wrote:
> 
> Matt Lewis wrote:
> > In a related vein, for 'true' OOP, you really need late binding, which 
> > basically means virtual functions.  I think this is very doable for ooeu.
> I'm pretty sure you are talking about precisely the stuff I "don't get".
> Erm...
> > }}}
<eucode>
> > euclass person( sequence p )
> >     sequence name
> >     virtual procedure print_name()
> >     end procedure
> > end euclass person
> umm...
> > for i = 1 to length(people) do
> >     people[i].print_name()
> > end for
> Youch! That kinda means that an integer has to have a virtual function
> of the same name... ??

It's not the integer that has a function.  It's the euclass 'person' and
its various subclasses that have this function.

> > backend issues).  However, I don't see a problem with the sort of thing
> > I've done with ooeu.
> Speaking of which, do you have any sort of design doc about ooeu's pbr?

No.  Just the implementation and the documentation in the ooeu docs.  It 
works slightly differently in the eu backend and the c backend.  There's
a real performance benefit in the c backend, because I avoid COW by not
Ref'ing and DeRef'ing.

The basic idea is that you declare pbr in the routine declaration.  
Whenever the routine is called, the interpreter checks to see if the
pbr parameter is a normal var (no temps, literals, constants or loop vars).
If it is, then it remembers where it came from.  When the routine returns,
it looks again to see if it remembers any pbr variables.  If there were 
any, then it updates the source variable.  In the eu-backend, it's just
a regular eu data copy, so you don't get any speedups.  In the c-backend,
it's just a copy of a pointer in the SymTab, so it gives a nice speed 
boost when working with a large sequence repeatedly.

> Pete
> PS is that what "virtual" actually means, ie "late binding"?

Basically.  In the example I gave, you have the euclass person.  A person
has a method that prints out his name.  I've also created subclasses that
use person--basically more detailed person classes.  This allows me to
do some specific things.  However, some parts of my code may want to do
certain things with respect to persons.  I'd like to be able to call the
correct routine to get that specialized routine, but I'd like to be able
to keep my code as generic as possible to prevent duplication and code
bloat (i.e., a big if-then to call person.print, customer.print, 
supplier.print, etc).

Early binding occurs when the actual routine can be resolved at compile
time.  Late binding is when the actual routine is not resolved until 
runtime, like using routine_ids.  In the above case, I'm telling the 
interpreter that I'm handing it a person, which may be a subclass which
will override the default behavior.  The interpreter will have to have 
information stored with the data that allows it to resolve the proper 
routine to call.

For ooeu, it would likely be a data member called vtbl that has a bunch
of routine ids.  Using the knowledge of the base class type (person) and
the vtbl data supplied by the actual data, the interpreter resolves which
routine to be called, and calls it.

Matt

new topic     » goto parent     » topic index » view message » categorize

11. Re: SS

Matt Lewis wrote:
> The basic idea is that you declare pbr in the routine declaration.  
> Whenever the routine is called, the interpreter checks to see if the
> pbr parameter is a normal var (no temps, literals, constants or loop vars).
> If it is, then it remembers where it came from.
I see. Any thoughts on what you could do in the front end for update(a[i])?
As you said, the back-end will only get to see a tmp, the front end would
need to emit an additional a[i]=tmp, perhaps.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

12. Re: SS

Pete Lomax wrote:
> 
> Matt Lewis wrote:
> > The basic idea is that you declare pbr in the routine declaration.  
> > Whenever the routine is called, the interpreter checks to see if the
> > pbr parameter is a normal var (no temps, literals, constants or loop vars).
> > If it is, then it remembers where it came from.
> I see. Any thoughts on what you could do in the front end for update(a[i])?
> As you said, the back-end will only get to see a tmp, the front end would
> need to emit an additional a[i]=tmp, perhaps.

Yeah, something like that.  I'm not sure on the details.  It'll involve
some extra front end and backend work, though.

Matt

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu