1. Type - Start Again
- Posted by Salix <salix at f?eem?il.hu> Aug 19, 2007
- 528 views
- Last edited Aug 20, 2007
Hello, Playing with Peter Robinson's suggestion I realized that many of my existing codes could have been simplified by his example.
type customer(sequence x) integer x[1] as id sequence x[2] as name sequence x[3] as address end type
Type definitions could replace the currently needed
constant id=1 constant name=2 constant address=3 type customer(sequence x) if length(x)=3 and integer(x[id]) and sequence(x[name]) and sequence(x[address]) then return 1 else return 0 end if end type
(Although he suggested using "." instead of "as".) Most of the answers replied to his general comment but I would like to hear your opinion on the simplification shown above. What do you think? Kind regards, Salix
2. Re: Type - Start Again
- Posted by CChris <christian.cuvier at ag?iculture.go?v.fr> Aug 20, 2007
- 518 views
Salix wrote: > > Hello, > > Playing with Peter Robinson's suggestion I realized that > many of my existing codes could have been simplified by > his example. > > }}} <eucode> > type customer(sequence x) > integer x[1] as id > sequence x[2] as name > sequence x[3] as address > end type > </eucode> {{{ > > Type definitions could replace the currently needed > }}} <eucode> > constant id=1 > constant name=2 > constant address=3 > type customer(sequence x) > if length(x)=3 > and integer(x[id]) > and sequence(x[name]) > and sequence(x[address]) > then > return 1 > else > return 0 > end if > end type > </eucode> {{{ > > (Although he suggested using "." instead of "as".) > > Most of the answers replied to his general comment > but I would like to hear your opinion on the > simplification shown above. What do you think? > > Kind regards, > > Salix Looks nice, but the parser will have a terrible time with this... I'd suggest either: * replacing "type" by "structure" and leave types as they currently are; * use a slightly different notation, the idea being to have a prefix, so that the parser knows what he is doing:
type customer(sequence x) member id: integer member name: sequence member address: sequence -- some optional code that would return a boolean, describing some axtra consistency constraint end type
This way we would extend types to _also_ include heterogeneous sequences, without altering their current functionality. CChris
3. Re: Type - Start Again
- Posted by Pete Lomax <petelomax at blu?yond?r.co.uk> Aug 20, 2007
- 499 views
Salix wrote: > > }}} <eucode> > type customer(sequence x) > integer x[1] as id > sequence x[2] as name > sequence x[3] as address > end type > </eucode> {{{ > > I would like to hear your opinion on the > simplification shown above. What do you think? > I can accept that, with some qualifications (see below) Peter Robinson wrote: > Once you accept a declarative shorthand for boolean expressions, > the following is equally intuitive:- > > type ten_ints( sequence x ) > length(x) = 10 – insert any boolean expression you want > end type > > Since type blocks are just a series of boolean expressions, why not ASSUME > that in a declarative syntax? But they are not. Types can be very useful in debugging, eg if I notice that my program has crashed because something has set bCFwd[31][2] to -7, then I can find where that happened by using a type, with any of:
if x[31][2]=-7 then return 0 end if if x[31][2]=-7 then ?9/0 end if if x[31][2]=-7 then trace(1) end if
Currently types, like functions and procedures, have implicit <locals> and <code> sections. I can accept this be changed to <fields> <locals> <code>. But I would not be happy with a change that meant type definitions could no longer hold local vars and code. CChris wrote: > Looks nice, but the parser will have a terrible time with this... It all seems pretty straightforward to me:
-- in type/routine definition (pseudocode) if <rtn type>=E_Type and <param type>=T_Sequence then -- process (optional) fields section: while isType() do nextToken() if tok[ID]!=<parameter> then -- complete first local var specially, since we accidentally -- just "ate" the sequence/integer/etc token [if needbe] exit end if expect "[" ... end while end if -- existing handling for <locals> and <code> follows
In the same way that <locals> must be defined before <code>, keep it simple by ruling that <fields> must be defined before <locals>. The scope of id,name,address etc is a far trickier problem, imo. The only thing I could suggest is have a look at the $ handling, however while mycustomer[name] is fine, mycustomer[f(name)] would not be... Also, in
type address(sequence x) sequence x[1] as addr1 sequence x[2] as addr2 end type type customer(sequence x) integer x[1] as id sequence x[2] as name address x[3] as addr end type ... .. mycustomer[<xxx>][<yyy>] .. ...
Then id,name,addr would be valid for <xxx>, but addr1 and addr2 would only be valid for <yyy> if <xxx> was (?the literal constant?) addr, and of course all invalid elsewhere on that line (barring another customer var subscript). Oh (and this was going to be a short post), is this going to be annoying?
procedure showName(object x) if customer(x) then puts(1,x[name]) ^ invalid
Of course when someone comes and optimises their code it must still work:
procedure showName(object x) integer cx cx=customer(x) if cx then puts(1,x[name])
Now /that/ is something a human sees well but gives a parser nightmares This is also getting perilously close to puts(1,x[name]) implementing late binding, but for that you would need to declare customer as an OO class. In fact on that note...... > This way we would extend types to _also_ include heterogeneous sequences, I would imagine that
type x(sequence of <type> y)
means it cannot have a fields section, a simple "and not <someflag>" after the E_Type test above. Of course you cannot have a fields section on a type declared as integer, atom, or object (assuming we get the ret 0 fix) either. Regards, Pete
4. Re: Type - Start Again
- Posted by CChris <christian.cuvier at agriculture.g?uv.?r> Aug 20, 2007
- 516 views
Pete Lomax wrote: > > Salix wrote: > > > > }}} <eucode> > > type customer(sequence x) > > integer x[1] as id > > sequence x[2] as name > > sequence x[3] as address > > end type > > </eucode> {{{ > > > > I would like to hear your opinion on the > > simplification shown above. What do you think? > > > I can accept that, with some qualifications (see below) > > Peter Robinson wrote: > > Once you accept a declarative shorthand for boolean expressions, > > the following is equally intuitive:- > > > > type ten_ints( sequence x ) > > length(x) = 10 – insert any boolean expression you want > > end type > > > > Since type blocks are just a series of boolean expressions, why not ASSUME > > that in a declarative syntax? > But they are not. Types can be very useful in debugging, eg if I notice that > my program has crashed because something has set bCFwd[31][2] to -7, then I > can find where that happened by using a type, with any of: > }}} <eucode> > if x[31][2]=-7 then return 0 end if > if x[31][2]=-7 then ?9/0 end if > if x[31][2]=-7 then trace(1) end if > </eucode> {{{ > > Currently types, like functions and procedures, have implicit <locals> and > <code> > sections. I can accept this be changed to <fields> <locals> <code>. > But I would not be happy with a change that meant type definitions could no > longer hold local vars and code. > > CChris wrote: > > Looks nice, but the parser will have a terrible time with this... > It all seems pretty straightforward to me: > }}} <eucode> > -- in type/routine definition (pseudocode) > if <rtn type>=E_Type and <param type>=T_Sequence then > -- process (optional) fields section: > while isType() do > nextToken() > if tok[ID]!=<parameter> then > -- complete first local var specially, since we accidentally > -- just "ate" the sequence/integer/etc token [if needbe] > exit > end if > expect "[" > ... > end while > end if > -- existing handling for <locals> and <code> follows > </eucode> {{{ That's the first ... section which worries me a little because of some corner cases. > In the same way that <locals> must be defined before <code>, keep it simple by > ruling that <fields> must be defined before <locals>. > Agreed. > The scope of id,name,address etc is a far trickier problem, imo. Nope, they have the same scope as the type they appear in, but should not be used as indexes for the type they are defined for. The dot syntax appears to be just fine. Using ':' like for a namespace is tempting, but would create nasty collisions, so I'd prefer using the dot. Remember I'm an heretic from the procedural religion. > The only thing > I could suggest is have a look at the $ handling, however while > mycustomer[name] > is fine, mycustomer[f(name)] would not be... Also, in > > }}} <eucode> > type address(sequence x) > sequence x[1] as addr1 > sequence x[2] as addr2 > end type > type customer(sequence x) > integer x[1] as id > sequence x[2] as name > address x[3] as addr > end type > ... > .. mycustomer[<xxx>][<yyy>] .. > ... > </eucode> {{{ Could you make it simpler by omitting the numbers, since they are defined by the statement # they appear in? This would lead to:
type address(sequence x) fields sequence addr1 sequence addr2 end fields <optional normal routine body here> end type type customer(sequence x) fields integer id sequence name address addr end fields end type ... if equal(mycustomer[<xxx>][customer.name],"Pete") then ... ...
assuming mycustomer is a "sequence of customer", or a "customer list", which I'd prefer as closer to the coder's intent. > Then id,name,addr would be valid for <xxx>, but addr1 and addr2 would only > be valid for <yyy> if <xxx> was (?the literal constant?) addr, and of > course all invalid elsewhere on that line (barring another customer var > subscript). > > Oh (and this was going to be a short post), is this going to be annoying? > }}} <eucode> > procedure showName(object x) > if customer(x) then > puts(1,x[name]) > ^ invalid > </eucode> {{{ > Of course when someone comes and optimises their code it must still work: > }}} <eucode> > procedure showName(object x) > integer cx > cx=customer(x) > if cx then > puts(1,x[name]) > </eucode> {{{ > Now /that/ is something a human sees well but gives a parser nightmares > Use x[customer.name], and the parser will be happy, won't he? Plus, if you use the wrong constant, you can get an error (customer.name may be 2 and supplier.name may be 4). The extra typing is a problem. To alleviate it, we'd have to be sure that x is a variable defined to be from a specific type with fields, and then forgetting the explicit "customer." would cause it to be assumed. If the condition is not met, then I'm not sure whether to throw an error. Could be the best thing to do. If you use a dotted constant with the wrong type, then it may be assumed that you know what yu are doing, so no error should occur. Probably a warning, just in case you didn't know what you were doing. > This is also getting perilously close to puts(1,x[name]) implementing late > binding, > but for that you would need to declare customer as an OO class. > > In fact on that note...... > > > This way we would extend types to _also_ include heterogeneous sequences, > I would imagine that > }}} <eucode> > type x(sequence of <type> y) > </eucode> {{{ > means it cannot have a fields section, a simple "and not <someflag>" after > the E_Type test above. Of course you cannot have a fields section on a type > declared > as integer, atom, or object (assuming we get the ret 0 fix) either. > Agreed for both points. CChris > Regards, > Pete
5. Re: Type - Start Again
- Posted by Peter Robinson <indorlaw at yah?o.c?m.au> Aug 20, 2007
- 531 views
Hello all I'd be absolutely delighted if a solution were implemented that allowed typing and aliasing of data within a sequence. To me, such improvements would merely enhance Euphoria's sequences, not detract from them. However, the suggested solutions don't address the issue of nested data. I am one of the apparently few people who want to constrain nested data (beyond the first dimension), and the same sort of idea arose in the discussion of "sequence of integer". I do believe a consistent approach to similar issues is more likely to preserve the clean design of the language. (If it's impossible, so be it). I can see how something like "sequence of sequence of integer" quickly becomes non-intuitive, and you have the question of where to draw the line. Natural language doesn't convey multiple dimensions well. My own suggestion was therefore aimed at a more visual representation through brackets. As I intimated in my post, I am happy for the contributors to make the decisions - I just wanted to raise the issues at a more general level, so that more generalised solutions could be considered. Cheers Peter Robinson
6. Re: Type - Start Again
- Posted by Pete Lomax <petelomax at blu?yo?der.co.uk> Aug 20, 2007
- 501 views
Peter Robinson wrote: > > However, the suggested solutions don't address the issue of nested data. Looks to me like it does. Can you expand a bit more on what is missing? Regards, Pete
7. Re: Type - Start Again
- Posted by Peter Robinson <indorlaw at yahoo.co??au> Aug 21, 2007
- 510 views
Hi These seem to me to be variations that deserve consideration. The general domain is approaches to constraining data internal to sequences in the same way that Euphoria allows typing of data external to an object. I deliberately restricted the cases to syntax within a type block. The aliasing idea is separate - excluded here. Case 1: Fixed heterogeneous sequences - typical entity objects, like the customer object discussed. I've also omitted any implementation-specific syntax that was discussed. Salix assumed that my example like:- type customer( sequence x ) integer x[1] id sequence x[2] name sequence x[3] address end type implied length(x) = 3. It's a reasonable asumption, but I actually didn't intend it one way or the other. Discussion between Pete and CChris, including aliasing, suggested that the x[num] part is superfluous, since the index is implied by ordering. Comment1: If you don't want to alias the subscripts, you're left with no identifier at all. Looks odd / unclear / ambiguous to me. Comment 2: If you leave out the index number, the number is implied, but may be hard for the eye to pick up if the sequence has several members. Comment 3: Is "field" a good Euphorian word? Case 2: Homogenous sequences Sequence of uniform type in n dimensions. Goal to avoid / simplify looping syntax.I suggested:- -- 1-dimensional sequence, all integers i.e. sequence of integer type list( sequence x ) integer x[] end type -- This is a more Euphorian alternative, but doesn't generalise well to > 1 dimension type list( sequence x ) integer x[1..$] end type -- which suggests type semi_loose_entity( sequence x ) integer x[1] sequence x[2..$] end type -- > 2-dimensions - highlighting visual hierarchy idea type matrix( sequence x ) sequence x[] -- 1st dimension all sequences integer x[][] -- 2nd dimension all integers end type I think that gives the picture. It didn't look to me that all these variations were considered. Maybe some were rejected out of hand. Since I started all this, I'm happy to do any documentation of any outcome or assist otherwise if I can, but I can't devote time to studying the interpreter code in depth. Cheers Peter Robinson
8. Re: Type - Start Again
- Posted by CChris <christian.cuvier at agric?lture.gouv.f?> Aug 21, 2007
- 517 views
Peter Robinson wrote: > > Hi > > These seem to me to be variations that deserve consideration. The general > domain > is approaches to constraining data internal to sequences in the same way that > Euphoria allows typing of data external to an object. I deliberately > restricted > the cases to syntax within a type block. The aliasing idea is separate - > excluded > here. > > Case 1: Fixed heterogeneous sequences - typical entity objects, like the > customer > object discussed. I've also omitted any implementation-specific syntax that > was discussed. > > Salix assumed that my example like:- > > type customer( sequence x ) > integer x[1] id > sequence x[2] name > sequence x[3] address > end type > > implied length(x) = 3. It's a reasonable asumption, but I actually didn't > intend > it one way or the other. > It looks like we'd need an extra keyword to mean "no other field may follow" or "other fields may follow". My own preference would be for a terminal "stop" keyword to mean that the sequence should only contain the fields listed above. Perhaps "end all_fields" is better than "stop end fields". I have very weak preferences there, but something should probably be added. > Discussion between Pete and CChris, including aliasing, suggested that the > x[num] > part is superfluous, since the index is implied by ordering. > > Comment1: If you don't want to alias the subscripts, you're left with no > identifier > at all. Looks odd / unclear / ambiguous to me. The idea I had was to make declaring fields as close as possible from declaring a variable. Hence each field must have a name, since each variable must have a name. Since aliases may collide between different structures, then, inside an index specification: * If the sequence is of a fielded type, and the unqualified alias is a known field, use this binding, else error; * If the field name is prefixed by a type name and a dot, then use the binding if the alias is known for the type of the conaining sequence, or if it has a unique offset, else error; * If an unqualified field name is used in conjunction with a sequence not of a fielded type, then use the common value if there's any, else error. Since a field declaration is syntactically identical to a local variable declaration, it needs some kind of block separation to differentiate. There may be either fields or local variables, or both. > Comment 2: If you leave out the index number, the number is implied, but may > be hard for the eye to pick up if the sequence has several members. Is it easier to read an index or to follow a list of "type name" lines? imho the latter. Note that numeric indexes are allowed, though not recommended. > Comment 3: Is "field" a good Euphorian word? What is the loose evaluation function to be used to tag a keyword as more euphorian than another? I thought being short and expressive helped. "fields" looks good, why not "items" or "parts". What would you advocate? > > Case 2: Homogenous sequences > Sequence of uniform type in n dimensions. Goal to avoid / simplify looping > syntax.I > suggested:- > > -- 1-dimensional sequence, all integers i.e. sequence of integer > type list( sequence x ) > integer x[] > end type > > -- This is a more Euphorian alternative, but doesn't generalise well to > 1 > dimension > type list( sequence x ) > integer x[1..$] > end type > > -- which suggests > type semi_loose_entity( sequence x ) > integer x[1] > sequence x[2..$] > end type > > -- > 2-dimensions - highlighting visual hierarchy idea > type matrix( sequence x ) > sequence x[] -- 1st dimension all sequences > integer x[][] -- 2nd dimension all integers > end type > > I think that gives the picture. It didn't look to me that all these variations > were considered. Maybe some were rejected out of hand. > I'm afraid that anything that looks too clearly like C will be rejected out of hand. I am not among the C haters, and have learned to appreciate C as I get more frustrated with the verrbosity and rigidity of EUphoria in some areas. But there are some on this list. > Since I started all this, I'm happy to do any documentation of any outcome or > assist otherwise if I can, but I can't devote time to studying the interpreter > code in depth. > > Cheers > Peter Robinson CChris
9. Re: Type - Start Again
- Posted by Jason Gade <jaygade at ya??o.com> Aug 21, 2007
- 487 views
CChris wrote: > > Peter Robinson wrote: > > -- > 2-dimensions - highlighting visual hierarchy idea > > type matrix( sequence x ) > > sequence x[] -- 1st dimension all sequences > > integer x[][] -- 2nd dimension all integers > > end type > > > > I think that gives the picture. It didn't look to me that all these > > variations > > were considered. Maybe some were rejected out of hand. > > > > I'm afraid that anything that looks too clearly like C will be rejected out > of hand. I am not among the C haters, and have learned to appreciate C as I > get more frustrated with the verrbosity and rigidity of EUphoria in some > areas. > But there are some on this list. There are? I've never noticed anyone who really hated C here... I don't know about this exact syntax -- I like the first part but not the second so much. I think it would be nice to have a built-ins similar to integer() and atom() and sequence() that check an entire level of a sequence which kind of seems like what is being suggested. And then you can define your own types and then compose the type definitions into more complicated types. Of course, then it kind of goes back to Pete's and Rob's suggestions of inserting that syntax into the argument list of a type definition. -- A complex system that works is invariably found to have evolved from a simple system that works. --John Gall's 15th law of Systemantics. "Premature optimization is the root of all evil in programming." --C.A.R. Hoare j.
10. Re: Type - Start Again
- Posted by Pete Lomax <petelomax at b?ueyonder.c?.uk> Aug 21, 2007
- 501 views
Peter Robinson wrote: > > Case 1: Fixed heterogeneous sequences > > Salix assumed that my example like:- > > type customer( sequence x ) > integer x[1] id > sequence x[2] name > sequence x[3] address > end type > > implied length(x) = 3. It's a reasonable asumption, but I actually didn't > intend > it one way or the other. Fair enough. If you wanted to enforce a customer record only ever had 3 fields then use the obvious if length(x)!=3 then return 0, otherwise elements 4..$ can exist and are untyped. > > Discussion between Pete and CChris, including aliasing, suggested that the > x[num] > part is superfluous, since the index is implied by ordering. I have no particular bias for [1],[2] or fields .. end fields notation. > Case 2: Homogenous sequences > > -- 1-dimensional sequence, all integers i.e. sequence of integer > type list( sequence x ) > integer x[] > end type I was thinking of using
type list(sequence of integer x) end type
> -- which suggests > type semi_loose_entity( sequence x ) > integer x[1] > sequence x[2..$] > end type Hmmm, not sure about that. After sle[idx]=x, if idx is a fixed literal integer constant (such as a field name) then the compiler will be able to limit type checking to the single modified element, but if idx is a var then the compiler cannot do the same level of optimisation, needing either extra code somewhere (key point being, where would that code be, exactly?) or it may be easier and quicker just to type-check the whole thing. > -- > 2-dimensions - highlighting visual hierarchy idea > type matrix( sequence x ) > sequence x[] -- 1st dimension all sequences > integer x[][] -- 2nd dimension all integers > end type > Seems to me this, and the previous example, would be better coded as:
type vector(sequence of sequence ss) end type type speeds(sequence of integer si) end type type matrix(sequence x) vector x[1] v speeds x[2] s end type
To me this has a clear advantage that when modifying the elements of a type matrix var, the work vars you need have a read-made named type, which in turn means the compiler can omit type checking completely:
procedure swap(matrix m, integer a, integer b) vector v v=m[v][a] m[v][a]=matrix[v][b] m[v][b]=v end procedure
Which is a pretty neat trick, considering you would still have full type-safety on user defined types. (First person to say C++ already does this gets a kick) > Since I started all this, I'm happy to do any documentation of any outcome > or assist otherwise if I can, but I can't devote time to studying the > interpreter code in depth. On may travels the other day (looking for something else entirely), I came across this by Derek Parnell: http://www.openeuphoria.org/cgi-bin/esearch.exu?thread=1&fromMonth=8&fromYear=8&toMonth=A&toYear=8&keywords=%22Last+Element+Reference%22 Same deal for the next stage: Articulate and concise, irrefutable and conclusive would probably work best. Also plenty of concrete examples - if they're not right, and convincing, it won't fly. Regards, Pete
11. Re: Type - Start Again
- Posted by Juergen Luethje <j.lue at gm?.d?> Aug 21, 2007
- 493 views
- Last edited Aug 22, 2007
Pete Lomax wrote: > Peter Robinson wrote: >> >> However, the suggested solutions don't address the issue of nested data. > Looks to me like it does. So does it look to me, too. > Can you expand a bit more on what is missing? I wonder why he does not answer this question. Regards, Juergen