The Qu Programming Language
Home  |  Download  |  Modules  |  Documentation  |  Repository  |  Tutorial  |  Mailing List

Example

Remember that there are many examples in the demo directory and a syntax highlighting definition file for Kate in the doc directory.

This is the famous Hello World program excessively written in Qu. We could just say:

print ('Hello World!')

but that wont be fun. Besides, the following example does tell you some things about Qu.

# A sample program
use Time

println (Time.web)
hello

sub hello (msg = nil)
    ```
    Prints a message for the world.
    ```

    local head = false
    do try
        msg is String or throw EValue, "me want string"
        msg.('l' _ 'en') or throw EValue
        print (msg.capitalize)
        head = true
    catch EValue
        msg = `hello`
        redo
    finally
        assert (head is true, "eh?")
        /*
            Lets do this right
        */

        println (' World!')
    ;;
;;

And here is a "simpler" one showing you the power of validators.

hello ('world!')

sub Message (x)
    return x is String and x and not x.isspace ? x.capitalize : false
;;

sub hello (s: Message)
    println ('Hello ', s) # guess what it prints!
end sub
# oh, you can use 'end' to close blocks, if you like

var name: String.isalpha
var path: File.isabs

enum Level
    LOW
    MEDIUM
    HIGH
;;

struct Person
    name : String
    age  : Integer
    pals : Array of Person
;;

sub foo (x: Person) -> Level
    ...
;;

const Picky = 1..10
const Weird = const [1, 2, 7, 9]

var foo: Picky

sub foo (x: Picky) -> Weird
    ...
;;

Here are some examples of Qu's flexible syntaxes.

println (x) if y > 10
println (x) for x in 1, 20

= [for i in 1, 2: [for j in i, i + 2: i + j]]
= [while i--: i if i & 1]
= {for c in 'abcde': c == 'd' ? break : c}

= sub (x) return x.len > 3 ;;
= lambda (x) x.len > 3
= {|x| x.len > 3}
= {|x| yield i for i in x}

a.sort (sub (x, y) return x <=> y ;;)
a.sort (lambda (x, y) x <=> y)
a.sort ({|x y| x <=> y})

Qu has an "experimental" feature that allows you to override or extend functions of any module and even methods of any class, provided that you do it from a trusted module. Extremely abusive but very useful in some situations.

sub Sys.print (*arg)
    Stream.stdout <<< x for x in arg
;;

sub String.notempty
    return self.len > 0
;;

sub class File.nicepath (x)
    return File.valid (x) and ' ' not in x
;;

var path: File.nicepath


# Here is a real example
use Sys

sub Sys.println (*arg)
    static linecount = 0
    Stream.stdout <<< ++linecount <<< ': '
    Stream.stdout <<< x for x in arg
    Stream.stdout <<< Stream.stdout.linebreak
;;

Stream.stdout.linebreak = ' :-)\n'

println ('Hello')
println ('World')

# can you guess the output?

Qu provides convenient ways to communicate with C. The Dlib class provides access to shared libraries. The Proc class makes it possible for C functions to call Qu functions. The Pointer class provides an easy way to deal with C structs.

local handler = Proc (@foo, 2)

sub foo (a:_int_, b:_float_, c:_String_, d:_double_) -> _String_
    println ('self = ' self)
    println ('a = ', a)
    println ('b = ', b)
    println ('c = ', c)
    println ('d = ', d)
    return 'Hello from Qu'
;;

= Dlib ('/opt/qu/lib/Qu.so')
l.call ('QuSetIt', '-:P', handler)
l.call ('QuCallIt')

struct Foo
    thing : _int_
    thang : _float_
;;

= Pointer (Foo)
p->thing = 1
p->thang = 2.3

Here is an example using the indentation style ala Python.
The difference is that you must only use tabs.

The pragma statement must be the first statement in the file. Once specified, it means you are using indentation style for the whole file.

The line continuation token is a triple dot.

hello ('Hello')

sub hello (s)
    if s
        for c in s
            print (c)
        println (' World!')
    else
        __exit__ (1)

= b + ...
    c + d

Did you know you can embed HTML code directly in your Qu program? Here's an example.

pragma html

options = [foo:1, bar:2, baz:3]

<FORM ACTION="/foo" METHOD="POST">
    <SELECT NAME="choice">
    for k, v in options
        <OPTION VALUE=v>(\k)</OPTION>
    ;;
    <INPUT TYPE="submit" VALUE="Send">
    </SELECT>
</FORM>

And finally a glance at Qu's object oriented style.

This is not the whole story, of course. And remember that in Qu using object oriented programming is just a matter of choice.

use Foo
use FooEdit
use FooDisplay

class Bar is Foo (FooEdit.FooEditStandard, FooDisplay) __final

    const ValidAge = 1..200

    var class flag = 1

    var name := ''
        ensure
            return name is String
                and name.len in 1..40
                and not name.isspace
        ;;

    var nice = true
    var age: ValidAge

    sub __init (name, age, nice = true)
        self.name = name
        self.age  = age
        self.nice = nice if nice
    ;;

    sub class setflag (x: Int) -> Null
        flag = x
    ;;

    sub say (x)
        static v = const ['bad', 'nice']
        println ([Int (self.nice)] ': ' x)
    ;;

    sub __print
        print ('I am a ' self.__name)
    ;;

    sub Nice
        return self.nice
    ;;
;;

var Her: Foo.Nice

 

Copyright © 2006 by Marc K.
Generated by Doc.qm Thu, 15 Jun 2006 02:13:48 GMT