You are at liberty to re-distribute this and other files in this package to anyone as you see fit. You may not modify the package contents, sell it, nor claim the work as your own. |
At various stages in this document there are links to sample programs which you can run. Your browser is likely to object and will ask you to approve. Just confirm that it's OK to run them when this happens; after a bit of huffing and puffing the program you picked willrun. In snippets of code in this document core Euphoria keywords are shown in boldface. In html listings they are shown coloured blue. |
This text is about the Euphoria programming language, in particular the version still current as of May 2011, version 3.1. The text is nothing like a full tutorial or specification of the language. I hope only to convey to people who have not used Euphoria and may be looking for a new, different or alternative programming language something of the "flavour" and capability of Euphoria. To play the adjective game rather loosely, the following "adjectives" can be fairly said to apply to Euphoria:
Usable | Intelligible | Easy to learn and use |
Simple functions a structures | Flexible | Good for daily use |
Delightful! |
I will cover only a very limited number of features of Euphoria, perhaps concentrating unfairly on the ones that appeal to me. For a more exhaustive description you really need to consult the very comprehensive documentation that comes with the Euphoria package. As I said, I will be happy if you come away with some feeling for the "flavour" of Euphoria.
I am not a professional IT person. I first ran into Euphoria when it was at version 2.5 (now at 3.1). Before that I had, over a long time, used and tried out a variety of computer languages; a nearly exhaustive list would be MS BASIC, COBOL and FORTRAN IV, PASCAL, C, C++, MS QBasic and MS Visual Basic. These were all in their own ways and making allowance for age, good solid workable programming languages, Of them all the only one I can say I really liked was QBasic, now alas overtaken by the advance of technology. Then one day I purchased a magazine which included a CD disk on which was an installing program for an interpreted computer programming language called Euphoria. I installed it on my creaky computer, had a quick look at the documentation (quite a bit of which did not appeal to me because it was about low-level stuff like memory allocation, bits, bytes and so on, of which I'm not a fan). But amongst the (to me) dross there were flashes of gold, like what it had to say about Euphoria's variable types, about creating your own types. Particularly interesting, even fascinating, was what it had to say about the variable type called a sequence. More about all this later.
Just let me say, that given all this, and my subsequent use of the language, at first just writing simple learner programs, later writing "real" programs that did useful or interesting things, I ended up falling in love with Euphoria. Its style of structuring and data representation is very flexible yet easy to learn and seemed to fit like a glove. After a bit of experience I found it increasingly easy to "think in Euphoria" so that problems to be solved in a projected program could be very quickly outlined and cast into a form that Euphoria could solve.
Computer technology is changing fast -- was it ever not?. Oldies like me will remember the days when, on small computers, MS-DOS was king of the operating systems (OS) on PCs, with CPM and Unix as poor princelings.These OSs' environments were all at first purely textual, with no provision for output of graphics (drawings or pictures) to screen. Later on they acquired a limited ability to put graphics to screen, all except CPM which disappeared from the scene.
From a programmer's point of view the next big innovation was the appearance of operating systems using GUI (Graphical User Interface) screens such as that supplied by MS-Windows.
Euphoria and Windows We are at a point where nearly all programs are going to have to cope with using MS-Windows (or equivalent GUIs under other OSs). Unfortunately there is a sense in which Windows and other GUI systems can be like the "tail that wags the dog", an obstacle to be overcome before you can write your program. Where Euphoria is concerned, the possibilities for using Windows' GUI as of now are:
GUI systems have had a profound effect on programmers and programming. Programs now are constrained by having to use GUIs for output to the screen as well as to printers, which are now all GUI orientated. Programs are also constrained by the fact that GUI OSs are "Event Driven", meaning more or less that a GUI program just sits there staring at you until you do something it can interpret as an event, such as clicking a button or other gizmo. This dramatically changes the style in which programs are written. Similar changes have also taken place in the world of Unix OSs.
When MS-Windows first appeared, Microsoft did not at first take any steps towards abolishing DOS for two reasons
Retention of DOS was achieved by including a DOS Emulator program in Windows to take the place of the missing DOS OS when needed.
But now there are signs that Microsoft is beginning to seriously consider dumping the DOS emulator, and hardware manufacturers are also beginning to follow this lead. For instance, most new computers no longer support the old DOS "full-screen graphics" mode. The move to abolish the DOS Emulator will be a matter of controversy and concern amongst those who have to teach and learn about programming and those people who write programs for professionall reasons (because paradoxically many programs, even Windows programs, still get written and tested in a DOS-like environment).
How does all this effect Euphoria? As of writing, the current release version of Euphoria is 3.1. On its own, Eu 3.1 is a DOS only language, Its capabilities can be upgraded to use GUI by incorporating the packages Win32Lib or EuWinGUI into your programs.
The next release of Euphoria is 4.0.0., still in a state of development. There are many differences from Eu 3.1, and I won't attempt to enumerate them. The overall effect of the changes is integration of Win32Lib more closely as an "official" part of Euphoria (hence a much stronger orientation of the language towards GUI applications), and abandonment of support for DOS graphics. You can still write and run pure DOS programs provided their screen output is textual only.
At this stage I would reccomend that anyone wanting to learn Euphoria should start with Euphoria 3.1. It is very stable (i.e., it has few if any bugs in it, an opinion with which I agree, having never encountered any that could be attributed to it). I now use the EuWinGUI wrapper alongside Euphoria v. 3.1 for programs that need graphics, or that need to be "presentable" on MS-Windows, and pure DOS programs rarely. A pure DOS program can still be handy quick way develop or test a particular piece of code or routine on its own without the bother of using a GUI.
Is Euphoria suitable as an (academic) teaching or learning language? I can not say dogmatically and must leave it to you (a teacher, instructor or learner) to reach your own conclusions after you investigate the language. However I can say that at a basic level, Euphoria 3.1 is easy enough for raw beginners to be able to produce simple functional programs pretty quickly. As they progress they should be able to rapidly master the simple flow-of-control structures in Euphoria 3.1; These are:
|
for index = start-value to
end-value [ by step ] do block-of-statements end do |
|
while condition then block-of-statements end while |
|
if condition-1 then block-of-statements-1 [ elsif condition-2 then block-of-statements-2 elsif ....] [ else block-of-statements-n ] end if |
This list looks excessively short, but can handle all common decision-making
situations Euphoria 4 will extend the list by having two new constructs:
(i) case ... end case and (ii) do ... until.
Other features of Euphoria 3.1 that would be relevant to teachers and learners would include
Of course a lot of other considerations go into decisions about choice of a language for learning or teaching. You will have to make your mind up about these yourself. A bit more about this later. An initial step might be to give Euphoria 3.1 a try out.
What I have to say throughout this document is purely my own opinion about things. I have no connection to the promoters of Euphoria, except as an occasional contributer of items to the Euphoria community web-site. They very likely would disagree with some things I have said (or not said).
So, on with the show ....
The "Hello World" program is synonymous with a beginner's first program or with the first program most programmers might write when trying out an unfamilier language. All the program does is to print the mythical greeting of a new-born to the world, "Hello World", on the screen. It is really impossible to form any serious judgement of a programming language on the strength of its "Hello World" program.
Without more to-do, click on the next link to run a Euphoria's DOS version of this program and then on the link after that to see a listing of the program.
Listing of Hello World (DOS) Program Source Code
Well, I agree, the output of program Hello World (DOS) is not very exciting, just the words "Hello World" printed in the corner of a black window (known as a console in the jargon). Yes, that miserable little window is what the designers of Windows have reduced the former "glory" of DOS full-screen text output to. It is really unsuitable for any sort of professional programming but just about adequate for learning and teaching some basic things about a computer language.
I hope you had a look at the listing too. Two dashes like "--" mark the beginning of a programmer's comment line in a Euphoria program. Comments are put into programs to explain what things are and what is going on as the program executes. Comments are totally ignored by the interpreter (the program that executes the program) There are really only two executable lines in this program, so it is a very short program indeed.
Now for something a bit more ambitious, a program that does much the same thing but this time using the EuWinGUI wrapper with Euphoria (so it's a Windows' program). Try running it and then viewing the program listing:
Listing of Hello World (WIN) Program Source Code
I am sure you will agree that when you run it, this version of "Hello World" is, in its modest way, more like what we are accustomed to seeing on screen when we run a program. Maybe the program window is a bit small, but then how much room do you need to write "Hello World"? So I just made a little window.
If you looked at the program listing you may have been surprised at its length. The fact is that it takes quite a bit of code just to create the window and the button you saw. So much code to produce so little effect!
I've got to admit that of the code in the listing I personally wrote hardly a line. EuWinGUI comes with a little program called the "Designer" which is a modest but powerful IDE (Integrated Design Environment) program specifically for EuWinGUI. An IDE program lets you design a window by selecting the controls you want to appear on your window and moving them around on the window's surface to occupy the position in which you want them. Within reason, you can make the window and its contents any size you want, and can add text to controls that need it (such as "Display Text" or "Quit Program" to buttons that the user will click on when she or he wants to do these things).
When you have the design to your liking you just order the Designer to produce the code for the program. The code produced by the Designer actually does nothing except display the window(s) you create. The Designer also and importantly creates the "Event Loop" in the code it produces, a gateway to the procedures and functions which you will have to write to make the program do whatever it is you want the program to do. You could call the code produced by the Designer a "shell" or raw outline for the program you want to end up with. I have added quite a few comments to the listing, to briefly hint at what components of the code are for. The actual code written is a mixture of "pure Euphoria" and of EuWinGUI commands.
Any programming language worth its salt has variables and Euphoria is no different. The surprising thing is that Euphoria has only three sorts of variable. You might think this limited number of variable types is a disadvantage but it is not -- see the Euphoria documentation for a full description of why this might be so. The limitation certainly makes learning about the variables easier and has the advantage of making you understand better how computers actually represent data in their innards ... namely that, to a computer, everything is just numbers.
The language is quite strict about enforcing its rules about variables. For example:
Euphoria's variable types are:
There is a curious situation relating to the control-variable in a for ... end for loop. We might have a for loop, like this one as a simple example:
for i = 1 to 10
do
? i -- ? is a crude instruction to print the value of
i on screen
end for
I'm sure you can figure out what this loop does. The curious thing is that the control variable, i, must NOT be declared! The i has a very transitory life. It comes into existence only when the loop starts to execute and disappears as soon as the loop ends execution.
The counting variable, i, in a for loop doesn't have to be an integer. For instance I could have written the first line of the loop like this instead:
for i = 0.1 to 1.0
by 0.1 do
? i
end for
Here i would have the characteristics of an atom and would execute the loop 10 times, like the first version of the loop, though what it prints will be different. In a speed-critical program you might try to avoid using the atom form if you could, because an atom used as a counter is slightly slower than an integer used as a counter. Incidentally, the counting variable doesn't have to be named i.; you can name it anything you like within reason.
The reserved words atom, integer and sequence are used to declare the names of variables, as in the following statements:
atom a
integer b, c, d
sequence x, y, z
These key words can also be used to test variables, as in this if statement:
if atom(a) then
puts(1, "a is an atom\n")
elsif integer(a) then
puts(1, "a is an integer\n")
elsif sequence(a) then
puts(1, "a is a sequence\")
end if
This statement judges the variable a not by its declared type but by what the value of its contents are whan the test is done. There are hazards associated with this testing, especially in a multi-condition if statement like this one. But the capability of testing what sort of value a variable holds can be -- well, invaluable!
We never test whether a variable is an object, because the data in every variable in a program will comply with the test and we learn nothing about the variable.
I would like to move on to sequences now and will take this up in the next chapter.
The authors of Euphoria rightly state in their documentation that to master Euphoria you need to master the use and manipulation of sequences. They are not wrong! Sequences have tremendous magic associated with them. They are to Euphoria as lists and arrays are to other languages. Euphoria has a wide selection of commands for working with sequences.
People with experience only of Fortran/Basic like languages languages will at first find sequences a bit alien. People with some familiarity with C or C++ will find some aspects of sequences familiar but may be not others.
As an introduction, run this little program and then read the listing of the program that produced it:
Listing of Seq1.ex Program Source Code
I hope you found that interesting (the result displayed I mean, not the miserable-looking console output screen).
Here we first make use of a standard library pre-written include file, misc.e, which contains amongst other things a function called reverse( ). It sorts the elements in a sequence into the reverse of its starting order.
Use of the '?' command: this, and a more complex procedure called pretty_print() are very useful when you are debugging a program and want a quick look at the data your program is working with or computing. '?' The '?' command will print the numeric value of the variable named, if the variable is numeric and in the case of sequences it will print the structure of the sequences as well as the numbers inside it. What '?' produces is pretty well how the programming language "sees" the sequence.
From the program run you will have noticed, I'm sure, that a sequence can be a set of numbers enclosed inside two braces like so {1,2,3}. A sequence can also be a null (empty) sequence, like so: { }. In fact if you go back and look at the definition of a sequence you will see that a sequence can hold any Euphoria object! Thus a sequence can contain any combination of objects you care to think of, In fact it can be complex to an arbitrary extent, subject only to memory constraints. For example you could have a sequence like this:
sequence arbitrary -- declare a sequence
arbitrary = {1, 2 ,3, {4,5,6, {98, 99, 100} }, 7, 8, 9 } -- create its
contents
Here, the outermost sequence contains: the numbers 1, 2, 3, then a sequence and then 7, 8, 9. The length of the sequence arbitrary is said to be 7 because it contains 7 objects. Individual objects in arbitrary can be referred to using one or more indices (in Euphoria an index is a number enclosed in square braces, like[5]. Given the little bit of code above program might continue with statements like these:
? arbitrary[1] -- this would print the number 1
? arbitrary[2] -- this would print the number 2
? arbitrary[3] -- this would print the number 3
? arbitrary[4] -- this would print the entire inner sequence
? arbitrary[5] -- this would print the number 7
and so on.
The internal sequence contains the numbers 4, 5, 6, followed by an even more internal sequence containing the numbers 98, 99 and 100. Just to show how objects in the internal sequence can be "got at" :
? arbitrary[4][1] -- this would print the number 4
? arbitrary[4][2] -- this would print the number 5
? arbitrary[4][4][1] -- this would print the number 98
So far I have said nothing about text. A general purpose programming language needs to be able to handle text. Let's agree to call a line of text a string. Many other languages have a variable type dedicated to handling strings. To a Euphoria programmer a string is just a simple sequence containing numbers to which he or she can apply any of the language's sequence-handling methods.
To reinforce the point about a simple sequence being capable of representing a list of numbers or a string of text characters, run program Seq2, then look at its listing.
Listing of Seq2.ex Program Source Code
So what is a sequence of numbers and what is a sequence of text is purely a matter of human interpretation in Euphoria. From the language's point of view everything is just numbers. When you write a Euphoria program it is up to you, as the author, to decide where in the program it should treat a simple sequence as representing text and where it should treat it as a sequence of numbers to be dealt with one by one for some other program purpose.
Euphoria has a wide selection of commands for dealing with sequences. Consequently these commands are used to manipulate sequences representing numbers and sequences representing text. Euphoria needs no string-dedicated commands such as Basic's MID$() and LEFT$(). This makes Euphoria simpler, to its advantage.
I once had an employer who remarked somewhat heartlessly, with reference to staff, that "entities must not be replicated without need!". This is as applicable to computer languages and programs as it is to staff; too many commands or program structures that duplicate other commands or structures are at least inefficient and at worst confusing.
For this, we will imagine that you have a simple sequence called a and that your program has assigned it a value like:
a = "Mrs Jane S. Murphy"
Then we could do things like this, using other variables you have declared
Title = a[1..3] -- value will be "Mrs"
Name1 = a[5..8] -- value will be "Jane"
Name2 = a[13..$] -- value will be "Murphy"
The '$' is an allowed shorthand designating the last element in a sequence. Each of these last 3 statements is said to copy a 'slice' of the sequence a. The numbers between the braces [ ] indicate the range of indices from which to take the slice in each case.
These slices have not changed sequence a itself. If we wanted to actually remove, say the "S. " from a we could do so with this statement:
a = a[1..9] & a[13..$]
The '&' symbol means to concatanate the two slices before assigning their value back to a. After this a would have the value
"Mrs Jane Murphy"
If we wanted to find whether the name Jane occurred in this last value we could use an integer p and write the following program line:
p = match("Jane", a)
After doing this we should find that p has the value 5, the position of the J of Jane in a. If a did not contain Jane, the value of p would have been 0 - the match() function returns 0 if it does not find what you are looking for.
Euphoria has other commands for working with sequences. The ones that follow can be used in the construction and development of sequences:
sequence a -- declare
integer b
a = repeat(0, 4) -- a is now {0, 0, 0, 0}
a = append(a, 1) -- add an element valued 1 at
the end of a.
-- a is now {0, 0, 0, 0, 1}.
a = prepend(a, {1,2,3}) -- adds a sequence
valued {1,2,3} to the front of a.
-- a is now { {1, 2, 3}, 0, 0, 0, 0, 1}.
b = length(a) -- b should be the number 6, the
number of elements in a
b = length( a[1] ) -- b should now be 3, the
number of elements in a[1]
b = length( a[2] ) -- *** illegal statement -
can't take the length of a number;
-- the program will halt here with an error message
We'll move on to things about more complex sequences. As mentioned earlier a sequence can be arbitrarily complex. A sequence can contain any sort of euphoria object(s) you like, that is atoms, integers and other sequences. You can develop a sequence into a structure that mirrors the information associated with something in the real world, or in an imaginary world. In this sense a Euphoria sequence somewhat resembles a structure you might create using OOP, - but it has no 'methods' associated with it as it might using OOP.
Of course if you make a sequence too big and too complicated you may very well end up with something you can't get your head around. So, wisely, most Euphoria programmers keep themselves in check and design their sequences so that they have a pattern or some sort of symmetry that makes it easy to understand. For instance, here is a sequence representing the sort of data you might want to collect about a new customer:
constant CUST_ID_FORM =
{ -- prompt -- field-length (# of chars)
{ "Name", 30}, -- for field 1
{ "Address-1", 20}, -- for field 2
{ "Address-2", 20}, -- etc ...
{ "City", 15},
{ "State/County", 20},
{ "Post Code", 4},
{ "Country", 20},
{ "Customer_ID", 7} -- for field 8
}
Some points about this sequence:
This structure amounts to a description of the data you might need to guide a typist who has to provide information about a new customer. The structure is basically information about information; such information is often known as meta-data (data about data). The structure will be used to prompt the typist about what is needed for each field, and what amount of space the typist has for typing the information for the customers' identifications.
Here is a demo program which uses CUST_ID_FORM and its listing:
Data Entry Form (DOS) Program Source Code
That would be quite a good way to get a customer account going. The screen is rather uninteresting, however, and from a programmer's point of view, the programmer has to write several routines to specifically deal with the physical activity of the typist typing. Using a GUI environment most of that is built into the edit-fields supplied by the GUI, saving you, the programmer a lot of work!
sequence A, B -- declare two sequence
A = {1,2,3,4,5} -- give A a value containing some numbers
? A -- let user see A's value -- it
will be {1,2,3,4,5}
B = A * 3 -- B should be {3,6,9,12,15}
? B -- verify that it is
Anyone vaguely acquainted with maths will recognise that this looks very much like what mathematicians call multiplication of a linear vector by a scalar, the vector being {1,2,3,4,5} and the scalar being the 3. The scalar acts on each element in A individually. In this snippet the math operator is ' * ', meaning multiply each element in {1,2,3,4,5} by 3. For operators in this case we could also have used ' + ' (add), ' - ' (subtract) or ' / ' (divide) and the corresponding math operation would have been carried out on the elements in {1,2,3,4,5}.
We can also do another favourite sort of operation for mathematicians, vector addition, subtraction, multiplication and division:
sequence A, B -- declare two sequence
A = {1,2,3,4,5} -- give it a value containing some numbers
? A -- let user see its value -- it
will be {1,2,3,4,5}
B = A * {2,2,2,2,4} -- B should be {2,4,6,8,20}
? B -- verify that it is
In this example each element of A is multiplied by the corresponding element in sequence {2,2,2,2,4}. This sequence must have exactly the same number of elements as has A, and each element must be of the same sort as the elements in A. We could have used operators '+', '-', or '/' instead of the '*' and would have got results appropriate to the operator we used (never forget in the case of division that a division anywhere by zero (0) is not allowed (in maths) and will crash your program (in Euphoria).
What other programming languages call arrays are easily represented in Eophoria:
sequence A
A = { {1,2,3}, {4,5,6}, {7,8,9} }
would represent a square 3 x 3 array. You could emphasize its "squareness" in your code by writing it like this:
A = {
{1,2,3},
{4,5,6},
{7,8,9}
}
which means exactly the same as thing as A = { {1,2,3}, {4,5,6}, {7,8,9} }, but is prettier and clearer (to humans).
A sort of sequence that occurs so often in Euphoria as to have earned an informal name is a polyline. a polyline looks like:
{ {x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}, .... {xn, yn} }
where each {x, y} represents the coordinates of a point in the Cartesian plane. A polyline sequence can be used to represent the points of a thing as simple as a straight line (which only needs 2 points to define it):
{ {1, 1}. {100, 100} } -- defines a straight line from point {1,
1} to point {100, 100}
or, slightly more complex, a rectangle:
{ {1, 1}, {1, 5}, {6, 5}, {6, 1}, {1, 1} }
If you follow these points in order they trace out a rectangle with its bottom left-hand corner at {1, 1}. Although a rectangle has only 4 corners I have included a fifth one, which is the same as the first one, to ensure that any program using the sequence to draw the rectangle would draw each side of the rectangle. A piece of code that would do this would be:
sequence rect rect = { {1, 1}, {1, 5}, {6, 5}, {6,
1}, {1, 1} } -- initial rect
draw_line(BLACK, rect)
This would draw a black rectangle on a DOS graphic screen (if we had one available to us).
The drawing instruction would be a bit more complicated in a EuWinGUI program:
SetPenColor(CL_BLACK) -- select drawing colour for the Pen
SetDrawingMB(mybitmap) -- select the memory bit-map to draw on
-- now draw the rectangle
for i = 1 to length(rect)-1
do
-- this draws each line segment one by one on the bit-map
DrawLine( rect[i][1], rect[i][2], rect[i+1][1], rect[i+1][2] )
end for
-- display the bitmap on a Picture control
SetPic(MyPictureControl, Picture, mybitmap)
You might be curious as to why you might draw on a memory bit-map rather than directly onto the Window's control I have named MyPictureControl, since that control is where the final picture will appear. Well, you can if you like and the drawing will be done on the control instead. A problem with this is that the drawing will be obliterated if for any reason another window should cover it up even briefly. You may have already seen this defect in some programs you have used. By using the bit-map, the control "knows" where the drawing came from and will automatically refresh itself from the bit-map if the drawing on the control gets obliterated. That's not the only reason we use bitmaps; with EuWinGUI you can copy all or part of one bit-map onto all or part of another, very useful and fast in such things as animated graphics.
Back to sequences. An interesting and perhaps curious feature of sequences is that the values inside a sequence are actually objects - by which I mean that a simple assignment statement can utterly change the type of an element in a sequence. For example if we have a sequence like this:
rubbish = { 1.2, "Happy Hikers", 3}
The first element ( rubbish[1] ) is an atom having value 1.2;
the second element ( rubbish[2] ) is a sequence having value "Happy Hikers";
the third element ( rubbish[3] ) is an integer having value 3.
But because each element in rubbish is an object we can write an assignment statement like:
rubbish[2] = 4.6
which will convert rubbish into { 1.2, 4.6, 3}, This is very convenient, but it does mean that you have to be careful where you put stuff when you are using sequences, the interpreter will not notice and warn you if you make a mistake. It perhaps could also be interpreted to mean that to this extent, Euphoria is not a strongly typed language.
No attempt to describe a language would be complete without mention what it has in the way of routines (routine being a blanket word used to cover such program constructs as euphoria's procedure and function).
Routines are like "black boxes" inside which you write code to carry out some particular task. Every time you want your program to do that task all you have to do is "call" the routine.
The form of a euphoria procedure is:
procedure procedure_name( optional_list_of_parameters )
-- You would usually write 1 or more comments here descrbing what the procedure does
-- declare variables that are local to this procedure here
-- write the the code that does the procedure's task here
end procedure -- this marks the end of the procedure
procedure_name would be whatever name you decided to give your procedure. The two braces ( ) are known as the procedure's parameter-list. The optional_list_of_parameters can contain information that your procedure needs to do its job. Sometimes you might leave the optional_list_of _parameters empty, if the procedure needs no information from outside to help it do whatever it does.
The way you call a procedure (ask it to do its job) in Euphoria is by writing its name followed by two braces ( ) enclosing an optional list of parameters, thus:
procedure_name( optional_list_of_parameters_values )
To clarify, here is a "real" procedure called DrSays() in a small DOS-style program, and a legal call to it:
procedure DrSays(sequence msg)
-- Display the text message in the sequence msg on the screen
-- printf() is a statement that here does 'formatted' display of
the msg
printf(1, "The Doctor says: \"%s\"\n\n",{msg})
end procedure
-- you can call the procedure DrSays() elsewhere in the program,
like this:
DrSays("How are you?") -- this call passes the words "How are
you?" to DrSays()
Procedure DrSays() itself has just one parameter in its parameter list. Parameters have to be declared in the parameter list and since this particular procedure expects to receive some text, msg is declared to be a sequence, and when we call DrSays() our call will have to send it a parameter value that is a sequence containing a string of text.
If you ran this little program you would see on the screen the words
The Doctor says: "How are you?"
and of course you can make the Doctor say as many things as you like by calling DrSays() over and over again, with a different message each time.
A function is very like a procedure, except that a function sends information back to the part of the program that called it. A function and a call to it look like this:
function AddTwoNumbers(atom a, atom b)
-- This function returns the sum of 2 numbers, a and b
return a + b -- compute and return the
sum
end function
atom result -- declare an atom
-- call the function, giving it 2 numbers to add:
result = AddTwoNumbers(4, 5) -- the result is assigned to
variable result
? result -- display the result
These illustrations of function and procedure are pretty trivial and don't really go anywhere near illustrating their power and usefulness. People who write programs that are in any way complicated just could not get along very well without functions and procedures.
There are a whole host of reasons why functions and procedures are a "good thing" in programs. Two of them are:
A restriction in Euphoria up to version 3.1 is that calls to functions and procedures must generally be made from a point in your program text that is subsequent to the place where your function or procedure is written. Some people might feel uneasy about this, but in practice you soon get used to writing your programs "upside down", so to speak. Euphoria 4 will remove this restriction.
As you will already have gathered, Euphoria's inbuilt types are atom, integer, sequence and the catch-all object. The first three are the ones used for most programming activities. The type object, if used, is usually restricted to situations where we cannot be sure what the nature of some input is going to be. Such situations can arise when handling files of unknown content, or when reading data transmitted from such things as scientific instruments, when the transmitting protocol is unknown.
Besides these types, Euphoria allows you to define your own data types. This is best illustrated by an example. Suppose you had a program that had to accept a string of text from the user, but a proviso was that the string should contain only the characters representing the digits 0 to 9, then you could define a type, called 'digit', as follows:
type digit(integer char)
-- Identifies if 'char' is a character representing a digit
if find(char, "0123456789") > 0 then
return 1 -- it is a digit
else
return 0 -- it is not a digit
end if
end type
A user-defined type must return either 1 (for true) or 0 (for false). In this type definition we have used a new function find(). The find() function will generate a number equal to the position of char in sequence "0123456789"; if char is not found in "0123456789" the find() function will generate a 0. So the definition of type digit will return 1 if char is a digit and 0 if it is not.
Then, later on in your program you could write a function that would identify whether the user had entered a string containing only digits, something like this (for sake of the example I assume that the user's string is in a sequence named 'user_in')
function test_digit(sequence user_in)
-- function tests if user_in contains only digit characters
-- returns 1 if they are all digit characters; ELSE
-- returns 0 if any of them is not a digit character; OR
-- if user_in is a null string
integer test_result -- declare this variable
if length(user_in) > 0 then
-- test each characters in user_in
for i = 1 to
length(user_in) do
-- note: using the digit type as the test here:
if digit(user_in[i] )
then
test_result = 1 -- OK so far - it is a digit
character
else
test_result = 0 -- not OK - it is not a digit
character
exit -- finished testing -
jump out of loop
end if
end for
else
-- user_in is a null string
test_result = 0 -- not OK - no digits in user_in
end if
return test_result
end function
If user_in contained the sequence "12345" then if we tested thus:
integer p
p = test_digit( user_in )
p would have value 1.
If user_in contained the sequence "12B45" then if we tested:
integer p
p = test_digit( user_in )
p would have value 0.
The type digit() is not limited to this use; we could have a procedure or function that needed a 'digit' in its parameter line like this:
procedure XYZ(digit y)
-- procedure description
-- statements that do whatever XYZ does
end procedure
If the value of y coming from a call to XYZ() is not a digit the program will halt. Then a call to the procedure
XYZ('3') -- this would work
XYZ('z') -- this would produce an error and stop the program
In short, the new defined type digit() can be used for all the purposes that an inbuilt Euphoria type can be used.
You can define a type in terms of one or more types that already exist, This gives you the ability to create types that can test for quite complex concepts, such as, say, alphanumeric.
To finish up, here (without much explanation) are some programs written in Euphoria, along with their listings. These programs are fairly simple ones but reasonably interesting from a programmer's point of view. Their purpose is so you can see some of what has been discussed in a realistic context. You will see a lot more besides in the programs, which I hope will help you in considering whether Euphoria is for you.
If you write graphic programs for users in which the user needs to pick a colour (such as in a drawing program), a "must" is to have a means for the colour to be picked. A common way of doing this is to present the user with an array of coloured squares on one of which he clicks to get a colour.
This program was the test-bed for routines which do this, using EuWinGUI. Eventually the routines (after more modifications) were moved off to an include file, from where they could be included in any EuWinGUI program that needed a colour-picker.
Program Developing Colour Picker (WIN)
Listing of Program Developing Colour Picker (WIN) Source Code
The game Connect-4 is old-hat. Nevertheless designing your own version of an existing game can be an interesting challenge, at least to you. At the start of a project like this it can be a bit troublesome to know where to start. At least I knew what Connect-4 looks like and how it behaves on screen.
Knowing what connect-4 looks like, a good place to start was to produce the basic windows and controls with the EuWinGUI Designer program. Two main windows were generated:
WinHwnd: the main window, on which the game would be played.As you probably know Connect-4 consists of an array of 12 rows, the rows appearing under one another and each row divided into 12 columns. The game is played by dropping coloured tiles into the top of the columns, down which they fall until they come to rest either on the bottom row or at a higher row supported by tiles played earlier.
The obvious thing was to represent each possible tile position by a small PictureButton control. Since there are 12 x 12 = 144 possible positions, this means sizing and laying out 144 PictureButtons. It would be horrible and laborious to do this with the Designer, so I left these buttons until later, to be created by the program itself "on the fly". So the work I did with the Designer was pretty slight for this program.
Listing of Connect4 Program (WIN)
This is a small DOS database program to record names and phone numbers of friends. It was written a long time ago and, even in DOS, I would write it differently now. The program would rank as a simple beginner's program.
The screen output uses colouring so you can see how colour can improve the appearance of the DOS console.
DOS text prgrams behave a little differently on screen from Windows' programs:
Euphoria has a very nice Euphoria Database System (EDS). It comes integral to Eu 4, but for Eu 3.1 you must download it separately. The EDS creates a datafile in which you can create Tables; each Table can hold data records according to your program's needs. The stored records require a unique key field, but a Table can also be searched sequentially. What you store in an EDS Table can be any of Euphoria's objects. I had not 'discovered' EDS when I wrote MiniDB.ex, so it doesn't use EDS to store the data. Instead I have used a file called "MyPhones.dat" which stores the records as sequential FLRs (fixed length records).
A program for a child (age about 4-7) to learn how to do simple "sums" involving two integer numbers, adding them, subtracting them, multiplying and dividing them. For a child's game you need a few gimmicks, and this has them ... music, birds and "boings", and a smiley face. There is a lot of descriptive stuff in the listing of this program.