|
Qu Programming Language |
|
Main
Others
|
Examples
This is the famous Hello World program excessively written in Qu.
We could just say:
'Hello World!' # tada! without calling the print function
but that wont be fun. Besides, the following example tells you one thing or two about Qu. It's not a good example but it does speak for itself.
# The Hello World program
use Time
println (Time.web)
hello
sub hello (msg = nil)
```
Prints a message for the world.
```
local head = false
do try
throw EValue, 'I want a string' unless msg is String
msg.('l' _ 'en') or throw EValue
print (msg.capitalize)
head = true
catch EValue
msg = `hello`;
redo
finally
assert head is true
/*
Lets do this right
*/
println (' World!')
;;
This example demonstrates Qu's validators.
As you can see, you can use numerous entities to set a variable type.
Not just classes.
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 is a version of the Hello World program showing you the power of validators.
hello ('world!')
sub Message (x)
return false unless x is String and x and not x.isspace
return x.toupper
;;
sub hello (s: Message)
println ('Hello ', s)
;;
When you run that program then you will get this output:
This example demonstrates Qu's flexible syntax.
a = ['foo' 1 2]
println ('hello' 1 2 3)
println (x) if y > 10
println (x) for x in 1, 20
'foo' for x in 10
x = [for i in 1, 2: [for j in i, i + 2: i + j]]
x = [while i--: i if i & 1]
s = {for c in 'abcde': c == 'd' ? break : c}
f = sub (x) return x.len > 3 ;;
f = lambda (x) x.len > 3
f = {|x| x.len > 3}
f = {|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})
# if you prefer the Pascal syntax to close blocks
sub foo (x y z)
if x
return [: x y z nil]
else
return 'foo'
end if
end sub
f = @foo (1)
f (2, 3)
var a
---
hello: 'Hello'
validate: @Valid.Email
---
sub bar
---
mynote: 'Important stuff'
---
return 1
;;
sub baz (x) = foo (x 1 2)
sub init __once
# do something once only
;;
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. Abusive perhaps,
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 a convenient way to access shared libraries directly
from your Qu code via the Dlib class.
The Pointer class provides an easy way to deal with C structs.
libm = Dlib ('/usr/lib/libm.so')
sin = libm.func ('sin', 'f:f')
r = sin (1.234)
println (r)
libm.close
struct Foo
thing : Cint
thang : Cfloat
;;
p = Pointer (Foo)
p->thing = 1
p->thang = 2.3
use Gtk
use Gtk.Dialog
class AboutDialog is Dialog
sub class new
return self.__inst (__extern Gtk.gtk_about_dialog_new "p:" ())
;;
sub get_name
return __extern Gtk.gtk_about_dialog_get_name "s:G" (self)
;;
;;
Here is an example that uses the indentation style ala Python.
The difference is that you must only use tabs and the line continuation
is a triple dot.
The pragma indent statement must be the first statement in the file. Once specified, it means you are using indentation style for the whole file.
We urge you not to use the identation style because they are problematic.
"The last thing you want is the compiler complaining about your indentation.
They simply can not be part of the language". In future Qu versions this
feature might be dropped.
pragma indent
hello ('Hello')
sub hello (s)
if s
for c in s
print (c)
println (' World!')
else
__exit__ (1)
a = b + ...
c + d
You can embed HTML code directly in your Qu program.
You can even define your own tags easily.
Since Qu 1.21.10 the HTML syntax has been changed to use lowercase
letters. Extending new tags has also been made simpler.
pragma html
options = [foo:1 bar:2 baz:3]
what = 'an option'
'Select ' (\what) ' then click on the Send button.'
<form action='/foo' method="POST">
<select name="choice">
for k v in options
<option value=v>(\k)</option>
;;
</select>
<input type="submit" value="Send">
</form>
sub html._bi (state)
if state == 1
'<b' attrs '><i>';
else
'</i></b>';
;;
;;
<bi css="Foo">Hello</bi> #-> <b class="Foo"><i>Hello</i></b>
There is also a nice and fast H module designed to make you more productive when writing web applications. The above program, for example, will be rewritten as follows.
Since Qu 1.21.10 using H has been drammatically changed.
You must now say pragma H instead of use H and calling the tags
are written using a HTML-like syntax.
pragma H
options = [1:'foo', 2:'bar', 3:'baz']
what = 'an option'
'Select ' (.what) ' then click on the Send button.'
<p>
<form "MyForm" false '/foo'>
<select 'choice' options>
<submit 'Send'>
</form>
There is really no need to write complicated templating engine and learn a second language. With Qu, you do it with Qu, and you get all the power of Qu. Note that the Qu website has abandoned server side rendering completely and now uses Javascript for client site rendering.
This example is just 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 (v [Int (self.nice)] ': ' x)
;;
sub __print
print ('I am a ' self.__name)
;;
sub Nice
return self.nice
;;
sub dontrepeatme __once
return 'Hi'
;;
;;
var Her: Foo.Nice
|