1. Structures; etc.
- Posted by Michael Nelson <mike-nelson-ODAAT at WORLDNET.ATT.NET> Jan 30, 2000
- 535 views
There seems to be a recurring demand for structures--in Euphoria terms, fixed-length sequences with type specified for each element and named access to the elements, preferably with dot notation. I'm not sure I see the point in doing this if we are going to stop there. No doubt implementing structures in the Eu interpreter would require extensive reprogramming. If Rob were to invest that much time and effort into redesigning the language, why only go half way to object orientation? Add access control, methods, and some form of inheritance and you have a true OOP language: E++. Is this the direction we want Euphoria to go? My inclination is to vote NO--and no one can accuse me of being anti-OOP. For those of us who want structures without having to hand code types for 20 to 50 sequence elementsand want dot notation, how about a preprocessor--perhaps along the lines of David Cuny's Dot preprocessor. --Mike Nelson, author of Object Euphoria, a full-featured Java-style OOP system for Euphoria.
2. Re: Structures; etc.
- Posted by Irv Mullins <irv at ELLIJAY.COM> Jan 30, 2000
- 520 views
----- Original Message ----- From: Michael Nelson <mike-nelson-ODAAT at WORLDNET.ATT.NET> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Sunday, January 30, 2000 4:38 AM Subject: Structures; etc. > There seems to be a recurring demand for structures--in Euphoria terms, > fixed-length sequences with type specified for each element and named access > to the elements, preferably with dot notation. Who said anything about fixed length? Implementing named and typed elements within an "object" is just a natural extension of Euphoria's existing named and typed elements (atom, integer, sequence). There's no reason to abandon the dynamic sizing of sequences just because they may be incorporated as part of a larger group of elements. Likewise, there seems to be no logical reason for abandoning the ability to type check integers just because you are using that integer variable as part of a larger variable. > I'm not sure I see the point in doing this if we are going to stop there. > No doubt implementing structures in the Eu interpreter would require > extensive reprogramming. If Rob were to invest that much time and effort > into redesigning the language, why only go half way to object orientation? > Add access control, methods, and some form of inheritance and you have a > true OOP language: E++. Is this the direction we want Euphoria to go? Extensive reprogramming? Consider this: every pre-defined or user-defined type already carries with it an identifier as to type. If they didn't, you wouldn't get error messages when making an incorrect assignment. Therefore, the only addition would seem to be some kind of container object to hold a list of variables, and when assignment is made to an object in the container, perform the existing type check just as it does when the member is a stand-alone variable. > My inclination is to vote NO--and no one can accuse me of being anti-OOP. > For those of us who want structures without having to hand code types for 20 > to 50 sequence elementsand want dot notation, how about a > preprocessor--perhaps along the lines of David Cuny's Dot preprocessor. Two reasons this isn't practical: 1. Rob has no choice but to fix the namespace problems. In so doing, he will either implement dot notation or some other workable arrangement. Whatever method he chooses, it is sure to be better than a pre-processor. 2. Calling the built-in type checking is _much_ faster than calls to user type() functions, which is what you would have if using a pre-processor. Remember, even if your "structure" is as simple as {x,y} where x and y are integers, any assignment to x, y or {x,y} must be run thru a user-written type() function, which then calls the built in integer type check for each. That can result in a major performance hit, especially if instead of two integers you are working with arrays of hundreds or thousands of integers/atoms. Irv
3. Re: Structures; etc.
- Posted by David Cuny <dcuny at LANSET.COM> Jan 30, 2000
- 508 views
Michael Nelson wrote: > There seems to be a recurring demand for structures > --in Euphoria terms, fixed-length sequences with type > specified for each element and named access to the > elements, preferably with dot notation. If Euphoria had classes, you wouldn't need structures. The data would be encapsulated into the classes, not in sequences. So you'd avoid having to add all that overhead to sequences. > I'm not sure I see the point in doing this if we are going to stop there. > No doubt implementing structures in the Eu interpreter would require > extensive reprogramming. If Rob were to invest that much time and effort > into redesigning the language, why only go half way to object orientation? > Add access control, methods, and some form of inheritance and you have a > true OOP language: E++. Is this the direction we want Euphoria to go? I vote Yes. Implementing namespace *is* OOP. For example: class = include file objects = scoped variables methods = scoped routines inheritance = scoped include files -- BEGIN EXAMPLE -- -- point.e integer x, y procedure init( initX, initY ) x = 0 y = 0 end procedure procedure plus( integer dx, dy ) x += dx y += dy end procedure -- END EXAMPLE -- The above example, declares a Point class. Currently, we only get a single instance of the class. Namespaces clarifies that we really *are* dealing with a class: point.init( 10, 20 ) point.add( 3, 4 ) ? { point.x, point.y } The only thing that we won't have is the ability to create more than one instance. If you add that, you've got a complete OOP system: module point declares class point point point1, point2 point1.init( 10, 20 ) point2.init( -30, 10 ) Note that: - types don't have to be added to sequences - old code doesn't break - people don't *have* to use OOP -- David Cuny
4. Re: Structures; etc.
- Posted by The Johnson Family <thedjs at INAME.COM> Jan 31, 2000
- 513 views
I personally would like EU to be Object Oriented, and the fact that it isnt is just about the only reason I still use Delphi/Object Pascal for much of my programming work. If eu were object oriented, I would use it for just about everything - Since I started OOP, I cant seem to stop programming like that, even in non OOP languages! Nick ----- Original Message ----- From: Michael Nelson <mike-nelson-ODAAT at WORLDNET.ATT.NET> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Sunday, January 30, 2000 10:38 PM Subject: Structures; etc. > There seems to be a recurring demand for structures--in Euphoria terms, > fixed-length sequences with type specified for each element and named access > to the elements, preferably with dot notation. > > I'm not sure I see the point in doing this if we are going to stop there. > No doubt implementing structures in the Eu interpreter would require > extensive reprogramming. If Rob were to invest that much time and effort > into redesigning the language, why only go half way to object orientation? > Add access control, methods, and some form of inheritance and you have a > true OOP language: E++. Is this the direction we want Euphoria to go? > > My inclination is to vote NO--and no one can accuse me of being anti-OOP. > For those of us who want structures without having to hand code types for 20 > to 50 sequence elementsand want dot notation, how about a > preprocessor--perhaps along the lines of David Cuny's Dot preprocessor. > > --Mike Nelson, > author of Object Euphoria, a full-featured Java-style OOP system for > Euphoria. > >
5. Re: Structures; etc.
- Posted by The Johnson Family <thedjs at INAME.COM> Jan 31, 2000
- 501 views
Yaaay! Wonderful! Wouldnt this be great to have? David has even illustrated a way that a class file would not really be any different from a current include file - we could probably reuse much of the existing include files, even if we have full OOP! Just one suggestion - add a single compiler directive that can be placed in include files to make the class a "static" one - a static class would not have to be instantiated- it could be used as if it was an instance- eg, a non-static class would be treated like this: Graphics Gr1, Gr2 Gr1.HRes = 200 Gr2.Hres = 768 Where a static class would be treated like this: Graphics.HRes = 1024 Graphics.VRes = 768 Nick ----- Original Message ----- From: David Cuny <dcuny at LANSET.COM> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Monday, January 31, 2000 7:03 AM Subject: Re: Structures; etc. > Michael Nelson wrote: > > > There seems to be a recurring demand for structures > > --in Euphoria terms, fixed-length sequences with type > > specified for each element and named access to the > > elements, preferably with dot notation. > > If Euphoria had classes, you wouldn't need structures. The data would be > encapsulated into the classes, not in sequences. So you'd avoid having to > add all that overhead to sequences. > > > I'm not sure I see the point in doing this if we are going to stop there. > > No doubt implementing structures in the Eu interpreter would require > > extensive reprogramming. If Rob were to invest that much time and effort > > into redesigning the language, why only go half way to object orientation? > > Add access control, methods, and some form of inheritance and you have a > > true OOP language: E++. Is this the direction we want Euphoria to go? > > I vote Yes. Implementing namespace *is* OOP. For example: > > class = include file > objects = scoped variables > methods = scoped routines > inheritance = scoped include files > > -- BEGIN EXAMPLE -- > > -- point.e > integer x, y > > procedure init( initX, initY ) > x = 0 > y = 0 > end procedure > > procedure plus( integer dx, dy ) > x += dx > y += dy > end procedure > > -- END EXAMPLE -- > > The above example, declares a Point class. Currently, we only get a single > instance of the class. Namespaces clarifies that we really *are* dealing > with a class: > > point.init( 10, 20 ) > point.add( 3, 4 ) > ? { point.x, point.y } > > The only thing that we won't have is the ability to create more than one > instance. If you add that, you've got a complete OOP system: > > module point declares class point > point point1, point2 > > point1.init( 10, 20 ) > point2.init( -30, 10 ) > > Note that: > > - types don't have to be added to sequences > - old code doesn't break > - people don't *have* to use OOP > > -- David Cuny > >
6. Re: Structures; etc.
- Posted by JJProg at CYBERBURY.NET Jan 30, 2000
- 494 views
I think the best way to go would be to use a pre-processor. This would allow the interpreter to stay small and fast, and it would not require any modification. It would also let people choose from a variety of pre-processors, or write one themselves, so they can decide on the style they like. Jeff
7. Re: Structures; etc.
- Posted by Irv Mullins <irv at ELLIJAY.COM> Jan 30, 2000
- 491 views
On Sun, 30 Jan 2000, you wrote: > I think the best way to go would be to use a pre-processor. This would > allow the interpreter to stay small and fast, and it would not require > any modification. It would also let people choose from a variety of > pre-processors, or write one themselves, so they can decide on the style > they like. Pretty much out of the question - we would still be using the type() function. Try this program: atom start type byte (object x) if x < 0 or x > 255 then return 0 else return 1 end if end type byte x start = time() for i = 1 to 10000000 do x = 5 end for ? time() - start -- takes avg. 4.51 seconds integer y start = time() for i = 1 to 10000000 do y = 5 end for ? time() - start -- takes avg. 0.54 seconds You can see that user-defined types are useless except for debugging purposes, as the overhead kills any performance whatsoever. This is for a single type check. I haven't even tried nested type checks. Any pre-processor would either have to let everything go untyped, or rely on the type() function. Neither is acceptable. This functionality needs to be built into the language itself. Irv
8. Re: Structures; etc.
- Posted by JJProg at CYBERBURY.NET Jan 30, 2000
- 487 views
EU>On Sun, 30 Jan 2000, you wrote: EU>> I think the best way to go would be to use a pre-processor. This would EU>> allow the interpreter to stay small and fast, and it would not require EU>> any modification. It would also let people choose from a variety of EU>> pre-processors, or write one themselves, so they can decide on the style EU>> they like. EU>Pretty much out of the question - we would still be using the type() functio EU>Try this program: EU>atom start EU>type byte (object x) EU> if x < 0 or x > 255 then return 0 EU> else return 1 EU> end if EU>end type EU>byte x EU>start = time() EU>for i = 1 to 10000000 do EU> x = 5 EU>end for EU>? time() - start -- takes avg. 4.51 seconds EU>integer y EU>start = time() EU>for i = 1 to 10000000 do EU> y = 5 EU>end for EU>? time() - start -- takes avg. 0.54 seconds EU>You can see that user-defined types are useless except for debugging purpose EU>as the overhead kills any performance whatsoever. This is for a single type EU>check. I haven't even tried nested type checks. Any pre-processor would eith EU>have to let everything go untyped, or rely on the type() function. Neither i EU>acceptable. This functionality needs to be built into the language itself. EU>Irv How would building object-orientation into the interpreter make this go faster? A pre-processor could be smart, and not do unnessicary type checking. For example: type sequenceOfIntegers(object x) if sequence(x) then for i = 1 to length(x) do if not integer(x[i]) then return 0 end if end for return 1 end if return 0 end type class MyClass sequenceOfIntegers seq1 sequenceOfIntegers seq2 sequenceOfIntegers seq3 sequenceOfIntegers seq4 sequenceOfIntegers seq5 end class MyClass instance instance.seq1 = repeat(0,100000) instance.seq2 = instance.seq1 instance.seq3 = instance.seq1 instance.seq4 = instance.seq1 instance.seq5 = instance.seq1 instance.seq5[50] = 1000 A smart pre-processor could optomize see that: 1. When instance.seq1 and instance.seq5[50] are assigned, there is no need to check everything else. 2. When instance.seq2-5 are assigned, there is no need to check them because instance.seq1 is the same type and they're ok In your example, a smart pre-processor could see that 5 is a byte, and therefore x doesn't need to be checked 10000000. In fact, an even smarter pre-processor could optomize the code to: byte x atom start start = time() x = 5 ? time()-start or: without type_check -- It knows there won't be any type checking -- errors integer x atom start start = time() x = 5 -- It knows that 5 is a byte ? time()-start What might increase speed a lot in some cases would be an array type. This would allow something like: integer bigArray[10000000] bigArray[10000000] = 5 to only check bigArray[10000000] instead of: sequenceOfIntegers bigArray bigArray = repeat(0,10000000) -- Big type checking operation here bigArray[10000000] = 5 -- Another big type checking operation Jeff
9. Re: Structures; etc.
- Posted by Irv Mullins <irv at ELLIJAY.COM> Jan 30, 2000
- 496 views
On Sun, 30 Jan 2000, JJ wrote: > EU>On Sun, 30 Jan 2000, Irv wrote: > EU>You can see that user-defined types are useless except for debugging > purpose > EU>as the overhead kills any performance whatsoever. This is for a single > type > EU>check. I haven't even tried nested type checks. Any pre-processor would > eith > EU>have to let everything go untyped, or rely on the type() function. Neither > i > EU>acceptable. This functionality needs to be built into the language itself. > > EU>Irv > > How would building object-orientation into the interpreter make this go > faster? A pre-processor could be smart, and not do unnessicary type > checking. For example: No one said object-orientation would make it faster. I don't even like OOP. What I said was, if Euphoria typed checked variables _wherever_ they were, using internal type checking functions, we would gain safety with very little loss in speed. This has not related to OOP. > type sequenceOfIntegers(object x) > if sequence(x) then > for i = 1 to length(x) do > if not integer(x[i]) then > return 0 > end if > end for > return 1 > end if > return 0 > end type > > class MyClass > sequenceOfIntegers seq1 > sequenceOfIntegers seq2 > sequenceOfIntegers seq3 > sequenceOfIntegers seq4 > sequenceOfIntegers seq5 > end class > > MyClass instance > instance.seq1 = repeat(0,100000) > instance.seq2 = instance.seq1 > instance.seq3 = instance.seq1 > instance.seq4 = instance.seq1 > instance.seq5 = instance.seq1 > instance.seq5[50] = 1000 > > A smart pre-processor could optomize see that: > 1. When instance.seq1 and instance.seq5[50] are assigned, there is no need to > check everything else. A smart pre-processor might see it, but it couldn't do anything about it without passing it thru your type() function. If user type checking one value takes 9x as long as a similar built-in integer check, just imagine how long that nested check it going to take. Worse, what if the array is not of a built-in type - perhaps it's an array of coordinates, for example. Then your type check loop has to call _another_ user defined type check. Nap time! > 2. When instance.seq2-5 are assigned,there is no need to check them > because instance.seq1 is the same type and they're ok > Nope. Suppose I change something in seq2. In fact, why would I even declare 5 sequences of integers _unless_ I planned to change the contents? Might as well use one. It's when assignments are made that the type checking must come into play. > In your example, a smart pre-processor could see that 5 is a byte, and therefore x doesn't need to be checked 10000000. In fact, an even smarter pre-processor could optomize the code to: > > byte x > atom start > start = time() > x = 5 > ? time()-start Sure. But what if that line was x = z ? z might be almost anything. Who knows, each time it might be different. Unless your pre-processor is psychic, I don't think it's going to be able to simplify things very much. Irv - busy inventing the Prophetic Pre-Processor.
10. Re: Structures; etc.
- Posted by Everett Williams <rett at GVTC.COM> Jan 30, 2000
- 511 views
- Last edited Jan 31, 2000
Gentlemen, This conversation is getting close to a religious discussion. There must be some happy medium. I thought I'd never hear myself say it, but I'm starting to sympathize with Rob's whines about minimalism. I think that the minimum set of changes should be implemented that will make all the things proposed in these posts possible. I really like Mr. Cuny's description of classes and instantiation for OOP, but I think that most of it could be accomplished through pre-processor if Euphoria had adequate namespace and structure capabilities with built-in type checking for sequences. Classes and Object orientation do not answer the need for structures. The one thing that makes structures absolutely necessary is the existence of that world of externally defined data that Euphoria has no control over. Objects, sequences, atoms and integers are arguably sufficient to describe any type of data in a world that only includes Euphoria, but that is not the world that we have to work in. At some point, we must be able to control the physical presentation of data down to the bit, bit order, byte, double byte or word, double word, paragraph, etc. level reliably or we will be peeking and poking or assembling and disassembling data forever, instead of working with it. If we wish to prefix these with the term external or foreign, then do it, but we must have these definitions. In addition, structures do not have to be fixed, only their descriptions. Variable length fields, nested structures and occurrences will allow the description of almost any form of well defined data. If null structures can be defined, then instantiation can be had through simple assignment of a null structure to an Eu object. If you don't mind the memory overhead of a full prototype, then null structures are not necessary(I don't recommend this because structures can be quite large). I believe that structure definitions themselves can be sequences interpreted by Euphoria as an internal type. Included in those sequences can be initialization logic triggered at definition for regular structures and at assignment time for null structures. I would very much like a syntax something like an example that Irv Mullins sent me that looked like this: PHONE_LIST = Customer[NAME,PHONE,PAST_DUE90] where Customer is a predefined structure and the fields are not contiguous and PHONE_LIST is a sequence or object. The only danger in this construct is that some will say that all we need for this is constants which will lead us right back around into namespace problems. They may have a constant value, but they cannot be explicit constants without all the many problems that have been pointed out by myself and a dozen other people over time. The need for internal type checking on defined type fields in at least Euphoria internal structures is a performance necessity. For performance purposes, arrays whose form if not length can be fixed are the last major area of need. Without these, many things become subject to a huge amount of explicit overhead that means little, contributes nothing to the programming process and is hugely inefficient. Arrays are a subset of structures or sequences and offer so many opportunities to make time saving assumptions in the interpretation process that it amazes me that they haven't just jumped in of their own accord. Add these to the prefixing of the namespace of includes and a more generalized and flexible calling capability and all else can be accomplished with preprocessors and libraries. Everett L.(Rett) Williams rett at gvtc.com On Sun, 30 Jan 2000 16:58:10 -0500, Irv Mullins <irv at ELLIJAY.COM> wrote: >On Sun, 30 Jan 2000, JJ wrote: >> EU>On Sun, 30 Jan 2000, Irv wrote: > >> EU>You can see that user-defined types are useless except for debugging >> purpose >> EU>as the overhead kills any performance whatsoever. This is for a single >> type >> EU>check. I haven't even tried nested type checks. Any pre-processor would >> eith >> EU>have to let everything go untyped, or rely on the type() function. Neither >> i >> EU>acceptable. This functionality needs to be built into the language itself. >> >> EU>Irv >> >> How would building object-orientation into the interpreter make this go >> faster? A pre-processor could be smart, and not do unnessicary type >> checking. For example: > >No one said object-orientation would make it faster. I don't even like >OOP. What I said was, if Euphoria typed checked variables >_wherever_ they were, using internal type checking functions, we would gain >safety with very little loss in speed. This has not related to OOP. > >> type sequenceOfIntegers(object x) >> if sequence(x) then >> for i = 1 to length(x) do >> if not integer(x[i]) then >> return 0 >> end if >> end for >> return 1 >> end if >> return 0 >> end type >> >> class MyClass >> sequenceOfIntegers seq1 >> sequenceOfIntegers seq2 >> sequenceOfIntegers seq3 >> sequenceOfIntegers seq4 >> sequenceOfIntegers seq5 >> end class >> >> MyClass instance >> instance.seq1 = repeat(0,100000) >> instance.seq2 = instance.seq1 >> instance.seq3 = instance.seq1 >> instance.seq4 = instance.seq1 >> instance.seq5 = instance.seq1 >> instance.seq5[50] = 1000 >> >> A smart pre-processor could optomize see that: >> 1. When instance.seq1 and instance.seq5[50] are assigned, there is no need to >> check everything else. > >A smart pre-processor might see it, but it couldn't do anything about it >without passing it thru your type() function. If user type checking one value >takes 9x as long as a similar built-in integer check, just imagine how long >that nested check it going to take. Worse, what if the array is not of a >built-in type - perhaps it's an array of coordinates, for example. Then your >type check loop has to call _another_ user defined type check. Nap time! > > > 2. When instance.seq2-5 are assigned,there is no need to check them >> because instance.seq1 is the same type and they're ok > > >Nope. Suppose I change something in seq2. In fact, why would I even declare >5 sequences of integers _unless_ I planned to change the contents? Might as >well use one. It's when assignments are made that the type checking must come >into play. > > > In your example, a smart pre-processor could see that 5 is a byte, >and therefore x doesn't need to be checked 10000000. In fact, an even >smarter pre-processor could optomize the code to: > >> byte x >> atom start >> start = time() >> x = 5 >> ? time()-start > >Sure. But what if that line was x = z ? >z might be almost anything. Who knows, each time it might be different. >Unless your pre-processor is psychic, I don't think it's going to be able to >simplify things very much. > >Irv - busy inventing the Prophetic Pre-Processor.
11. Re: Structures; etc.
- Posted by David Cuny <dcuny at LANSET.COM> Jan 30, 2000
- 520 views
- Last edited Jan 31, 2000
Everett Williams wrote: > ... I think that most of [OOP] could be > accomplished through pre-processor if > Euphoria had adequate namespace and > structure capabilities with built-in type > checking for sequences. That was my thinking when I was writing my 'dot' pre-processor, but polymorphism is a problem. For example: procedure foo( object bar ) bar.print() end procedure Casting 'bar' as an object causes it to lose any sense of identity. The same thing is true if you place the object in a sequence: s[1].print() The pre-processor has no clue what class to apply. In fact, you don't know what the class of the object is going to be until runtime. To get it to work, you need to place all the class methods in a lookup table: routine print() -- code goes here end procedure set_method( "foo", "print", routine_id("print" ) ) The calls then have to resolve the method at runtime. For example, bar.print() become: call_method( "print", bar, {} ) You don't even need namespaces to implement this, but it does a quite a bit of overhead. > Classes and Object orientation do not answer the > need for structures. It's not clear to me why not. For example: foo.bar represents an object's value that can be typed to anything. That should give the granularity you're asking for. Or am I missing something? -- David Cuny
12. Re: Structures; etc.
- Posted by Everett Williams <rett at GVTC.COM> Jan 30, 2000
- 528 views
- Last edited Jan 31, 2000
Please redo this discussion with Eu in front of the term "object" when that is what you mean(e.g. Euobject) even though that would be incorrect in the interpreter. Otherwise, I cannot separate out when you are using the term object as in OOP or as in Eu. From what I can understand, it is fairly evident to me that in an interpretive language of any kind, the late binding that you speak of is a "feature" of the interpretive process. If I understand what you are talking about, all the methods of a class would be renamed in the preprocessor to prevent the type of confusion that you are speaking of. Since I am right at the edge of my knowledge on this subject, it is highly probable that I am completely out in left field on this one. As for structures, they represent real world data that IS largely contiguous and has no overhead except that represented by alignment. Objects on the other hand may be grouped, but have no expectation of contiguity or any other physical relationship. As long as your OOP implementation is based on pure Euphoria data types, their can be no expectation of contiguity or of any other particular physical form. That is fine for pure Euphoria OOP objects, but not fine when dealing with that real world data. External or foreign structures as I characterized them may have similar syntax to Euphoria structures, but their physical form is known and fixed and not subject to Euphoria's "stateless" data types or shifting internal representations. For reasonably compact and more flexible calling routines that are reasonably self-documenting, we must be able to get to this fixed form(that doesn't mean fixed length) data without the atrocity of print() or the manually intensive and totally non-logical form of peeks and pokes that lose all field naming conventions of any sort. Everett L.(Rett) Williams rett at gvtc.com On Sun, 30 Jan 2000 19:53:08 -0800, David Cuny <dcuny at LANSET.COM> wrote: >Everett Williams wrote: > >> ... I think that most of [OOP] could be >> accomplished through pre-processor if >> Euphoria had adequate namespace and >> structure capabilities with built-in type >> checking for sequences. > >That was my thinking when I was writing my 'dot' pre-processor, but >polymorphism is a problem. For example: > > procedure foo( object bar ) > bar.print() > end procedure > >Casting 'bar' as an object causes it to lose any sense of identity. The same >thing is true if you place the object in a sequence: > > s[1].print() > >The pre-processor has no clue what class to apply. In fact, you don't know >what the class of the object is going to be until runtime. To get it to >work, you need to place all the class methods in a lookup table: > > routine print() > -- code goes here > end procedure > set_method( "foo", "print", routine_id("print" ) ) > >The calls then have to resolve the method at runtime. For example, > > bar.print() > >become: > > call_method( "print", bar, {} ) > >You don't even need namespaces to implement this, but it does a quite a bit >of overhead. > >> Classes and Object orientation do not answer the >> need for structures. > >It's not clear to me why not. For example: > > foo.bar > >represents an object's value that can be typed to anything. That should give >the granularity you're asking for. > >Or am I missing something? > >-- David Cuny
13. Re: Structures; etc.
- Posted by Michael Nelson <mike-nelson-ODAAT at WORLDNET.ATT.NET> Jan 31, 2000
- 511 views
David Cuny wrote: >If Euphoria had classes, you wouldn't need structures. The data would be >encapsulated into the classes, not in sequences. So you'd avoid having to >add all that overhead to sequences. > >I vote Yes. Implementing namespace *is* OOP. For example: > > class = include file > objects = scoped variables > methods = scoped routines > inheritance = scoped include files > >-- BEGIN EXAMPLE -- > > -- point.e > integer x, y > > procedure init( initX, initY ) > x = 0 > y = 0 > end procedure > > procedure plus( integer dx, dy ) > x += dx > y += dy > end procedure > >-- END EXAMPLE -- > >The above example, declares a Point class. Currently, we only get a single >instance of the class. Namespaces clarifies that we really *are* dealing >with a class: > > point.init( 10, 20 ) > point.add( 3, 4 ) > ? { point.x, point.y } > >The only thing that we won't have is the ability to create more than one >instance. If you add that, you've got a complete OOP system: > > module point declares class point > point point1, point2 > > point1.init( 10, 20 ) > point2.init( -30, 10 ) > >Note that: > > - types don't have to be added to sequences > - old code doesn't break > - people don't *have* to use OOP > >-- David Cuny > David, I find your ideas fascinating--would you be will to provide some more detailed examples? The idea class=include file seems very Java-Like to me. --Mike Nelson
14. Re: Structures; etc.
- Posted by The Johnson Family <thedjs at INAME.COM> Feb 01, 2000
- 656 views
> I think the best way to go would be to use a pre-processor. This would > allow the interpreter to stay small and fast, and it would not require > any modification. It would also let people choose from a variety of > pre-processors, or write one themselves, so they can decide on the style > they like. > > Jeff Preprocessers, and a different one per person?!? Source code havoc! Can you imagine the problems running someone elses source code in your own euphoria, with all those pre-processors to chose from? Let alone trying to include files written for different preprocessors into one application! Nick
15. Re: Structures; etc.
- Posted by Lee West <leewest at ALTAVISTA.COM> Jan 31, 2000
- 506 views
Hi All, I've been following the recent commentary on structures and OOP, especially as it relates to preprocessors. Personally, I don't understand some of the concerns that invoking these techniques via a preprocessor would somehow negatively impact Euphoria's processing speed... or cause the "type" command to be used. I have put together a simple example of a record structure that could be processed by a preprocessor and the Euphoria code that would result. It certainly doesn't require that the "type" command be used, therefore, I can't see where the performance degradation would occur. As to whether this is preferable or even desirable... I'll let you decide. But it does present an alternative to the, so called, MISSING language elements of Euphoria, without the performance penalties that may occur if they were incorporated into the Eu code itself. I believe an implementation of this type is completely feasible, and can even see the possibility of a full implementation of an OOP option as well. I'd love to hear your thoughts. The example follows: ----------------------- -- Define a record type record Employee Phone integer -- This is an embeded record type in the Employee record record Name First string Last string end record Amount real WeeklyCnt array[1..4] of integer end record -- Define a record variable of the type Employee eeRecord Employee -- Define a pointer to the record RecNo pointer -- Create a new instance of the record type RecNo = eeRecord.New -- Populate the new record using DOT notation eeRecord[RecNo].Phone = 1112223333 eeRecord[RecNo].Name.First = "John" eeRecord[RecNo].Name.Last = "Doe" eeRecord[RecNo].Amount = 1000.00 eeRecord[RecNo].WeeklyCnt[1] = 25 -- Create another instance of the record type RecNo = eeRecord.New -- Populate the new record eeRecord[RecNo].Phone = 2223334444 eeRecord[RecNo].Name.First = "Jane" eeRecord[RecNo].Name.Last = "Doe" eeRecord[RecNo].Amount = 2000.75 eeRecord[RecNo].WeeklyCnt[3] = 25 -------------------------------------------- -- PreProcess the above code and generate -- -- the following Euphoria code -- -------------------------------------------- -- Define the variables sequence temp, eeRecord constant Phone = 1, Name = 2, NameFirst = 1, NameLast = 2, Amount = 3, WeeklyCnt = 4 -- Define the record counter integer RecNo RecNo = 0 -- Initialize the record and record template eeRecord = {} temp = {0,{"",""},0.0,{0,0,0,0}} -- Based on the record definition -- Populate the first eeRecord eeRecord = append(eeRecord,temp) RecNo += 1 eeRecord[RecNo][Phone] = 1112223333 eeRecord[RecNo][Name][NameFirst] = "John" eeRecord[RecNo][Name][NameLast] = "Doe" eeRecord[RecNo][Amount] = 1000.00 eeRecord[RecNo][WeeklyCnt][1] = 25 -- Populate another occurrence of the eeRecord eeRecord = append(eeRecord,temp) RecNo += 1 eeRecord[RecNo][Phone] = 2223334444 eeRecord[RecNo][Name][NameFirst] = "Jane" eeRecord[RecNo][Name][NameLast] = "Doe" eeRecord[RecNo][Amount] = 2000.75 eeRecord[RecNo][WeeklyCnt][3] = 15 -- Print the record include print.e print(1,eeRecord) -- The following is printed -- {{1112223333,{"John","Doe"},1000,{25,0,0,0}},{2223334444, {"Jane","Doe"},2000.75,{0,0,15,0}}} Thanks. Lee.
16. Re: Structures; etc.
- Posted by "Cuny, David at DSS" <David.Cuny at DSS.CA.GOV> Jan 31, 2000
- 508 views
Lee West wrote: > Personally, I don't understand some of the > concerns that invoking these techniques via > a preprocessor would somehow negatively impact > Euphoria's processing speed... There's the namespace issue. What happens when you have two indexes for *different* records with the same name? This happens all the time. -- David Cuny
17. Re: Structures; etc.
- Posted by Lee West <leewest at ALTAVISTA.COM> Jan 31, 2000
- 490 views
David, I think I came in on the end of that discussion... Could you please give a small example? I know this must be old news to some... sorry. Thanks. Lee. On Mon, 31 Jan 2000 12:48:12 -0800, Cuny, David at DSS <David.Cuny at DSS.CA.GOV> wrote: >Lee West wrote: > >> Personally, I don't understand some of the >> concerns that invoking these techniques via >> a preprocessor would somehow negatively impact >> Euphoria's processing speed... > >There's the namespace issue. What happens when you have two indexes for >*different* records with the same name? This happens all the time. > >-- David Cuny
18. Re: Structures; etc.
- Posted by Irv Mullins <irv at ELLIJAY.COM> Jan 31, 2000
- 480 views
----- Original Message ----- From: Lee West <leewest at ALTAVISTA.COM> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Monday, January 31, 2000 3:08 PM Subject: Re: Structures; etc. > Hi All, > > I've been following the recent commentary on structures and OOP, especially > as it relates to preprocessors. Personally, I don't understand some of the > concerns that invoking these techniques via a preprocessor would somehow > negatively impact Euphoria's processing speed... or cause the "type" > command to be used. I have put together a simple example of a record > structure that could be processed by a preprocessor and the Euphoria code > that would result. It certainly doesn't require that the "type" command be > used, therefore, I can't see where the performance degradation would occur. > > As to whether this is preferable or even desirable... I'll let you decide. > But it does present an alternative to the, so called, MISSING language > elements of Euphoria, without the performance penalties that may occur if > they were incorporated into the Eu code itself. I believe an implementation > of this type is completely feasible, and can even see the possibility of a > full implementation of an OOP option as well. I'd love to hear your > thoughts. The example follows: > <snip code> > -------------------------------------------- > -- PreProcess the above code and generate -- > -- the following Euphoria code -- > -------------------------------------------- > > -- Define the variables > sequence temp, eeRecord > constant > Phone = 1, > Name = 2, > NameFirst = 1, > NameLast = 2, > Amount = 3, > WeeklyCnt = 4 > > -- Define the record counter > integer RecNo > RecNo = 0 > > -- Initialize the record and record template > eeRecord = {} > temp = {0,{"",""},0.0,{0,0,0,0}} -- Based on the record definition > > -- Populate the first eeRecord > eeRecord = append(eeRecord,temp) > RecNo += 1 > eeRecord[RecNo][Phone] = 1112223333 > eeRecord[RecNo][Name][NameFirst] = "John" > eeRecord[RecNo][Name][NameLast] = "Doe" > eeRecord[RecNo][Amount] = 1000.00 > eeRecord[RecNo][WeeklyCnt][1] = 25 > <snip more> Or, more likely, my program has bugs, so it assigns eeRecord[RecNo][Name][NameFirst] = 1, and eeRecord[RecNo][Amount] = 'Ralph". Nothing will stop it, until I try to do some math or format the record for printing, when I will get some strange results. I would prefer the error to occur at the point of invalid assignment, so I could fix the problem, not much later in the program. That's why some minimal type checking is needed. Sadly, the way user-defined type checking works in Euphoria doesn't help very much. First of all, it's slow, secondly, it can only abort the program with an error message. Far better would be a type() which incorporates some kind of graceful user-defined recovery. At least one step up from BASIC's "Redo from start" message, please! Secondly, the 3 programs I am currently working on have anywhere from 3 to 5 different ADDRESS, CITY, STATE, ZIP fields. (Customer address, shipping address, supplier address, customer's employment address... for example) This leads to awkwardly named constants, and makes it difficult to write generic routines to handle these otherwise similar constructs. Regards, Irv
19. Re: Structures; etc.
- Posted by Adam Weeden <adam_weeden at HOTMAIL.COM> Jan 31, 2000
- 490 views
------=_NextPart_000_1fed1d9b_22771c98$6a34cbfc I have made an include file that will help.. It allows the definition of records in a way similar to the ways we declare what variables a DLL has in a define_c_func or define_c_proc routine. I have attached it (It's only 2k). I hope it helps anyone. P.S. Rob can you post it to the recent user contribs. page, please. Adam Weeden ______________________________________________________ Get Your Private, Free Email at http://www.hotmail.com ------=_NextPart_000_1fed1d9b_22771c98$6a34cbfc
20. Re: Structures; etc.
- Posted by JJProg at CYBERBURY.NET Jan 31, 2000
- 518 views
EU>> I think the best way to go would be to use a pre-processor. This would EU>> allow the interpreter to stay small and fast, and it would not require EU>> any modification. It would also let people choose from a variety of EU>> pre-processors, or write one themselves, so they can decide on the style EU>> they like. EU>> EU>> Jeff EU>Preprocessers, and a different one per person?!? Source code havoc! Can you EU>imagine the problems running someone elses source code in your own euphoria, EU>with all those pre-processors to chose from? Let alone trying to include EU>files written for different preprocessors into one application! EU>Nick I am assuming that most people won't write their own preprocessor. There might be one or two main preprocessors, and a few less widely used ones. Competition is good! Eventually, the best ones will be the most widely used. Jeff
21. Re: Structures; etc.
- Posted by Everett Williams <rett at GVTC.COM> Jan 31, 2000
- 531 views
- Last edited Feb 01, 2000
On Mon, 31 Jan 2000 18:42:10 EST, JJProg at CYBERBURY.NET wrote: >EU>> I think the best way to go would be to use a pre-processor. This would >EU>> allow the interpreter to stay small and fast, and it would not require >EU>> any modification. It would also let people choose from a variety of >EU>> pre-processors, or write one themselves, so they can decide on the style >EU>> they like. >EU>> >EU>> Jeff > >EU>Preprocessers, and a different one per person?!? Source code havoc! Can you >EU>imagine the problems running someone elses source code in your own euphoria, >EU>with all those pre-processors to chose from? Let alone trying to include >EU>files written for different preprocessors into one application! > >EU>Nick > >I am assuming that most people won't write their own preprocessor. There >might be one or two main preprocessors, and a few less widely used ones. >Competition is good! Eventually, the best ones will be the most widely >used. > >Jeff Jeff, I agree with you, but as long as backward compatibility is "mostly" maintained, really basic facilities should be a part of the language maintained and shipped with the language. I am not a fan of full-blown OOP, but that is mostly a personal preference driven by my roots in an era when non-procedural languages existed only in non-commercial situations like research labs and graduate schools. Mr. Cuny's exposition of classes and methods I find very attractive and I would hope that he would write an OOP preprocessor or emulator in conjunction or in competition with the man who wrote Object Euphoria (Mr. Nelson, I think). If the items that I noted in a previous post are implemented, I firmly believe that the rest of this would be much more easily and efficiently accomplished to the benefit of us all. One thing I can be certain of, named constants as indexes are a disaster that must be repaired by the creation of true structures. A second thing that must be accomplished in the base is namespace management. Most of the rest of these things really flow logically from those two. Everett L.(Rett) Williams rett at gvtc.com