1. Constructive criticism
- Posted by Critic Mar 05, 2009
- 1214 views
I refer to section 2.3 of the docs: http://openeuphoria.org/docs/eu400_0011.html#_65_EuphoriaversusConventionalLanguages
Nearly every sentence is misleading or wrong or very biased. Please remove the whole section. It has no place in a reference manual, anyway.
2. Re: Constructive criticism
- Posted by jeremy (admin) Mar 05, 2009
- 1191 views
I am with you on fixing some of those items, however, I believe it is valuable information to show how Euphoria is different in the "Reference Manual." Before I would remove such items, I would vote for a change of the document name from Reference Manual to "The Euphoria Book" or something. It is our documentation and it will be expanding in the future as well. It's not purely a reference manual.
Jeremy
3. Re: Constructive criticism
- Posted by Critic Mar 05, 2009
- 1220 views
The parts that should be kept should be moved to or merged with the "yet another..." introduction part 1.1, IMHO.
4. Re: Constructive criticism
- Posted by kinz Mar 05, 2009
- 1198 views
I refer to section 2.3 of the docs: http://openeuphoria.org/docs/eu400_0011.html#_65_EuphoriaversusConventionalLanguages
Nearly every sentence is misleading or wrong or very biased. Please remove the whole section. It has no place in a reference manual, anyway.
Hi Critic,
It seems to me that you are totally wrond on this one.
Remember please, EU was released in July 1993.
It was purelly DOS32 system that time.
And it is multiplatform now.
If you want correctly tell us what is EU now and
compare it with the conventional languages,
you should find yet another language for DOS32 (from 1993),
for WIN32, for Linux, for FreeBSD and for Mac - all in one.
Then I'll listen to you with great interest.
PTSDOS 32, for example, is main OS for Russian atomic,
space and military systems - just now, in 2009.
Open Watcom 1.8 supports DOS as well.
It has separate packages for DOS16+32, WIN16+32, Linux just now.
Regards,
Igor Kachan
kinz@peterlink.ru
5. Re: Constructive criticism
- Posted by Critic Mar 05, 2009
- 1255 views
Lua's first version was released in 1993. Lua is around 21,000 lines of remarkably well written Ansi C, so one ought to be able to compile it on DOS with Watcom.
But I don't know if I got your message right: Even if this part of EU's doc refers to 1993, it should be updated or removed. Personally, I don't see the point of advertising EU in section 2.3 between Language Definition and Declarations.
6. Re: Constructive criticism
- Posted by kinz Mar 05, 2009
- 1247 views
Lua's first version was released in 1993. Lua is around 21,000 lines of remarkably well written Ansi C, so one ought to be able to compile it on DOS with Watcom.
Why do you say just about Lua again? Does Lua look like EU-system for you?
I'd like to hear about some conventional language which has same power
as EU-system.
Do you know something about a DOS32 version of Lua etc etc etc?
But I don't know if I got your message right: Even if this part of EU's doc refers to 1993, it should be updated or removed. Personally, I don't see the point of advertising EU in section 2.3 between Language Definition and Declarations.
This section is good to me and tell user about main features of EU.
And EU has these features from 1993 as commercial product.
But if you like Lua so much,
the http://www.lua.org/versions.html#1.1 doc reads:
Lua 1.1 was released on 08 Jul 1994. This was the first public release of Lua and is described in a conference paper. Lua 1.1 already featured powerful data description constructs, simple syntax, and a bytecode virtual machine. Lua 1.1 was freely available for academic purposes; commercial uses had to be negotiated, but none ever were.
Do you see 1994, not 1993 as you say?
In 1994, Lua didn't have any chance to be a commercial product.
But in 1994, EU was 1 years old commercial product.
So, section 2.3 is good, it is one of the traditional Rob's sections.
Regards,
Igor Kachan
kinz@peterlink.ru
7. Re: Constructive criticism
- Posted by Critic Mar 05, 2009
- 1160 views
Why do you say just about Lua again? Does Lua look like EU-system for you? I'd like to hear about some conventional language which has same power as EU-system. Do you know something about a DOS32 version of Lua etc etc etc?
Does Lua with its tables and automatic memory management and its simple syntax look unlike EU to you? But anyway, if you need a language that supports DOS32, Mac OS X, Linux, Windows, your Playstation or your toaster , Lua is ready. EU is not. It assumes 32bit pointers, for example.
This section is good to me and tell user about main features of EU.
And EU has these features from 1993 as commercial product.
Yes, EU was an awsome product in 1993.
Do you see 1994, not 1993 as you say?
In 1994, Lua didn't have any chance to be a commercial product.
But in 1994, EU was 1 years old commercial product.
Yes, sorry, I was wrong.
So, section 2.3 is good, it is one of the traditional Rob's sections.
<irony> Ok, leave section 2.3 as it is for historical reasons. Because people who read the documentation are more likely to be historians than programmers.</irony>
8. Re: Constructive criticism
- Posted by CChris Mar 06, 2009
- 1181 views
But it is totaly outdated. Any knowledgeable programmer will sneer at it, and will have uselessly negative impressions about the language.
IMHO the whole section should be removed. If some part of it has to go in some "history" section, fine. But not inside the manual.
CChris
9. Re: Constructive criticism
- Posted by MikeManturov Mar 06, 2009
- 1158 views
I wonder if Critic and CChris are the same person?:)
Anyway, I'd better program then listen such "constructive" criticism anymore.
10. Re: Constructive criticism
- Posted by kinz Mar 06, 2009
- 1142 views
But it is totaly outdated. Any knowledgeable programmer will sneer at it, and will have uselessly negative impressions about the language.
IMHO the whole section should be removed. If some part of it has to go in some "history" section, fine. But not inside the manual.
CChris
Hi CChris,
I think you are talking about that 2.3 section, yes?
Let's inspect it literally, which statement is outdated or wrong.
Maybe, such an inspection will be useful for some new
"history" section, as you say.
Explain please, what was wrong in 1993 or is outdated now:
"By basing Euphoria on this one, simple, general, recursive data structure, a tremendous amount of the complexity normally found in programming languages has been avoided. The arrays, structures, unions, arrays of records, multidimensional arrays, etc. of other languages can all be easily represented in Euphoria with sequences. So can higher-level structures such as lists, stacks, queues, trees etc.
Furthermore, in Euphoria you can have sequences of mixed type; you can assign any object to an element of a sequence; and sequences easily grow or shrink in length without your having to worry about storage allocation issues. The exact layout of a data structure does not have to be declared in advance, and can change dynamically as required. It is easy to write generic code, where, for instance, you push or pop a mix of various kinds of data objects using a single stack. Making a flexible list that contains a variety of different kinds of data objects is trivial in Euphoria, but requires dozens of lines of ugly code in other languages.
Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them.
Programming in Euphoria is based entirely on creating and manipulating flexible, dynamic sequences of data. Sequences are it - there are no other data structures to learn. You operate in a simple, safe, elastic world of values, that is far removed from the rigid, tedious, dangerous world of bits, bytes, pointers and machine crashes.
Unlike other languages such as LISP and Smalltalk, Euphoria's "garbage collection" of unused storage is a continuous process that never causes random delays in execution of a program, and does not pre-allocate huge regions of memory.
The language definitions of conventional languages such as C, C, Ada, etc. are very complex. Most programmers become fluent in only a subset of the language. The ANSI standards for these languages read like complex legal documents.
You are forced to write different code for different data types simply to copy the data, ask for its current length, concatenate it, compare it etc. The manuals for those languages are packed with routines such as "strcpy", "strncpy", "memcpy", "strcat", "strlen", "strcmp", "memcmp", etc. that each only work on one of the many types of data.
Much of the complexity surrounds issues of data type. How do you define new types? Which types of data can be mixed? How do you convert one type into another in a way that will keep the compiler happy? When you need to do something requiring flexibility at run-time, you frequently find yourself trying to fake out the compiler.
In these languages the numeric value 4 (for example) can have a different meaning depending on whether it is an int, a char, a short, a double, an int * etc. In Euphoria, 4 is the atom 4, period. Euphoria has something called types as we shall see later, but it is a much simpler concept.
Issues of dynamic storage allocation and deallocation consume a great deal of programmer coding time and debugging time in these other languages, and make the resulting programs much harder to understand. Programs that must run continuously often exhibit storage "leaks", since it takes a great deal of discipline to safely and properly free all blocks of storage once they are no longer needed.
Pointer variables are extensively used. The pointer has been called the "go to" of data structures. It forces programmers to think of data as being bound to a fixed memory location where it can be manipulated in all sorts of low-level, non-portable, tricky ways. A picture of the actual hardware that your program will run on is never far from your mind. Euphoria does not have pointers and does not need them."
Regards,
Igor Kachan
kinz@peterlink.ru
11. Re: Constructive criticism
- Posted by Critic Mar 06, 2009
- 1155 views
Here we go again...
"By basing Euphoria on this one, simple, general, recursive data structure, a tremendous amount of the complexity normally found in programming languages has been avoided. The arrays, structures, unions, arrays of records, multidimensional arrays, etc. of other languages can all be easily represented in Euphoria with sequences. So can higher-level structures such as lists, stacks, queues, trees etc."
Well, general graphs cannot be easily represented in EU with sequences, IMHO. But since it does not mention graphs explicitely, I can live with the paragraph.
"Furthermore, in Euphoria you can have sequences of mixed type; you can assign any object to an element of a sequence; and sequences easily grow or shrink in length without your having to worry about storage allocation issues. The exact layout of a data structure does not have to be declared in advance, and can change dynamically as required. It is easy to write generic code, where, for instance, you push or pop a mix of various kinds of data objects using a single stack."
Lack of pass by reference makes a stack harder to write...
"Making a flexible list that contains a variety of different kinds of data objects is trivial in Euphoria, but requires dozens of lines of ugly code in other languages."
Well, it is easy in JavaScript, Python, Lua, Lisp, Smalltalk, etc. The thing is called dynamic typing. Many languages have it nowadays. - Outdated.
"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them."
Copy-on-write does not avoid all copies. - Misleading.
"Programming in Euphoria is based entirely on creating and manipulating flexible, dynamic sequences of data. Sequences are it - there are no other data structures to learn. You operate in a simple, safe, elastic world of values, that is far removed from the rigid, tedious, dangerous world of bits, bytes, pointers and machine crashes."
True - if you do not interface with external libraries. - Misleading.
"Unlike other languages such as LISP and Smalltalk, Euphoria's "garbage collection" of unused storage is a continuous process that never causes random delays in execution of a program, and does not pre-allocate huge regions of memory."
Outdated - LIPS and Smalltalk have better GCs nowadays. Use Java as an example. One needs to tell JVM how much memory the program is going to use.
"The language definitions of conventional languages such as C, C, Ada, etc. are very complex. Most programmers become fluent in only a subset of the language. The ANSI standards for these languages read like complex legal documents."
That suggests that one learns a language by reading an ANSI standard. - Misleading.
"You are forced to write different code for different data types simply to copy the data, ask for its current length, concatenate it, compare it etc. The manuals for those languages are packed with routines such as "strcpy", "strncpy", "memcpy", "strcat", "strlen", "strcmp", "memcmp", etc. that each only work on one of the many types of data."
That refers to C only. EU has a similar problem with "equal" vs. "=". - Misleading.
Much of the complexity surrounds issues of data type. How do you define new types? Which types of data can be mixed? How do you convert one type into another in a way that will keep the compiler happy? When you need to do something requiring flexibility at run-time, you frequently find yourself trying to fake out the compiler.
Maybe for C or some other statically typed languages. - Misleading.
In these languages the numeric value 4 (for example) can have a different meaning depending on whether it is an int, a char, a short, a double, an int * etc. In Euphoria, 4 is the atom 4, period. Euphoria has something called types as we shall see later, but it is a much simpler concept.
Well, 4 never is an "int*" and never was - even in 1993. - Wrong.
Issues of dynamic storage allocation and deallocation consume a great deal of programmer coding time and debugging time in these other languages, and make the resulting programs much harder to understand. Programs that must run continuously often exhibit storage "leaks", since it takes a great deal of discipline to safely and properly free all blocks of storage once they are no longer needed.
The thing is called garbage collection and most languages have it nowadays. And Smalltalk and Lisp definitely had it in 1993. - Wrong, outdated and misleading.
Pointer variables are extensively used. The pointer has been called the "go to" of data structures. It forces programmers to think of data as being bound to a fixed memory location where it can be manipulated in all sorts of low-level, non-portable, tricky ways.
Well, that is exactly what EU's implementation does: If yout cast pointers to integers and store your type information in the lowest bits in the pointer, you violate ANSI C. But it does not follow that this is generally needed when programming in C.
"A picture of the actual hardware that your program will run on is never far from your mind. Euphoria does not have pointers and does not need them."
Well, for cyclic object structures, you have to work around the lack of references and pointers by using an index. So arguably, EU needs them just like any other programming language.
12. Re: Constructive criticism
- Posted by jimcbrown (admin) Mar 06, 2009
- 1151 views
Here we go again...
"By basing Euphoria on this one, simple, general, recursive data structure, a tremendous amount of the complexity normally found in programming languages has been avoided. The arrays, structures, unions, arrays of records, multidimensional arrays, etc. of other languages can all be easily represented in Euphoria with sequences. So can higher-level structures such as lists, stacks, queues, trees etc."
Well, general graphs cannot be easily represented in EU with sequences, IMHO. But since it does not mention graphs explicitely, I can live with the paragraph.
I have to agree with you here. It is possible, but it isn't intuitive, and argubly is rather ugly.
OTOH, you could always use allocate() and free() and peek4s() and poke4() and use pointers - then your graphs are also readable from C.
"Furthermore, in Euphoria you can have sequences of mixed type; you can assign any object to an element of a sequence; and sequences easily grow or shrink in length without your having to worry about storage allocation issues. The exact layout of a data structure does not have to be declared in advance, and can change dynamically as required. It is easy to write generic code, where, for instance, you push or pop a mix of various kinds of data objects using a single stack."
Lack of pass by reference makes a stack harder to write...
Hmm. I've never used PBR to write a stack, so I'll have to take your word for this.
"Making a flexible list that contains a variety of different kinds of data objects is trivial in Euphoria, but requires dozens of lines of ugly code in other languages."
Well, it is easy in JavaScript, Python, Lua, Lisp, Smalltalk, etc. The thing is called dynamic typing. Many languages have it nowadays. - Outdated.
Concurred.
"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them."
Copy-on-write does not avoid all copies. - Misleading.
As a native english speaker, I don't see much difference between the above and this:
"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them whenever possible."
"Programming in Euphoria is based entirely on creating and manipulating flexible, dynamic sequences of data. Sequences are it - there are no other data structures to learn. You operate in a simple, safe, elastic world of values, that is far removed from the rigid, tedious, dangerous world of bits, bytes, pointers and machine crashes."
True - if you do not interface with external libraries. - Misleading.
The standard library provides plently of routines that safely handle this. (See safe.e)
Even when we do crash due to external libraries, Eu is usually able to tell you that the crash occurred outside of your euphoria code, and what line of that code made the call to the external library.
"Unlike other languages such as LISP and Smalltalk, Euphoria's "garbage collection" of unused storage is a continuous process that never causes random delays in execution of a program, and does not pre-allocate huge regions of memory."
Outdated - LIPS and Smalltalk have better GCs nowadays. Use Java as an example. One needs to tell JVM how much memory the program is going to use.
Concurred. I've personally had experience (and many headaches) with GC issues in Java.
"The language definitions of conventional languages such as C, C, Ada, etc. are very complex. Most programmers become fluent in only a subset of the language. The ANSI standards for these languages read like complex legal documents."
That suggests that one learns a language by reading an ANSI standard. - Misleading.
I disagree. It states that most programmers become fluent in only a subset...
With the expanded language of 4.0, this section becomes misleading. But I think it is accurate as of 3.1.1
"You are forced to write different code for different data types simply to copy the data, ask for its current length, concatenate it, compare it etc. The manuals for those languages are packed with routines such as "strcpy", "strncpy", "memcpy", "strcat", "strlen", "strcmp", "memcmp", etc. that each only work on one of the many types of data."
That refers to C only. EU has a similar problem with "equal" vs. "=". - Misleading.
I agree with the first part (C only) but disagree with the second (as equal() works with everything).
Much of the complexity surrounds issues of data type. How do you define new types? Which types of data can be mixed? How do you convert one type into another in a way that will keep the compiler happy? When you need to do something requiring flexibility at run-time, you frequently find yourself trying to fake out the compiler.
Maybe for C or some other statically typed languages. - Misleading.
I agree that this paragraph seems to target C.
In these languages the numeric value 4 (for example) can have a different meaning depending on whether it is an int, a char, a short, a double, an int * etc. In Euphoria, 4 is the atom 4, period. Euphoria has something called types as we shall see later, but it is a much simpler concept.
Well, 4 never is an "int*" and never was - even in 1993. - Wrong.
Back in 1993, the i386 was only a few years old. Many programs were still 16bit. Back then, an int* with a value of 4 could point to a valid memory location. (Today, if you are writing OS code on the x86, it is still possible to use (int*)4 as a valid pointer.)
It is bad practice, but this is a valid operation. DOS apps written in C still use this method to access video memory.
Issues of dynamic storage allocation and deallocation consume a great deal of programmer coding time and debugging time in these other languages, and make the resulting programs much harder to understand. Programs that must run continuously often exhibit storage "leaks", since it takes a great deal of discipline to safely and properly free all blocks of storage once they are no longer needed.
The thing is called garbage collection and most languages have it nowadays. And Smalltalk and Lisp definitely had it in 1993. - Wrong, outdated and misleading.
I can't say for sure, but I'd reckon that Lisp's good GC came after 1993. (As Matt Lewis pointed out, earlier versions of Lisp did not have a perfect GC.) As I've personally experienced a situation where Java's GC lead to a memory leak (and eventually a server crash due to OOM), and that this occured in 2008, I don't see this as outdated, wrong, or misleading.
Pointer variables are extensively used. The pointer has been called the "go to" of data structures. It forces programmers to think of data as being bound to a fixed memory location where it can be manipulated in all sorts of low-level, non-portable, tricky ways.
Well, that is exactly what EU's implementation does:
Irrelevant. Who cares? The average EU programmer doesn't deal with EU's implementation of native EU datatypes.
If yout cast pointers to integers and store your type information in the lowest bits in the pointer, you violate ANSI C. But it does not follow that this is generally needed when programming in C.
This is correct. However, it doesn't account for the number of times that programmers (even experienced ones) end up shooting themselves in the foot because of accidental pointer misuse.
"A picture of the actual hardware that your program will run on is never far from your mind. Euphoria does not have pointers and does not need them."
Well, for cyclic object structures, you have to work around the lack of references and pointers by using an index. So arguably, EU needs them just like any other programming language.
Why does EU need cyclic object structures?
(EU already has a way to create and use pointers that are compatible with C, can simulate pointers in an ugly manner using indices, and 4.1 will probably have pass-by-reference - which, like Java, will not require the use of explicit pointers.)
13. Re: Constructive criticism
- Posted by Mike Mar 06, 2009
- 1144 views
The thing is, it's so easy to criticise, by merely choosing a suitable frame of reference. Nevertheless some of Critic's points are valid in my opinion. The "Unique Selling Points" of Eu in the early 90's are no longer so unique. In fact you could argue that Rob's frame of reference at the time the manual was written was static languages like C, but these days features like garbage collection and dynamic typing are standard in scripting languages, which does tend to weaken the "selling points" given in the manual.
The attractions of Eu for me are the simplicity and elegance of the syntax, its speed and low-level access, and the safety/debugging features. I guess it comes down to a subjective choice in the end. Some of the points raised by Critic seem rather contrived though - it's usually the case that there are workarounds for any particular feature that isn't present in a language, it depends on what kind of coding you're doing whether the lack of x or y is going to give you a headache, and I do wonder whether critic hasn't got too much time on his hands.
14. Re: Constructive criticism
- Posted by kinz Mar 07, 2009
- 1167 views
Here we go again...
"By basing Euphoria on this one, simple, general, recursive data structure, a tremendous amount of the complexity normally found in programming languages has been avoided. The arrays, structures, unions, arrays of records, multidimensional arrays, etc. of other languages can all be easily represented in Euphoria with sequences. So can higher-level structures such as lists, stacks, queues, trees etc."
Well, general graphs cannot be easily represented in EU with sequences, IMHO. But since it does not mention graphs explicitely, I can live with the paragraph.
OK, so 2.3 section is not totally outdated or wrong already. Good.
Try please this to be sure:
http://www.algorithmic-solutions.info/leda_guide/graph_algorithms/maxcard_matching.html
"Furthermore, in Euphoria you can have sequences of mixed type; you can assign any object to an element of a sequence; and sequences easily grow or shrink in length without your having to worry about storage allocation issues. The exact layout of a data structure does not have to be declared in advance, and can change dynamically as required. It is easy to write generic code, where, for instance, you push or pop a mix of various kinds of data objects using a single stack."
Lack of pass by reference makes a stack harder to write...
OK, so 2.3 section is not totally outdated or wrong twice. Very good.
Ask the EU community for the code of a stack you need.
"Making a flexible list that contains a variety of different kinds of data objects is trivial in Euphoria, but requires dozens of lines of ugly code in other languages."
Well, it is easy in JavaScript, Python, Lua, Lisp, Smalltalk, etc. The thing is called dynamic typing. Many languages have it nowadays. - Outdated.
But "trivial" and "easy" are different things. Then, "1993" and "nowadays" are different things too. Then, many languages still do not have this feature nowadays. Then, this feature itself can not be outdated at all, it is very useful feature, and EU is one of the very first languages with trivial using of this feature.
So, 2.3 section is not outdated or wrong here and never will.
"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them."
Copy-on-write does not avoid all copies. - Misleading.
OK, but "large data objects" is not "all" objects, so just read please the docs carefully to avoid just yours mistake.
So, 2.3 section is not Misleading here and never will.
"Programming in Euphoria is based entirely on creating and manipulating flexible, dynamic sequences of data. Sequences are it - there are no other data structures to learn. You operate in a simple, safe, elastic world of values, that is far removed from the rigid, tedious, dangerous world of bits, bytes, pointers and machine crashes."
True - if you do not interface with external libraries. - Misleading.
So, 2.3 section is not outdated or wrong here. Then, external libraries (of .dll form) are just from that "dangerous world of bits, bytes, pointers and machine crashes". Just avoid them, read please the docs carefully to avoid just yours mistake.
So, 2.3 section is not Misleading here and never will.
"Unlike other languages such as LISP and Smalltalk, Euphoria's "garbage collection" of unused storage is a continuous process that never causes random delays in execution of a program, and does not pre-allocate huge regions of memory."
Outdated - LIPS and Smalltalk have better GCs nowadays. Use Java as an example. One needs to tell JVM how much memory the program is going to use.
Sorry, LISP and Smalltalk families, both, consist of dozens of different versions, implementations, variants and packages. Give us, please, one LISP and one Smalltalk for DOS32, WIN32, Linux, FreeBSD, OSX to see if their GCs were and are so good as in EU from 1993 to nowadays.
Not sure?
So, 2.3 section is not outdated and never will.
"The language definitions of conventional languages such as C, C, Ada, etc. are very complex. Most programmers become fluent in only a subset of the language. The ANSI standards for these languages read like complex legal documents."
That suggests that one learns a language by reading an ANSI standard. - Misleading.
I do not see any suggestion here. It seems to be just yours mistake again.
So, 2.3 section is not Misleading here and never will.
"You are forced to write different code for different data types simply to copy the data, ask for its current length, concatenate it, compare it etc. The manuals for those languages are packed with routines such as "strcpy", "strncpy", "memcpy", "strcat", "strlen", "strcmp", "memcmp", etc. that each only work on one of the many types of data."
That refers to C only. EU has a similar problem with "equal" vs. "=". - Misleading.
To C only? The main language for the system coding is now *only*? There are dozens of different C and similar languages-derivatives.
In EU, anyone can use "equal" instead of "=" to compare atoms, is it
a problem to you?
So, 2.3 section is not outdated or wrong here and never will.
Same about Misleading.
Much of the complexity surrounds issues of data type. How do you define new types? Which types of data can be mixed? How do you convert one type into another in a way that will keep the compiler happy? When you need to do something requiring flexibility at run-time, you frequently find yourself trying to fake out the compiler.
Maybe for C or some other statically typed languages. - Misleading.
Not sure?
Try Basics please for yet another examples.
Just yours mistake.
In these languages the numeric value 4 (for example) can have a different meaning depending on whether it is an int, a char, a short, a double, an int * etc. In Euphoria, 4 is the atom 4, period. Euphoria has something called types as we shall see later, but it is a much simpler concept.
Well, 4 never is an "int*" and never was - even in 1993. - Wrong.
Ok, ok, maybe you are right here, I'm not sure, let's delete the letters
"an int *", just 8 letters, just as typo, just for you.
But you have to explain us why 4 can not to be a pointer.
But the paragraph still is good, not outdated, not wrong, I think.
Issues of dynamic storage allocation and deallocation consume a great deal of programmer coding time and debugging time in these other languages, and make the resulting programs much harder to understand. Programs that must run continuously often exhibit storage "leaks", since it takes a great deal of discipline to safely and properly free all blocks of storage once they are no longer needed.
The thing is called garbage collection and most languages have it nowadays. And Smalltalk and Lisp definitely had it in 1993. - Wrong, outdated and misleading.
Again Smalltalk and Lisp, again nowadays, again 1993 ...
OK, I'll reuse my objections too.
Sorry, LISP and Smalltalk families, both, consist of dozens of different versions, implementations, variants and packages. Give us, please, one LISP and one Smalltalk for DOS32, WIN32, Linux, FreeBSD, OSX to see if their GCs were and are so good as in EU from 1993 to nowadays.
Not sure?
So, 2.3 section is not wrong, outdated and and misleading here.
Pointer variables are extensively used. The pointer has been called the "go to" of data structures. It forces programmers to think of data as being bound to a fixed memory location where it can be manipulated in all sorts of low-level, non-portable, tricky ways.
Well, that is exactly what EU's implementation does: If yout cast pointers to integers and store your type information in the lowest bits in the pointer, you violate ANSI C. But it does not follow that this is generally needed when programming in C.
Ok, 2.3 section is not wrong, outdated and and misleading here.
This section is not about EU's source code at all.
"A picture of the actual hardware that your program will run on is never far from your mind. Euphoria does not have pointers and does not need them."
Well, for cyclic object structures, you have to work around the lack of references and pointers by using an index. So arguably, EU needs them just like any other programming language.
EU is not a language for the system programming, remember please.
Do you see that you seem to be almost totally wrond on 2.3 section, sorry?
EU docs need to be updated, sure, but the existing docs are not wrong,
are not totally outdated as you say, and are not misleading.
Tom hardly and nicely works on docs.
Regards,
Igor Kachan
kinz@peterlink.ru
15. Re: Constructive criticism
- Posted by Critic Mar 07, 2009
- 1119 views
Well, it takes too much time to answer that appropriately. I'm tired. Let me just say that I think you are wrong most of the time (I did not intend to differentiate between "easy" and "trivial", for example).
Section 2.3 remains awful. It throws in C/C/Ada/Smalltalk/Lisp and then goes on to talk about "other languages", but refers to C only most of the time. It reads like a "duper" if that is the right word.
16. Re: Constructive criticism
- Posted by DerekParnell (admin) Mar 07, 2009
- 1153 views
Here we go again...
Please bear with me because I may be misunderstanding you.
You do not seem to want to improve Euphoria nor do you seem to want to use Euphoria, so ( and this is not a rhetorical question) why are you here? What exactly is it that you want?
Well, general graphs cannot be easily represented in EU with sequences, IMHO.
I disagree. Describe a general graph that you feel cannot be implemented in Euphoria and I will attempt to show you it can.
Lack of pass by reference makes a stack harder to write...
I disagree. To prove it to myself, I just wrote a library file that implements stacks and it took me about five minutes to write and debug. I can make it public if you wish to see it.
It is also easy to use...
------ include stack.e include std/pretty.e -- Create two stacks. object s = new() object t = new() -- Push three values, of different types, onto the first stack push(s, 1) --> 1 -- push(s, "two") --> "two", 1 -- push(s, 3.4) --> 3.4, "two", 1 -- -- Play around with the second stack push(t, 100) --> 100 -- dup(t) --> 100, 100 -- push(t, 99) --> 99, 100, 100 -- swap(t) --> 100, 99, 100 -- push(t, 98) --> 98, 100, 99, 100 -- rot(t) --> 100, 99, 98, 100 -- push(t, 97) --> 97, 100, 99, 98, 100 -- rrot(t) --> 99, 97, 100, 98, 100 -- drop (t) --> 97, 100, 98, 100 -- sequence r -- Display all of the first stack for i = 1 to depth(s) do r = pop(s) pretty_print(1, r[1], {2}) puts(1, '\n') end for puts(1, "\n----\n") -- Display all of the second stack for i = 1 to depth(t) do r = pop(t) pretty_print(1, r[1], {2}) puts(1, '\n') end for ------
The output is ...
3.4 "two" 1 ---- 97 100 98 100
"Making a flexible list that contains a variety of different kinds of data objects is trivial in Euphoria, but requires dozens of lines of ugly code in other languages."
Well, it is easy in JavaScript, Python, Lua, Lisp, Smalltalk, etc. The thing is called dynamic typing. Many languages have it nowadays. - Outdated.
Please note that "many" is not the same as "all". In terms of the number of programs that are currently being maintained, I would guess that most are written in languages that do not support dynamic typing. For example, COBOL, Fortran, C, C, Assembler. Of course there are libraries available for each of these that emulate dynamic typing but it is not built into the languages themselves.
Also note that there are many respected programmers that feel that dynamic typing is a sign of poor programming discipline and the source of many bugs.
So, to dismiss Euphoria's claim that it supports dynamic typing as "outdated" seems to demonstrate that maybe the computing world is bigger than you care to admit or know about. But I'm just speculating here.
Additionally, Euphoria also supports static typing. If something is declared as integer then you can only assign integers to it, and likewise with atom and sequence. (NB. Integers are a subset of atoms, that is why you can assign all integers to atoms but not all atoms to integers)
"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them."
Copy-on-write does not avoid all copies. - Misleading.
What is misleading? The statement is true. For example, if you have a 1000-element sequence, and you change the 501st element, a copy of the sequence is not made, just the element is altered. This is what the documentation is referring to.
Copy-on-write is not what is being discussed here in the documentation. For those that maybe unsure of what this is, COW occurs when a sequence is modified and the original sequence is currently referenced by more than one variable. In this case, we take a copy so that the other references maintain an accurate view of the world.
sequence a sequence b sequence c a = "123" -- 'a' points to a literal b = a -- 'b' now points to the same literal c = a -- 'c' now points to the same literal a[1] = '0' -- 'a' is changed, so we take a copy of the -- literal, modify it and get 'a' to point to the new copy. -- This means that 'b' and 'c' still point to the original literal.
Notice that even though we have three sequences declared, in RAM there exists only two sets sequence data. 'a' points to one set, and 'b' and 'c' point to the other. This is efficient.
"Programming in Euphoria is based entirely on creating and manipulating flexible, dynamic sequences of data. Sequences are it - there are no other data structures to learn. You operate in a simple, safe, elastic world of values, that is far removed from the rigid, tedious, dangerous world of bits, bytes, pointers and machine crashes."
True - if you do not interface with external libraries. - Misleading.
What exactly is the misleading part? It is simply saying that if your program is Euphoria, you do not have to work with a multidute of data structures, pointers and complexity, which is a major source of bugs and maintenance costs. This is a true statement. It is not misleading. One has a choice. However, if your program must work with those data structures required by external libraries, you can.
"Unlike other languages such as LISP and Smalltalk, Euphoria's "garbage collection" of unused storage is a continuous process that never causes random delays in execution of a program, and does not pre-allocate huge regions of memory."
Outdated - LIPS and Smalltalk have better GCs nowadays. Use Java as an example. One needs to tell JVM how much memory the program is going to use.
When this was written, both LISP and Smalltalk were relevant comparision languages. Today, one could use other modern languages as examples, such as D. Some modern languages choose to do garbage collection only at specific events (eg. acquiring a new RAM block), during which time they suspend all threads until the GC has completed then resume those threads. This can cause programs to have momentary pauses. This happens with some languages today. Euphoria does a continuous GC so such pauses are not seen.
"The language definitions of conventional languages such as C, C, Ada, etc. are very complex. Most programmers become fluent in only a subset of the language. The ANSI standards for these languages read like complex legal documents."
That suggests that one learns a language by reading an ANSI standard. - Misleading.
How does it suggest that? "Most programmers become fluent in only a subset of the language" is a true statement. Why is that so? Because the full language specification is more complex than the average programmer needs or is prepared to absorb.
The implied point is that Euphoria is not as complex ... and I'm not so sure that is true anymore. Version 4 adds many new things to the language and the full language is not going to be used by the average Euphoria programmer. This simply means that the coder who currently uses v3.1 can still continue to code with that subset of the language.
"You are forced to write different code for different data types simply to copy the data, ask for its current length, concatenate it, compare it etc. The manuals for those languages are packed with routines such as "strcpy", "strncpy", "memcpy", "strcat", "strlen", "strcmp", "memcmp", etc. that each only work on one of the many types of data."
That refers to C only. EU has a similar problem with "equal" vs. "=". - Misleading.
Yes, it refers (mainly) to C. The template feature of C and D, makes it easier to avoid having to write similar functions that differ only in the data types being addressed. This is a side-effect of static typed languages, by the way.
And yes, the equality test is not handled well in Euphoria. We hope to address this in a future release. Currently, if one needs to 'bullet-proof' your tests, you need to use the equal() or compare() function because these operator on any datatype. The "=" operator does not work for sequences as an equality test.
Much of the complexity surrounds issues of data type. How do you define new types? Which types of data can be mixed? How do you convert one type into another in a way that will keep the compiler happy? When you need to do something requiring flexibility at run-time, you frequently find yourself trying to fake out the compiler.
Maybe for C or some other statically typed languages. - Misleading.
How is this misleading? Yes it is referring to static typed languages, which are still the ones most maintained in the world. It is a relevant statement.
In these languages the numeric value 4 (for example) can have a different meaning depending on whether it is an int, a char, a short, a double, an int * etc. In Euphoria, 4 is the atom 4, period. Euphoria has something called types as we shall see later, but it is a much simpler concept.
Well, 4 never is an "int*" and never was - even in 1993. - Wrong.
You are wrong. Take for example the AmigaDOS operating system. The value at RAM address 0x0000004 is the only predefined value in the system. So the numeric value 4 could actually mean an RAM address.
Issues of dynamic storage allocation and deallocation consume a great deal of programmer coding time and debugging time in these other languages, and make the resulting programs much harder to understand. Programs that must run continuously often exhibit storage "leaks", since it takes a great deal of discipline to safely and properly free all blocks of storage once they are no longer needed.
The thing is called garbage collection and most languages have it nowadays. And Smalltalk and Lisp definitely had it in 1993. - Wrong, outdated and misleading.
As it turns out, most used languages do not have a built-in Garbage Collector. COBOL, Fortran, C, Pacal, and Ada do not have one. Most interpreted scripting languages do have one and a few true compiled languages (eg. D) also have one.
The documentation is still relevant. It is neither wrong, outdated or misleading.
Pointer variables are extensively used. The pointer has been called the "go to" of data structures. It forces programmers to think of data as being bound to a fixed memory location where it can be manipulated in all sorts of low-level, non-portable, tricky ways.
Well, that is exactly what EU's implementation does: If yout cast pointers to integers and store your type information in the lowest bits in the pointer, you violate ANSI C. But it does not follow that this is generally needed when programming in C.
Why is the implemention of Euphoria being compared to the use of Euphoria? Of course the implementation uses pointers - it is written in C. Actually only part of the implementation is in C, a lot of Euphoria is actually written in Euphoria. This is the very point that the documentation is getting at. A coder using Euphoria does not have to think of memory addresses (pointers) and other RAM-Mapped structures because all that has been taken care of for you by the implementation (under-the-hood).
And I do not believe that storing data in a pointer is an ANSI C violation. Can you direct me to the relevant document from which you got that information from? I'm willing to be corrected. What the Euphoria backend is doing is using 29-bit pointers, being stored in a 32-bit object. As every RAM address used in the backend is aligned to an 8-byte boundry the rightmost 3 bits an address are always zeros. So the backend shifts the address right 3 bits leaving 29 bits containing the 'address' value. When this is stored in a 32-bit object, it leaves the leftmost 3 bits available for the backend to use. This is efficient.
"A picture of the actual hardware that your program will run on is never far from your mind. Euphoria does not have pointers and does not need them."
Well, for cyclic object structures, you have to work around the lack of references and pointers by using an index. So arguably, EU needs them just like any other programming language.
Needs what? Pointers? The documention only talks about pointers. Euphoria does not need pointers, that is a fact. It can use pointers, but does not need them. I think your argument here is misguided or disingenuous.
However, indexes as references are a different matter. As you are well aware, an index is not a RAM address (pointer / reference) so there is a significant difference right there. A sequence can be used to emulate RAM access, but there is a huge difference. Pointers only address single bytes, any bytes after the first byte pointed to must only be used in accordance to the data structure assumed to be there. Of course, with sequences, each 'location' can be used to store anything, not just single bytes. This leads to being able to store complex data structures in a simple manner, including cyclic objects.
So why are you here? Are you here to help Euphoria or something else?
On one thing I think we agree; that this section in the manual need's its language and focus updated.
17. Re: Constructive criticism
- Posted by SDPringle Mar 07, 2009
- 1102 views
How did you get <eucode>push( s, 1 ) </eucode> to work? When did you add pass-by-reference?
I think EUPHORIA's sequences are simple enough not to need stack routines. How about append() and <eucode>t = s[$] s = s[1..$-1]</eucode>.
Shawn Pringle
18. Re: Constructive criticism
- Posted by DerekParnell (admin) Mar 07, 2009
- 1102 views
How did you get push( s, 1 ) to work? When did you add pass-by-reference?
Pass-by-reference has not been added and is not needed for this implementation.
I think EUPHORIA's sequences are simple enough not to need stack routines. How about append() and t = s[$] s = s[1..$-1].
You are probably right, but push(s, x) and pop(s) are easy and you don't have to remember if the 'top-of-the-stack' is the first or the last item in the sequence.
The implementation is really very straight forward ...
include std/error.e /* private */ sequence stacks = {} /* private */ procedure validate(integer stack) if stack < 1 or stack > length(stacks) then crash("The stack identifier '%d' is invalid", stack) end if end procedure public function new() integer n n = find(0, stacks) if n != 0 then stacks[n] = {} return n end if stacks = append(stacks, {}) return length(stacks) end function public procedure delete(integer stack) validate(stack) stacks[stack] = 0 end procedure public procedure push(integer stack, object item) validate(stack) stacks[stack] = append(stacks[stack], item) end procedure public function pop(integer stack) object temp = {} validate(stack) if length(stacks[stack]) > 0 then temp = {stacks[stack][$]} stacks[stack] = stacks[stack][1 .. $-1] end if return temp end function public function depth(integer stack) validate(stack) return length(stacks[stack]) end function public procedure dup(integer stack) validate(stack) if length(stacks[stack]) > 0 then stacks[stack] = append(stacks[stack], stacks[stack][$]) end if end procedure public procedure drop(integer stack) validate(stack) if length(stacks[stack]) > 0 then stacks[stack] = stacks[stack][1 .. $-1] end if end procedure public procedure swap(integer stack) object temp validate(stack) if length(stacks[stack]) > 1 then temp = stacks[stack][$] stacks[stack][$] = stacks[stack][$-1] stacks[stack][$-1] = temp end if end procedure public procedure rot(integer stack) object temp validate(stack) if length(stacks[stack]) > 2 then temp = stacks[stack][$] stacks[stack][$] = stacks[stack][$-1] stacks[stack][$-1] = stacks[stack][$-2] stacks[stack][$-2] = temp end if end procedure public procedure rrot(integer stack) object temp validate(stack) if length(stacks[stack]) > 2 then temp = stacks[stack][$-2] stacks[stack][$-2] = stacks[stack][$-1] stacks[stack][$-1] = stacks[stack][$] stacks[stack][$] = temp end if end procedure
And with the v4.0's inlining action, most of these small function calls are actually inlined, which removes the calling overheads.
19. Re: Constructive criticism
- Posted by Critic Mar 07, 2009
- 1099 views
Please bear with me because I may be misunderstanding you.
Yes, you are, in almost every point I make, but I am sorry I am tired. There seem to be people who got what I refer to and what I have in mind, perhaps someone other can explain.
You do not seem to want to improve Euphoria nor do you seem to want to use Euphoria, so (and this is not a rhetorical question) why are you here? What exactly is it that you want?
Well then ask yourself: Why should I waste my time here criticising the parts of the documentation I mind in detail? Maybe because I want them to be improved? Maybe because I do want to help? Does that make any sense to you? It does to me.
But OK, you all love section 2.3 and I have no valid points whatsoever, so go ahead and keep it. I still think it's a dumper and misleading on purpose.
Now to the other points: In contrast to you, I treat you as a competent guy. So I assume you already know the problems in your stack implementation and the problems of COW in EU and the problems of EU's implementation.
20. Re: Constructive criticism
- Posted by DerekParnell (admin) Mar 07, 2009
- 1108 views
Please bear with me because I may be misunderstanding you.
Yes, you are, in almost every point I make, but I am sorry I am tired. There seem to be people who got what I refer to and what I have in mind, perhaps someone other can explain.
I hope so. Your posts seem to be plain enough and I didn't think I actually was misunderstanding you, so I would like to be enlightened.
You do not seem to want to improve Euphoria nor do you seem to want to use Euphoria, so (and this is not a rhetorical question) why are you here? What exactly is it that you want?
Well then ask yourself: Why should I waste my time here criticising the parts of the documentation I mind in detail? Maybe because I want them to be improved? Maybe because I do want to help? Does that make any sense to you? It does to me.
There are some "maybes" there and that is the problem. Maybe you do - maybe you don't. I don't know you at all except from these few posts of yours, and so far all I could see is "troll". I'm glad I'm wrong. I have come across people who argue about anything and tear down things with destructive criticism, just because they get a buzz from doing so. I was hoping you were not in that camp. I'll assume from now that you really are trying to be helpful and will listen closely to what you are saying. All I ask in return is that you also listen.
But OK, you all love section 2.3 and I have no valid points whatsoever, so go ahead and keep it. I still think it's a dumper and misleading on purpose.
You are being irrational and melodramatic. You have already said that some people "got" what you were saying, and I even said that I agree that the section needs updating. You have made some valid points. You have also made some incorrect ones too.
Now to the other points: In contrast to you, I treat you as a competent guy. So I assume you already know the problems in your stack implementation and the problems of COW in EU and the problems of EU's implementation.
Sorry that you feel I'm not treating you as a competent person. Is that because I don't agree with most of what you have said so far?
And no, I am not aware of the problems in that stack implementation. Can you please educate me so that I can improve? That goes also for the COW problems in Euphoria and the implementation problems in Euphoria. I cannot read your mind so I need to see what it is you are thinking. Concrete examples would be good.
21. Re: Constructive criticism
- Posted by Critic Mar 08, 2009
- 1069 views
Your example is quite typical EU code:
- Relies on a global variable (I refer to lifetime here, not visibility!) "stacks", because of lack of PBR - Because of this a "delete" operation is needed that the user code needs to call when done with a stack; otherwise the result is a memory leak! This should be totally unnecessary in a language with GC because the stack is cleary not an external resource.
- Common subexpression elimination is impossible to do efficiently in EU. Lets try with this code:
public procedure rot(integer stack) object temp validate(stack) if length(stacks[stack]) > 2 then temp = stacks[stack][$] stacks[stack][$] = stacks[stack][$-1] stacks[stack][$-1] = stacks[stack][$-2] stacks[stack][$-2] = temp end if end procedure
Hm, it sucks to refer to "stacks[stack]" all the time, but avoiding this introduces unnecessary sequence copies:
public procedure rot(integer stack) object temp validate(stack) object s = stacks[stack] -- we do not copy here: COW if length(s) > 2 then temp = s[$] s[$] = s[$-1] -- Ooops: here s is copied completely! s[$-1] = s[$-2] s[$-2] = temp stacks[stack] = s -- COW end if end procedure
So an optimization that appears in the manual (!) makes the algorithm O(n) instead of O(1). Ah, the "efficiency" and "elegance" of Euphoria.
22. Re: Constructive criticism
- Posted by jeremy (admin) Mar 08, 2009
- 1078 views
Critic, have you used Euphoria before? For any sizable application? I am just curious.
Jeremy
23. Re: Constructive criticism
- Posted by jimcbrown (admin) Mar 08, 2009
- 1055 views
- Last edited Mar 09, 2009
Your example is quite typical EU code:
- Relies on a global variable (I refer to lifetime here, not visibility!) "stacks", because of lack of PBR
This is really a matter of style. (Although I agree that PBR would be nice to have in any case.)
- Because of this a "delete" operation is needed that the user code needs to call when done with a stack; otherwise the result is a memory leak! This should be totally unnecessary in a language with GC because the stack is cleary not an external resource.
Agreed. A generic solution to this is still being discussed for 4.0 - this has turned into a huge problem in 4.0
- Common subexpression elimination is impossible to do efficiently in EU. Lets try with this code:
public procedure rot(integer stack) object temp validate(stack) if length(stacks[stack]) > 2 then temp = stacks[stack][$] stacks[stack][$] = stacks[stack][$-1] stacks[stack][$-1] = stacks[stack][$-2] stacks[stack][$-2] = temp end if end procedure
Hm, it sucks to refer to "stacks[stack]" all the time,
Hmm, you would prefer:
#define STACKS stacks[stack]
?
[quote Critic] but avoiding this introduces unnecessary sequence copies:
public procedure rot(integer stack) object temp validate(stack) object s = stacks[stack] -- we do not copy here: COW if length(s) > 2 then temp = s[$] s[$] = s[$-1] -- Ooops: here s is copied completely!
[quote Critic]
The parser (the bit of code that turns the euphoria source text into IL, a sort of bytecode) sees that stacks[stack] isn't used again until its completely replaced, which means that its safe to change s without separating the change from stacks[stack]. So it is smart enough to optimize the copy away.
[quote Critic]
s[$-1] = s[$-2] s[$-2] = temp stacks[stack] = s -- COW
[quote Critic]
Say what? I see only an O(1) operation occuring here.
end if end procedure
So an optimization that appears in the manual (!) makes the algorithm O(n) instead of O(1). Ah, the "efficiency" and "elegance" of Euphoria.
Concurred. ;)
24. Re: Constructive criticism
- Posted by Critic Mar 09, 2009
- 1049 views
Hmm, you would prefer:
#define STACKS stacks[stack]
No. Preprocessors are a bad idea for an IDE/debugger and thus for a language.
The parser (... thank you, I know what a parser is ...) sees that stacks[stack] isn't used again until its completely replaced, which means that its safe to change s without separating the change from stacks[stack]. So it is smart enough to optimize the copy away.
Where is this optimization in OpenEU's source code? I cannot find it.
Anyway, call a procedure in between and the optimization becomes invalid, because the procedure may modify "stacks[stack]". The problem here is EU's copy semantics where the programmer intended reference semantics. That's what I meant: EU needs references just like any other language.
s[$-1] = s[$-2] s[$-2] = temp stacks[stack] = s -- COW
Say what? I see only an O(1) operation occuring here.
Me too.
25. Re: Constructive criticism
- Posted by jimcbrown (admin) Mar 09, 2009
- 1034 views
The parser (... thank you, I know what a parser is ...) sees that stacks[stack] isn't used again until its completely replaced, which means that its safe to change s without separating the change from stacks[stack]. So it is smart enough to optimize the copy away.
Where is this optimization in OpenEU's source code? I cannot find it.
I was simply trying to distinguish compile.e and emit.e from parser.e and scanner.e (since both parts are referred to as "the parser").
Anyway, call a procedure in between and the optimization becomes invalid, because the procedure may modify "stacks[stack]".
Correct. A potential optimization might be to follow the procedure through to make sure that it doesn't modify stacks[stack], but I think we're both headed toward the same conclusion: once you've done all the optimizations possible, you hit a situation that you can't optimize away and you need to be able to specifiy whether you intended to make a true independent copy or just a reference.
The problem here is EU's copy semantics where the programmer intended reference semantics. That's what I meant: EU needs references just like any other language.
Agreed.
26. Re: Constructive criticism
- Posted by DerekParnell (admin) Mar 09, 2009
- 1348 views
Your example is quite typical EU code:
Thank you.
- Relies on a global variable (I refer to lifetime here, not visibility!) "stacks", because of lack of PBR
So what? It is owned by the module its in and is private. What exactly is it a problem if this sequence exists for the entire life of the run-time?
- Because of this a "delete" operation is needed that the user code needs to call when done with a stack; otherwise the result is a memory leak! This should be totally unnecessary in a language with GC because the stack is cleary not an external resource.
Yes. This is an issue. We are working on a generic release management solution that will cover that aspect.
On the other hand, using the 'delete' is no more a problem than closing files. We do that without bitching about it. A deleted stack takes up 4-bytes. I can live with that.
- Common subexpression elimination is impossible to do efficiently in EU. Lets try with this code:
public procedure rot(integer stack) object temp validate(stack) if length(stacks[stack]) > 2 then temp = stacks[stack][$] stacks[stack][$] = stacks[stack][$-1] stacks[stack][$-1] = stacks[stack][$-2] stacks[stack][$-2] = temp end if end procedure
Hm, it sucks to refer to "stacks[stack]" all the time, but avoiding this introduces unnecessary sequence copies:
public procedure rot(integer stack) object temp validate(stack) object s = stacks[stack] -- we do not copy here: COW if length(s) > 2 then temp = s[$] s[$] = s[$-1] -- Ooops: here s is copied completely! s[$-1] = s[$-2] s[$-2] = temp stacks[stack] = s -- COW end if end procedure
The first thing to note is that you have reminded me of that optimisation technique. Your version of the routine takes half the time than my original one. Even though you seem to be saying that it should be slower, it is fact much faster.
Secondly, the "common subexpression elimination" problem is of two types. The first is on a purely textual basis. I will be advocating a method of allowing some controlled textual substistutions in future versions of Euphoria. Something along the lines of ...
public procedure rot(integer stack) object temp validate(stack) alias stacks[stack] as s if length(s) > 2 then temp = s[$] s[$] = s[$-1] s[$-1] = s[$-2] s[$-2] = temp end if end procedure
This would "generate" the same code as my original version.
Further more, there is still many more optimisations that we can put into both the interpreter and translator that should allow caching of subexpressions. This would cause such code as above to automatically run as if it was coded more like your version.
And finally, it is anticipated that a 'swap' operator will be available in 4.1 that will further optimise this type of routine.
public procedure rot(integer stack) validate(stack) alias stacks[stack] as s if length(s) > 2 then s[$] <=> s[$-1] s[$-1] <=> s[$-2] end if end procedure
So an optimization that appears in the manual (!) makes the algorithm O(n) instead of O(1). Ah, the "efficiency" and "elegance" of Euphoria.
Try benchmarking it yourself and you will see that this is not so. The suggested optimisation works well.
27. Re: Constructive criticism
- Posted by Critic Mar 09, 2009
- 1046 views
Derek: Sorry I don't like to discuss this further.
Jim: Which file of openEU contains the optimization you mentioned? I am really interested.
28. Re: Constructive criticism
- Posted by jimcbrown (admin) Mar 09, 2009
- 1025 views
Jim: Which file of openEU contains the optimization you mentioned? I am really interested.
I don't know, I haven't messed with that part of the code. You'll need to trace it from Execute() of compile.e to the appropriate emit_op() line.
29. Re: Constructive criticism
- Posted by mattlewis (admin) Mar 09, 2009
- 1313 views
The first thing to note is that you have reminded me of that optimisation technique. Your version of the routine takes half the time than my original one. Even though you seem to be saying that it should be slower, it is fact much faster.
In fact, what happens is that repeated subscripting stacks[stack][$] requires extra references (basically, assignments to temporary variables), and requires more copy on writes. In particular, Derek's code causes two copies, while Critic's causes only one. So there are two savings, in that fewer copies are made, and fewer subscript operations are made.
The difference would be more pronounced with larger stacks.
Matt
30. Re: Constructive criticism
- Posted by mattlewis (admin) Mar 09, 2009
- 1044 views
Anyway, call a procedure in between and the optimization becomes invalid, because the procedure may modify "stacks[stack]".
Correct. A potential optimization might be to follow the procedure through to make sure that it doesn't modify stacks[stack], but I think we're both headed toward the same conclusion: once you've done all the optimizations possible, you hit a situation that you can't optimize away and you need to be able to specifiy whether you intended to make a true independent copy or just a reference.
The inlining code currently does this to see if it needs to assign to a temp to make sure the value isn't modified. A planned optimization to this is to detect when the passed parameter is assigned the result of the function, to make it behave the same as PBR.
Matt
31. Re: Constructive criticism
- Posted by Critic Mar 09, 2009
- 1032 views
In fact, what happens is that repeated subscripting stacks[stack][$] requires extra references (basically, assignments to temporary variables), and requires more copy on writes.
Why? There is no need for this.
32. Re: Constructive criticism
- Posted by mattlewis (admin) Mar 09, 2009
- 1292 views
In fact, what happens is that repeated subscripting stacks[stack][$] requires extra references (basically, assignments to temporary variables), and requires more copy on writes.
Why? There is no need for this.
I think you're right. In fact, this morning, we were just having a discussion about this on the dev list. I was basing this on the translator (since it's easier to see what's going on at that level), and there appear to be some extra reference counts added for the RHS_SUBS opcode.
It seems that sometimes it's necessary, and for others, it is not. In particular, it's not really required for:
if length(stacks[stack]) then
I think that the issue is something like, if it's part of an assign statement, it should be ref'd, but not if it isn't:
if length(stacks[stack]) then -- vs stacks[stack][$] = stacks[stack][$-1]
Matt