New alpha release 18-Feb-2015

A new alpha release of The World Programming Language is out with a lot of new features. Check World @ GitHub

Structures and routines

Examples are from under OS X. If the code here wants to be copy/pasted to the World prompt, turn auto-brackets off with Ctrl-A in World.

The libc routine gettimeofday returns the current calendar time as the elapsed time since the epoch. It takes pointers to two structures as arguments and fill those structures with data.

First libc needs to be loaded:

    w> libc: load/library %/usr/lib/libc.dylib

Then the structures and routine are defined:

    timeval: struct [
        slong sec
        sint32 usec
    ] none

    timezone: struct [
        sint minuteswest
        sint dsttime
    ] none

    gettimeofday: routine [
        [typecheck]
        libc "gettimeofday" [
            tp [struct!] pointer
            tzp [struct!] pointer
        ]
        sint
    ]

gettimeofday can now be called:

    w> gettimeofday timeval timezone
    == 0


timeval and timezone then holds the data. The routine localtime_r takes time and a struct tm as arguments and fill the structure with data:

    tm: struct [
        sint sec
        sint min
        sint hour
        sint mday
        sint mon
        sint year
        sint wday
        sint yday
        sint isdst
        slong gmtoff
        pointer zone
    ] none

    localtime-r: routine [
        [typecheck]
        libc "localtime_r" [
            time [struct!] pointer
            resultp [struct!] pointer
        ]
        pointer handle!
    ]

The time argument is a pointer to a slong holding the seconds. But that's the first variable in the timeval structure, so we can just pass that:

    w> localtime-r timeval tm

Now tm is filled with data, and we can e.g. get the day of the year:

    w> tm/yday
    == 353


There is some freedom in defining structures. C datatype and argument name can be exchanged. It's also possible to give initial values, so these two are the same:

    struct [float f] [1.0]
    struct [f float] [1.0]

Now find some more interesting libraries to integrate with!

Calling the outside World

World can call routines in dynamic link libraries, and with the addition of handle! and struct! datatypes, all possible calls are supported. Let's see a simple example with the routines "strerror" and "puts" from LIBC:
(Examples are done under OS X.)

    libc: load/library %/usr/lib/libc.dylib

    strerror: make routine! [
        libc "strerror" [
            [] uint
        ]
        pointer
    ]

This is a simple definition of "strerror" without advanced typechecking and no description or specification of argument name or World datatype. "strerror" can now be used like this:

    w> strerror 1
    == "Operation not permitted"

The returned string can be saved in a variable:

    w> str: strerror 1
    == "Operation not permitted"

Then "puts" is defined:

    puts: make routine! [
        libc "puts" [
            [] pointer
        ]
        sint
    ]

And "puts" can be used to write str to stdout:

    w> puts str
    Operation not permitted
    == 10

"strerror" and "puts" can also be defined operating on handles, and in this case the string isn't copied to a World string! datatype. This time, the special attribute, typecheck, is needed, and I'll also put in some extra description and variable names:

    strerror: make routine! [
        "Maps the error code to a descriptive error message."
        [typecheck]
        libc "strerror" [
            errnum [integer!] uint "Error code"
        ]
        pointer handle!
    ]

    puts: make routine! [
        "Writes a string to stdout followed by a newline."
        [typecheck]
        libc "puts" [
            s [handle!] pointer "The string"
        ]
        sint
    ]

Example of use:
(notice "strerror" no longer returns a string)

    w> handle: strerror 1
    w> puts handle
    Operation not permitted
    == 10

Use the help function on a defined routine to see, how the routine is used:

    w> help strerror

One week of open alpha

It has been a productive week:


  • Routines got a more complete implementation
  • Added routines to HELP
  • Added new datatype, handle!
  • Series got an overhaul
  • Added library libs/version.w
  • Added new tests
  • Added new native function: AS
  • Added AS-BINARY, AS-STRING and WITH to rebol.w
  • Added /reset refinement to COMPILE function
  • Implemented error system
  • Added sys-utils with PRINT-LAST-ERROR function
  • Documentation was updated
  • Various fixes were carried out

The World project is on track.

Introduction

This is the first public alpha release of the World Programming Language. World is strongly inspired by REBOL, developed by (some will say pioneer in these kinds of languages) Carl Sassenrath, which again is influenced by languages such as Self, Forth, Lisp and Logo.

World is also influenced by Lua and Stackless Python.

Why another language? After many years of programming experience, I find programming in most languages comparable to carving weird signs into stone. It's an enormous task, and when you look at all the weird signs and symbols, it quickly becomes unnecessarily complex and often unreadable.

With World, it's like having a printing press a la Gutenberg. There is a minimum of syntax and strange symbols, and the code is very much human readable. Consequence is, that developers become more productive and produce better code with less errors.

With my interest in science, a big goal with World is also to give scientists a tool to create their code with less effort, so they can concentrate on science instead of using their time to figure out strange programming languages.

REBOL programmers will have a head start to learn and understand World, even if World is quite different with its virtual machine, different binding rules and other minor or major differences.

The alpha release of World can be found at:

https://github.com/Geomol/World

!!! Remember this is an alpha release, so it's for testing only. Use it at your own risk. Do not distribute. !!!

Countdown: 1

In "Countdown: 9" earlier, we saw how World source code can be compiled into the machine language of the virtual machine (VM). Such compiled code can be disassembled, so the instructions for the VM can be seen:

w> a: 1    
== 1
w> block: [a: a + 1]
== [a: a + 1]
w> do block    ; this will compile and run the block of code
== 2              ; and we see the result, 2
w> disasm block
   0 GET_TVALUE    1             100312790
   1 LOADK         2             1
   2 ADD           1             1             2
   3 SET_TVALUE    100312790     1
   4 END           1

Beside series, NEXT and BACK also works on integers, so I can write:

w> block: [next 'a]
== [next 'a]
w> disasm compile block        ; this just compiles the block without running it
   0 LOADK         1             100117a18
   1 NEXT          1             1
   2 END           1

This new block does the same as the block above, but in fewer instructions, because it uses call-by-word. If TRACE is ON, the VM code is shown, while it's being executed:

w> trace on
   0 END_EXECUTE   0
   0 END           0
w> now
   0 LOAD_NONE     0                           2
   0 NOW           0
   0 END_EXECUTE   0
   0 END           0
== 03-Dec-2011/10:13:55+1:00

We came to the end of the countdown. In the last 10 days, the sources have grown with around 1,000 lines of C, so it's now close to 24,000 lines. And it'll continue growing to become version 1. The open alpha release of The World Programming Language can be on your computer tomorrow, so stay tuned!

Finally, the smallest "Hello, World!" program in the known Universe:

    .

Yes, it's a dot! Let's see it in action at the World prompt:

w> .
Hello, World!

Countdown: 2

World has much to do with dialects. Even World itself is a dialect (in fact several dialects), just like the language, we speak, consists of dialects.

An example in World, where we want to expand the language with an object oriented dialect:

w> do %mezz/object.w
w> obj: object [
    private [a: 1 b: 2]                   ; private data
    public [f: func [v][a + b + v]    ; two public methods, f and set-a
              set-a: func [v][a: v]]
]
w> help obj      ; notice we can't see A and B
obj is a context! of value:
   f               function! [v]
   set-a         function! [v]

w> obj/f 1       ; calling f inside obj with argument 1
== 4
w> obj/set-a 40
== 40
w> obj/f 0
== 42

World doesn't have keywords, as everything can be redefined. Beside the native functions and datatypes, the virtual machine understands directly, much of the basic part of the language is defined in World/Cortex. The Cortex part is just a World script named "cortex.w". The language is used to define itself and can be expanded into many dialects.

Introducing call-by-word, which can be compared to call-by-reference in other languages:

w> block: [a b c d]
== [a b c d]
w> next block       ; this doesn't change BLOCK
== [b c d]
w> block
== [a b c d]          ; as we can see here
w> next 'block       ; this is call-by-word and changes BLOCK
== [b c d]
w> block
== [b c d]             ; see!

A lit-word! value is recognized by a pre-fixed apostrophe ('). The code generator changes lit-words into words, so the function, NEXT, gets a word in the call-by-word example above.