Way back in 1986, the coolest thing I discovered about my new Commodore VIC-20 computer was that, while it was manipulating my friends, I could actually manipulate it. I could make this powerful electronic processor do what I wanted it to do by simply typing in some command words in a format that adhered to a few simple rules. Since then, I've been programming computers on the job and as a hobby.
You, too, can make computers do what you want (called "programming"). I don't want to say it's easy, because many professional programmers have spent countless hours past midnight building and fixing programs. But if you're the creative type, you enjoy or at least can tolerate math, you can think logically, and you aren't a quitter, you can have fun programming.
This tutorial will help you discover the art and science of programming. We'll be using the Euphoria programming language. It's a versatile little language, speedy and robust. It's both a great beginner's language, as well as sufficient for professional programming tasks. In fact, Euphoria is being used to manage and serve the content of this HTML book. Euphoria is great for CGI!
If you ever get stuck or have a question, send an email to the author by clicking the author's name in the upper right corner of this page.
Also, if you want to contribute to this document, please send me your comments and suggestions. This book is just a start and it is ready for your input! I expect it will be dynamic, never really finished, as every day new text is discovered to make learning Euphoria that much easier.
If you want more help, try these links:
Beginner's can get one-on-one mentoring here: UBoard.
If there's anybody else out there with tutorials or otherwise helpful Euphoria sites, let me know and I'll post them here.
Update 2009.08.23 - Euphoria has come a long way since this tutorial was first published. I'm going through the document now and updating it for Euphoria 4.
Programming is giving a computer commands and data (called "input") so that it gives you information (called "output"). From the simplest of calculator programs to the most advanced computer graphics program, a computer is given input so it will provide output. (During informal conversation, I like to say that programming is manipulating a computer to perform your every whim.)
In this study of programming and the Euphoria programming language, you'll learn enough to start cranking out your own programs. We'll step through some basics of programming, then quickly get into using Euphoria to do some programming.
Euphoria is simple-to-use and easy-to-understand but fast and powerful. It's cross platform, meaning a program you write for Windows could work in Linux or FreeBSD. There's a nice archive of already-written code available for study. There's a great user community that is always willing to help (even newbies).
Euphoria is a programming language developed by Robert Craig of Rapid Deployment Software. In order to use this programming tutorial, you will need to install a copy of the Euphoria programming software onto your PC. You should also at least have skimmed over (or better, read) the Euphoria Reference Manual and browsed the wiki.
If you need help installing Euphoria, and the Installing Euphoria instructions don't help, you can post a message on EUForum.
This tutorial is for those who are new to programming and/or Euphoria. If you are new to programming, you'll want to start at the very beginning where I explain the basic elements of programming in general, with some Euphoria-specific examples. Advanced users might want to skip ahead to the later sections, although a review of the basics never hurts.
And remember, you can always contact me via email by clicking on my name at the top-right of the page.
Euphoria program files are simple text files. You can create these text files using any text editor you desire. For starting out, I recommend using RDS' own "ed" editor. If you have installed Euphoria properly, you can simply type ed <filename> to create/open a text file. You can use ed from Windows, DOS, or Linux/FreeBSD. What's cool is that ed is completely written in Euphoria.
For a Windows-only editor, written completely in Euphoria, try Edita by Pete Lomax.
You can search the Euphoria programs archive for more editors written in Euphoria, or check out Euforum, where programmers editors have been discussed before.
There are several ways to run (or start) Euphoria programs.
Programmers create computer programs. Since we learn best by example, I'm going to create a very simple Euphoria program. Remember, a program is input that the computer uses to determine what it should output. Type the following line into a text file and save it as add.ex. (If you're using RDS' ed, just type ed add.ex from a command line.)
? 23489 + 1293374
The question mark is a shorthand way of saying, "print to the screen." I'll give you more details later. For now, just follow along.
At this point, the computer doesn't actually "understand" our program. The computer only understands numbers arranged in long sequences of ones and zeros. So, we'll need something (another program) to translate the program code in our text file so the computer understands it. We need a program to interpret our input and give it to the PC in a form it understands. That's where Euphoria comes in. Euphoria is a program interpreter, because it takes a program written in Euphoria syntax (that is, using Euphoria rules and grammar) and translates it into computer speak (ones and zeros).
When you "run" or "execute" the program, the Euphoria interpreter will convert it into machine-readable code and give that to the PC. Your PC will then take that input and provide you with output. So, let's run the program by typing the following:
eui add.ex
If everything is set up properly, you should see the following output on your screen:
1316863
By having our input (the program itself) inside a text file, I can send it to the interpreter any time I want! It also saves me from having to retype the input each and every time I want to know the sum of 23489 and 1293374.
For the rest of this book, anything that is input to the computer will be shown in Courier font on a light blue background (like above). Anything that is output from the computer will be shown in a Verdana font on a light blue background (like above).
We need to briefly touch on possible errors that might occur while you are learning to program. Euphoria has a strict syntax (a set of formatting rules) to which all input must adhere. If you vary from this syntax, Euphoria will print an error message to the screen. Errors are inevitable, and I don't want you to freak out if you see one. So, let's get familiar with them...
Create a new file called errors.ex and add the following line:
? one plus two
Do you know the answer to that formula? Sure you do! It's easy! (One plus two equals three.) Let's see what our computer can make of it. Save the program and run it (remember, type eui errors.ex). Here's what your screen should look like:
killme.exw:1
<0074>:: Errors resolving the following references:
killme.exw (1): plus
killme.exw (1): one
? one plus two
^
The first line of output tells us that there is an error on line 1 of the program errors.ex. The second line tells us what the error is ("Errors resolving the following references:"). The third and fourth lines help us pinpoint the problem on the line specified in line one of our output. This error happens to be an undeclared variable error, meaning that Euphoria doesn't know how to deal with the variable named "one."
This is the general format of an error message from the Euphoria interpreter. We'll discuss error messages in more detail along the way. I just wanted to give you an idea of what they were so you wouldn't be surprised if (or when) you encounter one.
Computer programming is an artful science. I say that because there are almost as many solutions to a particular programming problem as there are programmers. One programmer will "paint" a solution one way, another will "paint" it some other way. Both might be just as beautiful. The science of programming comes in when one program proves to be more efficient than the other. Some programs are more efficient than others, and some code looks better than others, just like the portraits of a woman painted by different artists will each look different. Some will look exactly like her, as though it was a photograph, while others will be more abstract, maybe showing no recognizable definition at all. The point is, a programmer is given a set of tools to provide input to a computer to get some output. There are no other constraints. Of course, one must understand the syntax, or formatting and grammar rules, of the input so that only good input is provided to the PC. A PC doesn't understand English (as we saw last chapter)! In fact, a computer's vocabulary is very very small. You want to be sure that the PC understands all the input you provide. Otherwise, you'll get bad output (like those error messages we saw last chapter). The process of giving a computer input it won't understand, and receiving undesired or unexpected output, is referred to as "garbage in, garbage out."
As an example, a programming contest was run in March of 2002 by Rapid Deployment Software, the makers of the Euphoria programming language. The purpose of the contest was as follows:
Write a program that tries to decipher a text file that has been encoded using a simple one to one cipher where each letter of the alphabet A-Z and a-z has been replaced by a different letter, but blanks, tabs and punctuation characters have been left alone.
There were a variety of entries, and each programmer approached the problem differently. Your approach might be unique as well. And while all of these programs accomplished the job, only one could be rewarded to getting the job done most efficiently.
Click here to see the contest specifications. Scroll down the news page to see the results.
The purpose of a hobbyist programmer is to know his art well enough to get the job done. The purpose of a paid programmer is to know his art well enough to get the job done most efficiently.
A computer can do nothing without input. Input is composed of the commands we give the computer and the data we want to manipulate. In our first program example above, we used two command inputs, "?" and "+," and two data inputs (the numbers). Given this input, the computer gave us output. Let's look at the input a little more closely.
Every computer language has two components: Commands and Data. Commands tell the computer what to do with data (including either manipulating data or outputting data). For instance, in our first program, we commanded the PC to print (the command) the result of adding (another command) two numbers (the data). We're going to look at the print command more closely.
There's no point in programming a computer if we're not going to get something out of it; namely, output. We give a computer input and expect some kind of result to be displayed for us, similar to the way our first program showed us the result of the addition of two numbers. In Euphoria, when we want to see the output displayed on the screen, we can use one of a few output commands.
| Output Command | Example Use |
| puts() | puts(1,"Hello, world!") |
| print() | print(1, 3 + 7) |
| ? | ?10+44 |
The puts() command is short for "output sequence." We'll get into sequences later when we consider the data portion of input. For now, just get it in your head that puts() means "output sequence."
The ? is actually short hand for the print(1,…) command. The '1' in the puts() and print() commands above tell the PC to output the result to the monitor screen. So, the following statements are equivalent:
print( 1 , 2 + 3 )
? 2 + 3
The reason we need to specify where to direct output is because the PC can not only "print" to the screen, it can also print to a file (disk) or to a printer.
Let's run our first program again. Type at the command line:
eui add.ex
This command tells your computer to use the program called "eui" to interpret the input found in the file "add.ex." "eui" is, of course, the Euphoria interpreter!
After running our program, we should get this on the screen:
1316863
We have commanded the PC to print to the screen the sum of our two numbers. Euphoria took our commands and converted them into language that the computer would understand. The computer then did what we told it to do.
You can run this program anytime and you will get the exact same results each time. By saving the set of commands, we make code reusable. This is very important, especially when you have programs that are tens of thousands of lines long. Not having to type the same commands each time you need output is a big time saver.
You might be asking, "What if I want to add two different numbers? What if I want to subtract numbers? Or multiply them? Or divide them?" Well, just hold on. We'll get to that later. Right now we're trying to get some basics in our head, okay? Onward...
Commands tell the PC what to do with the data we provide. In our first programming example (add.ex), the commands were '?' and '+,' and the data was the two numbers.
? is a command meaning "print"
+ is a command meaning "add"
23489 is numeric data
1293374 is numeric data
Essentially, commands tell the computer what to do. Data tells the computer what to do it to.
Euphoria has a provision for storing data in items called variables. A variable is simply a container of data. Just as a bucket would hold water, a variable holds a value. For example, this command set
integer x
x = 5
stores the value 5 in the variable x. (A variable is so named because its value can change.) We could then do things with x, such as
? x + 1
Can you guess what the output would be? If you're not sure, create a Euphoria program file and find out!
There are two types of data in the Euphoria programming language: atoms and sequences. Atoms hold single values and sequences hold a series of values. In order to use variables, we must declare them at the very beginning of our program. Here's what a variable declaration looks like:
atom x
sequence y
This tells the computer that the variable 'x' will hold data of type atom, and y will hold data of type sequence. By declaring these variables as atom or sequence, we let the interpreter know what to expect.
Storing values in variables is called assignment. The command
x = 5
is an assignment and means "assign (or store) the value of 5 to the variable x." Thank goodness we don't have to type that every time we want to store an item of data!
Atoms are single values (numbers). x is an atom. It stores the value 5.
Look at this assignment:
s = { 1, 2, 3 }
A sequence can hold atoms and other sequences. In the example above, we are assigning the sequence { 1, 2, 3 }, which is a series of three atoms, to the variable named s. Each item of data in a sequence is called an element. So, the variable s has three elements after the above assignment. The squiggly brackets are required when defining a sequence.
Here is a more complicated sequence assignment:
s = { 1, 2, { 1, 2, 3 } }
Notice that the first and second elements of s are atoms, but the third element is a sequence, which is itself a sequence of three atoms. Here are some more sequence assignments for you to consider:
s = { 1 }
In this one, we've assigned the sequence { 1 } to s. Yes! A sequence can have only one element. It can also have none, like this:
s = {}
That just means that s is an empty sequence at the moment.
s = { { 1 } , { 2 } , { 3 } }
s is now a sequence of three elements, each of which is a sequence with only one element each!
s = { { { 1 , { 2 , 3 } , 2 , { 1 , 2 , 3 } } , 2 , 3 } }
Have fun with that one!
When you want to reference an element in a sequence, you use the square brackets, like this:
s = { 1, 2, 3 }
?s[1]
1
The print command tells the PC to print the first value of the sequence s, which in this case is a '1'.
In this next series, s is now a sequence of 4 elements, with the third element being another sequence.
s = { 1, 2, { 1, 2, 3 } , 3 }
See if you can determine what the output of the following will be.
?s[2]
?s[3]
?s[3][2]
Here's the output:
2
{ 1, 2, 3 }
2
Look at that last command. Notice that we referenced the second element of the third element of s by using another set of brackets! Simple, huh?
One final note about sequences: you can use quotes to indicate a sequence of letters, also referred to as a string. For example,
s = "Hello 123"
When we use the ? command, we get the following output:
{72,101,108,108,111,32,49,50,51}
So, you might can guess that the following two assignments are equal:
s = "Hello 123"
s = {72,101,108,108,111,32,49,50,51}
Euphoria always sees it as the second assignment. If you want to see it in human readable/understandable format, you need to use puts(). Remember, puts() means "output sequence."
s = {72,101,108,108,111,32,49,50,51}
puts(1, s )
Hello 123
This distinction will come into play later, but for now it's good to know that quotes are used for text strings while the brackets are used for numeric data. That means the following are NOT equal assignments:
s = { Hello }
s = "Hello"
The first assigns a sequence with the element Hello to s. If Hello is not a previously defined variable, you'll get an error. The second assigns the string "Hello" to s, which is a valid assignment.
s = { H , 2 , Program , X }
This assignment is only valid if 'H,' 'Program,' and 'X' are previously defined variables. If not, you'll get an error.
These are all valid sequence assignments:
s = { 1, 0, -4, 13 }
s = { "1, 2, and 3 are nice." }
s = { " { 1, 2, 3 } , { 2, 4, 6 } " }
Euphoria has two more data types, but these are actually special cases of atoms and/or sequences. The integer variable is an atom that only holds integer values.
x = 1.3
y = 1
In this example assignment, x and y are both atoms, but only y is an integer. As you can see, y is really just a special case of atom. This will be important later.
The object is a special variable that can hold either atoms or sequences. If, for instance, you tell the PC that x will be an atom, then try to assign a sequence to it, you'll get an error message, and vice versa. Sequence variables can't hold atoms. Generally, you'll know in advance what a variable will hold and you will specify that with the following variable declarations:
atom x
sequence y
That declaration tells the PC that the variable 'x' is going to hold atom values only, and the variable 'y' is going to hold sequence values only. If you try to assign a sequence to x, you'll get an error message; the same if you try to assign an atom to y.
If you don't know in advance what a variable will hold, or you know that the variable will need to hold either atoms or sequences, you'll use the object declaration.
object x
Now x can hold either atoms or sequences. This series of commands is now perfectly valid:
object x
x = 1 --< first an integer
x = "a string" --< now a string (sequence)
x = 2.74 --< now an atom
x = {"one string","two strings"} --< now a sequence of two strings
One more thing about atoms and integers. They each have a limited value range. Atoms can have any integer or double-precision floating point value. They can range from approximately -1e300 (negative one times 10 to the power 300) to +1e300 with 15 decimal digits of accuracy. Integer variables can hold integer values from -1073741824 to +1073741823 inclusive.
We touched briefly on strings last chapter. I want to give you more examples, because knowing how to work with strings and sequences will be a key skill when using Euphoria.
Here are some examples of sequences and strings.
x = "My name is Johnny." -- a string
y = { "My name is Johnny." } -- a sequence of ONE element, which happens to be a string
z = { y } -- a sequence containing a sequence that contains a string
a = {"One","Two","Three"} -- a sequence of strings
b = "String" -- another simple string
c = {'S','t','r','i','n','g'} -- a sequence of six atoms which happens to be equal to b above
-- print b and c if you don't believe me
Here are some examples of subscripting strings.
x[4..7] is "name"
y[1][4..7] is "name"
z[1][1] is "My name is Johnny."
a[2] is "Two"
b[3] is 'r' -- notice that the third element of "String" is the atom 'r'
c[3] is 'r'
d = z[1][1][4..7] -- d now equals "name"
Here are some examples of appending and otherwise manipulating strings.
e = x & " " & a[3] -- e now equals "My name is Johnny. Three"
f = b[1..3]
g = b[3..6]
puts(1, f & g) -- outputs "Strring"
puts(1, g[1..length(g)]) -- outputs "ring"
Onward!
Open up your add.ex file. Change the program to look like the following:
integer x, y
x = 23489
y = 1293374
?x+y
Save the file and run it.
eui add.ex
1316863
You'll notice that we got the same output as before! You're seeing already how there are different ways to accomplish the same programming task. Generally, it's a matter of personal taste how one goes about accomplishing a particular programming task. For this particular task, however, our first program required a lot less typing, so it was a bit more efficient. The use of variables for a program that adds two numbers is overkill. When we have a program that will add two numbers together that we cannot determine in advance, we will have to use variables.
Variables come in handy when we don't know in advance what values we will be using in our program. What if we called our calculate and print program a "calculator." Technically, that's what it is and does. It calculates two numbers. But what happens when we want to calculate different numbers? We could modify the program and change the numbers, but that's not very efficient if we'll be doing this on a regular basis. It would be best if we get the values from the user at run-time (that is, when the program is run). Let's see how to do that in Euphoria.
Open up your mytest.ex file. Change the program to look like the following:
include get.e
integer x, y
x = prompt_number( "Enter x: ", {} )
y = prompt_number( "Enter y: ", {} )
?x+y
You'll notice two new items in this program: an include statement and a function called prompt_number().
An include statement tells the Euphoria interpreter to "include" the code found in the specified file (get.e). We want to access the code found inside that file, so we can use the include statement to have it made a part of our program. This is extremely useful because we can make use of code that others have already written. There are include files for graphics, windowing, special input from joysticks, and a lot more.
A function is simply a reference to a block of code that exists elsewhere in your program (or in an included file). Calling a function is like running the code it references. Here's a short example program to demonstrate the use of a function:
integer x, y, z
function add( atom x, atom y )
return x + y
end function
x = 1
y = 2
z = add( x, y )
?z
Let's examine this function closely.
function add( atom x, atom y )
First, we tell the Euphoria interpreter that the following lines of code are going to comprise a function called add. Functions must be declared before they can be called! The add() function requires two items of input (called parameters): an atom x and an atom y. Normally, the interpreter immediately executes any commands it encounters. However, in the case of a function, it knows not to run this code immediately. Function code is only meant to be run when "called," so it skips past the code at first.
Our next line
return x + y
tells the interpreter to add the two values it received then return that value to the calling statement. The final line simply tells the interpreter that the block of function code is done.
Now that we've defined the function add(), we can call it from our program.
x = 1
y = 2
z = add( x, y )
We pass the variables x and y to the function add(), which then returns a value which we assign to the variable z.
We could have saved ourselves some time and space by eliminating the variable z and giving the result of add() directly to the ? command, like this:
integer x, y
function add( atom x, atom y )
return x + y
end function
x = 1
y = 2
? add( x, y )
It's just another way to get the job done.
Let's get back to our prior example…
include get.e
integer x, y
x = prompt_number( "Enter x: ", {} )
y = prompt_number( "Enter y: ", {} )
?x+y
Hopefully you know what the include statement does. If not, go back and review! The prompt_number() function is probably self-explanatory, but it is a function provided by RDS in the get.e include file that gets a number from the keyboard.
Remember, a function returns a value to the calling statement. The prompt_number() function gets input from the keyboard and then returns that result. In our program, we call the function and assign the result to x. We then call the function again and assign the returned value to y. When we have our two values, x and y, we print the sum. At least, that's what we hope will happen. Let's run the program to find out.
Cool, huh?! The program prompted you for two numbers, then it output the sum of those two numbers. You can run the program again and use different values. In fact, you could run this program many times and use many different numbers.
Euphoria can get input in a variety of ways, not just from the keyboard. Another common way of feeding data to a program is through a file. (You can also get input through the various ports on your computer, such as from joysticks, MIDI keyboards, or thermometers!) We're going to look at getting input from a file… those other input methods will be left for you to explore.
Before we get started, create a text file called "mydata.ini" and put your full name in it.
Now, enter the following code into a new file and call it "inputs.ex."
sequence name
atom fn
fn = open( "mydata.ini" , "r" )
name = gets( fn )
close( fn )
puts(1, "\n" & name & "\n" )
Save the file and then run it from your command line.
eui inputs.ex
If it ran properly, you should see your name appear on the screen and then be returned to the prompt. If it didn't run properly, make sure you specified the right filename to open and that the filename you opened has your name inside it.
Let's see what happened!
First, we define our two variables. The sequence name will hold the result of receiving the input from our file. The atom fn will hold a file identification number, or what is termed a "handle" to the file. I'll explain this in a bit.
Next, we use the open() function to open the file and return a handle (or identification number) to the file "mydata.ini." We want to open the file for reading, so we specify "r" as the second parameter.
Next, we use the function gets() to read a sequence from the opened file. Basically, we tell gets() to "get the next sequence" from the file identified by fn, which is "mydata.ini."
Now that we've got our data, we close the file with the close() procedure.
Finally, we print our data using puts().
In the following section "Output," we'll see how to output data to files. This is handy for when you want to save settings between running your programs or for sharing the data created by your program with others.
Euphoria has a provision for making comments inside the programs you write.
There are two ways to create comments in Euphoria programs.
The comment marks, as well as everything after them, are ignored by the Euphoria interpreter. Comments are very useful for reminding yourself or informing others of the intent of your section of code. Comment liberally.
See the examples below.
atom a, b -- declare variables -- assign variables a = 5 b = 3 -- print ?a+b -- the sum -- print(1,a+b) -- this whole line will be ignored for t=1 to 10 do ?t end for /* Starting with the beginning of the above line, all of this text will be ignored by the interpreter. It will be ignored until the asterisk+slash is encountered. This is useful for embedding long commentary about the code in your program. It is also useful for embedding documentation for the end user. */
A computer is not very useful if it can't provide output. Imagine using a calculator and punching in the numbers, pressing '=,' and having nothing displayed. Let's see what kind of output Euphoria can give us.
Text
We briefly covered text output to the screen in the Input section above.
|
Output Command |
Example Use |
|
puts() |
puts(fn,"Hello, world!") |
|
print() |
print(fn, 3 + 7) |
|
? |
?10+44 |
In the above examples, fn represents a "handle" to an output device. It can be the screen, the printer, etc.
Euphoria's printf() procedure (printf means "print formatted") lets us massage our data for display. For instance, look at the different ways I can print the value "123.456" using the printf() procedure.
printf(1, "%d", {"123.456"} ) -- prints '123'
printf(1, "%f", {"123.456"} ) -- prints '123.456'
NOT FINISHED
Graphics
Euphoria can also output graphics, such as lines, points, and circles. Since there are a variety of ways to do so, all dependent on your OS, I'll leave this topic for another time. In the meantime, you can click the following links for helpful study pages.
Euphoria Graphics & Sound Docs
Functions and procedures allow us to organize our code into useful chunks. We can then incorporate these chunks into our programs, thus saving us having to rewrite a lot of our code.
A function is a group of code bundled together under one command. For instance, consider the following:
function fix( atom a, atom b )
atom c, d
c = a + b
d = a - b
return c * d
end function
atom z
?fix(3,4)
?fix(45,13)
?fix(6,143.3)
z = fix(72,44)
We created a function called fix() that consists of two lines of commands. If we weren't using the function, our code would look like this:
atom a, b, c, d, z
a=3
b=4
c = a + b
d = a - b
print(1,c * d)
a=45
b=13
c = a + b
d = a - b
print(1,c * d)
a=6
b=143.3
c = a + b
d = a - b
print(1,c * d)
a=72
b=44
c = a + b
d = a - b
z = c * d
You can see how more efficient our first program is! Now, imagine if we wanted to change the way we "fixed" the numbers. In our second example, we would have to change three instances of the code. In our first example, we have to change only one instance- the code inside the function.
Functions provide a return value. That is, when you call a function, it gives you a value. In early versions of Euphoria, you had to assign that value to a variable. Starting with version 4.0, you do not have to assign the return value.
As an example, consider the following code:
k = wait_key()
wait_key()
In versions of Euphoria prior to 4.0, you had to assign the result of wait_key() to a variable (like on the first line above), so the second line in the above code would produce an error message. In 4.0, the above code runs just fine, making you press a key on your keyboard twice. The first time, it assigns the result to the variable k. The second time, it ignores the result of the function and continues the program.
Procedures are similar to functions, except they do not provide a return value.
procedure fix(atom a, atom b)
atom c, d
c = a + b
d = a - b
print(1,c*d)
end procedure
fix(3,4)
fix(45,13)
fix(6,143.3)
In this program, the procedure fix() does the printing for us. The procedure also does not return a value, so if we were to try and assign a value or use it somehow, such as with print(1,...), we would generate an error.
x = fix(9,3) -- THIS GENERATES AN ERROR
Explore all the input/output options available with Euphoria.
All the commands available for input.
All the commands available for output.
Euphoria can be used to create a variety of graphic-intense programs in a variety of OS environments.
Search the Euphoria Code Archive for "graphics" and you'll find a plethora of libraries available for handling the graphics needs of your next program.
For GUI
If you're going to be doing GUI and graphics programming, it's best to make your attempt with a cross-platform library. You can be sure that 99% of your potential customers will have an OS that can run your software. If you use something that is only Linux specific, you leave out all the Windows customers, and vice versa.
For Graphics
Again, a cross-platform library is optimal. The OpenGL and SDL graphics libraries are quite capable.