Jazz Platform
1. Overview
Jazz is a programming language based on Scheme, conforming to the R5RS Scheme standard and implementing all optional features. For documentation, see R5RS Documentation. Jazz is built on top of the Gambit system, and has full access to every feature of Gambit. For documentation, see Gambit Manual. By using Scheme's load primitive, you can load any existing Scheme code.
2. Naming Conventions
Comments
- ;;;; Chapter comment : specifies the section title, and will be gathered in a chapter.
- ;;; Section comment : documents a section.
- ;; Definition comment : documents a definition; many lines may be used.
- ; Code comment : put at the end of a line of code to document it.
Units & Modules
Units and modules names are lowercase separated by .
-
jazz.ui
-
jedi.product
Classes & Interfaces
Class & Interfaces names are capitalized
-
View
-
Java-Text
Methods
Methods are in lowercase separated by -
-
get-application
Predicates
Predicates end with ?
-
eq?
-
string?
Mutators
Destructive functions end with !
-
set-cdr!
-
append!
Convertors
Type conversion functions have -> in their name
-
symbol->string
-
symbol->keyword
3. Lexical Syntax
Identifiers
Identifiers in Jazz are case sensitive, thus 'Foo' and 'foo' are treated as separate. This is commonly used to name a class 'X', and a variable containing an instance of 'X' as 'x'.
Identifiers can consist of any alphanumeric character, in addition to the following: ! $ % & * + - . / : < = > ? ^ _. All of the following are examples of valid identifiers:
3d-matrix Point eqv? ^$31337$:a-strange-identifier!
Whitespace
Since spaces, tabs, carriage returns and line feeds are considered whitespace, they can be freely inserted in Jazz code without changing its meaning.Both the following evaluate to 30:
(* 5 10 (/ 3 5)) ( * 5 10 (/ 3 5 ) )
Comments
Jazz offers two types of comments:
- ; starts a line based comment. It works like # or // in other languages.
- @name, where 'name' can be any symbol, is a powerful means of commenting out entire expressions. When placed before an s-exp, that entire s-exp is ignored.
(* 5 10 (/ 3 5)) ; this comment has no effect on the preceeding expression @this-comment-actually-comments-out-the-entire-following-sexp (* 5 10 (/ 3 5)) ; the following expression evaluates to 50 because the @foo comments out the (/ 3 5) (* 5 10 @foo (/ 3 5))
4. Functional Programming
Variable value
x
Function invocation
(f ...)
Example:
; define a function that squares its argument (define (square x) (* x x) ; now apply it to 2; result is 4 (square 2)
5. Functional Syntax
definition name value
A definition associates a name to a value within the scope of the module or class it's defined within. A definition never takes any space in instances.; it is stored in the class itself when defined within one. At class instantiation, the value is evaluated in empty lexical and object environments.
(definition PI 3.14159265) (definition circumference (lambda (diameter) (* diameter PI))) (circumference 10) ; returns 31.4159265
6. Functions
In Jazz, functions are first-order objects and can be freely manipulated like other objects, including being passed as parameters or stored in variables. Anyone who says functions are not object-oriented is just showing that they haven't thought enough on the problem!
Jazz supports the standard Scheme 'define', as well as 'definition' and 'method'. 'definition' is an extended form of 'define' that supports more features, and 'method' is used with classes. In the following examples we'll omit 'define'.
Parameters
Parameters can be passed using several techniques in Jazz:
Jazz uses the typical positional parameters seen in most languages. It also supports variadic functions and optional keyword parameters.
; standard positional (definition (double x) (* x x)) (method (double x) (* x x)) ; variable number of parameters ; args is a list containing the passed parameters (definition (sum . args) (apply + args)) (method (sum . args) (apply + args)) (* w h)) ; in this example 'base' is optional, and defaults to 10 (definition (any-log number (base 10)) (/ (log number) (log base))) (method (any-log number (base 10)) (/ (log number) (log base))) ; optional keyword parameters ; in this case 'width:' and 'height:' default to 1 when not provided (definition (area (width: w 1) (height: h 1)) (* w h)) (method (area (width: w 1) (height: h 1))
7. Syntax
(bindvariables-tree values-tree expr ...) |
syntax |
This is a little like Scheme's let, but can bind multiple values through pattern-matching; it takes a tree of identifiers and binds them by pattern-matching against a tree of values. Bind can also handle variadics. These are best understood by example:
; not too different from let (bind (x) '(1) ; x is now bound to 1 x) ; return 1 from expression ; bind a list of identifiers to a list of numbers (bind (x y) '(1 2) ; x is 1, y is 2 (+ x y)) ; return 3, the result of x + y ; bind a list of identifiers to a tree of numbers (bind (x y z) '(1 (2 3) ((4))) ; x is 1, y is (2 3), z is ((4)) (+ x (first y) (second y) (caar z))) ; returns 10 ; bind a tree of identifiers to a tree of numbers -- destructuring them (bind (x (y1 y2) ((z))) '(1 (2 3) ((4))) ; x is 1, y1 is 2, y2 is 3, z is 4 (+ x y1 y2 z)) ; returns 10 ; variadics (bind (x . rest) '(1 2 3 4) ; x is 1, rest is (2 3 4) (/ (apply + rest) x)) ; sum rest, then divide by x; returns 9
(receive(variable ...) values expr ...) |
syntax |
It's possible to return multiple values from a Scheme expression using 'values'. 'receive' takes these returned values and binds them to the given identifiers.
(receive (x y) (values 1 2) ; x is 1, y is 2 (+ x y)) ; evaluates to 3 (let ((foo (lambda () (values +2 -2)))) ; foo will return +2, -2 (receive (x y) (foo) ; evaluate foo and assign values to x, y (+ x y ))) ; returns 0
(quoteexpr) |
syntax |
This turns off the Scheme evaluator and returns its first argument without evaluating it first. The short form in particular is useful for list literals. This is best understood by example:
(quote (1 2 3)) ; evaluates as (1 2 3) '(1 2 3) ; short form, also returns (1 2 3) (1 2 3) ; this results in an evaluation error, since 1 is not a procedure (quote 12345) ; quoting a value returns that value, so 12345 in this case '12345 ; same thing
(iftest yes-expr no-expr ...) |
syntax |
Works much like you'd expect. It requires the yes-expr, but the no-expr is optional (although inadvisable -- use 'when' instead of 'if'). You'll want to look at 'begin' as well; it's handy in the common case where you'd like to evaluate multiple expressions in a conditional branch.
(if #t 1 2) ; evaluates as 1 (if #f 1 2) ; evaluates as 2 (if #t 1) ; can also omit the false branch (if (> 5 1) ; we use begin here because we're evaluating two expressions: (begin (display "congratulations!") ; if we omitted begin, then this would accidentally be the false branch: (display "math works on this machine")) (display "uh-oh!")) ; the actual false branch
(whentest yes-expr ...) |
syntax |
If test is true, all following expressions are evaluated. Similar to if, but doesn't take a false branch and can evaluate multiple expressions without begin.
(when #f (display 1)) ; returns #f and displays nothing (when #t (display 1)) ; displays 1 ; this evaluates multiple expressions (when #t (display "The secret of the universe is...") ; first it shows a sentence 42) ; then it returns 42
(unlesstest no-expr ...) |
syntax |
Works just like 'when', but only evaluates no-expr if test is false.
(unless #t (display 1)) ; returns #f and displays nothing (unless #f (display 1)) ; displays 1 ; this evaluates multiple expressions (unless #f (display "Does this example seem familiar?") ; first it shows a sentence "it should!") ; then it returns a string
(whiletest expr ...) |
syntax |
Works like a normal while loop -- as long as test is true, it re-evaluates its expressions.
; bind counter to 10 (define counter 10) ; print a count-down from 10 to 0 (while (>= counter 0) (display counter) (decrease! counter)) ; decrement counter by 1
(beginexpr ...) |
syntax |
Wraps one or more expressions and returns the result of the last one evaluated. Handy when used by special forms like 'if'.
(begin 1) ; evaluates to 1 (begin (* 2 3) (* 4 5)) ; returns 20, the result of the last expression
(prog1result-expr1 expr ...) |
syntax |
This behaves much like 'begin', evaluating all its expressions, except that it always returns the result of the first evaluated expression, not the last.This is sometimes useful to avoid an explicit temporary variable.
(prog1 (* 2 3)) ; returns 6 (prog1 (* 2 3) (* 4 5)) ; returns 6 -- contrast with the example in 'begin' above (prog1 42 ; returns 42 (display "The secret of the universe is...")) ; but shows string before return
(tie) |
syntax |
A convenient way to interpolate strings. If an identifier is bound in the scope where tie is used, the value of the identifier can be interpolated into the string using {identifier_name}.
(bind (x y z) '(1 2 3)
(tie "{x} + {y} = {z}"))
(casevalue ((key ...) expr ...) ... (else exp ...)) |
syntax |
This works similar to the switch statement in C-derivatives, except it's more flexible. A value is given to 'case' which then finds a key that matches, then evaluates the associated expression(s). The else clause at the end is optional.
NB: case uses 'eqv?' to determine the equality of two values. Cetain types of values, like strings and non-empty lists, always return false. If you need to use 'equal?' or some other sophisticated means of comparison, see 'cond' below.
; a toy function that checks whether a number is one of the first ten primes ; in this case it'll evaluate to 'not-prime, since 10 is not one of them (case 10 ; take value of 10 and check it against... ((2 3 5 7 11 13 17 19 23 29) 'prime) ; any of numbers listed are prime (else 'not-prime)) ; otherwise not a prime ; another example, using symbols -- displays 'edible fruit' and returns 'edible (case 'apple ; match for this ((carrot lettuce tomato) (display "edible vegetable") 'edible) ((pear plum apple) (display "edible fruit") 'edible) ; this matches ((rock) (display "yummy rock") 'in-edible))
(ecasevalue (key expr ...) ... (else exp ...)) |
syntax |
A specialized version of 'case' that only has one key per branch. This works almost identical to C-derivative switch statements. It can take an optional else clause.
(ecase 1 ; matches against 1 (0 (display "zero")) (1 (display "one")) ; takes this branch, displays 'one' (2 (display "two")))
(typecasevalue ((key ...) expr ...) ... (else exp ...)) |
syntax |
Like 'case', except matches on the object type of the value.
(typecase "this is a string" ; value to match is a String ((List) 1) ((String) 2) ; matches String class, returns 2 ((Number Symbol) 3) (else 4)) ; another example, testing an object for a class type from most- to least-specific (typecase 1+2i ; value to match is a Complex ((Rational) (display "this is a rational")) ((Number) (display "this is a number")) ; matches here ((Object) (display "this is an object")))
(cond(test exp) ... (else exp)) |
syntax |
Somewhat like case, but much more flexible. 'cond' does not take a value, but rather tests a series of expressions until it finds one that evaluates to true, then evaluates the branch of expressions associated with it. It can take an optional else clause.
; returns the absolute value of a number (definition (abs n) (cond ((< n 0) (* -1 n)) ; if n < 0, multiply by -1 and return ((> n 0) n) ; if n > 0, return n (else 0))) ; otherwise return 0 ; same function without the else clause (definition (abs n) (cond ((< n 0) (* -1 n)) ; if n < 0, multiply by -1 and return ((>= n 0) n))) ; if n >= 0, return n
(set!variable expr) |
syntax |
Changes the value an existing identifier is bound to. This is the same as assignment in other languages.
(definition a-variable 10) ; bind a-variable to 10 (set! a-variable 25) ; a-variable is now 25 (set! a-variable (/ a-variable 2)) ; a-variable is now 25/2 (set! a-variable (number->string a-variable)) ; a-variable is now '25/2'
(increase!variable expr {value}) |
syntax |
Increments a variable. This is a short-hand for (set! foo (+ foo 1)).
(definition a-variable 10) ; bind a-variable to 10 (increase! a-variable) ; a-variable is now 11 (increase! a-variable) ; a-variable is now 12 (increase! a-variable 8) ; increase by 8, a-variable is now 20
(decrease!variable expr {value}) |
syntax |
Decrements a variable. This is a short-hand for (set! foo (- foo 1)).
(definition a-variable 10) ; bind a-variable to 10 (decrease! a-variable) ; a-variable is now 9 (decrease! a-variable) ; a-variable is now 8 (decrease! a-variable 3) ; decrease by 3, a-variable is now 5
(let((variable expr) ...) expr ...) |
syntax |
'let' is a powerful tool that avoids most of the problems that assignment has in lesser languages (ahem); variable dependencies and scope are more explicit, uninitialized identifiers are unlikely and unidentified identifiers are caught at compile-time.
'let' binds a set of identifers to a set of evaluations before evaluating the main body. If the same identifier is in use before a 'let', its old value is shadowed only within the body of that 'let'. Note that within the section that binds values, evaluations that bind to prior let bindings cannot be used (see 'let*' and 'letrec' instead). 'let' is best understood by demonstation:
(let ((x 1) ; x is bound to 1 (y 2)) ; y is bound to 2 (+ x y)) ; evaluates to 3 ; a more complicated example (let ((list-1 (list (* 2 3) (+ 4 5))) ; list-1 is bound to (5 9) (list-2 '(12 14 15)) ; list-2 is bound to (12 14 15) (list-3 '(1))) ; list-3 is bound to (1) (display list-1) ; display (5 9) (display list-2) ; display (12 14 15) ; list-1 is rebound to (5 9 12 14 15 1) (let ((list-1 (append list-1 list-2 list-3))) (display list-1)) ; display (5 9 12 14 15 1) ; since we've left the prior let, list-1 is back to (5 9) (display list-1))
(let*((variable expr) ...) expr ...) |
syntax |
This works like let, but after an identifier is bound you can use it in following lines binding variables.
(let* ((x 1) ; x is bound to 1 (y (+ x 2)) ; note that x is now a valid identifier, so y is bound to 3 (z (/ x y))) ; x and y are both bound here, so z is 1/3 (+ x y z)) ; returns 13/3
(letrec((variable expr) ...) expr ...) |
syntax |
One of the limitations of 'let' is that it won't allow you to write recursive functions. An identifier is not bound until after its associated expression is evaluated. Unfortunately, recursive functions require an identifier to exist during definition. 'letrec' allows you to refer to an expression's identifier during evaluation.
; this here is a function that benchmarks function f count times (definition (bench-times f count) ; start the definition of the function assigned to 'times' (letrec ((times (lambda (f remaining) (when (> remaining 0) (f) ; notice that 'times' is used here recursively, even though the ; definition is not yet complete: (times f (- remaining 1)))))) (time (times f count))))
(catch(type variable expr ...) expr ...) |
syntax |
Evaluates expressions, and if an exception is thrown that matches the exception type, evaluates the catch expressions.
; the exception we'll catch, and an identifier to bind it to (catch (Server-Error error ; these two lines are evaluated when a Server-Error is caught (display "Caught exception: ") (display error)) ; the next three lines are where we can catch exceptions (display "Before exception. \n") (throw (new Server-Error)) ; throw a Server-Error (display "Should never get here... ")) ; never executed ; a simple version that doesn't do anything when it catches an exception (catch Server-Error (display "Before exception. \n") (throw (new Server-Error)) (display "Should never get here... "))
(throwvalue) |
syntax |
Raises an exception. Please see the catch example above.
(unwind-protectprotected-expr protection-expr ...) |
syntax |
If you need perform some expressions regardless of whether an exception occurs, this is a nice way to do it; it is similar to 'finally' in Java or Python. 'unwind-protect' takes two expressions, one which it will attempt to evaluate, and another which it will always evaluate. If an exception occurs during the first evaluation attempt, the second will still be run. This is particularly useful when dealing with external resources like files or sockets; regardless of whether an error occurs while writing to a file, you can ensure it's closed before returning or unwinding the stack due to an exception.
; both the following examples display 'after' (catch Server-Error (unwind-protect (throw (new Server-Error)) ; expression to attempt evaluation (display "after"))) ; expression to always evaluate at the end (catch Server-Error (unwind-protect ; in this case an exception isn't thrown, but 'after' will still be displayed (* 2 3) (display "after")))
(lambdaparameters-list expr ...) |
syntax |
An anonymous function. It binds the parameters with the passed arguments, then evaluates the body. This is particuarly useful with 'let' and higher-order functions.
; short-hand way to define a function (definition (inverse-sum . numbers) (/ 1 (apply + numbers))) ; actually, it's syntactic sugar for assigning an anonymous function to an identifier ; this is the same as the above function (definition inverse-sum (function numbers (/ 1 (apply + numbers)))) ; map is a higher-order function that applies the given function to each member of a ; list, returning a new list. In this case we're squaring a list of numbers, which ; evaluates to (1 4 9 16 25 36 49 64 81 100) (map (lambda (x) (* x x)) '(1 2 3 4 5 6 7 8 9 10)) ; there are several ways to pass arguments to lambda -- if you omit the parens around ; the parameters, it becomes a variadic (let ((foo (lambda x x))) ; all the arguments -- 1 2 3 4 5 -- are pushed into x, thus returning the ; list (1 2 3 4 5) (foo 1 2 3 4 5)) ; if you keep the parens around the parameters, it behaves like normal positional ; parameters (let ((foo (lambda (x y) x))) ; returns only the first of two required arguments (foo 1 2)) ; evaluates to 1 ; and you can mix the two, but placing a '.' between the required args and the rest (let ((foo (lambda (f . numbers) ; f is required, everything else goes in numbers (apply f numbers)))) ; turns numbers into the arguments for f ; f binds to +, numbers binds to (1 2 3 4 5) (foo + 1 2 3 4 5)) ; the result is the sum of the numbers, 15
(andexpr ...) |
syntax |
This syntactic form will return true unless one of its expressions are false. It will stop as soon as it encounters a false value and return false.
It differs from R5RS 'and' since it only guarantees that a returned true value will be true, not the last evaluated value. If you want R5RS semantics, use 'essay'.
Some examples:
(and) ; returns true (and 1) ; returns true (and 1 2 3) ; returns true (and 1 #f) ; returns false (and true (= 2 (+ 1 1))) ; returns true ; will not signal an error because the first test will fail: (and (symbol-bound? 'not-a-bound-variable) not-a-bound-variable)
(orexpr ...) |
syntax |
This syntactic form will return false unless any of the expressions are true. It will stop as soon as it encounters a true value and return true.
It differs from R5RS 'or' since it only guarantees that a returned true value will be true, not the first non-#f value. If you want R5RS semantics, use 'either'.
(or) ; false (or 1) ; true (or #f #f 3) ; true ; one simple application of the fact that 'or' stops as soon as it encounters a true ; value is in very clean code for managing simple lazy structures. (define a-big-structure-only-on-demand nil) (define (get-structure) (or a-big-structure-only-on-demand (set! a-big-structure-only-on-demand (new-structure))))
(assertasserted-expr) |
syntax |
Asserts the expression is true. If the expression returns false, an exception is thrown.
(assert #t) ; nothing happens (assert (* 12 82 54)) ; nothing happens (assert (zero? 10)) ; exception is raised
8. Units
unit modifier unit-name expr ...
A unit is effectively a named bundle of code in a file. Units can be automatically located and loaded by name, and the kernel ensures they're only loaded once. They can also load other units into their namespace. Unit names roughly match their filesystem path inside a package. 'unit' is primarily used in pure-scheme files, as is 'require' which is often used with 'unit'; Jazz files use 'module' and 'import' (see below).
; in file example/foo.scm (unit example.foo (define (hello-foo) (display "Hello Foo!"))) ; in file example/bar.scm (unit example.bar (require (example.foo)) ; pull in code from example.foo unit just above (define (hello-bar) (hello-foo) ; hello-foo comes from example.foo (display "Hello Bar!")))
module module-name dialect ...
A module is a unit that implements a specific dialect -- scheme or jazz. Whereas 'unit' is normally used with Scheme files, Jazz file always use 'module', and sometimes Scheme files do as well. Since modules are a superset of units, they are also automatically located and loaded by name, and the kernel ensures they're only loaded once. Modules offer the ability to export and import only specific definitions and are preferable to plain units. They're loaded with 'import'.
; this example assumes we're also using example/foo.scm and example/bar.scm from ; 'unit' just above (module example.xyzzy jazz ; note that this definition has a 'public' modifier -- no modifier defaults to ; private and wouldn't export (definition public (hello-xyzzy) (display "Hello Xyzzy!"))) ; in example/quux.jazz (module example.quux jazz ; when example.quux is imported, it'll also import example.xyzzy, not just the ;definitions inside example.quux (export (example.xyzzy)) (definition public (hello-quux) (display "Hello Quux!"))) ; in example/baz.jazz (module example.baz jazz ; this is used to import pure scheme code: (require (example.bar)) ; Jazz doesn't know about 'require'd pure scheme definitions, so this tells it ; what to import from example.bar: (native hello-bar) ; this imports what example.quux exports -- its public definitions and the public ; definitions of example.xyzzy (import (example.quux)) (definition (run descriptor) (hello-bar) ; displays 'Hello Foo!' 'Hello Bar!' (hello-quux) ; displays 'Hello Quux!' (hello-xyzzy)) ; displays 'Hello Xyzzy!' ; see 'products' below for details -- this is a detail unrelated to modules: (register-product 'baz title: "Baz" run: run))
'import' and 'export' can both be conditional. If an identifier exists during compilation, it can be used to decide what to export.
; 'x11', 'windows' and 'carbon' identify which platform the code is running on ; in example-b/carbon.jazz (module example-b.carbon jazz (definition public (what-am-i) (display "carbon"))) ; in example-b/windows.jazz (module example-b.windows jazz (definition public (what-am-i) (display "windows"))) ; in example-b/x11.jazz (module example-b.x11 jazz (definition public (what-am-i) (display "x11"))) ; in example-b/product.jazz (module example-b.product jazz (import (example-b.carbon (cond carbon)) ; import this file if on straight Mac (example-b.windows (cond windows)) ; import this file if on Windowss (example-b.x11 (cond x11))) ; import this file if using X11 (definition (run descriptor) ; what-am-i was only imported from one, so displays your platform (what-am-i)) ; see 'products' below for details -- this is a detail unrelated to modules (register-product 'baz title: "Example-B" run: run))
9. Object-Oriented Programming
9.1. Classes
Jazz supports a single-inheritance object system with multiple interfaces, similar to Java. The root class -- from which all classes eventually inherit -- is 'Object'. Jazz's object system is fairly dynamic, but with some restrictions: methods can be dynamically added at runtime, but slots cannot. Dynamically adding methods is a useful but sharp tool, so please only use this with caution; avoid 'monkey-patching'.
Classes can only be defined at the module level.
A basic example of a class and its use:
; in class-example/Example.jazz: (module class-example.ExampleClass jazz (import (jazz.tie)) ; so we can use (tie ...) ; defining 'ExampleCass', inherits from 'Object' (class ExampleClass extends Object ; instance variable 'name', initializes to empty string (slot name initialize "") (method (initialize a-name) ; the constructor -- takes a single argument (nextmethod) ; invoke the constructor of the parent class first (randomize) ; seed the random function (set! name a-name)) ; change the value of 'name' to the given argument (method public (display-hi) ; public method (display (tie "Hi, {name}!\n"))) ; display greeting with the value of 'name' (method public (display-bye) (display "Bye!\n")) (method public (display-a-number) ; method calls -within- a class behave like normal function calls (display (make-a-random-prime)) (display "\n")) ; this method defaults to private, so cannot be accessed outside class (method (make-a-random-prime) (let ((primes '(2 3 5 7 11 13 17 19 23 29)) (prime-index (random 10))) (element primes prime-index))) ; fetch randomly one of the first ten primes )) ; in class-example/product.jazz (module class-example.product jazz (import (class-example.ExampleClass)) (definition (run descriptor) (let ((example (new ExampleClass "Jane Doe"))) ; create new ExampleClass ; '~' appended to method name invokes method on passed object (display-hi~ example) (display-a-number~ example) (display-bye~ example))) ; see 'products' below for details -- this is a detail unrelated to modules (register-product 'class-example title: "Class-Example" run: run))
slot name
A slot is an object instance variable. The set of slots in a class defines the structure of the class's instances, thus the data that each instance can store.
Initialization of a slot is optional, but always initializing is safer. If it's not initialized, it'll default to #f.
(class Point extends Object (slot graph-id) ; when a Point object is created, this isn't initialized (slot x initialize 0) ; but the following three are initialized to 0 (slot y initialize 0) (slot z initialize 0))
property name
A property is a slot that can specify a getter and a setter. While this can be a short-cut for writing the getter and setter methods yourself, by using 'accessors generate' (see example), it also provides metadata to the system while is needed for object literals.
As with slots, initialization is optional, but it's safer to do so. They default to #f if not explicitly initialized.
(class ExamplePoint extends Object ; similar to (slot foo): (property foo) ; makes slot 'x' and 'get-x', 'set-x' methods: (property x accessors generate) ; similar to 'x', but initializes slot 'y' to 0: (property y initialize 0 accessors generate) ; specifies names of implemented getter and setter: (property z getter get-z setter set-z) (method public (get-z) z) (method public (set-z z) ; 'z~self' refers to object's slot 'z' to disambiguate with local variable 'z' (set! z~self z)))
method {modifiers} (name . parameters) {return-type} . body
A method is where an object's code resides. A method is effectively a function that works with objects.
; a robot that says what it thinks (class Robot ; since no modifier present, defaults to private (method (think) "EXTERMINATE! EXTERMINATE!") ; evaluates to a string ; modifier says it's a public method with a single argument: 'name' (method public (speak name) (display (tie "Attention, {name}!\n")) ; greets user (diplay (think)))) ; says what it thinks (exterminate!)
Method invocation
A method looks exactly like a function call when invoking from within the same class where it is defined. When called from outside, a tilde (~) is appended to the method name and the object is passed as the first argument; remaining arguments are passed after it. The scope within which a method can be called is affected by modifiers in the definition.
; invokes method 'display-hi' on object 'foo' (display-hi~ foo) ; couple of method calls, the first returning an object that's used for the second (invalidate-view~ (get-parent~ view))
9.6. Interfaces
Jazz interfaces work much like Java interfaces. An interface describe an API that classes using that interface promise to implement. The descriptive quality of interfaces must be emphasized -- they only describe the external interface -- i.e. methods that must be present and can be called -- but they do not implement the code necessary for API to actually function; that must be done by the classes implementing the interface.
Interfaces can only contain abstract methods. While a class can only inherit from a single parent, it can implement many interfaces. Like classes, interfaces can only be defined within modules.
(module class-example.DangerousGerbil jazz ; all animals must have a sound, appearance and action methods (interface Animal (method public virtual abstract (sound)) (method public virtual abstract (appearance)) (method public virtual abstract (action))) ; anything dangerous must have a weapon (interface Dangerous (method public virtual abstract (weapon))) ; here we have a class of gerbils -- dangerous animals! (class DangerousGerbil extends Object implements Dangerous Animal ; these methods are overrides of the interface's virtual methods -- if a method is ; virtual, any class that inherits and overrides it must explicitly state ; 'override' (just like in C#) (method public override (sound) "Squeak!") (method public override (appearance) "A man-eating gerbil.") (method public override (weapon) "Long incisors!") (method public override (action) "Nibbles at your finger ferociously!")) )
9.7. Meta-Classes
Classes are objects in Jazz, so just as objects have classes, classes have metaclasses. The methods of an object are stored in a class, not the object itself; they can use instance variables. Likewise, the methods of a class are stored in the metaclass, not the class; they can use class variables. Metaclasses are also notable since they're involved in construction of objects, inheritance hierarchy, and other strange things.
There are two ways of working with metaclasses: explicity make one, or use the 'meta' modifier on methods in a class.
; metaclasses are also classes, but they inherit from Class (class ExampleClass-Class extends Class (method (meta-string) "meta")) ; all this method does is return string 'meta' ; this class has the above metaclass (class ExampleClass metaclass ExampleClass-Class extends Object (method public (display-class) (display "class")) ; this method displays the string 'class' ; this method displays the string 'meta' (method public (display-meta) ; this gets the class of the object and invokes the meta-string method ; in effect it acts as a class method (display (meta-string~ (class-of self))))) ; this is exactly the same as the above, but uses the 'meta' modifier, so it doesn't ; require an explicit metaclass (class ShortExampleClass extends Object ; note that we omit the metaclass here (method public (display-class) (display "class")) (method meta (meta-string) ; note the 'meta' modifier "meta") (method public (display-meta) (display (meta-string~ (class-of self)))))
9.8. Construction & Destruction
Jazz invokes the 'initialize' method on every method creation. 'destroy' can be explicitly invoked using (destroy~ obj), or used with (with-destroy ...). 'initialize' can take arguments, while 'destroy' does not.
'destroy' is not automatically invoked by the GC upon collection, like Java's finalize(). Instead, Jazz supports deterministic finalization similar to C++, making idioms like RAII possible. Deterministic finalization is particularly useful for handling non-memory resources like file handles and sockets.
Jazz achieves this with 'with'. (with ...) behaves much like (let ...), except that objects that are newly bound by 'with' will have their destructor invoked when the 'with' expression completes evaluation. See the example:
(class LifecycleExample extends Object ; example of a constructor taking a parameter (method (initialize foo) ; invokes constructors of parent classes -- leaving this out can cause problems (nextmethod)) (display (tie "starting with {foo}\n")) (method (destroy) ; example of a destructor ; as with the constructor, calls parent destructors -- leaving this out can ; cause problems (nextmethod))) (display "ending\n") ; an example of using LifecycleExample that invokes the constructor but not ; the destructor ; this displays: ; - starting with 42 ; - leaving scope (let ((obj (new LifecycleExample 42))) (display "leaving scope\n")) ; an example of using LifecycleExample that invokes the constructor and the ; destructor ; this displays: ; - starting with 42 ; - leaving scope ; - ending (with ((obj (new LifecycleExample 42))) (display "leaving scope\n"))
9.9. Literals
Literals
Jazz supports object literals, a useful sugar for creating objects, and powerful concept when combined in forms (see components below). Any class can define its own literal constants. A literal is enclosed in #f and begins with the class name.
; a couple examples from the standard jazz library {Point 2 3} ; creates a Point with the given values {Color Red} ; creates a Color with the give value
Since object literals must be understood by the compiler before their use in the rest of the code, they can be added by creating install.scm and literal.jazz files which are used by '.package' in a package's root. Here's an example:
; in the .package file (package literal-example ; this is the line that is needed to call install: (root "src") (install literal-example.install) ... ) ; the rest doesn't matter for this example ; in src/literal-example/install.scm (unit literal-example.install ; this line adds the LiteralExample literal (jazz.define-literal LiteralExample literal-example.literals.construct-literalexample)) ; in src/literal-example/literals.jazz (module literal-example.literals jazz (import (literal-example.LiteralClass)) ; the function called to create the object when the literal is encountered (definition package (construct-literalexample h v) (new LiteralExample h v)))
9.10. Generic functions
Generic functionss are a useful way to extend classes without modifying the class itself. In many languages, in order to add a method to a class, the class must be inherited from. In more dynamic languages, classes can be reopened to add methods to them at runtime -- as can Jazz.
An alternate way to add functionality to a class are generic methods, which look and behave like functions, but dispatch on the type of arguments. Generic methods can be defined for any class regardless of which module the class is in and which module the generic method is defined in. Indeed, a generic method for a set of classes may be spread across many files.
Generic functions shine when dispatching against the types of multiple arguments -- a common example is binary operators. An experimental CLOS-like extension for Jazz exists which supports multiple-dispatch, but for now mainline Jazz dispatches solely on the type of the first argument.
; classes we want to use with a generic function (class Sum extends Object) (class Mul extends Object) (class InverseSum extends Sum) ; indicate to Jazz we're creating a new generic function (generic (perform (<Object> x) . rest) #f) ; specialize the generic function for Sum -- if a Sum object is the first ; argument, this executes (specific (perform (<Sum> x) . rest) (apply + rest)) ; specialize the generic function for Mul -- if a Mul object is the first ; argument, this executes (specific (perform (<Mul> x) . rest) (apply * rest)) ; specialize the generic function for InverseSum -- if an InverseSum object ; is the first argument, this executes i (specific (perform (<InverseSum> x) . rest) ; here we also call to the parent, invoking the Sum specialization (/ 1 (apply nextmethod x rest))) ; using a generic function (display (perform (new Sum) 1 2 3 4)) ; displays 10 (display (perform (new Mul) 1 2 3 4)) ; displays 24 (display (perform (new InverseSum) 1 2 3 4)) ; displays 1/10
10. Modifiers
Modifiers are used with methods and sometimes functions. They modify the scope of a method or function, and other attributes related to inheritance. Here's an example of a class with modifiers:
(class ModifierExample extends Object (slot foo) ; a class method that creates objects of this or inheriting classes (method meta public (factory-method foo) (new self (* 2 foo))) (method (initialize foo) ; a typical constructor (set! foo~self foo)) ; an abstract method that must be implemented by an inheriting class (method abstract chained public (public-method)) ; a private method that cannot be overridden (method private final (unoverridable-method) "too bad, so sad")) (class ChildModifierExample extends ModifierExample ; inherit from the above class (method public override (public-method) ; implement the required method foo))
meta
Defines a field of the meta class. Because a class is an object, meta methods can use self to refer to themselves (i.e. the class).
private
Access is restricted to classes that reside in the same file.
protected
Access is restricted to sub-classes and classes in the same package.
public
Access is unrestricted.
final
A final definition cannot be overridden.
virtual
A virtual definition can be overridden in sub-classes.
override
When overriding a virtual or chained definition in a sub-class, 'override' must be explicitly used to explicitly indicate this intention.
chained
A chained method can be overridden in sub-classes and the override must call the overridden method. It's effectively a virtual method with mandatory (nextmethod).
abstract
A abstract definition must be overridden in some sub-class. This modifier is currently unimplemented.
inline
An inline method permits the compiler to inline its code.
synchronized
A synchronized method is guaranteed to executing in at most one thread at a time.
11. Type Annotations
Jazz is a dynamically-typed language. It supports a superset of Gambit's types.
In dynamically-typed (also called untyped) languages, the type is attached to the objects themselves and is available at run-time. In statically-typed languages -- like most C-derivatives -- types are attached to identifiers. Dynamically-typed languages are more flexible than statically-typed languages, but they trade off some performance and the earlier detection of some classes of program errors in return.
In order to provide the programmer a choice between these two trade-offs in any piece of code, Jazz supports optional type declarations. This allows rapid early development and experimentation by using the strengths of dynamic typing, and once the design solidifies and bottlenecks are identified, type annotations can be added where needed to increase correctness and performance.
Types annotations can be added in all function and method signatures for arguments and return values. They're also used in slots and properties.
Types are denoted by <> brackes and the type name. For example, a few primitive types:
There are quite a few primitive types. To read the full list, find 'jazz.primitive-types' in walker.scm. A short list of the more common types is: null, char, string, number, fx (a fixnum), fl (a float), int, list, pair, symbol, vector. Note that some of these types are specializations of others. E.g. a fx is also a number.
Programmers can freely add types through classes as well, since every class has a type. Some examples of these:
Note that the above examples do not allow null. If your type signature must support null, append a '+' to the type name:
To increase the robustness of your code and catch errors earlier, do not allow nulls (using '+') unless necessary. The common NullPointerException in Java is caused by allowing nulls with every type.
Some examples of type annotations in action:
; this just squares an argument of type number, returning number (definition (square num <number>) <number> (* num num)) ; this takes a list, and returns a float (definition (inv-sum-floats num-list <list> ) <fl> (/ 1 (apply + num-list))) ; example of a class that uses type annotations in places (class TypeExample extends Object (slot divisor <number>) ; slot is a number (method (initialize divisor <number>) ; takes a number as an argument (nextmethod) (set! divisor~self divisor)) (method public (is-divisor-even?) <bool> ; returns a bool (= (modulo divisor 2) 0)) (method public (sum-and-divide num-list) ; untyped (/ (apply + num-list) divisor)))
12. Component Programming
One of the strengths of components is the integration of programming with the visual design it enables. By mixing programming code and view data, components bring the power of programming tools to design. Components are the basis for much of the UI.
More concretely, components are a means to create a hierarchy of objects without necessarily using inheritance, that can be entirely instantiated with a single 'new'. Components help unify composition and inheritance, and also provide ways to track parents, children and creators of each component in the hierarchy.
They're probably best understood by example:
; inherit from Component to support component behaviour (class Engine extends Component ; some properties to make data accessible to forms (property type accessors generate) (property size accessors generate) (property fuel accessors generate)) (class Vehicle extends Component (property wheels accessors generate) (property passengers accessors generate)) ; this inherits from a component, so it's still a component (class Car extends Vehicle ; a form is a bit like a constructor that initializes a composition of components ; and their properties (form ; install refers to the current component -- we're setting the two properties ; inherited from Vehicle (<install> wheels: 4 passengers: 4 ; here we create a child component of type Engine, setting its properties and ; giving it the reference name 'engine' (<Engine> name: engine type: internal size: 350 fuel: gasoline)))) ; we inherit from the above component (class SportsCar extends Car (form ; note that forms can inherit too (<install> ; with the ! we override the initialization of component 'engine' (see Car form) (<!> name: engine size: 450))))
Component
Inheritance and Composition
The Component class is the fundamental class for components. Is the foundation of the graphical user interface, but can be useful in non-graphical contexts. Here are some of the many methods:
(childname) |
method |
Returns the child whose name is name. If no such child is found, an error is signaled.
children | slot |
A list of all children of this component.
(concludeinitargs) |
method |
Invoked after all initialization is complete, but before calling show.
(find-componentname) |
method |
Returns the child whose name is name. If no such child is found, nil is returned.
(finishinitargs) |
method |
Invoked before the form structure from a containing form gets installed.
(installinitargs) |
method |
Installs the class form.
(locatename) |
method |
Similar to child, but probably preferable in use since it detects ambiguous names.
name | slot |
Every component can be named. A name must be a symbol or nil. A name of nil represents an anonymous component.
parent | slot |
The parent component of this component -- the object one step higher up the hierarchy.
(prepareinitargs) |
method |
Invoked before the form gets installed.
Form
A forms contains properties. Each child form -- forms on children of a class -- can redefine parts of the parent form. Properties can be added, modified or even removed.
For example, if class X has two properties, 'a' and 'b', the derived class Y can change either of them (e.g. 'a'). The resulting form after inheritance would contain both 'a' and 'b', with 'a' being the redefined property.
When a form is created, the base form is loaded, then each modification of the successive branches are applied, up to the final form.
A property initialized in a class can be impacted by the class's form and all subsequent form redefinitions in the subclasses.
13. Packages
This is a listing of many of the packages in Jazz. More commonly-used ones get more attention.
13.1. jazz.calendar
This is a calendar widget. It shows months and days, and tracks holidays and events. It also contains many of the components used as sub-elements in the widget.
13.2. jazz.console
This is a multi-console widget often used as a REPL. Entering text in this will cause the text to be sent through a provided port. It includes formatting, text completion, history and features useful for navigating definitions and references.
13.3. jazz.database
jazz.database is the package for interfacing with databases. It provides an abstracted API that can use several different relational databases. At the moment ADO and SQL Server are supported through jazz.database.ado and jazz.database.sqlserver. It also provides a UI for querying databases.
The actual call and response API for DBs is found in jazz.database.connection. Connection contains data about an existing connection, and provides an API for making requests and transactions. Connection-Printer is a subclass that provides the same API, but pretty-prints all arguments given to it. Recordset holds the results of a request, and provides various means to extract or iterate over these results. Recordset-Metadata holds information about the columns themselves, such as name and type.
jazz.database.designer contains UI widgets for editing column types.
This is a multi-console widget often used as a REPL. Entering text in this will cause the text to be sent through a provided port. It includes formatting, text completion, history and features useful for navigating definitions and references.
jazz.database.view has UI widgets for navigating different data sources and schemas. Data-Source-Chooser uses Data-Source-Browser to select a database. Likewise, Schema-Chooser uses Schema-Browser to select various schemas in a database.
13.4. jazz.debuggee
Remote debugger. This is the part of the debugger that is kept in the app that is being debugged.
13.5. jazz.debugger
This contains the debugger interface and the underlying communication mechanism to interact with the debuggee. The UI developers can use to debug a local or remote process is kept here.
13.6. jazz.designer
This contains the the support classes for the UI builder.
13.7. jazz.editor.*
Widgets with syntax highlighting and preferences for various languages, the most interesting being jazz.editor.c, jazz.editor.lisp, jazz.editor.jazz and jazz.editor.sql. Some of them contain support for catalogues. jazz.editor.sql also supports live connections and interactions with databases, the management of these connections, and the widgets needed for all this.
13.8. jazz.graphic
This handles most interesting operations in 2D graphics. It builds on surface operations -- like transforms and clipping -- and handles basic drawing operations like ellipses, quadrilaterals and lines. jazz.graphic also provides higher-level operations like colour conversions and fonts.
13.9. jazz.graphic.opengl
This package is a fairly complete cross-platform interface to OpenGL, GLU and GLUT, with some windowing operations. The API follows OpenGL's C API closely, so popular idioms will continue to work as expected.
jazz.graphic.image contains image handling functionality. Image represents the image data itself, as well as rendering and various manipulations and scaling thereof. Portfolio is a cache for images.
13.10. jazz.groupware
This contains the operations and UI needed for comparing forms, files, directories and databases. jazz.groupware's basis is Compare-Text and Compare-Tree. All the other comparators use them. It also contains the groupware workspace.
13.11. jazz.io
This contains most of the file and directory handling. This includes filesystem navigation and file manipulation.
13.12. jazz.jml
This contains a JML parser, transformer, and renderer. JML is Jazz's Markup Language, and shares much in common with HTML, except using s-expressions. Like HTML, JML nodes are organized in a tree, and each node has a tag, properties and possibly children.
jazz.jml.model contains the node classes used for construction of JML trees. JML-Element behaves much like an HTML element, and JML-Text stores plaintext in the tree. Both inherit from JML-Node, which provides the implementation for maintaining and traversing JML trees.
jazz.jml.parser contains JML-Parser. It takes a set of s-expressions conforming with JML and converts them to a tree of JML-Element and JML-Text.
jazz.jml.renderer has a basic class for rendering JML. It doesn't do much itself, but it's used by jazz.jml.xhtml.
jazz.jml.transformation contains JML-Transformation, which can be used to convert between JML trees that have different types of nodes.
jazz.jml.xhtml includes an JML-XHTML parser and renderer. The XHTML-Parser converts XHTML represented in JML into a JML tree, while XHTML-Renderer converts the tree into actual XHMTL. Jazz docs are written in JML and later transformed into XHTML.
13.12.1. jazz.jrm
This is used for remote object invocation, for other OS processes and processes on other machines. It also includes object serialization and deserialization.
jazz.jrm.register tracks objects by name. The Register class provides an API for registering and unregistering objects with various aliases. These objects can then be looked up by their alias.
jazz.jrm.remote contains the meat of remote invocation. IOR are Internet Object References; they refer to remote objects on machines that can be anywhere on the Internet. Local-Proxy acts as a proxy for a local object, while Remote-Proxy is used for any object addressable by an IOR. Remote-Listener is the server that receives remote invocations on local objects.
13.12.2. jazz.library
This is a big bag of tricks. It contains Components, Events, logging, cryptography and even raster resource handling and finite automata. If you can't find what you're looking for elsewhere, check here.
One of the more unusual things it contains is Exemplar. This is a small OO system where everything is modifiable at runtime, and has no class / instance distinction.
13.12.3. jazz.media
This provides a simple cross-platform API for playing sounds and music, although it is best supported on Windows.
13.12.4. jazz.network
This contains mechanisms for communicating over IPv4 networks with TCP, both as server and client. It also has a basic web server.
jazz.network.host contains classes for the TCP server and client. Host represents hosts on IPv4 networks, and can convert between IP addresses and domain names. There's not much in TCP-Client, but TCP-Server is the basis of processes that can receive packets from over the Internet. It attaches a thread to a host interface and port and listens.
jazz.network.http contains a client and server, much like jazz.network.host, but specialized for HTTP traffic. HTTP-Client can retrieve HTTP resources from across the Internet, and includes cookie handling for that purpose. HTML-Page represents page objects, with names and content. HTTP-Cookie stores a cookie name and value. HTTP-File-Response loads up a file off the filesystem and sends it out a port. HTTP-Message parses, stores and sends HTTP headers, including cookies. HTTP-Recorder records all traffic that occurs on an open port. HTTP-Request represents requests, and includes parsing for them. Similar applies to HTTP-Response. HTTP-Session is for tracking of live sessions.
HTTP-Server and Web-Server together comprise the web-server. It responds to most common HTTP requests, has session tracking, and handles basic authentication.
Web-Servers-Manager and Web-Servers-Actions create a UI for starting, stopping and changing local servers. jazz.network.server.Server-Panel provides a more basic functionality for the console.
13.12.5. jazz.platform
Much of the platform-specific code is kept in this package. This includes windows, surfaces, event reception, rendering of fonts and crash handling.
13.12.6. jazz.profile
Profiles are where user-specific preferences are stored for Jedi. This includes hot-keys for custom tests, recordings, and even SQL connections. It does not store key-bindings.
13.12.7. jazz.sample
A number of Jazz examples. They range from Hello World and fibonacci to Mandelbrot and a game server.
13.12.8. jazz.system
Some low-level facilities for applications. This includes jazz processes, handling for command-line arguments, some platform-specific key-handling, and platform-specific performance counters and logging. This contains the Application class, which serves as the basis for the IDE; it takes care of the starting menus, events, the clipboard, key bindings, and other basic facilities you'd expect a basic GUI to provide. It also has an API for windows services.
jazz.application serves as the basis for the IDE, and can be used for other GUI apps. Action-Actions contains a form with a number of actions useful for an editor -- e.g. new/open/close/copy/paste/etc -- which all have associated events that are sent to the application when triggered. Application-Bindings takes several different sets of actions, including Action-Actions, and combines them into a final set of key-bindings. Application-Preferences does the same for several sets of preferences. Exception-Presenter builds a UI that displays an exception stack. Application itself makes use of all these things to handle application setup and tear-down, clipboard, history, preferences, workspaces, windows and other basic UI handling for the app.
jazz.system.log is currently unimplemented.
jazz.system.performance can monitor CPU, memory, I/O, and Windows-specific resources. It supports counters as well. Currently this is only supported on Windows.
jazz.system.platform interfaces with the operating system to receive mouse and keyboard events, as well as a few other minor platform-specific things.
jazz.system.process contains the basis for Jazz processes. Command-Line is primarily devoted to display of options and help screens at the command-line. Process-Preferences keeps track of which directory a process is home to as well as the protocols it understands. The meat is in Process, which takes care of setting up the process for debugging, loads preferences, sets up a crash handler, and handles process threading and tear-down.
jazz.system.service handles registration, execution and debugging of Jazz processes as Windows services. It's currently disabled.
13.12.9. jazz.ui
This is where most of the UI and various widgets reside.
jazz.ui.action is used for key-bindings. An Action has a name and a context it operates within (e.g. 'application). An Action-Item provides handlers and shortcuts for actions and tracks whether they're currently active. Actions is a component whose children are Action-Items. Bindings is a component whose children are Actions. Figure-Mover is used for dragging. A Shortcut is a set of keys and modifiers that create a shortcut.
jazz.ui.activity is used for background processes and their management. An Activity is a background Jazz process, supporting Thread but adding registration and status reporting. Activity-Reporter is a widget that displays the relative progress and messages from an Activity, and provides a means of terminating the Activity. Activities register with an Activity-Manager and receive back and Activity-Reporter; the Activity-Manager is a widget which displays Activity-Reporters.
jazz.ui.clipboard handles copy & paste across all platforms.
jazz.ui.dialog contains a UI dialog and a large number of widgets that can be fitted in it.
Dialog is the the pop-up dialog window itself. Message-Box displays different messages or questions, and based on the type it provides combinations of OK/Yes/No/Cancel buttons in the dialog.
Color-Request has a UI for selecting an RGB colour. Date-Request is for dates. Directories-Request navigates, adds and removes from a list of directories. Directory-Request picks one directory. File-Request picks one file. Font-Request is for font handling. NewFile-Request is like File-Request, but for both saving and replacing a file. Password-Request does what you'd expect. Pathname-Request navigates the filesystem; it is the basis for Directory-Request, File-Request and NewFileRequest. Progress-Request shows the progress of an operation and provides an option to cancel. String-Request can accept any string in a box, but it can also be provided validator (and/or check that the value is unique). Text-File-Request is like File-Request, but provides various text encoding options with which to open a file. Text-Request is like String-Request, but allows vertical scrolling and will accept any string.
jazz.ui.dnd handles dragging and dropping. DnD tracks which view the drag'n'drop operation occurred in, and what the source and targets were. Drag-Source specifies what can be dragged from, and Drop-Target specifies where an object -- as well as what kind of object -- can be dragged to. A Drop-Event is what is fired when a user does a drag'n'drop.
jazz.ui.document is an interface for text-edit widgets and the surrounding framework that supports them. E.g. for opening/saving/closing them. Document-Controller provides basic services for all documents, such as watching for close-window or file modification events, generating summary captions for windows, and deciding whether a scrollbar is needed. Document-Moniker is a reference to a file on the filesystem. Document is the interface that any text editor widget that wants Document-Controller services must conform to. Documents-Preferences simply provides a default dimensions and colour for documents.
jazz.ui.effect has various visual effects that can be used to change content on the screen. Wipe-Effect is the sole one at the moment, allowing transitions up, down, left and right.
jazz.ui.event contains a default set of specializations of Event that are useful with the UI. E.g. the Focus event is fired when the focus between windows changes, and keeps track of the old and new focused windows.
jazz.ui.handler are specializations of event handlers. Right now there's just one: Selection-Handler.
jazz.ui.history for anything needing the tracking and display of prior user actions. History-Document-Item tracks a selection inside a document. History-File-Item is the same, but for a file. History-Menu is a piece of UI that lets the user move backward and forward through a history.
jazz.ui.hosting allows widgets to host other widgets, so they're not stuck to only behaving like the class they inherited from. It's split in two halves: the host and guest. The guest is the view with the meat; you can put it in a dialog host, a frame host, and so on.
jazz.ui.image contains the UI to display images. Image-Browser displays the images in a directory. Image-View is the UI for the display of a single image.
jazz.ui.layout contains the various layout engines, used to figure out how to arrange content within a view. Border-Layout keeps children on the north, south, east, west or centre of a view. Figure sticks the content at a specific pixel location. Flow-Layout places children one after the other, much like a toolbar. Snap-Layout snaps one widget relative to another. Split-Layout divides a view in two.
jazz.ui.locales is used for localization.
jazz.ui.skin has various visual styles for widgets. Default-Skin, Jazz-Skin and Windows-Skin are some existing styles.
jazz.ui.menu contains a menuing system and various widgets for building menus.
Item is the basis of every row in a menu; it mainly deals with width. Label-Item extends Item with shortcuts, icons, whether it's enabled or not, and much of the width calculations, fonts and rendering. Check-Item is a menu row that can either be enabled or not. Radio-Item is like Check-Item, but instead only one of the rows in a group can be checked at any one time.
Menu handles the placement of all the rows and whether the menu is open or not. Menubar contains a list of possible menus, whether they're open or not, and comes with a default maximize and close buttons. Context-Menu is the basis of context menus. Edit-Base-Menu is a menu with basic edit-related options -- e.g. edit/undo/copy/paste/etc. Edit-Menu extends Edit-Base-Menu with a history and a paste stack. File-Base-Menu is the basic File menu most apps have. File-Menu extends this with printing options and diffing against a saved file. Recorder-Menu lists options for recording a series of actions as well as their playback. Separator-Item is a horizontal divider line that goes in a menu. Window-Menu shows a list of existing frames as well as various ways of tiling them. Workspace-Menu lists existing workspaces.
jazz.ui.outline is the basis of the Text-View and Tree-View. Outline-Row renders an outlined row, and tracks relationships between rows. Outline-View handles operations on groups: the logic of expanding/contracting rows/trees, scrolling, selection and rendering.
jazz.ui.picker handles dragging of selection boxes and provides some functions related to selection.
jazz.ui.preferences contains preference classes for many different components as well as the UI to change them. There are many difference preference classes, named *-Preferences. Their name matches what they do, and they solely contain preference data that can be used elsewhere. E.g. Print-Preferences contains options useful for printing.
Bindings-Manager is the UI for changing and editing key-bindings for the app; Bindings-Tree is used for each row. Code-Text-Actions are a set of actions useful for code, such as evaluations, editing of definitions or references, as the ilk. Preferences-Manager is like Bindings-Manager but for a set of preferences. Shortcut-Chooser extends Shortcut-Viewer to display shortcut conflicts. Shortcut-Viewer is a UI for editing shortcuts. Text-Actions are a set of actions useful for editing text; e.g. moving around, scrolling, deletion, cut/copy/paste and anchors. View-Actions is a more limited form of Text-Actions.
jazz.ui.print is where all the widgets for printing to paper reside.
Page-Header and Page-Footer are used for rendering headers and footers respectively. Page-Setup is the layout for page display, and tracks the paper type, print resolution and orientation for printed paper. Page-Status is a UI status bar that lists the current printing status. Page-Text-Palette lists various page-metadata options which can go on the header and footer of every printed page, like file name, page number, date and time. Page-Text-View is a Text-View with a few minor specializations useful for the handling of page metadata. Page-Toolbar is a UI toolbar that lists various print-related options, like printing, preview, page setup and resizing. Page-Workspace is the workspace UI for dealing with printing and uses much of the above Page-* classes.
Preview-Page is a view used for the display of how a page will appear when printed. Preview-Pane the layout (and navigation) used for print preview. Preview-Status is a status bar for the preview display. Preview-Toolbar has various UI options for the navigation, zoom and printing of the preview. Preview-Workspace is a workspace UI for the preview of pages for printing, and uses much of the Preview-* classes.
Print-Job and Printer-Job handles the internal rendering and printing of pages.
jazz.ui.resizer is the little draggable resize widget seen on the lower-right of windows.
jazz.ui.search contains much of the searching-related UI. Directories-Search is a view that accepts directories and extensions, scans for matches and displays the results. History-Search-Item remembers various searches. Navigatable-Results is used by Search-Results; it contains a UI list of matches for a search. Projects-Search is the UI for searching a project for definitions or references of a class. Search-Manager is a window with tabs for various search types; it preserves a history and lists various options useful for any search type -- e.g. ignore case and whole-words. Search-Manager-Actions are a set of actions used by Search-Manager. Search-Menu is the main-menu item 'Search' seen in Jedi; it contains various search-related menu items. Search-Results-Tree shows the results of a search in tree form. Search-Results contains Search-Tree-Results and adds some widgets for search history. Search-View is another UI for search (and replace). Text-Search lists option for where to perform a search -- i.e. current file, jazz files or other files.
jazz.ui.selection provides an API for selection of rows or text. If a class implements the Selection-Provider interface, it can be used by Selection-Manager. Selection-Manager tracks the current selection operation, whether there are multiple selections, and any key modifiers that apply.
jazz.ui.syntax is the basis of syntax highlighting and code completion. Code-Syntax is used by many syntax specializations, and is a thin wrapper around Text-Syntax. Text-Syntax provides auto-completion, services for syntax highlighting, a catalog, and even some form of key translation.
jazz.ui.text contains widgets useful for the display of text.
Text-View is a critical component in text handling and rendering; many of the above classes work together here. Modification and saving are tracked in Text-View, although it can also be set read-only. Focus, key-handling and mouse-events go through here too. Paragraph creation, colourization, the cursor and the caret (the little blinky thing which appears where you type) occur here. Drag'n'drop does. Text navigation and context menus... the list goes on. In order to use text-related widgets, you need to understand what this class offers.
A Style supports arbitrary stylistic attributes that can be applied to text, including images. A Run is a chunk of text with a single style; it handles rendering and can wrap. Line is a paragraph line containing text, offset and calculations for height and width. Paragraph contains text too, but also tracks format and number of lines. It handles wrapping and style as well. Text is just a storage for paragraphs of text.
Code-Explorer programatically navigates through expressions in the code -- backward, forward, and also can remove comments. Column-Menu is a context menu that includes a couple options useful with columns. Explorer-Mark tracks symbols: the kind (e.g. char) and range it exists in the text. Symbolic-Completer searches a domain and returns all strings that begin with the same prefix.
Format-Menu is a context menu with options for upcasing/downcasing/capitalizing/etc text. Format tracks non-font-related formatting for text like margins, justification and bulleting. Formatted-Text-Action contains various actions (and shortcuts) that can change formatting, like heading style. Formatted-Text tracks formats, styles and paragraphs of text.
Hyperlink-Style tracks a chunk of text and the action that should fire if clicked. Image-Style is an image that sits next to text. Info-Style renders various information about a page, such as what page number, how many total, and which file it came from.
Code-Text-View is the basis of much of the text editing UI in Jedi; it navigates through code, finds definitions and references, handles syntax highlighting, editing, and copy'n'paste. A Date-Text-View is a Text-View specialized for dates -- it doesn't do anything beyond its parent. Entry-Text-View adds some focus and manager handling to a Text-View. Formatted-Text-View renders formatted text; it includes a ruler, anchors, and has a table of content with chapters based on headings. Password-Text-View renders '*' instead of characters when entering a password, and disables copying. Plain-Formatted-Text-View is a Formatted-Text-View with some default formats and styles provided. Plain-Text-View has a single default style and includes some heuristics to guess if the file is Jazz or C (although it doesn't have to be either). Ruler is a horizontal ruler widget that can be rendered as a header.
Table-Border is a bordered view with a header and a Table-Tree-View inside. Table-Cell is a single table element, also with a small border. Table-Text-View is a normal text view with some padding. Table-Tree-View contains trees and behaves more like a table.
Text-Color-Combo is a button with a name that pops up a Color-Picker. Text-Colorizer actually applies styles, not colours specifically, to runs in a section of paragraph. Text-Combo is the parent of several classes used for font and style of text: Text-Font-Combo (pick one of several type-faces), Text-Size-Combo (pick one of several font sizes), and Text-Style-Combo (apply one of several styles).
Text-Context-Menu lists text-related options like cut/copy/paste. Text-Explorer is a programmatic interface for navigating through the characters, words, paragraphs and styles of some text. Text-Palette is a panel with typeface, size, alignment, colour and indentation options that affect currently-selected text. Text-Style has various attributes for font faces, weights, colour and highlighting; it also handles wrapping and rendering.
TextToHTML-Explorer converts a chunk of text into a a chunk of HTML with the same content. While text is preserved, the style of the HTML is an approximation of styles on the text.
jazz.ui.tree is used for the display and manipulation of tabular and tree-related data. Tree-View does much of the work with trees. Using many of the below classes it handles highlighting, scrolling, resizing, drag'n'drop, tooltips, keyboard navigation, expand/collapse, and so forth. To understand trees or excel-like tabular layout, Tree-View is the first step.
Tree-Actions are the set of actions that can be sent to a tree by default; these including moving around, expanding and collapsing. Tree-Column are the equivalent of Excel-style columns; it handles the title, width, tooltips, sorting and selection. Tree-Layout-View is a layout engine. Tree-Data tracks the background and frame colour, but isn't used at the moment. Tree-Drag-Source and Tree-Drag-Target are used for dragging cells around in a columnar tree view. Tree-Header is the box that contains all the column titles; it handles scrolling titles horizontally (titles don't scroll vertically) and column resizing. Tree-Highlight tracks which cells are highlight and with which colours. Tree-Image-Column is a column that renders a title cell with an image or icon -- note the title is actually optional. Tree-Image is the image or icon itself. Tree-Label-Column is a column that renders a title cell. Tree-Node-Column renders the switches (and titles) that expand/contract children of a node, as well as passing on other clicks that could potentially be used for editing. Tree-Node has a title and image. Tree-Path-Column and Tree-Path are used to display how a tree was traversed to reach the wnode. Tree-Row renders a single row; all the children of a row compose each column of the row.
jazz.ui.view has a large number of UI containers and a few buttons. The most critical file is View, which is the Jazz concept of windowing. As can be expected for something used for windowing, View has many properties useful for this: title, font, background, tooltips, size, draggability and the many handlers for events that are useful. Some examples of these handlers are for move movement and clicks, key handling, cursor updates, drag'n'drop and even reception of files. Many of the things necessary to make windows work hook together here, including scrolling, printing, context menus, tooltips, layouts and even workspaces. Note that views can contain other views, which is essential since many widgets and containers are views themselves. In short, to understand the UI, View is the first step.
Action-Icon is a small icon with a tooltip. Border-View renders various borders around its contents. Check-Box tracks the state of a checkbox: whether it's active, editable, in focus, and its colour. Chooser is a view that lists a title, description, several options and okay/cancel.
A Color-Button is a pushable button that displays the currently-selected colour. Color-Combo is a dropdown which offers several colours as choices. Color-Picker displays a choice of 23 different colours as well as a button leading to a popup that allows selection of an arbitrary colour. Color-Text-View is like a Color-Combo, but displays the text names of colours instead of the colours themselves.
A Combo-Box is a drop-down option box that allows selection of several choices, but when inactive only shows the selected option. Combo-Button is the button pushed to expand a combo. Combo-Text-View displays the combo text options in a dropdown. Combo-View is more general than Combo-Text-View.
A Container really just lays out content within itself; Content-View allows resizing and scrolling. Drawing is a surface for painting on; it can have children drawings and understands scaling. Entry-Combo-Box and Entry-Combo-View allow a text combo box that also accepts arbitrary strings by the user. Frame-Button renders the maximize/restore/close buttons seen on most windows. Group-Box draws a box around its contained content. Header-View is a Container with a header. Horizontal-Line is exactly what it sounds like. Image-Tool is the basis of buttons that have a raster image inside them, like radio buttons. Label-Tool is just a label, and Label-Views are good for that too. Layout-View lays content out inside according to an algorithm; the algorithms can be found in jazz.ui.layout. Line-View draws lines of various styles. Pad-View is a padded view. Progress-Bar renders a bar that displays the stepped progress of something.
Push-Button is your typical button. Push-Combo, Push-Icon and Push-Tool are all used for a button that displays options so long as the mouse button is down. Radio-Button and Radio-Tool renders buttons that only allows one of a group to be selected. Scrollbar does exactly what it sounds like.
Scroller-View is a container that is affected by a Scrollbar. Separator-View separates two areas. Splitter-View is a much more flexible version that allows orientations and multiple divisions. A Splitter is a bar with an orientation that often can also be dragged. Stage is the parent of internal frames (as opposed to external frames -- frames in an OS window).
Status-Label and Status-Toolbar both are used for displaying the status of something. Tab-View is a set of tabs, each leading to a Tab-Sheet; only one Tab-Sheet at a time can be displayed. Tool-Button is actually a layout with four states: inactive, highlighted, pushed, out-pushed. Toolbar lays out various option widgets from left to right. Tooltip-* are all used for tooltips. Vertical-Line does what it says.
jazz.ui.widget contains some random widgets. The most interesting of these are related to monikers; monikers acts a bit like high-level references.
jazz.ui.window deals with actual OS windows, including their creation, min/maximization, drag'n'drop, key events, scrolling and the underlying message pumps. Desktop is an abstraction of the OS desktop; under X11 it's the root window. A Frame is a window, but it can either be based on Window (an OS window) or Stage (parent of internal Jazz frames). Menu-Transient, Popup and Tooltip are all similar; they deal with temporary menus, popups, and tooltips respectively. Toplevel is the top-level in a window. View-Player is any window that supports the viewing system. Window is non-platform-specific code that deals with most events a window is interested in -- such as minimization, resizing and closing.
jazz.ui.workspace has the basis for workspaces. Default-Workspace is a blank workspace. Standard-Workspace adds a menu-bar, tool-bar and status-bar. Workspace-Button is a radio button which switches between spaces; it can also display if there are errors in a space. Workspace-Preferences is the basis of workspaces; it tracks various things like maximization and shortcut, and maintains children frames and status. Workspaces-Preferences can contain several workspaces.
13.12.10. jazz.validation
This has the framework necessary to run unit tests. It includes a set of tests for various important classes in Jazz.
13.12.11. jazz.contrib.irregex
While there is also a basic regular expression system in jazz.library, this is what you want to use when munging text with regex. It is Unicode-clean, can optimize regex, and supports most of the non-regular features of PCRE.
13.12.12. jazz.contrib.statprof
A profiler! It will not give the exact number of invocations per method or function, but it has low overhead.
13.12.13. jazz.contrib.srfi-19
A fairly comprehensive set of date-time objects and their handling. This includes time and date parsing, conversions, and rendering. Handles leap years and even includes the modified Julian calendar. Veni, vidi, vici.
14. Numbers
14.1. Generic Arithmetic
15. Symbols
Jazz is symbolic language where symbols are used extensively. Symbols can be used as a very efficient higher level abstraction replacement for integer enumerations
16. Sequences
16.1. List
Lists are the most flexible data structure available in Jazz. They can grow to accommodate any number of elements and this very efficiently. As they are sequences, they are supported by a large number of manipulation functions
16.2. Vector
16.3. U8Vector
16.4. String
16.5. Queue
16.6. Axis
16.7. Subseq
17. Iteration
17.1. Sequences
17.2. Loop Macro
(loop...) |
syntax |
for
in
in-properties
iterate
from
repeat
do
sum
collect
18. Exceptions
18.1. Exception
19. Input / Output
19.1. File
19.2. Directory
19.3. Aliases
Aliases are symbolic names for directories. They are similar to CommonLisp's logical pathnames. The following aliases are predefined:- Home
- Jazz
- Build
19.4. Formatted Output
Implements formatted output.
Directives
Name | Accessor | Description |
---|---|---|
ASCII | a | human readable |
SEXPR | s | reader readable |
TEXT | t | textual representation |
p | ascii or sexpr or text | |
REAL | r | real number |
CHAR | h | character |
LIST | l | remove parenthesis |
PROPERTIES | k | properties list |
UNSIGNED | u | unsigned integer |
HEXADECIMAL | x | hexadecimal integer |
COLUMN | c | column |
TAB | & | insert tab character |
NEW_LINE | % | insert new line |
LOCALIZE | z | localized string |
FORMATTED | f | formatted control |
Parameters
{x :a value :b value ?}
:v -> takes the info from the parameters
Examples:
-
(format :string "{_ 5}")
-
(format :string "{a :width :v :justify right}" bonjour 20)
Parameters can be optional and can be keyword based.
- list?
- width
- justify -> :left :right
- padding
- separator
- last-separator
- precision
- properties
- empty-value
- detail
20. Regular Expressions
21. Date / Time
22. Source Control
A depot is an abstraction for a source control system.23. User Interface
The cross-platform UI is a high level framework written in Jazz that uses Cairo for backend. It runs on Mac OS X, Windows and X11.23.1. Drawing
23.1.1. Cairo
23.1.2. Surface
23.1.3. Color
23.1.4. Font
23.1.5. Point
23.1.6. Dimension
23.1.7. Rect
23.1.8. Cell
23.1.9. Range
23.2. Windows
Window
Toplevel
Stage
A stage window is the parent window of all documents.Palette
Windows of this class should be permanent popups.Popup
Windows of this class should be temporary popup windows like tooltips, menus, ... For permanent popups see Palette.Dialog
23.3. Basic Views
View
Border-View
Check-Box
Group-Box
Label-View
Layout-View
Push-Button
Radio-Button
Scroller-View
23.4. Text-View
Text-View
23.5. Tree-View
Tree-View
Tree-Header
Tree-Node-Column
Tree-Label-Column
Tree-Row
23.6. Hosting
23.6.1. Host
23.6.2. Guest
23.7. Layouting
Flow-Layout
Border-Layout
23.8. Activation
Event | Description |
---|---|
focus-gained | Sent to a view that gained focus |
focus-lose | Sent to a view that loses focus |
host-activate | Sent to guest when host gains focus |
host-deactivate | Sent to guest when host loses focus |
client-activate | Sent to each tool when a document activates |
client-deactivate | Sent to each tool when last document closes |
stage-activate | Sent to stage when last document closes |
stage-deactivate | Sent to stage when a first document activates |
23.9. Menus
Menu
Label-Item
Separator-Item
23.10. Events
Event encapsulation puts almost no pressure on the framework because almost everywhere the direct class override is used. Events encapsulate amongst other things, modifiers state that is necessary for recording user actions.Event
23.11. Clipboard
23.12. User Interaction
message-box24. C Interface
24.1. Syntax
c-constant name value
A c-constant cannot be modified. Note that currently, a constant definition is simply a definition.
c-enumeration enumeration-name (name1 value1) (name2 value2) ...
A c-enumeration definition. This enumeration will create a definition enumeration-name containing an Enumeration object that can be queried at runtime and create constant definitions name1 : value1, name2 : value2, ...
c-structure structure-name (type1 field1
A c-structure is a template that can be used to create records containing primitive types. Here, type is any primitive type and field is a symbol that can be used to access this field is records of type structure-name. If the optional n is specified, then an array of n elements of type will be inserted.
c-external unit-name return-type (name param1 param2 ...)
A c-external entry point into a Windows unit, i.e. a dynamic-link library or an executable.
License
Licensing module.This module which is in development, will provide classes to enforce commercial licensing strategies.
Designer
Designer
A Designer is the interface between a jazz object and a form
Component-Editor
View-Editor
Traits-Editor
Components-Editor
Card
Custom-Card
Properties-Card
Value-Row
Component-Surrogate
Property
Property-Entry
Property-View
Domain
Designer Events
- property-change
- child-add
- child-remove
- child-move
- update
- refresh
Editor Events
- client-change
- designer-change
- branch-changing
- branch-change
- selection-changing
- selection-change
- saving
Notes
- Editing a form is done through a Designer and an instance of the form. Any changes to the instance or its children should be done by calling methods of the designer instead of going to the instance directly. The designer will take care of making the changes as well as recording them.
- Note that by having events generated when properties are modified and some others, this process could be made more automatic. But, this would imply a great performance overhead on the system and also we do not want programmatically modified properties to be recorded by the designer. This is why Jazz sticks will a manually calling the designer approach.
- So, if we have a Z -> Y -> X class hierarchy, an instance of Z can be used to edit the class form of X, Y or Z.
- When Jazz edits an object, it monitors every descendant by installing surrogates in them. Even if the edited component is changed (by double-clicking), we keep the upper surrogates installed (even if they could conceptually be removed) so as to still be able to double-click on them to change again the edited component.
- Surrogates take the place of an edited component and its descendants when there's a need to trap user events sent to the component. They are most commonly used for visual components like views.
- An editor is an view that will permit edition of its client and do so by calling designer methods in response to events generated three optional subviews: a traits tree, a descendants tree and a properties tree. An editor has an installed client on which you can put one or more (currently only one) designers on specific descendants of the client. Each designer will record edition to its part of the client descendants tree.
- So, we have a component and its descendants being monitored by surrogates and one of then is the edited component (so changes to it or any of its descendants is being sent to the designer).
- When editing a form I should also specify the edited branch (can be nil of course).
- Note that branch and form unification while desirable is not a good idea because always having an installed branch for every component instance would impose to great a memory load for a very small gain. Also the present approach has the very nice property of having branches as ordinary objects that could have been developed outside of the main system. They are as any other component, they simply have a different behavior.
- The designer and the various elements of the editor follow the MVC model. The designer plays the model role and the editor elements are views of this model. The editor never modifies its view directly. Instead it calls methods of the designer that will modify the edited component and also send events to every listening view who can then update their interface accordingly.
Library
Node
A node is a class that supports dynamic properties
- An node can optionally be named
Node properties, for efficiency are stored as slots for direct access but can also be accessed in a generic fashion via the get-property method
Element
An element is a node with a hierarchical structure
Exemplar
An Exemplar is a dynamic class whose hierarchy can be modified at runtime
- Exemplars don't have instances
- All properties are fully inherited in the sense that whenever an exemplar is modified, every descendant is automatically updated. Because the most used operation is by far property access, exemplars have a full internal copy of every property. To implement inheritance, exemplars also have a list of which properties are owned by the exemplar, i.e. what properties should not be updated when an ascendant is modified
- Exemplar properties, for efficiency are stored as slots for direct access but they can also be accessed in a generic fashion via the get-property method
- Exemplars are grouped in an Exemplar-Domain which is the domain in which an exemplar name is a valid reference
-
An Exemplar can be named and can inherit from another exemplar via its
base
Java
Java integration module
This module is at an experimental stage at the moment though it was used to implement full database access through Java's JDBC library.
SQL
SQL access module.
This module is a very mature module that provides a sophisticated UI over the database access classes of the Access module.
30. Units
jazz
30.1.1. Boolean
(eq?x y) |
method |
Tests if x is physicaly equal to y. In other words, if both memory pointers are the same.
(neq?x y) |
method |
The inverse test of eq?.
(eqv?x y) |
method |
eqv? will succed if the two objects are eq? or if they can be simply compared without going into their structures. For example, (eq? 2.3 2.3) migth return false whereas (eqv? 2.3 2.3) will always return true.
(equal?x y) |
method |
The most general equivalence predicate of all.
equal? will succed if the two objects are eqv? but will also try to determine if the two objets structures are identical. For example, (eq? (list 1 2 3) (list 1 2 3)) returns false but (equal? (list 1 2 3) (list 1 2 3)) returns true.
(notobj) |
method |
Returns the logical negation of obj.
(boolean?obj) |
method |
Tests if obj is of Boolean
type.
Examples
-
(boolean? true)
returns true. -
(boolean? false)
returns true. -
(boolean? nil)
return false.
(xorx y) |
method |
(=obj1 obj2 obj3 ...) |
method |
(/=obj1 obj2 obj3 ...) |
method |
(<obj1 obj2 obj3 ...) |
method |
(<=obj1 obj2 obj3 ...) |
method |
(>obj1 obj2 obj3 ...) |
method |
(>=obj1 obj2 obj3 ...) |
method |
(ci=obj1 obj2 obj3 ...) |
method |
(ci/=obj1 obj2 obj3 ...) |
method |
(ci<obj1 obj2 obj3 ...) |
method |
(ci<=obj1 obj2 obj3 ...) |
method |
(ci>obj1 obj2 obj3 ...) |
method |
(ci>=obj1 obj2 obj3 ...) |
method |
(booleanobj) |
method |
(boolean->integerbool) |
method |
(integer->booleanz) |
method |
30.1.2. Char
(char?obj) |
method |
(jazz-constituent?obj) |
method |
(cpp/java-constituent?obj) |
method |
(alphabetic?obj) |
method |
Tests if obj is alphabetic. An object is alphabetic if it is an alphabetic character or a sequence composed only of alphabetic parts.
(numeric?obj) |
method |
Tests if obj is numeric. An object is numeric if it is a numeric character or a sequence composed only of numeric parts.
(alphanumeric?obj) |
method |
(whitespace?obj) |
method |
Tests if obj is whitespace. An object is whitespace if it is a whitespace character or a sequence composed only of whitespace parts.
(upper-case?obj) |
method |
Tests if obj is upper-case. An object is upper-case if it is an upper-case character or a sequence composed only of upper-case parts.
(lower-case?obj) |
method |
Tests if obj is lower-case. An object is lower-case if it is a lower-case character or a sequence composed only of lower-case parts.
(upcaseobj) |
method |
Converts obj to upper-case. If obj is a sequence, every part of obj with be converted to upper-case.
(downcaseobj) |
method |
Converts obj to lower-case. If obj is a sequence, every part of obj with be converted to lower-case.
(capitalizeobj) |
method |
Converts obj to capitalized form where every word starts with a capital letter and the rest is in lower-case. If obj is a sequence, every part of obj with be converted to capitalized form.
30.1.3. Class
The Class type is the supertype of every class. It enables a class to be inspected and manipulated as any other object.
(class?obj) |
method |
(class-membersclass) |
method |
Returns a list of all members of class.
(class-fieldsclass) |
method |
Returns a list of all fields of class.
(class-slotsclass) |
method |
Returns a list of all slots of class.
30.1.4. Closure
(closure?obj) |
method |
30.1.5. Collector
(gc) |
method |
30.1.6. Control
(throwname) |
method |
(exit) |
method |
30.1.7. Debugger
(signalexception) |
method |
(errorformat-string obj ...) |
method |
30.1.8. Enumeration
(enumeration?obj) |
method |
30.1.9. Eval
(evalexpr) |
method |
(identityobj) |
method |
30.1.10. Format
(formatformat-string obj ...) |
method |
30.1.11. Function
(function?obj) |
method |
30.1.12. Hashtable
(hash-refhashtable key) |
method |
Gets the value associated with key inside hashtable.
(hash-set!hashtable key value) |
method |
Sets the value associated with key inside hashtable to value.
(hash-clearhashtable key) |
method |
(empty-hashtablehashtable) |
method |
(load-hashtablehashtable file) |
method |
(hash-remove!hashtable key value) |
method |
(for-each-hashproc hashtable) |
method |
30.1.13. Integer
(integer?obj) |
method |
(even?z) |
method |
(odd?z) |
method |
(quotientz1 z2) |
method |
(moduloz1 z2) |
method |
(separatez1 z2) |
method |
(randomize) |
method |
(randomn) |
method |
(bit-notn) |
method |
(bit-andn ...) |
method |
(bit-orn ...) |
method |
(bit-xorn ...) |
method |
(bit-setn1 n2 n3) |
method |
(bit-set?n1 n2) |
method |
(shift-leftn1 n2) |
method |
(shift-rightn1 n2) |
method |
30.1.14. Interface
(interface?obj) |
method |
30.1.15. List
(carpair) |
method |
Returns the car field of pair.
(cdrpair) |
method |
Returns the cdr field of pair.
(set-car!pair obj) |
method |
Sets the car field of pair to obj.
(set-cdr!pair obj) |
method |
Sets the cdr field of pair to obj.
(consx y) |
method |
Returns a newly allocated pair whose car is x and whose cdr is y.
(reverseseq) |
method |
Reverses a sequence.
(list?obj) |
method |
Returns true if obj is a list, false otherwise.
Examples
- (list? nil) -> true
- (list? '(a b c)) -> true
- (list? 2) -> false
(nil?obj) |
method |
Returns true if obj is the empty list, false otherwise.
(not-nil?) |
method |
(pair?obj) |
method |
Returns true if obj is a pair and otherwise returns false.
Examples
- (pair? 2) -> false
- (pair? nil) -> false
- (pair? (cons 1 2)) -> true
- (pair? '(a b c)) -> true
(atom?obj) |
method |
(caarpair) |
method |
Returns the car field of the car field of pair.
(cadrpair) |
method |
Returns the car field of the cdr field of pair.
(cdarpair) |
method |
Returns the cdr field of the car field of pair.
(cddrpair) |
method |
Returns the cdr field of the cdr field of pair.
(listobj ...) |
method |
Returns a list constructed of all its arguments.
(memq?obj list) |
method |
(memv?obj list) |
method |
(member?obj list &key key test) |
method |
(assqobj list) |
method |
(assvobj list) |
method |
(assocobj list &key key test) |
method |
(rassocobj list &key key test) |
method |
(reverse!list) |
method |
(remove!obj list) |
method |
(getpropplist key) |
method |
(getfplist key) |
method |
(setfplist key value) |
method |
(for-each-pairproc list) |
method |
(for-each-propertyproc list) |
method |
30.1.16. Manifest
(loadunit-name) |
method |
(unit-loaded?unit-name) |
method |
(in-manifest?unit-name) |
method |
30.1.17. Map
(map-refmap key) |
method |
(map-set!map key value) |
method |
(map-clearmap key) |
method |
(empty-mapmap) |
method |
(load-mapmap file) |
method |
(for-each-mapproc map) |
method |
30.1.18. Metaclass
(metaclass?obj) |
method |
(metaclass-instancemetaclass) |
method |
30.1.19. Number
(+obj ...) |
method |
(-obj1 obj2 ...) |
method |
(*obj ...) |
method |
(number?obj) |
method |
(zero?obj) |
method |
(positive?obj) |
method |
(negative?obj) |
method |
(/obj1 obj2 ...) |
method |
(relatex y) |
method |
(signz) |
method |
(floorr) |
method |
(roundr) |
method |
(ceilr) |
method |
(absz) |
method |
(minobj ...) |
method |
(maxobj ...) |
method |
(between?n lower upper) |
method |
(betweenlower n upper) |
method |
(in-interval?n lower upper) |
method |
(normx) |
method |
(near?x y distance) |
method |
30.1.20. Object
(object?obj) |
method |
(copyobj) |
method |
30.1.21. Package
(package?obj) |
method |
30.1.22. Printer
(displayobj &optional printer) |
method |
(writeobj &optional printer) |
method |
(describeobj &optional printer) |
method |
(new-line&optional printer) |
method |
(print-unreadableobj printer proc) |
method |
30.1.23. Procedure
(procedure?obj) |
method |
30.1.24. Reader
(read&optional reader) |
method |
(get-char&optional reader) |
method |
(unget-charchar &optional reader) |
method |
(peek-char&optional reader) |
method |
(end-of-stream?&optional reader) |
method |
30.1.25. Real
(real?obj) |
method |
(sinr) |
method |
(cosr) |
method |
(tanr) |
method |
(asinr) |
method |
(acosr) |
method |
(atanr1 r2) |
method |
(sqrtr) |
method |
(expr) |
method |
(logr) |
method |
(exptr1 r2) |
method |
(percentagepart total) |
method |
(percentpercent n) |
method |
30.1.26. Sequence
Sequences are an abstract data type representing objects capable of storing sequences of objects. Some examples of sequences are lists, strings and vectors. The Jazz language possesses a important number of sequence manipulation functions
(sequence?obj) |
method |
Tests if obj is of Sequence type.
(lengthsequence) |
method |
Returns the number of elements in seq.
(elementsequence n) |
method |
Returns the nth element of sequence.
(set-element!sequence n value) |
method |
Destructively sets the nth element of sequence to value.
(empty?sequence) |
method |
(tailsequence n) |
method |
Returns the elements of sequence that range from n to the end. Note that this operation can be done very efficiently for lists.
(lastsequence) |
method |
Returns the last element of sequence.
(last-tailsequence) |
method |
Returns a sequence made-up of only the last element of sequence. Note that this operation can be done very efficiently for lists.
(butlastsequence) |
method |
Returns a sequence made up of every element of sequence except the last.
(subseqsequence start &optional end) |
method |
Returns a sequence made up of the elements of sequence that range from start to end exclusively. If end is omited, the elements are taken till the end of sequence.
(subseq!sequence start &optional end) |
method |
(sortpredicate sequence &key key test) |
method |
(for-each-reversedsequence) |
method |
(appendsequence) |
method |
Returns a sequence composed of all the elements of seq.
Examples
- (append) -> nil
- (append '(a b c) nil '(1 2) '(1 2 3)) -> (a b c 1 2 1 2 3)
- (append \"Hello\" \" \" \"there\") -> \"Hello there\"
- (append 2 3) ->
"
(append!sequence ...) |
method |
(insert!obj sequence pos) |
method |
(insert-sequence!sequence inserted pos) |
method |
(replace-subseq!sequence start end replacement) |
method |
(element-reversedsequence n) |
method |
(for-eachprocedure sequence1 &optional sequence2) |
method |
Applies procedure to every element of sequence1 and optionaly sequence2
(mapprocedure sequence1 &optional sequence2) |
method |
Applies procedure to every element of sequence1 and optionaly sequence2 and collects the results in a list that it returns.
(map-totype proc sequence) |
method |
(gathersequence) |
method |
(collectproc sequence) |
method |
(collect-ifpredicate sequence) |
method |
(collect-typetype sequence) |
method |
(countobj sequence) |
method |
Finds the number of occurences of obj in sequence.
(count-ifpredicate sequence) |
method |
(count-typetype sequence) |
method |
(findobject sequence) |
method |
(find-ifpredicate sequence) |
method |
(skippredicate sequence) |
method |
(some?predicate sequence) |
method |
(every?predicate sequence) |
method |
(unionsequence ...) |
method |
(intersectionsequence ...) |
method |
(differencesequence1 sequence2) |
method |
Returns the set difference sequence1 \ sequence2.
(removetarget sequence) |
method |
(remove-trailingtarget list) |
method |
(remove-duplicatessequence) |
method |
Returns a sequence that has exactly the same elements as sequence and in the same order but with no duplicates.
(remove-falsesequence) |
method |
(mismatchtarget sequence) |
method |
(prefixsequences) |
method |
(prefix?target sequence) |
method |
(searchtarget sequence) |
method |
(splitsequence separator) |
method |
(split-justifiedsequence width separators) |
method |
(joinsequences separator) |
method |
(substituteold new sequence) |
method |
(substitute-alistreplacements sequence) |
method |
(fill!sequence object) |
method |
(replace!sequence replacement) |
method |
(insert-ordered!object sequence) |
method |
(merge-orderedproc x y) |
method |
(random-elementsequence) |
method |
(partitionsequence &key key test) |
method |
(starts-with?string target) |
method |
(ends-with?string target) |
method |
(firstsequence) |
method |
(secondsequence) |
method |
(thirdsequence) |
method |
(fourthsequence) |
method |
(fifthsequence) |
method |
(sixthsequence) |
method |
(seventhsequence) |
method |
(eighthsequence) |
method |
(ninthsequence) |
method |
(tenthsequence) |
method |
(set-first!sequence object) |
method |
(set-second!sequence object) |
method |
(set-third!sequence object) |
method |
(set-fourth!sequence object) |
method |
(set-fifth!sequence object) |
method |
(set-sixth!sequence object) |
method |
(set-seventh!sequence object) |
method |
(set-eighth!sequence object) |
method |
(set-ninth!sequence object) |
method |
(set-tenth!sequence object) |
method |
30.1.27. String
(string?object) |
method |
(empty-string?object) |
method |
30.1.28. Symbol
(symbol?object) |
method |
(keyword?object) |
method |
(symbol->keywordsymbol) |
method |
(keyword->symbolkeyword) |
method |
(string->symbolstring) |
method |
(symbol->stringsymbol) |
method |
(find-symbolstring) |
method |
(generate-symbol&optional prefix) |
method |
(symbol-bound?symbol) |
method |
(symbol-unbound?symbol) |
method |
30.1.29. Thread
(primordial-thread) |
method |
(current-thread) |
method |
30.1.30. Time
(clock) |
method |
30.1.31. Type
(type?object) |
method |
(newclass object ...) |
method |
(new-incontext class object ...) |
method |
(coerceobject type) |
method |
(class-ofobject) |
method |
(is?object type) |
method |
(is-not?object type) |
method |
(typed?object type-name) |
method |
(subtype?class type) |
method |
(subtyped?class type-name) |
method |
30.1.32. Unit
(unit?object) |
method |
(all-units) |
method |
30.1.33. Values
(valuesobject ...) |
method |
30.1.34. Vector
(vector?object) |
method |
31. Jedi
31.1. Searching directories
Note that searching in directories works a little different in Jedi. If you go to Search > Find In > Directories, there is a field that accepts directories. These are not actual directory paths though. Instead, aliases are used. For example, 'Jazz' (without the quotes) will search the Jazz source tree. All repositories and packages have aliases that refer to themselves (e.g. jazz.ui), so if you create your own repository named 'foo', searching in 'foo' (without the quotes) will dig through all the files in that repository.
Note that you can use expressions like {Directory Home} in the 'Directory:' field as well. If you want to search arbitrary locations outside of existing aliases, paths can be found by issuing certain expressions to Jedi's console to find the path. When the following expressions are evaluated in Jedi's console, a popup appears that does the following based on the expression:
(cf) = choose file
(cd) = choose directory
(cp) = choose directory and put the path in clipboard
Note that you can configure what is searched by the Jazz and Scheme file options in the search dialogues by using Text-Search-Preferences; the labels, directories and extensions can be changed.
Table of Contents
Index
* + - / < = >A B C D E F G H I J K L M N O P Q R S T U V W X Z