LtU Forum

ChucK : A Strongly timed language

Hi all,

I've been lurking here for a while - but this is my first post - so I hope I've got the
formatting right!

I thought perhaps this might be of interest to the community here:

ChucK : Strongly-timed, Concurrent, and On-the-fly Audio Programming Language

From the language specification:

"ChucK is a strongly-timed language, meaning that time is fundamentally embedded in the language. ChucK allows the programmer to explicitly reason about time from the code. This gives extremely flexible and precise control over time and (therefore) sound synthesis."

The idea of a programming language providing explicit support for being able to statically reason about how much real time a procedure requires (as opposed to it's O(n) time-complexity) seems new to me, and potentially of significant value in areas well outside ChucK's domain of audio processing i.e. real-time systems in general, and possibly even other application areas.

Your thoughts appreciated!

BSGP: bulk-synchronous GPU programming

A SIGGRAPH paper by Qiming Hou, Kun Zhou, Baining Guo, abstract:

We present BSGP, a new programming language for general purpose computation on the GPU. A BSGP program looks much the same as a sequential C program. Programmers only need to supply a bare minimum of extra information to describe parallel processing on GPUs. As a result, BSGP programs are easy to read, write, and maintain. Moreover, the ease of programming does not come at the cost of performance. A well-designed BSGP compiler converts BSGP programs to kernels and combines them using optimally allocated temporary streams. In our benchmark, BSGP programs achieve similar or better performance than well-optimized CUDA programs, while the source code complexity and programming time are significantly reduced. To test BSGP's code efficiency and ease of programming, we implemented a variety of GPU applications, including a highly sophisticated X3D parser that would be extremely difficult to develop with existing GPU programming languages.

The language acts to simplify CUDA, which reminds me of assembly code even if it uses C syntax, with, among other things, a higher-level memory model and implicit data-flow (so you don't have to explicitly partition your code between different kernels). Here is one trick that really impressed me:

findFaces(int* pf, int* hd, int* ib, int n) {
  spawn(n*3) {
    rk = thread.rank;
    f = rk/3;  
    v = ib[rk];
    thread.sortby(v); 
    require
      owner = dtempnew[n]int;
    rk = thread.rank;
    pf[rk] = f;
    owner[rk] = v;
    barrier;
    if (rk == 0||owner[rk-1] != v)
      hd[v] = rk;
  }
}

After the call to sortby, all threads are sorted by rank according to the values of v, rather than explicitly sorting a list or some other auxiliary data structure that would have to be allocated into memory. In other words, the call forces a reality where all the threads are coincidentally arranged in the way we want them to be...an interesting PL concept.

Lagoona, component-orientation

(i thought i read a comment on LtU about Franz, but can't find it now.)

Lagoona apparently addresses some issues around component-oriented approaches to systems development, and has roots in Niklaus Wirth's works such as Oberon. Is anybody on LtU more familiar with this stuff, such that they could opine / compare / contrast?

(tags like: "component-oriented", "distributed extensibility", "decentralized", sorta beyond-OO, that kind of fun kool-aid.)

Is Small Still Beautiful?

(LTU appropriate punchline at end) I suppose I'm just old enough to have been raised on the "small is beautiful" philosophy, and I still hold in awe some languages built from a relatively spare set of primitive concepts: Forth, Smalltalk, Scheme, C and the Unix shell + utilities + pipeline all come readily to mind.

But recently, I've had some time on my hands and spent some time "swimming" about in the programming language space. A few observations.

Some of our modern languages (some a decade+ old already) have type systems that require a PhD to understand fully. We have a low level threading model in languages like C and Java that almost require a PhD to use effectively in any sufficiently complex system. (Not to make a fetish of the PhD.)

In Pike's Power Point on system research, recently posted in another thread, he mentions, IIRC, that 80% of the Inferno (?) effort was spent conforming to existing, externally imposed standards! Turning to the most mainstream, popular, *production* languages - we have TRULY giant libraries that boggle the mind.

Designing an effective GUI library for the modern, newly more complex UI was a grand challenge of the late '80s and early 90s.

But today, we have Java/JVM, Perl, Python, C#/CLR (different, but still pregnant with oodles of MS API's), MS binary APIs, a growing body of de facto Linux binary APIs, and even fairly rapidly growing complex Scheme libraries (PLT) that actually require a separate complex application to locate, manage and update - and that's prior to presumably learning the eventually using the libraries in our applications. We're not in Kansas anymore.

The documentation effort alone for any of these language specific "package databases" is daunting.

And all the while, the famous "principle of least surprise" is growing stronger and stronger both with each new generation of computer user and each new generation of computer programmer. It recall's the joking "10 principles" of successful programming language design, the first of which, IIRC, was "use C style curly braces" :-)

I guess that Pike's PowerPoint on systems research had a big impact on me, and that I readily seemed able to apply it to today's situation with programming language design and development. Will new languages be increasingly be relegated to "toy" status until more and more design efforts and research just whither away?

And at least my aging collection of language texts still emphasize a notion of programming language made up of a small set of data and control concepts easily combined - typically, the smaller the better. It reminds me of my formal logic training, where the search for a set of primitives to provide the foundations of logic, set theory and mathematics formed some sort of holy grail (sound a little like Scheme?).

So I ask - do we need an about face? Do we need to study (and teach) how to build *large* programming languages: languages with type-checked integrated SQL syntax; built in rich XML support; myriad native persistence, serialization and network communications facilities; a diverse family of concurrency mechanisms; language level transaction support, including distributed transaction facilities (MQ Series style?) to better support cluster computing.

As for library infrastructure and a (poor) degree of platform based language interoperability, we have the JVM we know and love today frankly by an historical mistake. We have the CLR because MS has to produce a "one up" version of whatever else is popular in the computing world. I won't restate the many, many gripes about each made by folk targeting, or potentially targeting, these platforms for their new, innovative languages (while, acknowledging, that surely each also has its many interesting implementation virtues). But I will invite us to recall the gripes :-)

It's arguable that we need an academic/industry consortium effort to redesign the JVM (presuming we don't start from scratch), with a new, concerted focus on language support - advanced calling convention support such as generalized last call optimization (or think of efficiently supporting Common Lisp calling conventions, even CLOS multimethods, combined with higher order function just for a brain teaser); integration of compiler analysis with runtime call/loop support for optimizing GC or thread switch safety points; optimized execution models to support logic programming and expert system style languages; type systems divorced via some well defined barrier between (more limited) capabilities of the runtime/JIT and new, innovative (unanticipated) future type systems at the language level; safe and efficient intermixing of manifestly and latently typed code and data; rule or specification based per-language calling conventions to facilitate "auto-glue" supporting automatic cross-language library interoperability; support for compiler and linker customization to support a variety of module systems of varying complexity; same potentially for macro facilities, and yada yada yada.

Just a brief scenario based on examples, but I hope you get the idea. I'm sure many of us could go on and on, based on current personal research or commercial interests, likely isolating even more fundamental and/or timely issues that beg attention in order to support language innovation in this apparent new era of "Big is Beautiful."

Like it or not, are we in the era of "Big is Beautiful" language design, and if so, what are we to do about it?

Put another way, given the above described "issues," the raw CPU itself gets in our way least of all! So what's the problem? The problem is the scale of the libraries one must support in a modern language. The problem is increasing productivity of smallish research teams by sharing a low level 3 address code, set of SSA optimizations and code generator - and other relatively neutral infrastructure. The problem is composing language features, *larger* features, and on a *larger scale* than the minimalist principles laid down in the days of yore.

In summary, it *appears* that the glue holds some promise, and clearly some languages benefit from it better than many others. So can the "glue" truly become the *solution* for future language research, design and implementation?

Scott

Pragmatic declarative event abstraction

My recent exploration of Rx has gotten me thinking again about events. Ever since I read Conal's original Fran paper, I've been fascinated and confused by the relationship between discrete streams of events vs. continuous behaviors. Although they can be wrapped up in one abstraction (signals), this unification leads to pragmatic if not semantic mismatches resulting from the difference between discrete and continuous.

Bling, my current language effort, provides very concise syntax for creating continuous relationships between properties; e.g., Matrix.Bind = Matrix4Bl.MakeScale(.8d) * Rotate would bind a matrix property to a rotation matrix scaled down 80%. The programmer doesn't need to create a value converter, populate a binding object, or even express a closure. On the other hand, the programmer has to manipulate values indirectly because they are "lifted." This is problematic when we need to change a property's value discretely. Consider updating a 3D quaternion rotation via a virtual trackball. The idea is to take a 2D mouse position and convert it into a 3D sphere position:

var Mouse2D = sphere.Mouse.Position / sphere.Size;
Mouse2D = (Mouse2D * 2d - 1d);
var Mouse3D = MouseAt.AddZ((1d - Mouse2D.LengthSquared).Max(0d).Sqrt).Normalize;

Now, we want to update the Rotate property, and for efficiency reasons, we want to generate code that does this update:

var Rotation0 = this.Temporary(QuaternionBl.Identity);
var Mouse3D0 = this.Temporary(Double3Bl.Zero);
Action Begin0 = Rotation0.MkAssign(Rotation);
Action Begin1 = Mouse3D0.MkAssign(Mouse3D);
Action Update = Rotation.MkAssign(Mouse3D.AngleBetween(Mouse3D0) * Rotation0);

Rotation0 and Mouse3D0 are explicit temporary properties that remember the 3D mouse position and initial rotation when a rotation begins. The update then takes the current 3D mouse position, finds its angle with the remembered 3D mouse position, and prepends that to the remembered quaternion rotation. Finally, these actions are used in a drag state machine subscription:

DragBegin.Subscribe(() => { Begin0(); Begin1(); });
DragUpdate.Subscribe(() => Update());

This was the typical way to handle events in Bling, where a lot behavior occurs by updating and manipulating UI properties. This solution was sub-optimal for the following reasons:

  • Update actions and subscriptions are separate steps.
  • Explicit temporaries are ugly, and we still have to create update actions and subscriptions for these temporaries.

Then I realized we could treat events themselves as indices of "time" into a lifted values, much like an integer is an index of space into an array. So a[e] represents the value of expression a when event e fires, in essence e is like a continuation. This is how things work in Rx; e.g.,

from mouseLeftButtonDown in this.GetMouseLeftButtonDown()
let rotation0 = this.Rotate.CurrentValue
let position0 = Mouse.GetPosition(this)
...

where "let" binds in the context of mouseLeftButtonDown event/continuation. So I thought, that's essentially what I'm writing so much code to do anyways, so let's do that in Bling. Also, we can flip the syntax to also control assignment: a[e] = ... would cause a value to be pushed into the a expression when e fires. Redoing my virtual trackball example in the new syntax:

Rotate[outer.Mouse.Drag.Update] =
  Mouse3D.AngleBetween(Mouse3D[outer.Mouse.Drag.Enter]) * Rotate[outer.Mouse.Drag.Enter];

No temporaries, updates, or subscriptions, just an assignment: so much better! An artifact of my approach is that events can't directly carry data payloads; they are just points in time. However, I've solved this problem (for now) by making event data available via dynamic context.

Done before? Crazy language idea?

how to resolve the compatibility issues of libraries.

When we use a library, it is often faced with compatibility issues. Sometimes, to migrate from one library to another, sometimes, the library will be upgraded to a new version.

During this process, the BUGs is very vague and difficult to test.
There is a settlement to resolve the issues.

This approach is described as follows:

For each of the library function,we named an input-output relationship, rather than a specific function.So the auto test module can be run and determine which function is compatible.

for example:
define:
def X as relation(in[...],out[...])
using:
X(...,...,...)

Top rated programming conferences?

I have my own programming language (these days who hasn't?), and would like to learn what would be the best way to promote it. LTU publishes conference materials, but usually after the fact. I understand that submitting something to JVM language summit can give the project some visibility, but it it is at least half a year away... What other conferences you recommend?

P.S. I'm submitting my stuff to SIGMOD/PODS but this is within database community. Sadly, there is not much communication between PL and database people.

"Corpus" of lisp/scheme programs which can be used for research

Are there any good bodies of such programs perhaps ideally which are pure that can be used for research studies? I am trying to get a sense of how scheme/lisp routines are typically structured without having to construct a body of my own routines which may be a non trivial task.

Go Interfaces

Ian Lance Taylor, one of the authors of Go, just posted two articles: Go Interfaces and Go Interface Values.

I consider these part of the hopefully upcoming "Go for Smalltalk Programmers". ;)

Library which provides unification of "Type Classes" in Java?

Hello LtU,

Please excuse me if I get my terms wrong, not a type system expert in any way. Since I don't really know what I'm talking about and what details are relevant I'll try to keep this short. I think it's best to discuss this and I'll come up with the details during the discussion.

I want to "map" different "type classes" into a unified system. I understand there is no such thing as a universal type system, so I'm looking for something pragmatic.

For example,

I could write a Map<String, -type- > view (or call it record, named tuple, etc) of a Java Class.

class Person {
   String name;
   int age;
}

Would become something like:

{ "name": String, "age", int }

Similarly, I could combine an XML document

<person age="23" name="Meh"/>

with a list of named & typed XPath expressions

("age", int, /person/@age)
("name", String, /person/@name)

and view that as a similar Map.

Another example would be a query on a database of similar form.

I'd then like to have operations such as:

  • trimming the Map to a new Map with a subset of it's fields
  • projecting a field of the map to the type of it's value
  • taking the union of some maps into a new Map

It's important that I can dynamically walk (incrementally) the structure of a type and build a user interface on that.

Finally I'd like to (structurally) check equality of two types.

Currently I'm trying to write this myself but there are lots of details that make this rather complex. For example, efficiently dealing with values from derived types (obtained from slice/combine operations), etc.

Is there any (Java) library that does what I'm looking for? Does this sort of thing have a name?

Thanks a lot for your input!

Jelle.

XML feed