A Bit About Euphoria

Fred Mangan

Euphoria Logo

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.

Introduction Chapter 1. The Hello World Program
Chapter 2. A Brief Description of Euphoria's Variables Chapter 3. About Sequences
Chapter 4. Procedures and Functions Chapter 5. User Defined Types
Chapter 6. Some Euphoria Programs


Introduction

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:

  1. You can use Euphoria alone to directly access API routines. It is I think the rare programmer who does this. Using the API directly is tricky. You will need to be a programmer with an advanced knowledge of C or C++, thoroughly conversant with the OS and probably with the hardware too in some situations. (It helps to be a Ph. D. in computer science!)

  2. A "wrapper" is a file that can be incorporated into a program. The effect of a wrapper is to add extra commands to a language. The Euphoria web site has a wrapper called Win32Lib. The commands it adds to Euphoria programs are ones relating to the API. By including the file Win32Lib.ew in your program and using its routines, you can create and manage screen windows and controls. Win32Lib is just a little easier to use than the API. It is however no pushover and you will need to have or develop some of the sorts of skills that you would need to use the API directly; you can't just toddle in the door and immediately write a stunning program with it. Win32Lib is an optional separate download from the Euphoria web site, You need to download it separately if you want to use it with Euphoria 3.1.

  3. You can use a "wrapper" like EuWINGui, also a separate download from the Euphoria web site. This is what I use, but others are available (see one called Arwen). If you include the file EuWinGUI.ew in your program it allows you to create a main window for your program and as many sub-menus (called Dialogs in EuWinGUI) as you like subject only to memory limitations and to create the buttons, lists, check-boxes, picture and other controls that programmers populate windows with. The range of controls is more limited than you would get from Win32Lib or the API and there are some other limitations too. But EuWinGUI will get you up and going with windows, so that you have somewhere that your program can write output to screen, can get typed input from users and do a bit of drawing, graphing and colouring too. You can often improvise simulations and work-arounds to avoid some of EuWinGUI's limitations. EuWinGUI will also manage output of text and pictures to graphic printers. It can also handle bitmap files of the BMP variety. EuWINGui comes with a mercifully short yet pretty comprehensive html Manual file which will give you the gist of how to use it. If you can use Euphoria you will be able to use EuWinGUI with little extra learning and mercifully, without having to learn any arcane stuff relating to the OS. A wrapper like EuWinGUI is people for whom Windows is a means to an end, not an end in itself.

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

  1. Heritage reasons: There were too many important programs in the world which ran under DOS (important, that is, to the people who used the programs).
  2. Learning reasons: It would be just too hard for beginner programmers to have to struggle with learning the basics of a computer language AND learning about the API all at the same time. Beginners usually start learning programming in the DOS (or raw Unix) environment.

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.

Euphoria for Teaching and Learning?

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 LOOP
for index = start-value to end-value [ by step ] do
    block-of-statements
end do
WHILE LOOP
while condition then
    block-of-statements
end while
IF CONDITION
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

  1. Robust variable typing and encapsulation;
  2. Flexible routines (two flavours, "procedure" which returns no values, and "function" which can return one value; or multiple values as the contents of a sequence;
  3. No goto statement allowed in version 3.1. But, surprisingly, goto is a new statement in version 4.0.1!.
  4. Provision for include (header) files to avoid perpetual wheel reinvention. Euphoria comes with a good supply of useful pre-written include files to get you started.
  5. Euphoria is not an inherently OOP language. However for those who might need OOP capability as part of a teaching/learning experience there are wrappers at the Euphoria web site which should satisfy.

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

Chapter 1. The Hello World Program

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.

Hello World (DOS) 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:

Hello World (WIN) Program

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.

Chapter 2. A Brief Description of Euphoria's Variables

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:

  1. Variables must be declared before they are used.
  2. Variables must (of course) be named when they are declared and can have long meaningful names.
  3. Immediately after it is declared, a variable has no default value. If a variable has no value your unthinking use of it may crash a Euphoria program in some circumstances. This is not a fault but rather a good thing. It prevents a program having this defect from running on and producing nonsense results.
  4. There is a variety of scoping rules applicable to variables, too many for me to want to describe here. The scope of a varianble relates to what part or parts of a program can "see" a particular variable. Euphoria's scope rules can be quickly and easily learned and are pretty logical. For instance, a variable called HamAndCakes, declared inside a procedure or function, will not be be confused by the interpreter with another variable called HamAndCakes declared outside the procedure or function. There are other scope rules but I won't describe them here.

Euphoria's variable types are:

  1. atom: a type of variable that can hold floating-point and also integer values.
  2. integer: this type of variable can hold only integer values. The range of values it can hold is less than the range of integer values that an atom can accommodate.
  3. sequence: a type that can hold lists of objects or many-dimensioned arrays of objects. More about sequences soon.
  4. object: this type of variable can hold any sort of value, an atom, an integer or a sequence. It is much like the variant type used in Visual Basic. All Euphoria variables are objects.

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.

Chapter 3. About Sequences

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:

Seq1.exe Program

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

Some points about the program

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.

Seq2.exe Program

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.

Sequence Slicing

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.

Sequence related Commands and Statements

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

Some Sequence Magic

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:

  1. Most Euphoria statements can be split over multiple lines like this, though you may need to pick the "break" points carefully to avoid making it nonsensical. In this case splitting it makes the structure of the CUST_ID_FORM clearer and more understandable to a human reader. Euphoria itself doesn't care what we make the structure looks like, so long as it is correct when the program is run.
  2. This statement declares CUST_ID_FORM to be a constant. A constant is a variable the value of which can't be changed by the program. The variable type that a constant has is determined by what comes after the '=' symbol in the statement. In this case CUST_ID_FORM is a sequence that contains 8 sub-sequences. The form of each of the 8 is similar as the lay-out emphasises. A comment has been added to emphasise the column-like nature of the 8 sequences.

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

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!

Sequences and Maths

I was blown away when I first saw Euphoria statements like this:

   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 Polyline

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.

Chapter 4. Procedures and Functions

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.

1. Procedure

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.

2. Function

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:

  1. Each function or procedure is like a building brick in your program. It does a particular, often quite small, task. You can create your program by making calls to functions and procedures in a suitable logical order to achieve the goal of your program.
  2. Whenever you write a procedure or function that you consider would be of use in other programs, you can write it in an include file which can be later included in those programs. Doing this makes it easier to write future programs and saves you writing similar code over and over again.

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.

Chapter 5. User Defined Types

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.

Chapter 6. Some Euphoria Programs

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.

1. A Colour Picker

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

2. Connect4 Game

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.

Basic Screen Design:

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.
LogoDialog: a child-window on which a Picture control was placed to display a Logo.bmp picture loaded from disk.

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.

Connect4 Program (WIN)

Listing of Connect4 Program (WIN)

3. MiniDB.ex

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:

Mini Data Base Program (DOS)

Listing of Mini Data Base Program (DOS)

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

4. Sums.exw

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.

Kids' Arithmatic Program (WIN)

Listing of Kids' Arithmatic Program (WIN)