1. Constructive criticism

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.

new topic     » topic index » view message » categorize

2. Re: Constructive criticism

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: Constructive criticism

The parts that should be kept should be moved to or merged with the "yet another..." introduction part 1.1, IMHO.

new topic     » goto parent     » topic index » view message » categorize

4. Re: Constructive criticism

Critic said...

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: Constructive criticism

http://www.lua.org/news.html

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.

new topic     » goto parent     » topic index » view message » categorize

6. Re: Constructive criticism

Critic said...

http://www.lua.org/news.html

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?

Critic said...

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

new topic     » goto parent     » topic index » view message » categorize

7. Re: Constructive criticism

kinz said...

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 smile, Lua is ready. EU is not. It assumes 32bit pointers, for example.

kinz said...

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.

kinz said...

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.

kinz said...

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>

new topic     » goto parent     » topic index » view message » categorize

8. Re: Constructive criticism

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

new topic     » goto parent     » topic index » view message » categorize

9. Re: Constructive criticism

I wonder if Critic and CChris are the same person?:)

Anyway, I'd better program then listen such "constructive" criticism anymore.

new topic     » goto parent     » topic index » view message » categorize

10. Re: Constructive criticism

CChris said...

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

new topic     » goto parent     » topic index » view message » categorize

11. Re: Constructive criticism

Here we go again...

EUDOC said...

"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.

EUDOC said...

"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...

EUDOC said...

"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.

EUDOC said...

"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.

EUDOC said...

"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.

EUDOC said...

"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.

EUDOC said...

"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.

EUDOC said...

"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.

EUDOC said...

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.

EUDOC said...

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.

EUDOC said...

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.

EUDOC said...

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.

EUDOC said...

"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.

new topic     » goto parent     » topic index » view message » categorize

12. Re: Constructive criticism

Critic said...

Here we go again...

EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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."

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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

Critic said...
EUDOC said...

"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).

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...

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.

Critic said...
EUDOC said...

"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.)

new topic     » goto parent     » topic index » view message » categorize

13. Re: Constructive criticism

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. smile

new topic     » goto parent     » topic index » view message » categorize

14. Re: Constructive criticism

Critic said...

Here we go again...

EUDOC said...

"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

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

"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

new topic     » goto parent     » topic index » view message » categorize

15. Re: Constructive criticism

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.

new topic     » goto parent     » topic index » view message » categorize

16. Re: Constructive criticism

Critic said...

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?

Critic said...

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.

Critic said...

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 

EUDOC said...

"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."

Critic said...

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)

EUDOC said...

"Data structure manipulations are very efficient since the Euphoria interpreter will point to large data objects rather than copy them."

Critic said...

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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

"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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

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.

Critic said...
EUDOC said...

"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.

new topic     » goto parent     » topic index » view message » categorize

17. Re: Constructive criticism

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

new topic     » goto parent     » topic index » view message » categorize

18. Re: Constructive criticism

SDPringle said...

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.

SDPringle said...

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.

new topic     » goto parent     » topic index » view message » categorize

19. Re: Constructive criticism

DerekParnell said...

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.

DerekParnell said...

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.

new topic     » goto parent     » topic index » view message » categorize

20. Re: Constructive criticism

Critic said...
DerekParnell said...

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.

Critic said...
DerekParnell said...

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.

Critic said...

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.

Critic said...

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.

new topic     » goto parent     » topic index » view message » categorize

21. Re: Constructive criticism

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. smile

new topic     » goto parent     » topic index » view message » categorize

22. Re: Constructive criticism

Critic, have you used Euphoria before? For any sizable application? I am just curious.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

23. Re: Constructive criticism

Critic said...

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.)

Critic said...

- 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

Critic said...

- 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.

Critic said...
    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. smile

Concurred. ;)

new topic     » goto parent     » topic index » view message » categorize

24. Re: Constructive criticism

jimcbrown said...

Hmm, you would prefer:

#define STACKS stacks[stack] 

No. Preprocessors are a bad idea for an IDE/debugger and thus for a language.

jimcbrown said...

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.

jimcbrown said...
        s[$-1] = s[$-2]  
        s[$-2] = temp 
         
        stacks[stack] = s    -- COW 

Say what? I see only an O(1) operation occuring here.

Me too.

new topic     » goto parent     » topic index » view message » categorize

25. Re: Constructive criticism

Critic said...
jimcbrown said...

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").

Critic said...

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.

Critic said...

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.

new topic     » goto parent     » topic index » view message » categorize

26. Re: Constructive criticism

Critic said...

Your example is quite typical EU code:

Thank you.

Critic said...
  • 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?

Critic said...
  • 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.

Critic said...
  • 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  
Critic said...

So an optimization that appears in the manual (!) makes the algorithm O(n) instead of O(1). Ah, the "efficiency" and "elegance" of Euphoria. smile

Try benchmarking it yourself and you will see that this is not so. The suggested optimisation works well.

new topic     » goto parent     » topic index » view message » categorize

27. Re: Constructive criticism

Derek: Sorry I don't like to discuss this further.

Jim: Which file of openEU contains the optimization you mentioned? I am really interested.

new topic     » goto parent     » topic index » view message » categorize

28. Re: Constructive criticism

Critic said...

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.

new topic     » goto parent     » topic index » view message » categorize

29. Re: Constructive criticism

DerekParnell said...

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

new topic     » goto parent     » topic index » view message » categorize

30. Re: Constructive criticism

jimcbrown said...
Critic said...

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

new topic     » goto parent     » topic index » view message » categorize

31. Re: Constructive criticism

mattlewis said...

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.

new topic     » goto parent     » topic index » view message » categorize

32. Re: Constructive criticism

Critic said...
mattlewis said...

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu