### 1. Structs

I just realised that what I want first is the perfect documentation for structs, perhaps like enum or multiple assignment - anyone care to give it a [quick] stab?
Imagine the compiler has been updated, what would you want/hope/expect the documentation to look like?

Obviously

This forum is perfectly capable of all the formatting(needed), or feel free to use the wiki, it is the content that matters.

I would like to keep this thread tidy: please edit existing posts rather than say one thing on Tuesday and then contradict yourself 7 posts further down on Thursday!

<My attempt will probably go here>

### 2. Re: Structs

My idea for struct documentation would be something similar to how structs are used in C. Something like

```
Struct Rect
integer x
integer y
integer w
integer h
End Struct

Rect.x = 10
Rect.y = 10
Rect.w = 10
Rect.h = 10
```

Something along those lines.

### 3. Re: Structs

Sometimes it might be convenient to "package" several related variables together into another. We call this a "variable structure," or "struct" for short.

You define a structure like this:

```struct name
string first
string middle
string last
end struct

string street
string city
string state
string zip
end struct

-- structs can hold other structs
struct employee
name name
end struct
```

You instantiate a struct like other variable types:

```name nName
employee nEmployee
```

You assign values to a struct like this:

```nName.first = "Billy"
nName.middle = "Gene"
nName.last = "Smith"

nAddress.street = "1200 Independence Pkwy"
nAddress.city = "New York City"
nAddress.state = "New York"

nEmployee.name = nName
```

### 4. Re: Structs

well here is my version and sorry i am bad at explaining.

Define some dummy structures for demonstration of my imagination: a structure can contain all primitve datatypes for ex.

```struct dummy_struct_t
atom a1,
sequence s1,
--  sequence s2,
object o1,
integer i1,
string s1,
wstring sw1,
\$
```

Structure fields may not be initialized within the struct. some structs:

```struct dummy_struct_1
atom a1,
object o1,
\$

struct dummy_struct_2
atom a2,
object o2,
integer i2,
\$
```

define some new structure with a structure variable used in it

```struct container_struct
atom crap1,
sequence scrap1,
dummy_struct_1 st1,
\$
```

now we have a structure that is extended and contains a structure for ex.

```struct e_c_s_1 extend dummy_struct_2
atom crap1,
sequence scrap1,
dummy_struct_1 st1,
\$
```

e_c_s_1 now contains (inherited) the fields of structure dummy_struct_2 and a struct variable dummy_struct_1. This I think could be maybe a future single inheritance thing just like Oberon uses it. Since we are not shooting for classes, forward procedure or function declarations are not allowed in the structure. Oberon would give you the possibility for something like that for ex.

```struct xxx_1 extend dummy_struct_2
atom x,
sequence crap1,
struct dummy_struct_1,
function average(atom a, atom b),  -- function signature
procedure plot(integer x, integer y, integer char=‘*‘), -- procedure signature
\$
```

declaring and using a structure for ex.

```global e_c_s_1 x
-- or can use the private attribute or initialized for ex.
global (private) e_c_s_1 x = {1.0,{5,1.5},{{5.0,"3"}}}
-- or
global (private) e_c_s_1 x = {1.0,{5,1.5}} -- here the dummy_struct_1 part is initializes by the compiler to {}
...
```

using struct in procedures or functions

```function plot(e_c_s_1 x, integer y, integer char=‘*‘)
-- the default value for e_c_s_1 x could be {} or some other legal initializer s. obove,
-- or initializers are forbidden in signatures

container_struct y = {0.1, {}, {1.5,"x"}}
or
container_struct y
y.crap1=0.1
y.scrap1={{},5,1.5}
y.st1.a1=0.1
y.st1.o1="ddddd"

position(x.y, y.crap1)
puts(1, char)
return {y.crap1, y.st1, y}
end function
```

i guess i get slapped now.

### 5. Re: Structs

Since a lot of Eu programming involves interfacing with .dlls and .so libraries, it seems to me that structs should be able to declare C types as well as Euphoria types.

That would do away with all the allocating, poking and peeking difficulties.

### 6. Re: Structs

yep, that would be neat, but then we should have unions too. but phix has that in cffi already.

### 7. Re: Structs

after some discussions with my two other people we came to the conclusion, that the following should be possible in my example:

```struct dummy_struct_t
atom a1,
sequence s1,
--  sequence s2,
object o1,
integer i1,
string s1,
wstring sw1,
end struct
```

the extension was something they liked for 2 reasons:

1.) you can keep your general structures in a module and specialize them

and

2.) even so not envisioned, the possibility of inheritance.

Richard

### 8. Re: Structs

It is gentler to extend ideas that we already have (less learning, simpler) then to invent a complete new "struct" syntax.

## simplest case

A "struct" is a kind of "enum".

```struct point X, Y, \$
```

What you get is local enums `X` and `Y` for exclusive use in dot notation

```point mydot
mydot.X = 3
mydot.Y = 5

? mydot
--> {3,5}
```

Simple and convenient. The sequence `mydot` is free to have any data-values and any kind of changes. The names `X` and `Y` can be freely used in alternative local scopes. Classic Euphoria freedom.

## adapt existing user `type`

A "struct" is a special case of user "type".

An extension of the existing `user data-type`. Use it with or without type-checking. This adds the convenience of dot-notation.

```type point( object x )

struct
integer X,
atom Y,
string s,
\$

return true
end type

point mydot

mydot.X = 4
mydot.Y = 8
mydot.s = "blue"

? mydot
--> { 4, 8, "blue" }

? point( {2,3} )
--> false
```

This way both kinds of "struct" could co-exist. The simple form could be used most of the time in general programming. The user-type version when you need rigor.

_tom

### 9. Re: Structs

_tom said...

The simple form could be used most of the time in general programming. The user-type version when you need rigor.

The only reason I'd go with a more complicated spec with a block definition is so structs can eventually have private/public variables and, eventually, methods.

### 10. Re: Structs

euphoric said...

The only reason I'd go with a more complicated spec with a block definition is so structs can eventually have private/public variables and, eventually, methods.

You invent OOP

Current Phix dot notation is an option that you get when compiling Phix into an executable. That means is is a low cost option that can be ignored (via a simple switch) when creating Phix. Inventing OOP will take major design thinking.

_tom

### 11. Re: Structs

I don't think adding to OOP to Euphoria would be a good idea. The idea of Euphoria is to be simple. I know structs are kinda like a low-key OOP, but they're still pretty easy to understand. Like my idea of structs (I did post about this earlier, but restating my position on keeping structs simple)

```struct player
integer health
atom x_pos,y_pos
string name
end struct

player.health = 100
player.x_pos = 15
player.y_pos = 15
player.name = "bob"
```

That would be my idea for structs, I think a couple other users had similar idea to mine.

### 12. Re: Structs

_tom said...
euphoric said...

The only reason I'd go with a more complicated spec with a block definition is so structs can eventually have private/public variables and, eventually, methods.

You invent OOP

Almost, but that's not the intent.

### 13. Re: Structs

structs that mirror the style used by 'c' makes a lot of sense; this enables easier .so interfacing -- no argument here

what is needed is a complementary "generic" form

• no need for each item to have a fixed data-type
• just names for index values so existing Phix dot-notation is nicer to use
• ability to extend to nested sequences
• building new forms by composition

_tom

### 14. Re: Structs

#### data-types

A data-type "limits the values permitted for an object."

Everything is an object; an object is the unlimited data-type.

Two fundamental objects: atom, sequence

Variations on the two fundamentals:

```
atom --> integer
sequence --> string , struct

type --> user defined data-type
```

Question? Interfacing with 'c'; can special data-types be invented to make interfacing with an .so easier?

A struct is "a sequence; each item has a data-type; each item has a named index; default values may be assigned to an item."

```struct zoo
string name = ""
integer legs = 0
atom  height = 0
atom speed = 0
end struct
```

This syntax creates a zoo struct identifier, a zoo() function for testing, and a zoo_new() function for initialization, and local enums (name,legs,height,speed) that can be used with dot-notation.

• The struct name zoo is used to declare an new instance of the zoo struct-sequence.
```zoo critter
```
• The zoo_new() function assigns default values
```critter = zoo_new()
? critter
--> { "", 0, 0, 0 }

zoo fauna = zoo_new( name := "osterich" )
? fauna
--> { "osterich", 0, 0, 0 }
```
• The zoo() function tests if an object belongs to a struct.
```? zoo( critter )
--> true

? zoo( 3.14 )
--> false
```
• You can subscript struct items
```critter[1] = "emu:
critter[2] = 2
critter[3] = 1.9
critter[4] = 50
```
• you can use dot-notation with struct items
```critter.name = "emu"
critter.legs = 2
critter.height = 1.9
critter.speed = 50

? critter
--> { "emu", 2, 1.9, 50 }
```

_tom

### 15. Re: Structs

Things like this are often necessary and useful. So the dot notation shouldn't really stop at a single level:

```point = {integer x, integer y)

critter.position = point

critter.position.x = 10
critter.position.y = 20

critter.position = {20,20}

critter.position += {50,40}

critter.path = repeat(critter.position,10) -- i.e. an array in which you could store the last 10 locations

```

### 16. Re: Structs

irv said...

Things like this are often necessary and useful. So the dot notation shouldn't really stop at a single level:

You can do this today using Phix

```enum X,Y

sequence point = {0,0}

point.X = 10
point.Y = 20

sequence position = {}
position &= point
? position
--> {10,20}

position = repeat( point, 4 )
? position

position.2.X = 3
position.2.Y = 5

? position
--> {{10,20},{10,20},{10,20},{10,20}}

--> {{10,20},{3,5},{10,20},{10,20}}

for i=1 to 4 do
position.i.Y = i
end for
? position
--> {{10,1},{3,2},{10,3},{10,4}}
```

_tom

### 17. Re: Structs

euphoric said...
_tom said...
euphoric said...

The only reason I'd go with a more complicated spec with a block definition is so structs can eventually have private/public variables and, eventually, methods.

You invent OOP

Almost, but that's not the intent.

Oh yes it is.

Some brief thoughts about object orientation:

• It is a perfectly valid programming paradigm, sometimes.
• Other perfectly valid programming paradigms do exist.[1]
• Problems arise when shoe-horning (parts of) a solution into an inappropriate programming paradigm.[1]
• The best solution is probably quite often a mixture of different programming paradigms.[2]
• Fundamental radicalism is almost as bad in programming as it is in politics and religion.[2]
• Trivial components in no way guarantee that the larger system is automatically bug free.[3]
• Thousands of trivial components do not make complicated problems any easier to find.[3]
• Making something harder to debug does not help anyone, ever.
• Forcing someone to use something they hate or do not understand does not usually help much either.
• Allowing someone else to do things in their own (peculiar) way is just plain old fashioned common decency.

Footnotes: Repeat firmly and calmly [1]yes they do [2]yes it is [3]no they do not. Resist temptation to shout.

Anyway, enough of that. If we can sneak in a few little extras in a way everyone is comfortable with, we should.

Whether you love or hate oop, I think we can all agree we all want something like this:

Suppose you have say struct rectangle, struct square, struct circle, and struct triangle.
Do you want to be able to pass any of those to a generic routine that accepts a struct shape?
If so, how do we define struct shape, and something else, say struct address, that naturally cannot be(/type checks if) passed into a struct shape parameter?
How do we best express that sort of relationship in a simple, natural and intuitive way?

PS Let's just all agree not to even consider multiple inheritance!

### 18. Re: Structs

wow Pete this great i like to suggest some things, that, i am sure i will to have to edit. but here it goes:

```-- The object-oriented features of PHIX all come from classes. The class hierarchy has as its root the class Object.
-- Object defines a minimum level of functionality that each derived class has, and a default implementation for that functionality.
-- Classes are programmer defined types. Support for classes are what makes PHIX an object oriented language, giving it encapsulation,
--   inheritance, and polymorphism. PHIX classes support the single inheritance paradigm, extended by adding support for abstract classes.
-- A class can be exported, which means its name and all its non-private members (those that are not decorated with public) are exposed
--   externally to the DLL or EXE
-- All member functions of 'synchronized' (decorator for a class) classes are synchronized for threads.
-- Classes can not be nested

-- optinal '(' with 'T' list for generics ')', when brackets are used, atleast one 'T' has to be in the list
-- if a class is decorated with [public] it is visible outside the definition file
-- if a class is decorated with [abstract] class
-- Class methods are defined exactly like a normal procedure or function procedure.
-- Abstract procedures/functions can be declared within an abstract class. Abstract procedures are not implemented within a class.
-- They are simply placeholders defining how a given method is implemented in classes which inherit an abstract class.
-- optinal '(' with 'T' list for generics ')', when brackets are used, atleast one 'T' has to be in the list
-- Base class construction is done by calling the base class constructor by the name 'super'

-- ALL CLASSES METHODS ARE VIRTUAL
-- [abstract | override] Procedure/function header
-- Class methods are defined exactly like a normal procedure or function procedure. Abstract procedures can be declared within an abstract class.
-- Abstract procedures are not implemented within a class. They are simply placeholders defining how a given method is implemented in classes which
--  inherit an abstract class.
-- To override a class method defined in an inherited class you prefix the method definition with the OVERRIDE keyword. Overridden methods preserve the
--  interface but replace the implementation. Method calls will always refer to the method implementation according to the dynamic type of a object.
-- By overriding a method no new component is established. The existing method is replaced with the overridden method.
-- Methods that are decorated with 'final' can not be overriden.

class point
atom x, y, w, h      -- initialized with NAN
string description   -- initialized with ""
public dummyint = 1  -- if = 1 is omitted, it should also be initialzed, maybe to the larges neg. INT possible
public sequ = {4, 5, 6}  -- or default initialized with {}

point() -- initializer, does nothing
end point

point(atom x, atom y, atom w, atom h) -- initializer overloaded
.x = x .y = y .w = w .h = h     -------  the period '.' is short for this
end point

point(atom x, atom y, string description) -- initializer overloaded
.x = x .y = y .description = description
end point

public procedure description(string descript)
.description = descript
end description

public function description()
return .description
end function

public procedure setxy(atom x, atom y)
.x = x .y = y
end description

public procedure getx()
return .x
end description

public procedure getMultiplierSequence()
return .sequ
end description

end class

-- make a new class - maybe there should be a new keyword 'class', but object should be able to be synonym
object p1 = new(point())  -- or
object p2 = new(point(1,2,3,4))  -- or
object p3 = new(point(1,2,"some text"))

-- make a new sequence of classes
sequence s1 = new(point(1,2,"some text"), 100)

-- copy a sequence of classes. s2 contains a distinct new deep copy of s1, therefore s2[1] != s1[1], but with same data content
sequence s2 = s1
sequence s2[2] = {}  -- s2[2] is empty, s1[2] is not

bool test = ISMEMBER(s2[2], point) -- returns true

-- destroy a/the class/es
destroy(p2)
p3 = {}
s1 = {}

-- use
p3.x = 0.01 -- error variable not public, must be set by setxy(atom x, atom y) or some other defined method
p3.dummyint = 1 -- correct is public
integer testint = p3.dummyint -- correct is public
sequence w = sq_mul(5, p3.sequ)  -- w is {20, 25, 30} (out of phix help)
--or
w = sq_mul(5, p3.getMultiplierSequence())

--sequence use
s1[50].setxy(0.1, 0.2)

-- inherit class point
class circle extend point  -- single inheritance, the compiler check for circulars an pukes if necessary.
super(1,2,3,4)
end class

-- abstract classes describe a list of functions that a class that inherits from the abstract class must implement.
--   A class that implements an abstract class can be converted to a reference to that abstract class.
abstract class phix1

procedure foo()
function bar(integer x)

final procedure finalproc(integer x) -- this procedure or function may not be implemented in a class
...
end procedure

end class

-- An instance of an abstract class cannot be created.

class phixC extend point implements phix1 -- ,phix2, ..

function bar(integer x) -- ok
...
end procedure

procedure foo() -- ok
...
end procedure

procedure finalproc() -- error, cannot override final finalproc
...
end procedure

end class
```

### 19. Re: Structs

petelomax said...
euphoric said...
_tom said...

You invent OOP

Almost, but that's not the intent.

Oh yes it is.

No. All I really want is encapsulation, which is part of OOP, but is not OOP.

We can already encapsulate code in modules (include files). This would just be a different form of that, with maybe better protection or ease-of-use.

I haven't thought too hard about it, so I don't have a list of pros/cons just yet.

### 20. Re: Structs

here is a little language, that is interesting for some ideas. they use struct in an oberon way, but took out a lot of the oo possibilities.

### 21. Re: Structs

Any decisions yet? After a long time to think about that again, i think the oberon way may the correct minimal way.

### 22. Re: Structs

hallo petelomax,

have you come to any conclusions yet?

### 23. Re: Structs

Not really. I put it on the back burner hoping for some sudden inspiration that never happened. I think I needed a kick.

I still can't decide on the right storage approach.

Phix sequences are obviously appealing and fit in best with existing debugging mechanisms (ie ex.err).

However there are other obvious benefits to C structs (raw address) and reference structs (opaque index), which may make debugging somewhat harder.

In the first instance I need to whip up a struct.e (probably with a somewhat ugly/clunky interface) that delivers the needed functionality.
I had assumed that would be pretty trivial, but indecision has got in the way.

### 24. Re: Structs

petelomax said...

Not really. I put it on the back burner hoping for some sudden inspiration that never happened. I think I needed a kick.

Well consider yourself kicked :)

petelomax said...

I still can't decide on the right storage approach.

Phix sequences are obviously appealing and fit in best with existing debugging mechanisms (ie ex.err).

However there are other obvious benefits to C structs (raw address) and reference structs (opaque index), which may make debugging somewhat harder.

In the first instance I need to whip up a struct.e (probably with a somewhat ugly/clunky interface) that delivers the needed functionality.
I had assumed that would be pretty trivial, but indecision has got in the way.

well, then go the easiest way, that will give us at least structures with sequences etc. in them.