Header Bar

Personal Programming

By Nick Antonaccio
Updated 9-8-2017


1. What if?
2. Computers everywhere, but they're too complicated to program... right?
3. Take a look at these examples
3.1 Tile Game (6 lines of code)
3.2 Simpler Tile Game (2-3 lines):
3.3 Multiple Camera Video Feed Viewer (4 lines)
3.4 Bar Chart Generator (2 lines)
3.5 Image Effect Demo (4 lines)
3.6 To-Do List (5-6 lines)
3.7 Madlib (3 lines of code, 1 line of default madlib text)
3.8 Pig Latin (3 lines)
3.9 GUI Calculator (7-8 lines)
3.10 Calendar/Scheduler (5-6 lines)
3.11 Speed Reader (3-4 lines)
3.12 Paypal Report (3 lines)
3.13 Local and Remote IP Addresses (2 lines)
3.14 FTP Site Editor (4-5 lines)
3.15 Wave File Sound Player (3-4 lines)
3.16 Freehand Draw (7-8 lines)
3.17 3D Gradient Cube (5-6 lines)
3.18 Animated 3D Image Transform (4-5 lines)
3.19 Full Screen Slides (6 lines)
3.20 TCP Text Messenger (9-10 lines)
3.21 HTML Form Server/Processor (8-9 lines)
3.22 File Encrypt/Decrypt Utility (6-7 lines)
3.23 Compress and Embed a Binary File in Code (3 lines)
3.24 Chord (Sound Accompaniment) Looper (11-12 lines)
3.25 Blogger (6-7 lines)
3.26 Email Account Setup/Reader/Sender (9 lines)
3.27 Generic CRUD App - Card File (7 lines)
3.28 Grid w/ edit, add, delete, find, sort, sum, save/load, etc. (20 lines)
3.29 VOIP Network Intercom (19 lines)
3.30 Catch Game (11 lines)
3.31 Snake Game (11 lines)
3.32 Mine Field Game (10 lines)
3.33 Guitar Chord/Scale Diagram Maker (13 lines)
3.34 Cash Register (13 lines)
3.35 Form Entry Validation (8 lines)
3.36 Help (4 lines)
3.37 Year Calendar (9 lines)
3.38 UDP Chat (11 lines)
3.39 3D Graphics - r3D library example (17 lines)
3.40 CGI Photo Album (7 lines)
3.41 CGI Group Chat (6 lines of Rebol code + 6 lines of HTML form code)
3.42 Desktop Group Chat (5 lines)
3.43 Pie Chart - q-plot library demo (3 lines)
3.44 Parse URLs (1-6 lines)
3.45 Multi-User File Uploader (9 lines)
3.46 Recursive File Search (9 lines)
3.47 Image Slide Show (7 lines)
3.48 Coin Flip (4 lines)
3.49 Math Quiz (5-6 lines)
3.50 Days Between Dates Calculator (4 lines)
3.51 Multiple Pane GUI Demo (6-7 lines)
3.52 Click Counter (2 lines)
3.53 6 One-Line Apps (6 lines)
3.54 Echo Clipboard to File (4 lines)
3.55 Live Code Editor (3 lines)
4. Objectively Compare and Try to Recreate These Apps Using Any Other Tool
4.1 A powerful little computing utility Swiss army knife
5. Why pay any attention to me at all? Why not just learn Python, Javascript, Java...?

1. What if?

Do you have some curiosity about software development (i.e., creating apps, writing code, programming, etc.)?

What if I could show you how to create a little graphic puzzle app by writing 2-3 lines of code? That doesn't sound like it'd be too difficult, right? What if you could build a customized blogging application by writing 7 lines of code? It might be possible to grok that without months of study, I bet. What if you could build a custom web site chat app, image editing app, music practice tool, web server, network messenger, etc., all with just a few simple lines of code? And what if you only had to download a little half-megabyte tool (absolutely nothing else) to run the examples? It sounds quick and easy to get started with that, right? In this text, you'll see and be able to play with 60 app examples which average less than 7 lines of code each, using a tool which takes just a few seconds to download and install.

2. Computers everywhere, but they're too complicated to program... right?

There are computers everywhere in our lives. Most of us carry powerful programmable devices in our pockets, with broadband access to the Internet, multiple cameras, powerful graphics, sound and network features, and tremendous data processing capabilities. The ability to use those machines to accomplish specific tasks, customized exactly according to our own needs, is fantastically enabling. Modern machines can be used for work and for fun, to organize personal and business activities, to collect and manage private and group data, to communicate and share information with others specifically in the ways we choose, etc.

Unfortunately, for the overwhelming majority of modern computer users, learning to program the amazing ubiquitous devices around us seems out of reach. Most users never have a chance to learn more than how to download apps and browse web sites which potentially, hopefully, satisfy at least some intended usage goals (perhaps in a roundabout way, using some proprietary design and set of features implemented by an unknown developer). Many people learn how to use speadsheets, but most users never consider learning to build their own customized apps. After all, learning to develop software is time consuming, and the enormous mess of modern software development tooling doesn't lend itself well to casual tinkering.

Approaching the process of productively creating personalized custom software seems impossible, when there are hundreds of diverse programming languages and even a greater number of popular methodologies, multi-gigabyte IDEs to learn for each language, SDKs with dozens of layers of dependencies to install and maintain, multiple varied and often incompatible 3rd party libraries needed to complete any type of work, APIs with thousands of pages of documentation, etc. Tens of thousands of pages of required reading and hundreds of hours of preliminary study are generally required just to understand the tooling, ecosystems, and work environment associated with each modern development system. Separate tools, and dramatically different schools of thought are associated with building mobile apps, web sites, business systems, games, etc. It's no wonder that software development is generally approached as a full time career endeavor, rather than a part time personal activity.

Well, that complex mainstream experience is the norm, but it's not a necessity. There are lesser known tools which work better than those in mainstream use, for people who are interested in personal programming. It is possible to learn how to create incredibly useful software, quickly and easily, without the overwhelming work and mess associated with building enterprise commercial systems. Specific little programs which do exactly what you want and need, that allow you to use computers to do things which are useful for your own business and personal life, can be built quickly and easily, if you learn to use the right development tools. This page will introduce you to them, and show you how to get started creating software that is actually useful and productive, in a matter of days.

3. Take a look at these examples

There are 60 varied apps in this demonstration, in only 399 lines of readable, non-minified Rebol code: http://re-bol.com/shorter_examples.r The Rebol2 interpreter needed to run these apps on any common OS is about 600 kilobytes, with no external dependencies - all libraries included.

Sound impossible? Give it a try. It literally takes 1 second to download.

Get Rebol from http://rebol.com/download-view.html,
click the console icon and type or copy/paste "do http://re-bol.com/shorter_examples.r" to run all 60 examples.

There's a video run-thru of the apps at https://youtu.be/D50XULVZaYY . They include:

  1. Games and puzzles
  2. 2D and 3D graphics
  3. Photo and image manipulation
  4. Sound and music
  5. Parsing, validation and manipulation of structured and unstructured text
  6. A wide variety of CRUD, database, and business apps
  7. User interfaces of all sorts, a full featured data grid example, etc.
  8. Network (TCP and UDP) text and binary data transfer
  9. Stand alone custom web server implementation
  10. CGI scripting and web site building/management tools for 3rd party servers
  11. Configuration and use of Email, FTP, HTTP, and other standard protocols
  12. Manipulation of HTML, CSV, and other standard data and code formats
  13. DLL/dynamic library examples
  14. Help/documentation
  15. Encryption
  16. Math
  17. I/O
  18. etc...

2 of these examples were written to demonstrate language dialects ('r3D' and 'q-plot'). Each of those tiny libraries is written in 100% pure Rebol code (i.e., no OpenGL, etc. required). All the other examples require absolutely no 3rd party modules or tools of any sort. UI, network, graphics, sound, math, compression, email, CGI, security, DB, protocols, parse, help, etc. are all integrated in the 1/2 meg exe (absolutely no supporting software, not even a web browser, *nothing* else required). Each example here averages just *6.5* lines of code, includes a user interface in the code, and represents the full scope of tooling and work needed to implement the app (no IDE or GUI builder is needed to create any of these examples - you can even use the text editor built into Rebol to edit any of the code). The written descriptions of features in each app actually require many more lines of text than there are total lines of code in all the apps, and just about any tiny text editor used to read this article is likely many times larger then the entire Rebol development system/runtime! No language or development system cuts bloat or improves productivity as dramatically as Rebol. Doubt that statement? Then try to recreate these diverse examples, more productively (i.e., with less total work, time, effort, configuration, setup, layout, etc.) using any other tool. You'll find that it's not possible using any of the mainstream language environments.

Here are the instructions again:

  1. Get Rebol from http://rebol.com/download-view.html
  2. Click the console icon and type or copy/paste "do http://re-bol.com/shorter_examples.r" to run all 60 examples.

Give it a quick try!

3.1 Tile Game (6 lines of code)

The interface displays 1 empty square space and 15 square boxes. Each box displays a unique number on its face. When the user clicks a box, it slides into the adjacent empty space (boxes are only allowed to move if they are next to the empty space). The boxes are arranged in a different random layout, and are displayed in different random colors every time the game is played. The point of the game play, for the user, is to rearrange the boxes in numerical order (so that the rows display the numbers 1,2,3,4; 5,6,7,8; 9,10,11,12; 13,14,15).

random/seed now  g: [style t box red [
  if not find [0x108 108x0 0x-108 -108x0] face/offset - e/offset [exit]
  x: face/offset face/offset: e/offset e/offset: x] across
] x: random repeat i 15 [append x:[] i]  repeat i 15 [
  repend g ['t mold x/:i random white] if find[4 8 12] i [append g 'return]
] append g [e: box]  view layout g

3.2 Simpler Tile Game (2-3 lines):

Here's the simplest possible playable version of the app above, without any extra features. It's possible to explain how this code works in a matter of minutes, even even to children who've never seen any sort of programming language code before.

view layout [
  style t box red [x: face/offset  face/offset: e/offset  e/offset: x]
  across t"8" t"7" t"6" return t"5" t"4" t"3" return t"2" t"1" e: box

3.3 Multiple Camera Video Feed Viewer (4 lines)

The interface consists of an image widget and a list selector widget, which displays the URLs of 27 active cameras. When the user selects any camera URL, a live motion video feed from that camera is displayed in the image widget. Error handling ensures that an unavailable Internet connection or other network problem is taken care of gracefully with a message notifying the user.

for i 2 27 1 [append b:[] rejoin [ i ".jpg"]]
view w: layout [
  i: image 320x240  text-list 320x200 data b [forever [if error? try [
    set-face i load value wait 1 if not viewed? w [unview break]
  ][alert "Connection Error"]]]

3.4 Bar Chart Generator (2 lines)

A pop-up text requestor displays a list of month names and related numerical values. The user can edit (add, delete, change, etc.) these values. When the user submits the values, they are plotted on a graphic bar chart. Each bar in the chart is labeled by one of the user-entered month names, and the size of the bar graphic represents the numerical value related to that month. Error handling ensures that the app doesn't break if the user enters bad data, cancels the entry process, etc.

d: do request-text/default {["April" 13 "May" 9 "June" 21 "July" 29]}
attempt [foreach [m v] d [append g:[] reduce['btn m v * 10]] view layout g]

3.5 Image Effect Demo (4 lines)

An image is downloaded from a URL and displayed in the interface. A list selector widget allows the user to select from a variety of possible effects which can be applied to the image. When an effect is chosen by the user, that effect is applied to the image and displayed in the interface (in this example, the available effects are "Invert" "Grayscale" "Emboss" "Blur" "Flip 1x1" and "None", but many more are included in Rebol). As with many of the other examples, this code can be easily explained to anyone, regardless of previous experience:

view layout [
  pic: image load http://re-bol.com/palms.jpg
  text-list data ["Invert" "Grayscale" "Emboss" "Blur" "Flip 1x1" "None"]
    [pic/effect: to-block value  show pic]

3.6 To-Do List (5-6 lines)

The interface includes a text entry field that allows the user to enter a line of text representing a task to be completed. All of these 'to-do' line items are displayed in a list selector, as they're entered. The user can click on any line item to delete that particular task - a pop-up requestor confirms that the line should actually be deleted. The user can also move the position of any selected item toward the top of the list, one line at a time, by clicking on the 'up' button in the interface. The user can also save the current list to a file, and load a previously saved list by clicking 'save' and 'load' buttons in the interface. Error handling includes not only the delete confirmation, but also any attempt to move selected items beyond the top of the list, and any attempt to load a data file which hasn't yet been created (or which is in an inappropriate format, corrupted, etc.).

view layout [
  t: text-list [if request "Delete?" [remove find t/data value  show t]]
  field [append t/data copy value show t clear-face face] across
  btn "Up" [attempt[move/to z: find t/data t/picked(index? z)- 1]show t]
  btn "Save" [save %todo.txt t/data  alert "Saved"]
  btn "Load" [attempt [t/data: load %todo.txt  show t]]

3.7 Madlib (3 lines of code, 1 line of default madlib text)

The interface displays a default example madlib text, which can be freely edited by the user. The edited text may include any number of lines, any number of madlib word choices, etc. (in this example, the madlib choice descriptions are displayed within angle brackets in the editable text). When the user submits the text, the app parses out the madlib choice entries, requests each of the madlib words from the user, and then displays the final created madlib, with the bracketed choices replaced by the words chosen by the user.

t: {<name> found a <thing>. <name> ate the <adjective> <thing>.}
view layout [a: area wrap t  btn "Make Madlib" [x: a/text unview]] 
if value? 'x [parse x [any [to "<" copy b thru ">" (append w:[] b)]to end]
foreach i unique w [replace/all x i ask join i ": "]  alert x]

3.8 Pig Latin (3 lines)

The interface allows the user to enter a line of text, which is then parsed and converted according to the rules of Pig Latin. In this example, the input and output are displayed in a console interface.

foreach t parse ask "Type a sentence:^/^/" "" [
  x: parse t "aeiou" prin rejoin [
    either m: find/match t x/1[m][t]x/1 either m["ay"]["hay"]" "
] ask "^/^/Press ENTER to Continue..."

3.9 GUI Calculator (7-8 lines)

The user interface provides buttons numbered 0-9, a decimal point, and buttons representing addition, subtraction, multiplication, division, and equals operations. When the user clicks any button, a text field widget is updated to display the current computation (just as in a typical physical calculator), and when the equal sign is pressed, the displayed computation is evaluated. Error handling is provided so that divide-by-zero and other inappropriate operations don't break the app.

view layout [ 
  style b btn 50x50 [append f/text face/text show f]
  f: field 225x50 font-size 25  across
  b "1"  b "2"  b "3"  b " + "  return 
  b "4"  b "5"  b "6"  b " - "  return 
  b "7"  b "8"  b "9"  b " * "  return 
  b "0"  b "."  b " / "  b "=" [
    attempt [f/text: form do f/text show f

3.10 Calendar/Scheduler (5-6 lines)

The user is able to select any date using a calendar requestor widget. Events for the selected day are automatically saved to a file, and can be easily retrieved, altered, added to, deleted, etc., by simply reselecting and editing the contents of any chosen day.

write/append %m ""  forever [ 
  if not d: request-date [break]
  view layout [ 
    text bold form d 
    a: area form select (l: load %m) d 
    btn "Save" [save %m head insert l reduce[d a/text] unview]

3.11 Speed Reader (3-4 lines)

This app provides a means for the user to practice and test their own speed reading ability. The interface consists of a text area, two buttons, and a slider. The user types or pastes text into the text area, selects a speed with the slider, and clicks the button. Each consecutive word of the text is then displayed using a 45 point font on the face of the large button, at the selected speed (calculated as words per minute). The speed can be adjusted while the text is being displayed.

view layout [
  area "Reader Text"[foreach i parse face/text ""[a/text: i show a wait s]]
  a: btn 400x200 font-size 45  b: btn 400x30 bold (form 60 * 1 / s: 1)
  slider 400x30 [attempt [b/text: form round 60 * 1 / s: 1 - value show b]]

3.12 Paypal Report (3 lines)

The intent of this report is to go through each line in a Paypal account file and display the money value of any transaction which occurred between midnight and noon on any day. A Paypal account transaction CSV file is downloaded from a URL. The first line of that file consists of descriptive headers, so this report begins processing at line 2. The data values in each line are separated at the comma delimiters. The second item on each line is converted to a time value. If that time value is greater than midnight, or less than noon, then the eighth value in the line (the money value for that transaction), is collected and displayed in a list.

foreach line at read/lines http://re-bol.com/Download.csv 2 [
  time: to-time second row: parse/all line ","
  if (time >= 0:00am) and (time <= 12:00pm) [append rp:[] row/8]
] view layout [text-list data rp]

3.13 Local and Remote IP Addresses (2 lines)

The local (LAN) IP address of the user's machine is obtained from local DNS information, and the external address is retrieved from a remote server. In this case, the WAN address is parsed from a small Rebol CGI script running on a private web server, but that information could be just as easily parsed from the results of any public 'what-is-my-IP' type server.

parse read http://guitarz.org/ip.cgi [thru <title> copy w to </title>]
alert rejoin [read join dns:// read dns:// " -- " last parse w none]

3.14 FTP Site Editor (4-5 lines)

This app enables the user to visually list, select, and edit any file on any FTP server. The interface allows the user to enter Username and Password credentials to any FTP server URL, and select a folder. Every file in the selected folder is displayed in a list selector. When the user selects a file, that file opens in a text editor, where it can be edited by the user, and then saved back to the server. Error handling is provided to notify the user of any connection errors.

view  layout [
  f: field 600 "ftp://USER:PASS@URL.com/public_html/" [if error? try [
    if dir? do value [t/data: sort read to-url value  show t]
  ][alert "Proper username, password, URL and folder required"]]
  t: text-list 600x400 [editor to-url join f/text value]

3.15 Wave File Sound Player (3-4 lines)

A folder selector allows the user to click on any folder available on the local machine. Only the .wav files found in that folder are displayed in a list selector, and the selected WAV sound is played when the user clicks a file name. Error handling is provided in case a chosen .wav file is not the proper format, is corrupt, etc.

files: remove-each f read d: %/c/Windows/media/ [%.wav <> suffix? f]
view layout [
  t: text-list data files [attempt [
    insert s: open sound:// load join d value  wait s  close s

3.16 Freehand Draw (7-8 lines)

A blank canvas is provided in the interface, and the user can sketch freehand drawings with the mouse (touch screen, pointing device, etc.). The user can save any drawing to a file name of their choice, by clicking the 'Save' button. The user can also clear the screen and begin a new drawing by clicking the 'Clear' button.

view layout [
  s: area 500x400 white feel [
    engage: func [f a e] [
      if a = 'over [append s/effect/draw e/offset  show s]
      if a = 'up [append s/effect/draw 'line]
  ] effect [draw [line]]
  btn "Clear" [s/effect/draw: copy [line] show s]
  btn "Save" [save/png request-file/only/file %myimage.png to-image s]

3.17 3D Gradient Cube (5-6 lines)

This app is a demonstration of Rebol's 'Draw' dialect. The interface displays a box, on which a 3D cube is drawn, using 3 polygons of different colors. A gradient color effect is applied to the entire drawing.

view layout [box 400x220 effect [
  draw [
    fill-pen 200.100.90    polygon 20x40 200x20 380x40 200x80
    fill-pen 200.130.110   polygon 20x40 200x80 200x200 20x100
    fill-pen 100.80.50     polygon 200x80 380x40 380x100 200x200
  ] gradmul 180.180.210 60.60.90

3.18 Animated 3D Image Transform (4-5 lines)

This is another Draw dialect demo. The interface consists of a black box, upon which the Rebol logo is drawn. A loop is repeated 4 times to produce an animated transformation in which the logo appears to twist and spin with a 3D effect.

view/new layout/tight [b: box 400x400 black effect [draw []]]
loop 4 [t1: 50x10 t2: 350x200 t3: 250x300 t4: 50x300  loop 155 [
  t1: t1 + 1x1  t4: t4 - 1x1 
  b/effect: [draw [image logo.gif t1 t2 t3 t4]] show b
]] unview

3.19 Full Screen Slides (6 lines)

This app displays a presentation of 3 consecutive full screen slide layouts. Each page is sized to cover the user's entire screen, and begins with a text header in the top left corner. The first page displays a single list box, the second page displays 3 images, and the 3rd page displays 2 box graphics with color and gradient effects. When the user clicks any blank space on each slide, the presentation is moved forward to the next slide.

hdr: [at 0x0 box system/view/screen-face/size white [unview] at 20x20]
foreach s [
  [h1"List" text-list"1""2""3"]
  [h1"Images" image stop.gif image info.gif image help.gif]
  [h1"Graphics" box 300x300 effect[gradient sky] box red]
][view/options center-face layout append copy hdr s 'no-title]

3.20 TCP Text Messenger (9-10 lines)

The interface allows the user to run this app as either a server or a client. The local IP address is displayed, and a user running the app in client mode can edit the address of the server. A text entry field allows the user to type messages to be sent between client and server. Received messages are displayed in a scrolling text area (users of both the client and server can both send and receive messages). Two instances of the app are opened in separate processes, to demo the app communicating on a single localhost machine.

write %messenger.r {REBOL [] view layout [ across
  b: btn "Serve"[focus g p: first wait open/lines tcp://:8 z: 1]text"OR"
  k: btn "Connect"[focus g p: open/lines rejoin[tcp:// i/text ":8"]z: 1]
  i: field form read join dns:// read dns://  return
  r: area rate 4 feel [engage: func [f a e][if a = 'time and value? 'z [
    if error? try [x: first wait p] [quit]
    r/text: rejoin [x {^/} r/text] show r
  ]]]  return
  g: field "Type message here [ENTER]" [insert p value  focus face]
]} loop 2 [launch %messenger.r]

3.21 HTML Form Server/Processor (8-9 lines)

A TCP server is started on port 80, and an HTML form is served to any browser which connects (the server can handle as many local or remote connections as your machine's hardware will allow). To demonstrate the server, the default browser is opened on the host machine, and the served HTML form is displayed. All data entered from connected browsers is displayed in the server console, and each entry is stored to a log file. The server can be closed by typing "quit" into the HTML form.

port: open/lines tcp://:80   browse http://localhost?   print ""
forever [
  p: port/1 attempt [
    probe x: decode-cgi replace next find p/1 "?" " HTTP/1.1" ""
    write-io p h:  {HTTP/1.0 200 OK^/Content-type: text/html^/^/
    <HTML><BODY>'QUIT' to close server<br><br><FORM action="localhost">
      Name:<input type="text" name="name"><input type="submit">
    </FORM></BODY></HTML>} length? h  write/append %f join x/2 newline
  ] close p  if x/2 = "quit" [break]

3.22 File Encrypt/Decrypt Utility (6-7 lines)

The interface allows the user to select a file from any drive on the local machine. The user then types a password and clicks the 'encrypt' button, and the file is saved in encrypted format to any file name chosen by the user. The user can then select and decrypt any previously encrypted file by typing the appropriate password and clicking the 'decrypt' button.

view layout [
  across  f: field  btn "Select File" [f/text: request-file/only show f]
  return  f2: field "(enter password)"  btn "Encrypt" [
    save request-file/only/save/title/file 
      "Save encrypted file as:" "" to-file f/text  
      to-binary encloak read to-file f/text f2/text  alert "Saved"
  btn "Decrypt" [editor to-string decloak load to-file f/text f2/text]

3.23 Compress and Embed a Binary File in Code (3 lines)

A file requestor dialogue allows the user to chose any local file to be embedded in code (a file of any sort, even executable, video, etc., could by chosen to be embedded in code, but for the purposes of this example, the user is expected to chose an image type (jpg, png, gif, png)). The file is compressed and converted into a text format which, for example, could be copied and pasted into a script, sent in an email, posted on a web page, etc. The code containing the embedded file is displayed in a text editor, for the user to examine, edit, save to a file, copy to the clipboard, etc. The embedded version of the file is then decompressed, and the image contained in the file is displayed in a GUI window.

system/options/binary-base: 64
editor picture: compress form read/binary request-file/only
view layout [image load (do decompress picture)]

3.24 Chord (Sound Accompaniment) Looper (11-12 lines)

The interface allows user to type in names of musical chords, enter a speed setting, and click a 'play' button to continually play the sound of those chords in a loop. The user can click a 'stop' button to stop the sound from playing. Songs made up of any number of entered chord names can be saved and loaded. The sounds are downloaded in a single binary file in which the WAV data of every chord sound is encoded (using the standard Rebol format to encode binary files of any type, demonstrated in the previous example).

do load-thru http://re-bol.com/chords.r
check: does [if unset? snd/state/inBuffer [break] if not viewed? w [break]]
view w: layout [
  h2 "Chords:"  a: area {bm bm g g d d em gb7}  across
  h2 "Speed:"   f: field 50 "3.3"
  btn "PLAY" [
    snd: open sound://
    forever [check  foreach s load a/text [
      check  insert snd do s  wait snd  wait (1 / load f/text)
  btn "STOP" [close snd]
  btn "Save" [attempt [save request-file/only/save a/text]]
  btn "Load" [attempt [a/text: load request-file/only show a]]

3.25 Blogger (6-7 lines)

The interface allows the user to enter username, password, URL, and folder information for an HTML file which will display blog entries created by the user. The user can type a new entry and click the 'publish' button, and that entry will be automatically added to the user's blog page. The blog page is then opened in the user's browser to allow the changes to be viewed. The user can edit the contents of the blog at any time, by clicking the 'edit' link in the interface. Error handling allows the app to respond gracefully if the server can't be connected or if the user chooses to cancel the connection.

u: do request-text/default "ftp://user:pass@url.com/public_html/blg.html"
if all [u  not error? try [write/append u ""]][
view layout [
  a: area 400x300 "Today I ..." across 
  btn "PUBLISH" [ 
    write u rejoin [{<pre>}now{^/^/}get-face a{</pre><hr>}read u] browse u
  ] text "Edit" [editor u]

3.26 Email Account Setup/Reader/Sender (9 lines)

The code of this app demonstrates how to configure Rebol's connection to an email server (username, password, SMTP and POP hosts, email address, etc.). The interface allows the user to enter an email address and a message, and the message can be sent by clicking the 'send' button. The user can also read each of the emails in an account inbox by clicking the 'read' button. By default, only the first 5000 characters of each email are displayed. Error messages are displayed to gracefully handle any trouble encountered when sending or reading emails.

system/user/email:  you@url.com   ss:  system/schemes  
ss/default/host:  "smtp.url.com"  ss/default/user:  "username"
p: ss/pop/host:  pop://url.com    ss/default/pass:  "password"
view layout [
  f: field "name@url.com"  a: area "(message)"
  btn "Send" [alert either attempt[send do f/text a/text]["Sent"]["Error"]]
  btn "Read" [if error? try [
    foreach m read p [y: import-email m  ask copy/part y/content 5000]
  ][alert "Error Connecting to Server"]]

3.27 Generic CRUD App - Card File (7 lines)

The interface allows the user to enter two fields and one multi-line area of text. The user can click buttons to save, edit, delete, create new records, edit the raw database info directly, etc. Error handling ensures that the app won't crash if the user cancels any operation, attempts to open an empty file, etc. All data is stored to a single file which is generated automatically, and which can be moved to any machine on which Rebol runs (no third party database system or any other tools are required).

n: [foreach i[a b c][set-face get i""]focus a]  s: [save %d d  alert"ok"]
x: [do z  repend d[a/text b/text c/text] save %d d  do n]  
y: [attempt[r: copy/part(find/skip d (request-list"" extract d 3)3)3
  repeat i length? j:[a b c][set-face get j/:i r/:i]]]
z: [remove-each[i j k]d[i = a/text] do s]  write/append %d ""  d: load %d
view g: layout[a: field b: field c: area across btn"New"[do n]
  btn"Save"[do x] btn"Edit"[do y] btn"Delete"[do z do n]btn"Raw"[editor %d]

3.28 Grid w/ edit, add, delete, find, sort, sum, save/load, etc. (20 lines)

A block of random data is generated, with 999 rows, each consisting of 3 columns: a unique incremented numeric ID, a random date/time value, a randomly ordered string of the characters "abc". The interface displays the data block in a grid widget. The user can sort the columns visually by clicking column headers. The numeric column values are sorted ordinally, the date values are sorted chronologically, and the text values are sorted alphabetically. The user can edit any of the text column values, but the other columns are left uneditable, and the display of each column is styled differently to clarify which are editable. A slider widget is provided to allow the user to scroll the grid up or down, and a key scroll option is also available to provide finer grained control (the down arrow key scrolls the display 10 rows down). Although this example only displays 999 lines, the display performance is just as fast if tens of millions of rows are displayed (obviously, sorts, searches and other data processing features are slower with enormous data sets, but the visual scrolling performance is just as quick, regardless of the data set size). The user can add new randomly generated rows by clicking the 'add' button (adding rows based on other criteria is just as easy). The user can also delete any desired row. A 'find' button allows the user to enter a search term, view the rows in which the term is found, and then jump to that row in the display. 'Save' and 'load' buttons are provided to allow the user to store and retrieve the entire data block to/from a file. 'Sum', 'Average', and 'Max' buttons are provided to allow the user to perform those computations on the first column of numerical values (of course, any other imaginable computation could be performed upon any set columns, rows, or definable subset of the data block). Error handling is provided where needed to ensure the user won't break the app unintentionally by canceling, entering bad values, or otherwise misusing the features of the grid. It's important to note that the code needed to display the grid data consists of 3 lines. All of the features of this app are created using basic Rebol language series functions which can be composed and manipulated as needed (i.e., this app is created using plain native Rebol code, not some monolithic grid library with an esoteric API). The grid layout itself can also be used to display any other type of widget which can be displayed in Rebol's default VID (GUI) dialect: images, animations, buttons, etc.

s: 0  asc: 1  repeat i 999 [repend/only x:[] [i random now random "abc"]]
edit: func [f] [f/text: request-text/default f/text show l]
srt: func [c] [sort/compare x func [a b] [(at a c)< at b c]
  if asc: not asc [reverse x] show l]
view g: layout [
  style t text 91x24 edge [size: 2x2][edit face]  across  space 0x0
  h4 "ID" 55 [srt 1]  h4 "Date" 200 [srt 2]  h4 "Text" [srt 3]  return
  l: list 350x412 [across  space 0x0  info 55 tan  info  t] supply [
    face/text: either e: pick x count: count + s [e/:index] [none]
  ] sl: slider 20x412 [s: value * length? x show l] return
  btn "Add"[y: maximum-of x repend/only x[1 + y/1/1 random now cp""]show l]
  btn "Delete" [r: do request-text/title"#" remove-each i x[i/1 = r]show l]
  btn "Find"[u: cp[] h: request-text foreach i x[if find v: form i h[append
    u v]] if not f: request-list""u[exit]s:(do first parse f"")- 1 show l]
  btn "Save" [attempt [save request-file/only/save/file %x.txt x]]
  btn "Load" [attempt [x: load request-file/only/file %x.txt show l]]
  btn "Sum" [sm: 0 foreach i x [sm: sm + i/1] notify form sm]
  btn "Avrg" [sm: 0 foreach i x [sm: sm + i/1] notify form sm / length? x]
  btn "Max" [foreach i x [append y:[] i/1] notify form first maximum-of y]
  key keycode [down] [sl/data: (s: s + 10)/ length? x show g]

3.29 VOIP Network Intercom (19 lines)

Two separate apps are launched as separate processes: 1 sender and 1 receiver. The receiver app opens a TCP network port (with error handling), and opens a sound port. This server then waits for binary Wave (sound) files to be transferred from the sender app. Each sound is played on the receiver machine, as they are received. The sender app opens a TCP connection to the server machine and sends recorded wave files over the network. The sender app is intended to be run on an MS Windows machine, and demonstrates how to load and use the winmm.dll file found on Windows systems. That DLL is used to record streams of sound from the sender microphone. The recorded sound streams are compressed and sent over the network. A squelch feature is included so that only sounds which are louder than a set limit are sent. The code syntax used to access DLL files in this example works across platforms (i.e., this code demonstrates the same basic method and syntax used to access dynamic libraries on Linux, Mac, and other systems too).

write %ireceive.r {REBOL []
if error? try [port: first wait open/binary/no-wait tcp://:8] [quit]
wait 0  speakers: open sound://
forever [
  if error? try [mark: find wav: copy wait port #""] [quit]
  i: to-integer to-string copy/part wav mark
  while [i > length? remove/part wav next mark] [append wav port]
  insert speakers load to-binary decompress wav
]} launch %ireceive.r   write %isend.r {REBOL []
lib: load/library %winmm.dll
mci: make routine! [c [string!] return: [logic!]] lib "mciExecute"
if (ip: ask "Connect to IP (none = localhost):  ") = "" [ip: "localhost"]
if error? try [port: open/binary/no-wait rejoin [tcp:// ip ":8"]] [bbb: 0]
mci "open new type waveaudio alias wav"
if not value? 'bbb [forever [
  mci "record wav"  wait 2  mci "save wav r"  mci "delete wav from 0"
  insert wav: compress to-string read/binary %r join l: length? wav #""
  if l > 4000 [insert port wav]  ; squelch (don't send) if too quiet
]]} launch %isend.r

3.30 Catch Game (11 lines)

The user controls a paddle image which moves back and forth across the bottom of the screen. The direction of the paddle movement is switched by pressing the space bar. The paddle stops moving whenever it touches either the left or right hand edge of the screen - movement continues again whenever the user presses the space bar. An image (in this case the Rebol logo) continually falls from random positions along the top of the game screen. The user must time the movement of the paddle to catch the falling logos. The point of the game is to continue catching falling logos for as long as possible. The speed of the falling logos progressively increases as the game goes on. A timer in the top left corner of the screen keeps track of how long the game runs. The game is over when more logos have been missed than caught. The final score is the amount of time for which game play was sustained. When the game is over, a dialogue requesting the user's name is displayed. A high score board, with all the names and scores, sorted from highest to lowest, is displayed to the user. Note that this game is created without the use of any special game development library. It's made entirely using the standard GUI dialect which ships with Rebol (11 lines of code total).

s: 1 p: 3 d: 10 n: now/time
r: func [x] [y/offset: random 500x-20  p: p + .1  s: s + x] 
view/new ww: layout/size [ 
 t: text 200 y: image logo.gif #" "[d: negate d] at 350x415 z: btn blue
] 600x440 forever [ 
  y/offset/2: y/offset/2 + round p z/offset/1: z/offset/1 - d 
  z/offset/1: switch/default z/offset/1[0[0 + d]550[550 + d]][z/offset/1]
  if overlap? z y [r +1] if y/offset/2 > 420 [r -1] 
  t/text: form now/time - n wait .01 show ww if s = 0 [ 
    write/append %h "" save %h sort/skip append h: load %h reduce 
    [t/text request-text/title "Name:"]2  request-list""h  unview break

3.31 Snake Game (11 lines)

The game interface consists of a 20x20 grid of snow colored squares. The player's snake is initially made up of 1 red square, which moves continually around the screen. The direction of the snake's movement can be changed to up, left, down, or right using the WASD keys on the keyboard. The point of the game is to navigate the snake to 'eat' blue 'food' squares which appear at random locations on the grid. Every time the head of the snake eats (collides with) a food square, the length of the snake's tail grows by 1 segment, and the snake moves a bit faster. Each segment in the snake's tail follows the path of the snake's head. If the snake head collides with any outer wall of the playing field or with any segment of the snake's body, then the game is over. The final score is determined by counting the total number of segments in the snake's body.

f: random 400  p: .3  d: 20  s: copy [1]  g: copy [
  across key #"w"[d: -20]key #"s"[d: 20]key #"a"[d: -1]key #"d"[d: 1]origin
] repeat i 400 [
  append g reduce [to-set-word join "p"i 'box 'snow 20x20]
  if i // 20 = 0 [append g 'return]
] e: does [alert "Oops" unview break]  w: view/new layout g  forever [
  if any [all[d = -1 s/1 // 20 = 1] all[d = 1 s/1 // 20 = 0]] [e]
  if find s h: s/1 + d[e]insert head s h do rejoin["p"last s"/color: snow"]
  either f = s/1 [f: random 400  p: p - .01][remove at s length? s]
  repeat i length? s[if error? try[do rejoin["p"s/:i"/color: red"]][e]]
  do rejoin ["p"f"/color: blue"]  show w  if not viewed? w [break]  wait p

3.32 Mine Field Game (10 lines)

The interface starts with a 10x10 grid of empty buttons. The user left-clicks any button to uncover what's hidden underneath. If the user clicks a button where a mine is found, the game is over, and the user loses. Otherwise, the number of mines found under each surrounding button is calculated and displayed. The user can right-click any button to mark it as a location where a mine is found. The goal is to mark all the mines, without being blowing up. The game will determine when all the mines have been properly found and marked. The number of lines and columns, and the number of mines can be easily edited in the code.

m: copy/part random repeat i k: 100 [append m:[] i] l: 14
e: does [x: 0  y: 0  foreach b system/view/screen-face/pane/1/pane [
  if b/text <>""[++ x]if b/text ="X"[++ y]if all[x = k y = l][alert"Win"]
]]  g: [across  style b btn 50x50 [c: 0  foreach [i j] reduce [-10 yes 10
  yes -11 s: 1 <>(face/d // 10)-1 s 9 s -9 t: 1 <>(face/d // 10)1 t 11 t
][if all [j find m(i + face/d)][++ c]]
  face/text: c  if find m face/d [face/text:"X" alert"Boom!"unview break] e
][face/text: "X" e]]  repeat i k [
  repend g ['b 'with compose[d:(i)]]  if 0 =(i // 10)[append g 'return]
] view layout g

3.33 Guitar Chord/Scale Diagram Maker (13 lines)

The purpose of this app is to help guitarists, bassists, ukulelists and players of other stringed/fretted instruments quickly draw and save images of labeled chord, scale, and arpeggio diagrams. A text requestor dialogue allows the user to set the number of frets in each diagram (default number of frets is 5). The interface consists of 6 vertical 'strings' segmented into the chosen number of frets. The user can click any string/fret segment, and a finger marker is placed at that location. Clicking a chosen finger marker again toggles that location back to an empty segment. Right-clicking a segment allows the user to choose any character which will be placed at that location. Clicking the header text allows the user to type a name or descriptive title for the diagram (i.e., a chord, scale, or arpeggio label, etc.). Right-clicking the header allows the user to save the created image to any file name of their choice (default file name is the text entered into the header line).

f: request-text/title/default "Number of frets in each diagram:" "5"
g: copy [
  backdrop white across  space 0x0  origin 0x0
  style s box 20x20 "|" font-size 20 font-color black shadow 0x0 [
    face/text: either "|" = face/text ["O"]["|"]
  ][face/text: request-text]
  t: text 120x24 bold center font-size 18 "Chord Name" [
    face/text: request-text/default face/text
  ][attempt [
    save/png request-file/save/only/file join t/text ".png" to-image w
  ]] return
] loop to-integer f [append g [s s s s s s return]] 
alert "Right-click chord name to save image"  view w: layout g

3.34 Cash Register (13 lines)

The user interface consists of a text area, 2 buttons, and 5 text entry fields. 2 of those fields above the text entry area are labeled 'Item', and 'Price'. In those fields, the user continuously enters descriptions and prices of items which customers have brought to a retail checkout. Error handling ensures that the user cannot enter non-decimal numbers into the price field. Each item entry is added to a scrolling list display in the large text area, and the subtotal, tax, and total sale values are calculated and displayed in the text fields labeled 'Items', 'Tax', and 'Total', below the text area. When all the retail items have been entered into the register, the user clicks the 'Save' button. This saves all the data in the sale (item descriptions/prices, and current date-time) to a record in a file, using a native format which can be easily parsed and computed for later reporting. A receipt image (neatly cropped screen shot) is displayed in the browser, where it can be printed for the customer. The fields of the cash register screen are then automatically cleared so that a new sale can be entered. The user can click the 'Report' button to calculate and display the total dollar amount of items sold on the current day, as well as a total of cash collected (including sales tax) and a count of the total number of items sold. A report of any complexity, using any criteria (dates and times, item prices and descriptions, as well as any other info added to the register layout (cashier name, for example)) could be easily created using this code, simply by specifying the desired conditional operations to be performed. No SQL or RDBMS required. See http://freeconsignmentsoftware.com for a popular commercial POS consignment software system written in Rebol, by the author of these examples.

view g: layout [
  across  m: field"(item)"  p: field"(price)" [
    if error? try [to-money p/text][alert "Price error" return]
    repend a/text [mold m/text tab p/text"^/"] m/text: cp"" p/text: cp""
    u: 0  foreach [i r] load a/text [u: u + to-money r]
    s/text: u  x/text: u * .06  t/text: u * 1.06  show g
  ] below a: area 600x250 s: field"Items" x: field"Tax" t: field"Total"
  btn "SAVE"[write/append %sold rejoin [mold load a/text now/date]
    focus t save/png %rc copy/part at to-image g 18x50 604x350 browse %rc
    foreach i ['s 'x 't 'a] [do rejoin [i {/text: cp""}]] focus m  show g
  ] btn "Report" [if attempt [l: load %sold  u: $0 c: 0][
    foreach [i d] l [if now/date = d [foreach [k j] i [++ c u: u + do j]]]
    notify rejoin [{Total sales today: } u { (}u * 1.06{) }c{ items}]

3.35 Form Entry Validation (8 lines)

This app demonstrates how to validate the syntax of data entered into a user interface form. The user is notified whenever a value has been submitted with improper formatting during the process of data entry. In this example, 2 types of character sets are defined. 'nums' are defined as the numbers 0-9, and 'alfs' are defined as the characters 'a'-'z' lowercase and 'A'-'Z' uppercase. 4 fields are presented in the user interface. The code contains a user-defined 'validate' function, whose purpose is to scan each of these fields according to separate data format rules. Data entered into the first field must consist of any 8 numbers. Data entered into the second field must consist of any 4 numbers. The third field is intended to contain a phone number, and must consist of an opening parenthesis, 3 numbers, a closing parenthesis (the area code), 3 numbers, a dash, and then 4 final numbers. The last field is intended to contain an email address, and must consist of any number of alphabetic characters, then the '@' symbol, then any number of alphabetic characters again, then a dot, and then 3 alphabetic characters. When the user starts the app, the first field is focused, and an alert message pops up any time a data entry error is encountered.

nums: charset "0123456789" alfs: charset [#"a" - #"z" #"A" - #"Z"] call ""
validate: func [f rule] [if not parse f/text rule [alert "Invalid"]]
view layout [ 
  f1: field "12345678" [validate face [8 nums]] 
  field "1234" [validate face [4 nums]] 
  field "(555)123-2345" [validate face ["(" 3 nums ")" 3 nums "-" 4 nums]]
  field "me@url.com" [validate face [some alfs "@" some alfs "." 3 alfs]]
  do [focus f1] 

3.36 Help (4 lines)

This app displays all of Rebol's built-in functions (a total of 556) in a list selector. When the user clicks any function, the source code (if available) and help information for the selected function is displayed. This help requires no externally loaded information. All the help is drawn entirely from documentation contained in the tiny Rebol executable.

foreach i copy first system/words [
  attempt [if any-function? get to-word i [append w:[] i]]
] p: does [print "^/^/"] view layout [
  text-list data sort w [x: to-word value source :x p ? :x p]

3.37 Year Calendar (9 lines)

The user is asked to enter a year (default is the current year). A properly formatted calendar is printed for all 12 months of the chosen year. A header for each month is printed, followed by column headers displaying labels for the days Monday-Sunday, then a layout showing each numbered day of each month, laid out with the first day starting in the correct day column, wrapping each line at Sunday, and ending with the proper last day of the month. Leap years are handled correctly.

do [if "" = y: ask "Year (ENTER for current):^/^/" [prin y: now/year]
foreach m system/locale/months [
  prin rejoin ["^/^/     " m "^/^/ "]
  foreach day system/locale/days [prin join copy/part day 2 " "]
  print ""  f: to-date rejoin ["1-"m"-"y]  loop f/weekday - 1 [prin "   "]
  repeat i 31 [
    if attempt [c: to-date rejoin [i"-"m"-"y]][
      prin join either 1 = length? form i ["  "][" "] i
      if c/weekday = 7 [print ""] 
] ask "^/^/Press ENTER to Continue..."]

3.38 UDP Chat (11 lines)

A pop-up dialogue requests the user's name. The user can then send and receive messages with any other user(s) on the local network. Messages are displayed in a scrolling text box. The point of this example is not just to demonstrate another chat app, but to demonstrate use of the UDP network protocol. UDP does not require any connection to a centralized server. Instead, messages are simply broadcast over the network, and any other listeners can receive those broadcast messages. This connectionless protocol is especially useful in game designs which require the fastest possible network communications, because UDP requires none of the time consuming error checking enforced by TCP. UDP is also useful in creating certain types of network utilities (which for example, could be used to broadcast the IP address of a TCP server to clients, or any other application in which machines need to connect without previously having access to a known server address).

net-in: open udp://:9905   net-out: open/lines udp://
set-modes net-out [broadcast: on]
name: request-text/title "Your name:"
gui: view/new layout [
  a1: area wrap rejoin [name ", you are logged in."] 
  f1: field 
  k1: at 0x0 key #"^M" [
    if f1/text = ""[return]  insert net-out rejoin [name ":  " f1/text]
] forever [
  focus f1  received: wait [net-in]  if not viewed? gui [break]
  insert (at a1/text 1) copy received  show a1

3.39 3D Graphics - r3D library example (17 lines)

This interface consists of a black box which displays a drawn 3D cube, and 6 slider widgets which allow the user to control all 3 axes of the cube's rotation, along with 3 axes of camera angle from which the cube can be viewed. This example makes use of the r3D library by Andrew Hoadley, which is downloaded from http://re-bol.com/r3d.r in the code. The r3d library is 105 lines of compressed pure Rebol Draw dialect code. Draw dialect is built into all versions of Rebol/View by default, runs the same on every operating system, and requires absolutely no 3rd party dependencies of any sort (no OpenGL, etc.). This app displays the draw dialect commands created by the r3D dialect, in real time, as the user manipulates the scene (this feature can be shut off by simply commenting out the 'probe RenderTriangles' code at the end of the 'update' function).

do http://re-bol.com/r3d.r
Transx: Transy: Transz: 300.0  Lookatx: Lookaty: Lookatz: 100.0
update: does [ 
  append world: copy [] reduce [
    reduce [cube-model (r3d-scale 100.0 150.0 125.0) red]]
  camera: r3d-position-object reduce [Transx Transy Transz]
    reduce [Lookatx Lookaty Lookatz] [0.0 0.0 1.0]
  RenderTriangles: render world camera r3d-perspective 250.0 400x360
  show scrn   probe RenderTriangles
view layout [
  scrn: box 400x360 black effect [draw RenderTriangles] across
  slider 60x16 [Transx: (value * 600 - 300.0) update]
  slider 60x16 [Transy: (value * 600 - 300.0) update]
  slider 60x16 [Transz: (value * 600) update]
  slider 60x16 [Lookatx: (value * 400 - 200.0) update]
  slider 60x16 [Lookaty: (value * 400 - 200.0) update]
  slider 60x16 [Lookatz: (value * 200) update] do [update]

3.40 CGI Photo Album (7 lines)

This example is a web app, meant to run on an Apache server. To run it, just upload the tiny Rebol interpreter to your server, set permissions to 755, and edit the location of the Rebol interpreter in the script. This app is commented out in the running example code because it needs to be installed on a server, but you can see it run at http://re-bol.com/photos.cgi (these examples automatically open the user's browser to that page). The script reads a listing of all the files in the folder where it is located on the server, removes any file from the folder list which is not an image, and then displays each of those images centered in the user's browser, along with a count of the total number of images displayed.

#!./rebol -cs   ; location of Rebol interpreter
REBOL [title: "CGI Photo Album"]  print {content-type: text/html^/}
print {<HTML><HEAD><TITLE>Photos</TITLE></HEAD><BODY>}
c: 0  foreach file read %./ [
  if find [%.png %.jpg %.gif %.bmp] suffix? file [
    print rejoin [{<BR><CENTER><img src="} file {"></CENTER>}] c: c + 1
] print rejoin [{<BR>Total Images: } c {</BODY></HTML>}]

3.41 CGI Group Chat (6 lines of Rebol code + 6 lines of HTML form code)

This is another web app, which can be found running at http://re-bol.com/chat.cgi (the user's browser is opened to that page). This app displays an HTML form into which users can type their name and a message. All messages from all users are displayed, along with their name and a date-time stamp. The basic structure of this app can be used to implement forums and other multi-user, multi-topic web apps. See http://rebolforum.com for such a web app, which has received 10s-100s of thousands of monthly user views since 2010.

#!./rebol -cs
REBOL [title: "CGI Group Chat"]  print {content-type: text/html^/}
write/append url: %./chat.txt ""   sbmttd: decode-cgi read-cgi
if sbmttd/2 <> none [
  write/append url rejoin [now " (" sbmttd/2 "):  " sbmttd/4 "^/^/"]
print rejoin [
  "<pre>" copy read url "</pre>"
    Name:<br><input type=text size="65" name="username"><br>
    Message:<br><textarea name=message rows=5 cols=50></textarea><br>
    <input type="submit" name="submit" value="Submit">

3.42 Desktop Group Chat (5 lines)

This console app displays the messages entered using the web chat above, and allows the users to enter messages into that chat, and visa-versa. The two apps are totally interoperable. Any messages typed into the web app appear in the desktop app, and any messages typed into the desktop app appear in the web app.

if attempt[write/append url: ftp://usr:ps@url.com/public_html/chat.txt""1][
  name: copy ask "^LName:  "
  forever [
    if "" <> msg: ask rejoin [newpage copy read url "Message:  "][
      write/append url rejoin [now " (" name "):  " msg "^/^/"]

3.43 Pie Chart - q-plot library demo (3 lines)

This app is the only other 3rd party library demo in all the examples. It demonstrates just a few features of the q-plot language dialect. Language dialects are one of the main reasons for Rebol's existence. Rebol was designed from the ground up to create dialects (small purpose- built languages) such as this. Dialects are one of the primary reasons why Rebol code is always so ridiculously short and simple, and why the Rebol interpreter itself is so dramatically tiny compared to other language tools. Rebol attacks the problems of complexity and bloat in many ways (see http://redprogramming.com/Why%20Rebol%20and%20Red.html for an explanation), but the idea of dialecting is one of the most powerful, and dialects which provide concise solutions to nearly any sort of problem in any domain of computing, can be created easily in pure Rebol code. This example simply demonstrates a pie chart on a 400x400 pixel screen, which plots the numbers [10 3 6 1 8], labels them [A B C D E], with sections [3 5] exploded, titled "Exploded Sections C and E", using the style 'vh2'. The 2 lines of dialect code in this example could not possibly be more concisely structured to display the desired chart output. The 1st line of code downloads the q-plot dialect library to a local cache, so that it doesn't need to be re-downloaded every time it's used.

do load-thru http://re-bol.com/q-plot.r   view quick-plot [
  400x400  pie [10 3 6 1 8] labels [A B C D E] explode [3 5]
  title "Exploded Sections C and E" style vh2

3.44 Parse URLs (1-6 lines)

This is an example of Rebol's built in 'parse' dialect. Parse allows developers to accomplish the same sort of tasks for which regular expressions are usually used (pattern matching, searching, splitting, validation, etc. of structured and unstructured text/data), but using a language which is much simpler to write and far and away easier to read. Parse is one of Rebol's most fascinating features, and is a single reason alone why some developers choose to use Rebol. Parse is extremely powerful, performs very fast, and is unique among options for accomplishing this kind of work. No other language has this feature, and once you compare it to regular expressions (which are used in nearly every other modern language), it's very hard to go back. Parse is one of the main features in Rebol which makes it well suited for building language dialects. This little example simply searches for URLs in a text string and wraps those URLs in HTML link tags.

parse join text: "link1: http://guitarz.org link2: http://yahoo.com" " " [
  any [
    to "http://" copy link to " " (
      replace text link rejoin [{<a href="} link {">} link {</a>}]
  ] to end
] editor text

3.45 Multi-User File Uploader (9 lines)

The username and password credentials for an FTP server are hard-coded into this app. The user can edit those credentials, along with a starting folder, to which any number of selected local files are uploaded. An HTML page is then created (or appended to), on which links to the uploaded files are written. The user can edit the HTML page as desired (the code is displayed in a text editor), and then the final page is displayed in the user's browser. The purpose of this app is to replace 3rd party file sharing services such as Dropbox. You can instantly create any number of new pages for any user, or for any topic, etc., or upload and add files to any existing pages. All that's needed to create unlimited private pages for any user or topic, is access to a single FTP folder.

if login: request-text/default"ftp://user:pass@url.com/public_html/files/"[
  filename: join request-text/default "links" ".html"  html: copy {}
  foreach f request-file [
    print file: last split-path f
    write/binary to-url join login file read/binary f
    append html rejoin [{<a href="} file {">} file {</a><br>} newline]
  write/append html-file: to-url join login filename html
  editor html-file   ; edit and re-save page, if desired
  browse join "http://" replace next find html-file "@" "public_html/" ""

3.46 Recursive File Search (9 lines)

A text requestor dialogue asks the user to enter some text to find, and a folder to start in. The app then searches for any file in which the text is found, in that folder, and in any subfolder(s), subfolders of those subfolders, etc. The file names of any file in which the search term is found, are displayed as the search progresses, then that list of file names is displayed in a text editor, so that the list can be edited, saved to any file name the user chooses, etc.

phrase: request-text/title/default "Text to Find:" "the"
change-dir start: request-dir/title "Folder to Start In:"  found-list: ""
recurse: func [folder] [ 
  foreach item (read folder) [ 
    either dir? item [change-dir item  recurse %.\  change-dir %..\][
      if find (read to-file item) phrase [
        print rejoin [{"} phrase {" found in:  } what-dir item]
        found-list: rejoin [found-list newline what-dir item]
] recurse %.\  editor found-list

3.47 Image Slide Show (7 lines)

A directory requestor dialogue allows the user to select any local folder. The app then removes any file names which are not images, and consecutively displays each individual image file contained in the selected folder. The user clicks on each image to progress to the next file, or closes the window to end the slide show (instructions about clicking each image to continue, are displayed on the user interface).

flag: 1  change-dir folder: request-dir/title "Choose an Image Folder:"
foreach file files: read %. [
  if all [flag = 1  find [%.png %.jpg %.gif %.bmp] suffix? file] [
    flag: 2  
    view center-face layout [
      image file [flag: 1  unview]
      text "Click image to continue slide show..."

3.48 Coin Flip (4 lines)

Images of a quarter's head and tail sides are downloaded from a URL. The user clicks a user interface button labeled 'flip', and the image is randomly flipped between heads and tails.

t: load http://re-bol.com/tails.jpg
view layout [
  i: image (h: load http://re-bol.com/heads.jpg)
  btn "Flip" [do first random [[i/image: h] [i/image: t]] show i]

3.49 Math Quiz (5-6 lines)

A random addition problem is generated and displayed to the user. In this case, the first random addend is generated between the numbers 1-10 and the second addend is generated between 1-20. The user types the answer to the addition problem, and is greeted with a 'yes' pop-up message if the answer is correct, or a 'no' message if the answer is incorrect. The process is repeated until the user closes the window.

x: func [] [rejoin [random 10 " + " random 20]]
view layout [
  f1: field x
  f2: field "(Type Answer Here)" [
    alert either f2/text = form do f1/text ["Yes!"]["No"]
    f1/text: x  show f1  focus f2

3.50 Days Between Dates Calculator (4 lines)

The interface consists of 'start' and 'end' buttons and a text field labeled 'Days Between'. When the user clicks on the 'start' button, a date requestor dialogue allows for the choice of a starting date. Likewise, the end date button allows the user to select an ending date. When both dates have been selected, the number of days between those dates is calculated and displayed in the text field below.

view layout [
  btn 200 "Start" [face/text: s: request-date]
  btn 200 "End" [face/text: e: request-date  f/text: e - s  show f]
  text "Days Between:"  f: field

3.51 Multiple Pane GUI Demo (6-7 lines)

The interface initially displays 2 text entry fields and 1 multi-line text entry area, along with 2 buttons. The user can click one of the buttons to switch the interface to display a text-list selector. The user can click the other button to switch the interface back to displaying the text entry field panel. Data entered into the text field panel and lines selected in the list panel are persisted as the panels are swapped on and off screen.

pane1: layout/tight [field 400 field 400 area 400]
pane2: layout/tight [text-list 400x200 data system/locale/days]
g: layout [
  b: box 400x200
  btn "Switch to Textlist" [b/pane: pane2 show b]
  btn "Switch to Fields"   [b/pane: pane1 show b]
] b/pane: pane1  view g

3.52 Click Counter (2 lines)

This app can be used to count any sort of items, event occurences, etc. The user simply clicks the button to increment the number displayed on its face. Data is saved to a log file, so the app can be closed and re-opened, with the count continuing right where each previous session was ended.

if error? try [to-integer read %cntr][write %cntr "1"]
view layout[btn read %cntr 60[write %cntr face/text: 1 + do face/text]]

3.53 6 One-Line Apps (6 lines)

The next six examples can each be displayed in 1 line of code. The code of these 6 apps has been broken apart at the 69th character or less, so that they can be easily printed, sent in the text of an email, etc. The six apps demonstrated here are the classic FizzBuzz, a restaurant tip calculator, 99 bottles of beer, the game Tric-Trac, an SMS text sender (using the API presented by freetxtapi.com), and a web site favorites bookmark loader. There are many more one-liner examples at http://re-bol.com/short_rebol_examples.r and http://www.rebol.com/oneliners.html

repeat i 100[print select reduce[i // 15"fizzbuzz"i // 3"fizz"i // 5
  "buzz"0 i]0]

view layout[f: field"$9"t: rotary".15"".18"".2"[set-face x(1 + do 
  t/text)* do f/text]x: info"(with tip)"]

for i 99 1 -1[print rejoin[i b:" bottles of beer"o:" on the wall. "i
  b ". Take one down, pass it around. "(i - 1)b o"^/"]]

g: [across btn "Roll" [alert form 1 + random 11]] 
 repeat i 12 [append g reduce ['text mold i 'check]] view layout g

read/custom http://freetxtapi.com reduce['POST{phone=5551212&message=hi}]

view layout[text-list"yahoo.com""google.com""msn.com"[browse value]]

3.54 Echo Clipboard to File (4 lines)

This app watches for any text be copied to the system clipboard, then echos it in the Rebol console, and appends the data to a running log file. This app also demonstrates how Rebol can asynchronously watch for keystrokes in console apps, separately from running a continuous forever loop. In this case, when the user presses the ENTER key in the Rebol console, the app is ended.

z: open/binary/no-wait console:// x: cp{} alert "ENTER to end..."  forever[
  if not none? wait/all [z :00.01][wait z  if "^M"= to-string cp z [break]]
  wait .1  if x <> y: read clipboard:// [
    write/append %clipboard.txt y  probe y  x: copy y

3.55 Live Code Editor (3 lines)

This example provides the user with a text entry area containing some default GUI code. The app created by this code is displayed in a box widget in the layout. The user can edit the default code, while the created app is running, and the created app will change in real time. State in the created app is maintained (i.e., the created app doesn't just stop and start with each new code edit - it actually changes while running. Any variables, environment conditions, etc. are maintained in the live running app). This app also demonstrates how Rebol can watch for events asynchronously from the main event loop of a GUI app. In this case, if the user presses CTRL-X, the app ends.

insert-event-func func[f e][if e/type = 'key[if "^X"= form e/key[quit]]e]
w: view/new layout [b: box  a: area {btn "Time" [print now]}] 
forever [if attempt[g: layout/tight load a/text][b/pane: g show b]wait .1]

Note that the link presented at the top of this page is neatly spaced and formatted for easy readability (it's actually 450 lines, with the extra spacing). A version without the extra lines and spacing, still readable and non-minified, is available at: http://re-bol.com/shortest_examples.r (359 lines).

4. Objectively Compare and Try to Recreate These Apps Using Any Other Tool

Most software development tools will require many thousands of lines of code to recreate these apps, and those tools will also typically require hundreds of megabytes, if not gigabytes, of complicated infrastructure (SDKs, IDEs, libraries, multiple layers of dependencies and supporting technology (often from third parties), API documentation, etc.) to recreate these apps. You will NOT find another software development system which can produce such a wide variety of broadly useful, composable, generally productive, concise code examples in a less bloated, simpler to implement and simpler to use environment, anywhere. By modern mainstream standards of development tooling, the thought of creating these examples with such a dramatically small code base, using absolutely nothing but a 600K tool is truly incomprehensible, and such a feat is utterly impossible using any other mainstream language/tool kit in common use. Many of these examples are so simple that they can be explained even to a child, without any previous coding experience, in a matter of minutes. For more insight about how Rebol reduces bloat and achieves unheard of simplicity and productivity, see: http://redprogramming.com/Why%20Rebol%20and%20Red.html

4.1 A powerful little computing utility Swiss army knife

The Rebol interpreter is so astonishingly small, and purely devoid of bloat, that the entire environment, for every popular operating system, can be sent as an email attachment smaller than a typical digital photo. Because of its size and broad capability, Rebol is also useful as a versatile cross-platform utility app for managing files, scraping and parsing web sites and emails, editing images, creating and updating content, and performing endless small computing tasks, using built-in functions and minuscule configurable scripts, which would otherwise require separate purpose-built apps. It's typically faster to write throw away scripts in Rebol than to download, install, configure, and test 3rd party utility apps, to perform a wide variety of common tasks. You'll find that your productivity dramatically increases as a power user when you've got this amazing little 600k Swiss army knife immediately available on any computer. Improving general productivity, outside of serious 'software development' activities, is simple with such a light weight and easily implemented package of integrated tools.

Keep in mind that Rebol is a mature professional instrument. It's been used and proven in demanding commercial production environments for nearly 2 decades. An open source (Apache licensed) version is available for desktop, server, mobile, and web platforms, and the new Red language (modified BSD license) is preparing to bring Rebol to a whole new generation of platforms and users. If you've ever thought that modern software development is a confounded mess, then take a look:

Rebol coding quick-start: http://re-bol.com/rebol_quick_start.html

Rebol App Builder (a fun way to learn): http://withoutwritingcode.com

CRUD Tutorial: http://re-bol.com/data-management-apps-with-rebol.html

Free 800 page book (really dig in): http://business-programming.com

WHY REBOL?: http://redprogramming.com/Why%20Rebol%20and%20Red.html

Ask questions at http://rebolforum.com

Extended short examples: http://re-bol.com/short_rebol_examples.r

MANY more, and more complex examples: http://re-bol.com/examples.txt

Be sure to dig into all the code at: http://rebol.org

Multi-user apps: http://re-bol.com/rebol-multi-client-databases.html

Mobile/Web apps with jsLinb/Sigma and Rebol: http://re-bol.com/jslinb

A commercial GPL app written in R2: http://freeconsignmentsoftware.com

A huge commercial success story: http://www.atronixengineering.com

Another successful business built on Rebol: http://www.nlpp.ch

5. Why pay any attention to me at all? Why not just learn Python, Javascript, Java...?

If you search for "business programming", "consignment software", "learn rebol", "livecode tutorial", "ns-basic", "learn haxe", "rfo tutorial", "computer programming tutorial", "etsy api tutorial", "without writing code", "easiest programming language", and many other topics related to software development, you'll see my web sites in the very top line or few of Google results. I've been writing software for nearly 40 years, have created numerous commercial apps which are responsible for maintaining critical business processes across a wide variety of industries, and have been actively involved in teaching people how to write practical, useful software, for several decades. Every part of my life is organized and made more efficient by hundreds of apps which I've written from scratch (and thousands of additional little throw away scripts), to suit my needs exactly. People who've worked in businesses I've owned, and in the businesses of clients for whom I've written software, have been using my applications daily, for decades. Software that I wrote 25 years ago is still running in production environments. One of my own pieces of business software has become a leading core operations app in the consignment industry. Another of my businesses which has been running for 14 years on home brew software has been featured on the front page of the New York Times. I've saved hundreds of millions of dollars of expenses for clients over the years, and enabled businesses which have earned even more total income. My own apps help me enjoy every hobby in which I'm involved, and several additional web sites and tools which I've created around those hobbies are top on the web for their topics (look up "guitar chord diagram maker", "learn powered paragliding", "paramotor tutorial", etc.), thanks to the ability to use software development tools.

Here's the kicker: I've done all of that software development work (and provided support, maintenance, upgrades, etc., for every single client for whom I've ever created a critical piece of software) in my spare time, without ever once in my life working as a software developer full time (I did own and operate an IT support business for years, but that work was geared more towards installation, maintenance, and training of third party systems). I couldn't have achieved all of the software development goals which have been useful in my life and work, without using the right tools. Even if I'd used Python or other popular tools which are considered 'productive', it would have taken 3x-100x more total time and effort to create the same software solutions, and that difference would have changed my life. I would never have been able to work with the same necessary freedom and mobility. For example, I often installed Rebol on remote client systems (instantly) and wrote code while communicating with clients and testing code live, in person at their location, or by using screen sharing software with distant users. That sort of flexibility is not imaginable using tools such as Java. It does make a difference to use the smallest and most productive tools possible! I have used many other productive software development environments, which will be added to this page in the future (take a look at AutoIt and Livecode for a start), but I've always come back to Rebol as a favorite for many of the most common development and scripting tasks.

The ability to write useful software, especially utility scripts which save tremendous amounts of time and work, doesn't need to be as complex as the mainstream software development community makes it out to be! Most professional software developers aren't aware that something like Rebol even exists (they're only concered with using the popular tools which are most likely to secure paying jobs, and it can actually be in their best interest to use tools which generate more billable hours). There are many complex reasons why tools become popular and commercially successful in the software development industry, but productivity and light weight are not among the highest priority money making reasons. Take a look at the links above, and see if Rebol is potentially useful for your personal programming goals. It has the potential to change your life, and for your own needs, you may never have to look at another software development tool.

Copyright 2000-2017 Nick Antonaccio