Home   Archive   Permalink

More short examples

There are certain examples that I see over and over in tutorials for other languages, and especially in tutorials for GUI toolkits. I enjoy making concise Rebol versions. The coinflip example was fun: http://rebolforum.com/index.cgi?f=printtopic&permalink=Nick28-Nov-2013/6:55:29-8:00&archiveflag=new
Here's a tiny tile game:
R E B O L [title: "Tiles"]
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
A little text editor:
R E B O L [title: "Notepad"]
view layout [
     a: area
     btn "Load" [attempt [a/text: read/string request-file/only show a]]
     btn "Save" [write request-file/only a/text alert "Saved"]
A .gif image viewer:
R E B O L [title: "GIF viewer"]
files: read %./
remove-each file files [%.gif <> suffix? file]
view layout [
     text-list data files [i/image: load value show i]
     i: image 200x200
Tip calculator:
R E B O L [title: "Tip Calculator"]
view layout [
     f: field "49.99"
     t: field ".20" [
         x/text: to-money ((to-decimal f/text) * (1 + (to-decimal t/text))) show x
     x: title "Total, with tip:"
A bar chart displaying some data values:
R E B O L [title: "Bar Chart"]
d: ["March" 13 "April" 9 "May" 21 "June" 29 "July" 10]
g: [] foreach [m v] d [append g reduce ['btn m v * 10]] view layout g
R E B O L [title: "Calculator"]
view layout [
     origin 0 space 0x0 across
     style btn btn 50x50 [append f/text face/text show f]
     f: field 200x40 font-size 20 return
     btn "1" btn "2" btn "3" btn " + " return
     btn "4" btn "5" btn "6" btn " - " return
     btn "7" btn "8" btn "9" btn " * " return
     btn "0" btn "." btn " / " btn "=" [
         attempt [f/text: form do f/text show f]
This app generates 2 different reports, computed on columns of values in a downloaded .csv file (sum calculation and name search):
R E B O L [title: "Paypal Reports"]
do %r3-gui.r3
sum: $0
foreach line at parse read/lines http://re-bol.com/Download.csv "^M" 2 [
     attempt [sum: sum + to-money pick row: parse/all line "," 8]
     if find row/4 "Saoud" [print rejoin [row/1 ", Saoud Gorn: " row/8]]
Here's an R3 example displaying a sortable table of values, read from a remote server. As above, no RESTful interface required, no JSON data or library to deal with, just plain text read over a standard protocol, using the simplest possible format:
R E B O L [title: "List-View/Grid display"]
do %r3-gui.r3
webdata: load to-string read http://learnrebol.com/griddata.cgi
view [text-table ["Text" 100 "Dates" 200 "Numbers"] (webdata)]
Here's a console pig Latin generator:
foreach t parse ask""""[x: parse t"aeiou"prin rejoin[either q: find/match t x/1[q][t]x/1 either q["ay"]["hay"]" "]]
And in response to discussions like this: http://wiki.tcl.tk/1386 , there always seems to be a concise Rebol answer:
sum: 0 foreach [x y] load %data.txt [sum: sum + (x * y)] sum

posted by:   Nick     6-Dec-2013/6:30:30-8:00

And although not typical of examples in tutorials or books (probably because they are just too far out of the scope of such instructional texts), below are some of my other favorite short examples. Here's a game with random and user-controlled graphics movement, collision detection, boundary movement logic, incrementally increasing speed, centered window layout, score tracking, saved and sorted high score display, and more - all in 11 lines of code. Press the space bar to catch the falling REBOL logos with your blue player piece:
R E B O L [title: "Catch Game"]
s: 1 p: 3 d: 10 n: now/time random/seed now
r: func [x] [y/offset: random 500x-20 p: p + .1 s: s + x]
view/new center-face g: 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 g if s = 0 [
        write/append %h "" save %h sort/skip append h: load %h reduce
        [t/text request-text/title "Name:"]2 request-list "High Scores:" h q
Here's a walkie-talkie (Voice Over IP) app for MS Windows, which let's you talk to other people on a computer network:
R E B O L [title: "VOIP"] do [write %ireceive.r {R E B O L []
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
lib: load/library %winmm.dll
mci: make routine! [c [string!] return: [logic!]] lib "mciExecute"
print rejoin ["Your IP address is: " read join dns:// read dns:// "^/"]
if (ip: ask "Connect to IP (none = localhost): ") = "" [ip: "localhost"]
if error? try [port: open/binary/no-wait rejoin [tcp:// ip ":8"]] [quit]
mci "open new type waveaudio alias wav"
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

posted by:   Nick     6-Dec-2013/6:36:08-8:00

My old obfuscated demo, too. Ten different programs:
R E B O L [title:"Demo"]p: :append kk: :pick r: :random y: :layout q: 'image
z: :if gg: :to-image v: :length? g: :view k: :center-face ts: :to-string
tu: :to-url sh: :show al: :alert rr: :request-date co: :copy g y[style h
btn 150 h"Paint"[g/new k y[s: area black 650x350 feel[engage: func[f a e][
z a = 'over[p pk: s/effect/draw e/offset sh s]z a = 'up[p pk 'line]]]
effect[draw[line]]b: btn"Save"[save/png %a.png gg s al"Saved 'a.png'"]btn
"Clear"[s/effect/draw: co[line]sh s]]]h"Game"[u: :reduce x: does[al join{
SCORE: }[v b]unview]s: gg y/tight[btn red 10x10]o: gg y/tight[btn tan
10x10]d: 0x10 w: 0 r/seed now b: u[q o(((r 19x19)* 10)+ 50x50)q s(((r
19x19)* 10)+ 50x50)]g/new k y/tight[c: area 305x305 effect[draw b]rate 15
feel[engage: func[f a e][z a = 'key[d: select u['up 0x-10 'down 0x10 'left
-10x0 'right 10x0]e/key]z a = 'time[z any[b/6/1 < 0 b/6/2 < 0 b/6/1 > 290
b/6/2 > 290][x]z find(at b 7)b/6[x]z within? b/6 b/3 10x10[p b u[q s(last
b)]w: 1 b/3:((r 29x29)* 10)]n: co/part b 5 p n(b/6 + d)for i 7(v b)1[
either(type?(kk b i)= pair!)[p n kk b(i - 3)][p n kk b i]]z w = 1[clear(
back tail n)p n(last b)w: 0]b: co n sh c]]]do[focus c]]]h"Puzzle"[al{
Arrange tiles alphabetically:}g/new k y[origin 0x0 space 0x0 across style
p button 60x60[z not find[0x60 60x0 0x-60 -60x0]face/offset - x/offset[
exit]tp: face/offset face/offset: x/offset x/offset: tp]p"O"p"N"p"M"p"L"
return p"K"p"J"p"I"p"H"return p"G"p"F"p"E"p"D"return p"C"p"B"p"A"x: p
white edge[size: 0]]]h"Calendar"[do bx:[z not(exists? %s)[write %s ""]rq:
rr g/new k y[h5 ts rq aa: area ts select to-block(find/last(to-block read
%s)rq)rq btn"Save"[write/append %s rejoin[rq" {"aa/text"} "]unview do bx]]
]]h"Video"[wl: tu request-text/title/default"URL:"join"http://tinyurl.com"
"/m54ltm"g/new k y[image load wl 640x480 rate 0 feel[engage: func[f a e][
z a = 'time[f/image: load wl show f]]]]]h"IPs"[parse read tu join"http://"
"guitarz.org/ip.cgi"[thrucopy my to]i: last parse my none
al ts rejoin["WAN: "i" -- LAN: "read join dns:// read dns://]]h"Email"[
g/new k y[mp: field"pop://user:pass@site.com"btn"Read"[ma: co[]foreach i
read tu mp/text[p ma join i"^/^/^/^/^/^/"editor ma]]]]h"Days"[g/new k y[
btn"Start"[sd: rr]btn"End"[ed: rr db/text: ts(ed - sd)show db]text{Days
Between:}db: field]]h"Sounds"[ps: func[sl][wait 0 rg: load sl wf: 1 sp:
open sound:// insert sp rg wait sp close sp wf: 0]wf: 0 change-dir
%/c/Windows/media do wl:[wv: co[]foreach i read %.[z %.wav = suffix? i[p
wv i]]]g/new k y[ft: text-list data wv[z wf <> 1[z error? try[ps value][al
"Error"close sp wf: 0]]]btn"Dir"[change-dir request-dir do wl ft/data: wv
sh ft]]]h{FTP}[g/new k y[px: field"ftp://user:pass@site.com/folder/"[
either dir? tu va: value[f/data: sort read tu va sh f][editor tu va]]f:
text-list[editor tu join px/text value]btn"?"[al{Type a URL path to browse
(nonexistent files are created). Click files to edit.}]]]]

posted by:   Nick     6-Dec-2013/6:39:15-8:00

99 bottles of beer, with proper grammar. "Bottles" changed to "bottle" at the end of the 2 line, and throughout the 1 line. 0 changed to "No" in the last line:
R E B O L []
for i 99 1 -1 [
     x: rejoin [
         i b: " bottles of beer" o: " on the wall. " i b
         ". Take one down, pass it around. " (i - 1) b o "^/"
     r: :replace j: "bottles" k: "bottle"
     switch i [1 [r x j k r at x 10 j k r x "0" "No"] 2 [r at x 40 j k]]
     print x
] halt
Here's a 1 line version:
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"^/"]]

posted by:   Nick     8-Dec-2013/0:00:59-8:00

Fizzbuzz one liner:
repeat i 100[j:""if i // 3 = 0[j:"fizz"]if i // 5 = 0[j: join j"buzz"]if j =""[j: i]print j]

posted by:   Nick     8-Dec-2013/0:26:22-8:00

A little CRUD app to create, save, load, edit, and delete field and area text. This one is particularly representative of Rebol features because it uses a flat file data structure entirely created from scratch, using only native series constructs. There's no RDBMS required, no SQL, no other platform requirements, etc. It's pure Rebol:    
R E B O L [title: "Simple CRUD App"]
write/append %s ""
view g: layout [
     h3 "Name:" x: field h3 "Info:" z: area wrap across
     btn "Save" [do-face d 1 save %s sort/skip repend f m 2]
     l: btn "Load" [
         if not c: request-list "Select:" extract f: load %s 2 [exit]
         x/text: first find f c z/text: select f x/text show g
     n: btn "New" [clear-face x clear-face z focus x]
     d: btn "Delete" [
         if true = request "Sure?" [
             m: reduce [copy x/text copy z/text]
             remove/part find f: load %s x/text 2 save %s f do-face n 1
     btn "Edit Raw Data File" [editor %s]

posted by:   Nick     8-Dec-2013/7:44:38-8:00

A little personal calendar app (this one was in the demo above):
write/append %s ""
forever [
     if none = d: request-date [q]
     view center-face layout [
         h5 form d
         a: area form select (l: load %s) d
         btn "Save" [
             save %s head insert l reduce [d a/text]

posted by:   Nick     8-Dec-2013/7:47:42-8:00

Web site editor in 53 bytes - open, edit, and save changes to any file on your web server. Use the file format "ftp://usepass@yourwebsite.com/yourpath/public_html/file.ext"
view layout[f: field btn"Edit"[editor to-url f/text]]

posted by:   Nick     8-Dec-2013/7:56:41-8:00

Paint one-liner:
view layout[s: area feel[engage: func[f a e][if find[down over]a[append x: s/effect/draw e/offset show s]if a = 'up[append x 'line]]]effect[draw[line]]]

posted by:   Nick     8-Dec-2013/8:00:20-8:00

There are lots more examples at http://easiestprogramminglanguage.com and http://re-bol.com/examples.txt

posted by:   Nick     8-Dec-2013/11:17:56-8:00

Tric Trac Game, one liner version:
random/seed now g: [across btn "Roll" [alert form 1 + random 11]] repeat i 12 [append g reduce ['text mold i 'check]] view layout g
Instructions and a nicer version are at http://www.rebol.org/view-script.r?script=trictrac.r

posted by:   Nick     11-Dec-2013/9:30:16-8:00

.png slide show one liner:
forever[foreach i read %.[if find i".png"[unview view/new layout[image i[q]]wait 3]]]
Displays a slide show of all .png images in the current folder, each displayed for 3 seconds. Click any image to end the program. (Change ".png" to ".jpg", ".gif", or ".bmp" to work with other image types).

posted by:   Nick     11-Dec-2013/9:50:28-8:00

Tip calculator, 1 line version:
view layout[f: field"$9"t: field".2"[x/text:(to-money f/text)*(1 +(to-decimal t/text))show x]x: field]

posted by:   Nick     11-Dec-2013/10:08:49-8:00