Introduction

IFCX Wings (http://www.ifcx.org/wiki/Wings.html)
aims to bring the aesthetics and ease-of-use of Mathematica's
notebook-oriented environment to the Open Source Software world and
to do so for arbitrary programming and scripting languages. As a
preliminary proof-of-concept, this OpenOffice
Writer
document contains a macro implemented using Groovy For OpenOffice
(http://www.ifcx.org/wiki/GroovyForOpenOffice.html)
that enables Groovy scripts to be evaluated in-place. This
little mash-up currently does nothing intelligent with syntax, nor
does it do any of the cool display formatting that is possible (it
simply displays the result of the last expression as a string). Also
it is limited to just Groovy script (whereas the idea is to support
any language) and the execution environment is within OpenOffice
(which has some special potential uses, but a client/server
implementation will have more general uses and fewer quirks).

The way Wings works is that you enter some Groovy script into
paragraphs with the 'GroovyCode' style, then invoke the
'Wings:WingsEval.groovy' macro (which is bound here via
'Tool:Customize...' to the cmd-Enter key as
well as the 'Wings:Evaluate' menu). The result of the
last expression will then be displayed as a string in a paragraph
with the 'GroovyResult' style. The cursor will then
move to the next 'GroovyCode' paragraph, unless an exception occurs
in which case it will not move.

If the key binding doesn't work for you (they don't seem to be
preserved very well across releases and/or platforms), then you can
recreate it (unless you're using OOo 2.2 in which the UI for creating
key bindings to macros stored in documents is broken) via the
'Tools:Customize...' dialog. Choose the "Keyboard"
tab, then scroll the "Category" pane all the
way to the bottom to find the 'OOo Macros' entry.
Twiddle the triangles to locate the 'Wings:GroovyEval.groovy'
macro in this 'Wings-0_x' document and set the key chord
you like.

A simple example:

1 + 2 * 3 / 4

2.5

1 / 2

0.5

If an exception or syntax occurs, that will be displayed in a
'GroovyException' styled paragraph and the cursor will
remain where it was.

1 / 0

java.lang.ArithmeticException: /
by zero

If you try to do an evaluation and the cursor is not located in a
'GroovyCode' paragraph, then an empty one will be
inserted at the cursor's location.

Beware that you should turn off quote replacement in
'Tools:AutoCorrect...:Custom Quotes' or you will get
funky syntax errors. Automatic "uncorrection" is one of
the features that need to be added to the macro. Another desirable
feature is to make undo work as a single action, unfortunately the
OpenOffice API does not currently allow that.

Apache Ant

Ant is a great way to do things with files. The Groovy AntBuilder
supplies the fileScanner pseudo-task that lets you
iterate over filesets. Filesets have filtering options to cover
pretty much every conceivable situation. Note that the type to
supply to attributes like 'basedir', 'dir', or 'file' is java.io.File
(rather than simply a path string).

If you like a method so much that you want to do Groovy's trick of
"adding methods" to an existing class that you can't
otherwise extend, you can use the Category feature. A Category is a
class, which when specified in a 'use (category [, category]*) {
statements }' statement, causes the static methods to be matched by
their first parameter.

Inject and Curry – calculate the functional way

Fun with closures. Collection.inject takes an initial value and a
closure for two parameters. The first parameter is the previous (or
initial) value and the second is the current element of the
collection. The result is the last value returned.

Regular
Expressions

The java.lang.String.split
method chops up a string given a string that is a regex pattern and
returns an array of strings. Notice the curly braces in the printed
result. Also Groovy's string quote stripping doesn't descend into
the array elememts.

This uses Groovy's regex matcher operator and a pattern which
matches runs of "word" class characters. A matcher is
iterable, but doesn't have a helpful printed form, so we run collect
on it to gather up the matching strings into a list. Notice the
square brackets indicating a list and the quotes are stripped from
the elements that are strings.

We don't need to define a variable to hold a closure of course, we
can just supply one as a literal and Groovy also lets us omit the
parenthesis. Furthermore, in Groovy 1.5 the value of the each
method is the target (previously it was void). And
finally, the key of a map literal entry is a string by default, so
quotes are not needed.

def map = [a:1, b:2, c:3, d:5]map.each
{ it.value *= 4 }

{a=4, b=8, c=12, d=20}

Of couse we don't need a variable for the map, as a literal can be
operated on just as well.

[a:1, b:2, c:3, d:5].each { it.value +=
it.key.toUpperCase() as int }

{a=66, b=68, c=70, d=73}

Sometimes you want a map literal but some or all of the keys are
computed rather than being literal themselves. In that case enclose
the key value in parenthesis.

[(10.power(3)):'kilo',
(10.power(6)):'mega', (10.power(9)):'giga']

{1000=kilo, 1000000=mega,
1000000000=giga}

Collections

[1, [2, 3, [4, 5]], 6].flatten()

[1, 2, 3, 4, 5, 6]

[1, 2, 3].collect { it * 2 }

[2, 4, 6]

Sublists

Subscripting a list using a range results in a sublist. Negative
numbers in ranges refer to the end of the list (the last element is
-1, the one before that is -2, etc.).

If you have a collection and then access it as a property or a
method call, and that property or method call doesn't exist for the
collection's class, then the property acces or method call will be
performed on each element of the collection and the resulting values
are collected and returned as a list.

So to find out if one range subsumes another, then test if all the
elements are in the list (Collection.containsAll).

(10..20).containsAll(14..19)

true

(10..20).containsAll(15..25)

false

Groovy has inclusive and exclusive range limits. It also has
relative-to-the-end-of-a-list indicies which are negative values.
Ranges can have negative limits of course, but you can’t combine
the two in quite the way you might expect.

System
Exec

One of Groovy's more amusing features is the 'execute' method on
strings, which returns a j.l.Process. Groovy then has the helper
method 'getText' which will gather up the output of the process into
a string. These little examples usually won't do much on Windows
(unless you've done something clever with Cygwin), but you can
substitute the name of your favorite executable (like command.exe)
too make it go.

For mathematical folks, being able to handle formulas for both
input and output by integrating with symbolic math engines, which can
be done using the scripting engine framework API just like we do for
any other language, would be the cat's meow. Of course there are
other language processors that Wings aims to integrate such as
Scilab,
GNU
Octave,
Rlab,
Matrex,
Matlab,
etc. that would be of more interest to folks who like formulas.

Apache
Ivy

Wings integrates Apache
Ivy
("the agile package manager") for adding other packages to
the classpath. By default
Ivy configured
to access the public Maven 2 repository (Ibiblio) along with a local
per-user cache.

The current form of integration is that you specify an Ivy File
using a Groovy MarkupBuilder embedded in the global 'XWINGS.IVY'.
That will also result in the dependencies being resolved and added
to the Wings classpath for this document. No progress feedback is
currently provided by Wings, so you will have to watch your system
console to find out what is happening when it takes a long time
(which may happen for example if it has to download a large
artifact). If the resolution is successful, the array of artifacts
is the result so you can see what was set on the classpath.

A future IFCX development will be annotation processors (both
Javadoc-style and Java 5 Annotations) to simplify and automate
dependency management. So that the "@use" annotation in
this script would be equivalent to the following Ivy file.

Beware
the map!

It is dangerous to use property access ('object.class')
when trying to get the class of an object of unknown type. That is
because if the object happens to be a map, then the property name
will be used to do a get on the map and not fall through to the
getter (Object.getClass()) as you're intending with the
shorthand. Ditto for Object.getMetaClass(). But since
we know we're dealing with an enumeration here, we can favor the
terse style. This example shows calling a literal closure, which
also illustrates why Groovy doesn't permit statement blocks simply
enclosed by curly braces (as it would be ambiguous with closures).

enum Day { mon, tue, wed }{ e ->
"${e.class.name}.$e" } (Day.mon)

Day.mon

Day.tue

tue

// Can't do this because we can't know
if it is a statement or a closure...{ 2 }

org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed, Script32.groovy: 2: Ambiguous expression could be
either a parameterless closure expression or an isolated open code
block; solution: Add an explicit closure
parameter list, e.g. {it -> ...}, or force it to be treated as an
open block by giving it a label, e.g. L:{...} @ line 2, column 1.1
error

Converted to Wings-style. Here we can simply chop up the script
into pieces that do "just enough" to move along to where
we're interested in the result. Not only does that eliminate the
need for printlns or asserts to check on what has happened, it also
allows the bits of script to be reevaluated in various orders. That
is common for dealing with something that fails, you can just redo
that part, or to verify that some code does what is expected you
might leave it out when manually evaluating a particular sequence.

PLEAC

Section 3: Dates and Times

Introduction

Batch style:

//----------------------------------------------------------------------------------//
use Date to get the current timeprintln new Date()// =>
Mon Jan 01 07:12:32 EST 2007// use Calendar to compute year,
month, day, hour, minute, and second valuescal =
Calendar.instanceprintln 'Today is day ' +
cal.get(Calendar.DAY_OF_YEAR) + ' of the current year.'// =>
Today is day 1 of the current year.// there are other Java
Date/Time packages with extended capabilities, e.g.://
http://joda-time.sourceforge.net/// there is a special Grails
(grails.codehaus.org) time DSL (see
below)//----------------------------------------------------------------------------------

Tue May 06 15:02:14 PDT 2008Today
is day 127 of the current year.

Wings style:

new Date()

Tue May 06 15:02:18 PDT 2008

cal
= Calendar.instance'Today is day ' +
cal.get(Calendar.DAY_OF_YEAR) + ' of the current year.'

Shopping
Cart

I was watching a lightning talk about Scala illustrated with the
classic shopping cart example, so I whipped up this version while
they showed the Scala version. While Groovy doesn't have Scala's
type inferencing and static typing performance, it is even terser.
This version doesn't follow their example of initializing all the
quantities to zero because that isn't plausible if the catalog can be
large. It does however use strong typing on the catalog to show we
can have that if we want it. Also the Scala version showed the
special price handling in the total function, and while I could do
that too (and even put it all on one line), I think it is a better
separation of concerns to have that it a separate function.

The famous Elvis operator (':?') is used which
demonstrates a key difference between Java and Groovy which is the
notion of "true". Groovy
Truth
is weakly typed and treats not only false, and Boolean.FALSE as
false, but also null, empty strings, empty collections, numbers with
a zero value, and regex matchers with no match. Anything else is
true. So Elvis evaluates the left-hand side, and if it is true then
returns that value (which could of course be something like a
non-zero number or non-empty string). Otherwise it returns the value
of the right-hand side. This is not simply the ternary operator
because the LHS appears only once and is evaluated only once. There
is an example of Collection.inject earlier
in this document.

GUI Forms and Map Binding

This is the first bit of Groovy I wrote (well, almost,
SwingBuilder.build was my first contribution to Groovy as a
replacement for the boilerplate previously needed to use
SwingBuilder) to find out how binding of a model to a GUI view would
be done in Groovy (the acid test for any language). The trick here
is actually just Java Collections in that the map entry you get when
iterating over a mutable map will modify the map if you change the
value part. Once again this example doesn't show well in Wings
(although the frame will get displayed) because it doesn't (yet)
handle standard output.

javax.swing.SwingUtilities.isEventDispatchThread()

false

def
someBean=['abc':1,'def':2,'xyz':3,'foo':99]

// def
MYFRAME

groovy.swing.SwingBuilder.build
{ MYFRAME=frame(title:'My Frame')
{ def map=[:] // from text field widget to
pair entry in someBean panel()
{ // initialize
map with labels and inital values from someBean for
(pair in someBean) {
t=textField(text:pair.value) label(text:pair.key).labelFor=t //
map textfield to someBean label/value pair map[t]=pair
} //
Notice that I can supply a closure and it gets adapted to an
ActionListener. button(text:'OK',
actionPerformed:{ //
update map with current value from widgets for
(pair in map) pair.value.value=pair.key.text
//
show we got updated for
(pair in someBean) println("${pair.key}:
${pair.value}") //
We should look for our parent frame to close, but this is
handy: MYFRAME.hide() }) } } MYFRAME.pack() MYFRAME.show()}

Classes are different than Groovy scripts. The Groovy Script
class provides the convenience methods for printing and Wings does
the right thing for JSR-223 so that we can get the output into this
document. But if you use 'println' in a Groovy Class
then it's going to use the GDK println which will use
System.out which will go to the system console. So
here's one way of getting the output to remain well behaved in a
scripting context.

Pretty
Printing

Someone on groovy-user asked how to do pretty-printing of lists
and maps in Groovy. Although Groovy has a bunch of stuff dealing
with output and formatting, none of it is really suited to
pretty-printing. This is the start of a way to do it (but I'm gonna
go a different way since hypertext is better for this sort of thing).
It is factored into an improved indenter (writer rather than stream
based, it's a value object, and written as Java so it's useful in
less groovy environments) and simple formatter.

Multiple
Languages

The current version of the Wings prototype supports any language
with a JSR-223 Java scripting engine (other sorts of language APIs
are planned of course).

Some of these engines take a while to initialize, and at the
moment Wings doesn’t provide any feedback or control with long
running scripts. So you should be patient and perhaps check your CPU
activity monitor if you think Wings is stuck. After the first hit
though, all these engines zip right along.

Ruby/JRuby

Ruby is a popular language of late. JRuby
is an implementation for the JVM, and Wings supports it by default.

This
is JSR-223 script engine for SISC - Java implementation of Scheme
language. SISC is available for download at http://sisc-scheme.org/.
We have built and tested with SISC version 1.16.6.

(+ 1 2 4 5)

12

Note
on accessing jsr-223 Binding variables from Scheme:

SISC
implementation has support for pluggable top level environments. But,
SISC engine expects to map symbol to ints and use that when looking
those ints up later. But, jsr-223 supports variables though a Map and
map entries maybe changed/deleted/added freely -- both from Java and
the underlying scripting language. So, the way jsr-223 Bindings
works is as follows:

Scheme
user has to use "var" procedure to access/update the
variables exposed by jsr-223 bindings. To access variable "foo"
from Scheme, you use (var 'foo). To update variable "foo",
you need to use (var 'foo <value>).

For
example, you can use the following expression to print the current
file name.

This
part of the manual is a tutorial introduction to the Objective Caml
language. A good familiarity with programming in a conventional
languages (say, Pascal or C) is assumed, but no prior exposure to
functional languages is required. The present chapter introduces the
core language. Chapter 3
deals with the object-oriented features, and chapter 2
with the module system.

1.1 Basics

For
this overview of Caml, we use the interactive system, which is
started by running ocaml
from the Unix shell, or by launching the OCamlwin.exe
application under Windows. This tutorial is presented as the
transcript of a session with the interactive system: lines starting
with #
represent user input; the system responses are printed below, without
a leading #.

Under
the interactive system, the user types Caml phrases, terminated by
;;,
in response to the #
prompt, and the system compiles them on the fly, executes them, and
prints the outcome of evaluation. Phrases are either simple
expressions, or let
definitions of identifiers (either values or functions).

1+2*3;;

Value(long)=7

-
: int = 7

let
pi = 4.0 *. atan 1.0;;print_float pi;pi

3.14159265359

Value(block)=fr.x9c.cadmium.kernel.Block@d5ef4b

val
pi : float = 3.14159265358979312

let
square x = x *. x;;

Value(long)=0

val
square : float -> float = <fun>

square(sin
pi) +. square(cos pi);;

Value(block)=fr.x9c.cadmium.kernel.Block@73124b

-
: float = 1.

The
Caml system computes both the value and the type for each phrase.
Even function parameters need no explicit type declaration: the
system infers their types from their usage in the function. Notice
also that integers and floating-point numbers are distinct types,
with distinct operators: +
and *
operate on integers, but +.
and *.
operate on floats.

1.0
* 2;;

fr.x9c.cadmium.kernel.CadmiumException:
callback exception

This
expression has type float but is here used with type int

Recursive
functions are defined with the let
rec
binding:

let rec fib n = if
n < 2 then 1 else fib(n-1) + fib(n-2);;

Value(long)=0

val
fib : int -> int = <fun>

fib
10;;

Value(long)=89

-
: int = 89

1.2 Data
types

In
addition to integers and floating-point numbers, Caml offers the
usual basic data types: booleans, characters, and character strings.

(1
< 2) = false;;

-
: bool = false

'a';;

-
: char = 'a'

print_string
"Hello world";;

Hello world

Value(long)=0

-
: string = "Hello world"

Predefined
data structures include tuples, arrays, and lists. General mechanisms
for defining your own data structures are also provided. They will be
covered in more details later; for now, we concentrate on lists.
Lists are either given in extension as a bracketed list of
semicolon-separated elements, or built from the empty list []
(pronounce “nil”) by adding elements in front using the ::
(“cons”) operator.

let
l = ["is"; "a"; "tale"; "told";
"etc."];;

Value(long)=0

val
l : string list = ["is"; "a"; "tale";
"told"; "etc."]

"Life"
:: l;;

Value(block)=fr.x9c.cadmium.kernel.Block@290aac

-
: string list = ["Life"; "is"; "a";
"tale"; "told"; "etc."]

As
with all other Caml data structures, lists do not need to be
explicitly allocated and deallocated from memory: all memory
management is entirely automatic in Caml. Similarly, there is no
explicit handling of pointers: the Caml compiler silently introduces
pointers where necessary.

As
with most Caml data structures, inspecting and destructuring lists is
performed by pattern-matching. List patterns have the exact same
shape as list expressions, with identifier representing unspecified
parts of the list. As an example, here is insertion sort on a list:

The
type inferred for sort,
'a
list -> 'a list,
means that sort
can actually apply to lists of any type, and returns a list of the
same type. The type 'a
is a type
variable,
and stands for any given type. The reason why sort
can apply to lists of any type is that the comparisons (=,
<=,
etc.) are polymorphic
in Caml: they operate between any two values of the same type. This
makes sort
itself polymorphic over all list types.

print_endline
(sort [6;2;5;3]);;

fr.x9c.cadmium.kernel.CadmiumException:
callback exception

-
: int list = [2; 3; 5; 6]

sort
[3.14; 2.718];;

Value(block)=fr.x9c.cadmium.kernel.Block@3aaf52

-
: float list = [2.718; 3.14]

The
sort
function above does not modify its input list: it builds and returns
a new list containing the same elements as the input list, in
ascending order. There is actually no way in Caml to modify in-place
a list once it is built: we say that lists are immutable
data structures. Most Caml data structures are immutable, but a few
(most notably arrays) are mutable,
meaning that they can be modified in-place at any time.

1.3 Functions
as values

Caml
is a functional language: functions in the full mathematical sense
are supported and can be passed around freely just as any other piece
of data. For instance, here is a deriv
function that takes any float function as argument and returns an
approximation of its derivative function:

#let
deriv f dx = function x -> (f(x +. dx) -. f(x)) /. dx;;

val
deriv : (float -> float) -> float -> float -> float =
<fun>

#let
sin' = deriv sin 1e-6;;

val
sin' : float -> float = <fun>

#sin'
pi;;

-
: float = -1.00000000013961143

Even
function composition is definable:

#let
compose f g = function x -> f(g(x));;

val
compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>

#let
cos2 = compose square cos;;

val
cos2 : float -> float = <fun>

Functions
that take other functions as arguments are called “functionals”,
or “higher-order functions”. Functionals are especially useful to
provide iterators or similar generic operations over a data
structure. For instance, the standard Caml library provides a
List.map
functional that applies a given function to each element of a list,
and returns the list of the results:

#List.map
(function n -> n * 2 + 1) [0;1;2;3;4];;

-
: int list = [1; 3; 5; 7; 9]

This
functional, along with a number of other list and array functionals,
is predefined because it is often useful, but there is nothing magic
with it: it can easily be defined as follows.

The
following function tests if a parameter is a tuple with a member
named "ind":

hasMember
{ind} = true| _ = false;

[hasMember {ind=a}, hasMember {
foo=ind }, hasMember { }]

[true,false,false]

It
is possible to name a pattern, so that this name can be used to
reference the object of this pattern. Special symbol '@' can be
used to name a pattern. The following function returns the tuple
itself if it contains member "ind", an empty tuple is
returned otherwise:

test t@{ind} = t| _ = {};

[test{ind=a},
test{a=1, b=2}]

[{ind=a},{}]

Scala

Let's try some Scala!
This will take a while the first time, so be patient and just wait
for the I-beam cursor to start blinking again.

Adenine

Adenine
is the language of the MIT
Haystack Semantic Desktop.
It features a RDF data model, Pythonic syntax, and is implemented
for the JVM. IFCX.org has extricated it's implementation from
Eclipse and packaged it with a JSR-223 engine adapter so that Wings
can support it by default.

+ 1 2 3

6

The current Adenine engine doesn't support top-level constructs
and instead evaluates everything as expressions (blocks). The IFCX
implementation provides an implied @base for the engine instance.

The ^ shorthand is a URI that refers to the "current
document", which in this case is the instatiation of the Adenine
engine for this Wings document. In the future it will refer to the
Wings document itself.

Sleep isn’t working because the scripting engine adapter doesn’t
have input/output implemented.

import
java.awt.Point;

$p = [new Point];setField($p, x => 33,
y => 45);println($p);

Java

There is a JSR-223 engine for Java in the scripting.dev.java.net
suite, but it requires JDK 1.6 to build and run. It probably works
fine but it hasn't been tested here yet. There are other ways to
implement Java support such as Apache Commons JCI and perhaps most
interestinly for Wings would be to use the Groovy integrated
Java/Groovy compiler (thanks JetBrains!). In the meantime there is
BeanShell which is a lot like Groovy but is more complete wrt. Java
language syntax.

BeanShell

BeanShell (http://www.beanshell.org/)
is a scripting engine that supports Java syntax and is an approved
JCP standard as JSR-274.

BUG: If the get from an artifact URL fails, we wind up with an
empty JAR. Yikes!

Here we tell Wings to associate some paragraph styles with the
Scala engine. We set the name of both the resultStyle
and outputStyle to ScalaOutput here because
we're only getting one type of output from the Scala interpreter
right now and it is likely the manner of doing that will change in
the future. This will make it easier for such changes to be backward
compatible. Uh, nevermind. Turns out the formatting logic gets a
bit confused if the output and result styles have the same name and
we wind up with extra blank paragraphs getting inserted.

Once this initialization stuff is working reliablity, it can be
embedded in the WingsEval Groovy macro. You can see
how that's done by looking at Tools:Macros:Organize
Macros:Groovy... then twiddling the triangles to navigate to
Wings.odt (this document name):Wings:WingsEval.groovy.
A soon to come enhancement will be including the Ivy dependencies in
the registration so it all happens lazily and out-of-sight.

Take Off!

Okay! We're ready to evaluate some Scala!
This will take a while the first time, but if you've gotten this far
without errors, odds are good that you'll eventually get the right
results.

1 + 2

res0: Int = 3

Roadmap...

List of things To Do

Handle standard in, out,
err.

Handle long running scripts.

Progress indicator.

Stop/Cancel dialog.

Display standard I/O during
evaluation.

JSR-223
support using engines loadable via Ivy.

Preprocessing for Ivy/Maven @use Javadoc
annotation.

In Wings.

Maven plug-in.

XDoclet for Ant+Ivy scripts.

Client/Server interaction and other non-JVM
languages.

SystemExec

ShellExec

Move to next code to traverse TextContents
tree.

Maven & Ivy Repository support.

IFCX repository.

Ivy RoundUp scripts & repository.

Get language implementors to publish
working implementations in Maven repositories.

Multiple versions of the same language.

That already works by using different
style names, but this refers to the idea of having suitable metadata
and dependency/configuration support to automate it.