World Programming Language
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
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> 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:
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:
And "puts" can be used to write str to stdout:
"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
(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
]
libc "puts" [
[] pointer
]
sint
]
And "puts" can be used to write str to stdout:
w> puts str
Operation not permitted
== 10
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:
The World project is on track.
- 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. !!!
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
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
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
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!
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
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
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> now0 END 0
0 LOAD_NONE 0 2
0 NOW 0
0 END_EXECUTE 0
0 END 0
== 03-Dec-2011/10:13:55+1:000 NOW 0
0 END_EXECUTE 0
0 END 0
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.
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.
Subscribe to:
Posts (Atom)