One Effort Multiple Platforms

8th™ is a secure, robust, cross-platform, and fun programming language

Sample code

Since you probably would like to see 8th “in action”, we’ve provided a few simple samples to give an idea of what 8th code looks like:

Many more samples are available in the 8th distribution, as well as on the 8th forum and on Rosetta Code.

Hello, world!

It’s almost obligatory to demonstrate how a language handles the task of printing out “Hello, world!”. Here’s the shortest “hello world” application possible in 8th:

"Hello, world!\n" . bye

Note that you don’t have to write all sorts of declarations, and that the “string” declaration is just like you’re used to from C++ or Java. For details about what’s going on here, just download 8th and read the tutorials and manual and sample code. But we digress…

You can get a little fancier if you decide to wrap your code in a “word” (the equivalent of a “function” in other languages):

: hi "Hello, world!\n" . ; hi bye

This accomplishes the same thing. You created a new “word” named “hi”, and afterwards invoked the phrase “hi bye”.

And one last version: do all this just from the system’s command-line. Great for short scripts!

8th -e '"Hello, world!\n" . bye'

Processing CGI on a web-server

The Common Gateway Interface, or “CGI” as it’s more commonly known, is a method often used for processing user requests on a web-server, such as form submissions. The protocol is simple, and CGI scripts are often written in “perl” or “bash”. While this works well, one disadvantage of such use is that the server-side script is left in plain-text, and is therefore vulnerable to modification or disclosure of intellectual property should the server be compromised.

8th programs can be run as “scripts”, just as a bash or perl program may. However, 8th also lets Professional and Enterprise customers produce an encrypted binary of the script, thereby both protecting the encrypted script from modification, making it much more difficult to derive information from it and easing deployment.

The actual 8th code for this sample is here, and you may view it with any text-editor you like. A few highlights from the code will be mentioned below.

First, note the #! /usr/local/bin/8th line at the top of the script. It tells the Linux (or Raspberry Pi) system you’re running on that it should use the 8th binary located in /usr/local/bin to run the script. If you are running the script as an encrypted binary, that line is superfluous (though harmless: the #! word is considered a comment in 8th).

Second, note that all POST or GET variables passed to the script are folded into a single map variable called “vars”. Accessing any variable then simply requires a phrase such as vars @ "HTTP_FROM" m:@ for instance, to access the “HTTP_FROM” CGI variable.

Third, note the use of quote to conveniently handle multi-line HTML for output. The response header as well the start of the body are given at the same time.

You can try out this code on Linux or macOS etc, by something like:
echo "a=b&c=d" | 8th cgi.8th

Download and create IP-address-to-country database

Sometimes, your application needs to know with some degree of certainty where a client is connecting from. Perhaps you are constrained to only deal with one of a set of countries. IP addresses seem a good solution to the problem, but the IP to country web services can get expensive.

The solution described here demonstrates a few of the varied capabilities 8th brings to bear. The script:

  • Creates a new SQLite database
  • Downloads a ZIP file containing an IP to country database
  • Extracts the relevant CSV file
  • Process it into the database

All of these processes take place using 8th’s built-in functionality; no external programs are used, and the same code may be run on any of the platforms 8th supports.

The 8th source code for the IP-to-country database is here, and you may view it with any text-editor you like. A few highlights from the code will be mentioned below.

First, note that the remote ZIP-file is downloaded and the relevant content is unpacked, completely in-memory — it never hits the disk. This is a good solution if the data don’t take up too much of your system’s RAM, but beware that it isn’t always suitable.

Next, note the use of s:eachline to iterate over the CSV data. The script accesses the CSV data as one large string, and s:eachline splits it up into lines and feeds those lines to the actual data processing code.

Then note the use of prepared SQL statements and in particular the way they can take an array of data as arguments to the “bind” words. In this sample we’re actually using “bind-exec” to bind parameters and execute the SQL at one go.

Finally, note the manner in which we “fix up” problems. We start parsing the CSV file by splitting the string on “,”. But the last field is country-name, which may contain commas! So we look to see if the data to be inserted into the country table has more than two fields. If it does, we shift off the first item (which is the country code), and do a “join” on the remaining entries (using a “,” as the joining text). Then we “close” the two items on the stack into an array again.

After running the script, you’ll have a new SQLite database containing one table with the IP address ranges given to each country, and another containing the two-character country-code and long country-name. You would use the database by converting an IP address to a number, perhaps with code like this:

: ip2num \ xx.yy.zz.bb -- n "." s:/ ( swap >n swap 256 n:* n:+ ) 0 a:reduce ;

And then issuing a SQL query such as:

SELECT cc FROM ips WHERE ip1 = ?

What are you waiting for? Get 8th now!

Back to the main page