Elegant solution
- Posted by Ralf Nieuwenhuijsen <nieuwen at XS4ALL.NL> Feb 02, 1999
- 459 views
Ive now read all post about this subject, knowing I too was pushing upto the table of final discussion. However, what do I notice ? New datatypes, New operators, etc. all really creative though. But not really relevant. You all had lots of fun with dots, namespace, recursing, etc. sequence clients of addreses, etc., etc. I aksed to add structures to Euphoria. Thats all. I didnt mean to add everything from C/C++ or Pascal so that structures are (accidently possible. Almost all ideas given looked like non-euphoria code. And I wonder... (this is a very very short summery of this ideas presented in this mail) - structures - are like sequence: however initialized from the beginning, and provided as types - constants local to a type - free to manipulate in any way you want - arrays - fixed number of dimensions and optionally a fixed length in each dimension. - free to manipulate in any way you want (arguments and possible issues will be handled as well as the advantages and disadvantages) Here's the solution I mentioned before. That introduces merely a new syntax to define the structure of a sequence and the associating type check function. So.. what features *do* I add ? * constants local to a datatype for slicing * That it. Next to the new way to define the structure of a sequence (with thus the type check function) this is all we need. They are still recursive. Its still a sequence. ==>> Its still a sequence. (repeatance) <<== You can slice it if you want. Use normal indexes on it, if you want, etc. All normal sequence tricks are available. Except for one new fancy something. Slicing this sequence (only when declared as the right structure!) <== it says structure not type *can* (however, no obligation) be done using a constant *local* to the associated structure. Example: structure client do sequence name = "" integer age = -1 end structure -- this already issues one problem: by initializing we prevent it from having to be a sequence containing no initial values (which I would desire, would steal break you code, rather than quitly set it to some value) client record1 record1[name] = "Jan" -- a typical dutch name record1[age] = 18 ? client (record1) -- Prints out a 1: 'record1' matches the type 'client' ? record1[1] record1 = revers (record1) -- crash! type check failure: age is declared as an integer, not a sequence -- In other words I can slice and manipulate the sequence as I want, however I am only allowed to store a legal, matching sequence in 'client' About the recursiveness of structures vs sequences: Sequences may contain structures, however those structures are not type-checked. Structures may contain sequences, that may contain structures. Such deeply nested structures are *not* type-checked. Structures may contain structures, that may contain structures. All of them are type-checked. In one line, the soon as something is declared as sequence rather than structure, the type-check mechanism of structures stops. This is logical. An exception would be where the sequence had its own type check function that had some element checked against the type-check function of the structure. This means we still have all freedom regaring to the data and sequence manipulators. * We just have an alternative way to set up a type check and to initialize the sequence. * There can now be constants local to a type (a structure works like a type) However, now I jump over to another point of me: For an array, using or not using structures, is irrelevant. For structures, using arrays may be very handy. Example: client records[20] Rather than having to do this: type specific_for_records (object s) if not (sequence(s) and length(s) = 20) then return 0 end if for index = 1 to 20 do if not client (s[index]) then return 0 end if end for return true end type This however shows the only problem I can find with implementing both structures and arrays like this. Look at this example code: integer picture[100][100] = 0 Notice I immidiately initialize it. The reason is obvious. Arrays are a pain to initialize. Just as structures. The above would be read like: [skip type-check function: its as big as the one above] specific_integer_array_of_100x100 picture picture = repeat (repeat(0, 100),100) Like structures, arrays only add an alternative way of declaring the structure of a sequence. Its still a sequence. And esspecially for arrays, no changes are needed for the actual code that uses it. (for structures neither, but with them you have the choice of using friendly and logical names) What are the advantages ? You just prevented to having to write a long type check function. A lookup in a predefined array, such as: my5dpicture[100][100][100][100][100] Would be as fast as using an atom. Since no clipping checks have to be made. It can thus insert (preproccess) direct memory addreses to the value into your code, rather than the memory addres of the variable, and the memory addreses of the variables containing the slicing index. (in this case 6 lookups could be made into 1) Normally this is possible as well, if *only* the interpreter could be sure of the structure of the sequence. (if you are allowed to change it, its dynamic memory tricks might move parts of the data around) This 'only' issue I found (which I have mentioned a little while earlier) is, that with arrays defined of structures, you need not to initialize them. This might be confusing for some. Example: integer my5dpicture[100][100][100] = 0 client records[100] -- structures are self-initialized For Robert, structures and arrays add more complexicity than this. A sequence and a structure can 'share' data. (such as sometimes happens now). However, when the data is changed, the new copy should always be made for the sequence rather than the structure. (to maintain the same enormous speed benefit). Other than this (and the changes in the preproccesor), I dont see much conflicts and consider this to be a reasonably elegant solution, that does it claims: add structures. But does not add: new syntaxes in variable addresing, etc. The last note I want to make, are for the 'variable-length-arrays' (you would say: thats a sequence!). Its not a sequence in the normal sence. It still has a *fixed* number of dimensions. Example: procedure print_debug (integer txt[]) object junk if platform () = DOS32 then puts (1, txt) elsif platform () = WIN32 THEN junk = message_box (1, "Message", txt) -- might be wrong end if end procedure The point is, this procedure will never fail due to bad arguments. This is the type check function you would normally need. (but not now, since I declared: "integer txt[]" ) type flat_integer_sequence (object x) if not sequence (x) then return 0 end if for index = 1 to length(x) do if not integer(x[index[) then return 0 end if end for return 1 end type Notice that its longer that the procedure that is suppose to use it ? So, no type check function maybe ? What about simply declaring it as a sequence ? Well, the 'sequence found inside character string' error would occur on both platforms with misuse of the routine. This ends up my mail. A short summery: - structures - are like sequence: however initialized from the beginning, and provided as types - constants local to a type - free to manipulate in any way you want - arrays - fixed number of dimensions and optionally a fixed length in each dimension. - free to manipulate in any way you want Thats it. Now.. can any one find any reason not to add the above features ? Any reason that is relevant to *this* implementation of structures, rather than to *other* implementations used in other languages ? Ralf Nieuwenhuijsen nieuwen at xs4all.nl ralf_n at email.com UIN:// 9389920