Just In Time Programming

"Passenger to taxtidriver: take me to number 37. I'll give you the street name when we are there." 

(an austrian math teacher's joke)

Disclaimer: there is no time, really; punctuality is your personal responsibility though.

Just in time programming (or: live coding1, on-the fly-programming, interactive programming 2) is a paradigm that includes the programming activity itself in the program's operation. This means a program is not seen as a tool that is made first, then to be productive, but a dynamic construction process of description and conversation - writing code becomes a closer part of musical practice. SuperCollider, being a dynamic programming language, provides several possibilities for modification of a running program - this library attempts to extend, simplify and develop them, mainly by providing placeholders (proxies) that can be modified and used in calcuations while playing. There is some specific networking classes which are made to simplify the distribution of  live coding activity.

Jitlib consists of a number of placeholders (server side and client side) and schemes of access.

These two aspects of space corresponding to inclusion and reference, depend on their context - here the placeholders are like roles which have a certain behaviour and can be fulfilled by certain objects.

It is useful to be aware of the three aspects of such a placeholder: a certain set of elements can be their source, they can be used in a certain set of contexts and they have a certain default source, if none is given.

Tutorial: Interactive Programming with SuperCollider and jitlib

This tutorial focusses on some basic concepts used in JITLib. There are many possibilities,

such as server messaging and pattern proxies which are not covered in tutorial form presently.


placeholders in sc [jitlib_basic_concepts_01]

referencing and environments [jitlib_basic_concepts_02]

internal structure of node proxy [jitlib_basic_concepts_03]

timing in node proxy [jitlib_basic_concepts_04]

Overview of the different classes and techniques:

• One way or style of access is the 'def' classes (Pdef, Ndef etc.)

it binds a symbol to an object in a specific way:

Pdef(\name) returns the proxy

Pdef(\name, object) sets the source and returns the proxy.

the rest of the behaviour depends on its use.

client side: [Pdef] [Pdefn], [Tdef], [Pbindef]

server side: [Ndef]

• Another way, for server side NodeProxies, is an environment that returns placeholders on demand:


~out = { ...}

helpfile: [ProxySpace] for the use together with other environments, see [jitlib_basic_concepts_02]

• there is also direct access without using the access schemes: NodeProxy, TaskProxy etc. provide it.

internally the former use these as base classes.

client side: [PatternProxy], [EventPatternProxy], [TaskProxy], [PbindProxy], [Pdict]

server side: [NodeProxy], [RecNodeProxy]

• in remote and local networks thanks to sc-architecture node proxies can be used on any server, 

as long as it notifies the client and has a correctly initialized default node.

note that the client id should be set.

using the network classes, groups of participants can interfere into each other's composition

by sharing a common server, using SharedNodeProxy and exchanging code and comments 

in a chat (see Client)

networking classes:


[Public] distribute environments over networks.

[public_proxy_space] how to distribute a ProxySpace

[Client] simplifies client-to-client networking. 




tutorials: [proxyspace_examples]







live coding without jitlib: [basic_live_coding_techniques]

storage: [NodeMap] storing control setting

[Order] ordered collection

unconnected other classes:




for suggestions / comments contact me

Julian Rohrhuber,  rohrhuber@uni-hamburg.de

Thanks a lot for all the feedback and ideas!

[1] see for example http://toplap.org

[2] dynamic programming would have been a good term, but it is in use for something else already






october node proxy: developments with alberto de campo:

added playN method for larger multichannel setups

getKeysValues and controlKeys 


node proxy: 

unset works (not tested for setn)

nodeproxy.at now returns source, not play control object

control rate proxies now crossfade really linearly.

NodeProxy (BusPlug) can be passed a parentGroup now.

also ProxySpace can play in a given group (proxyspace.group = ...)


pattern proxies: added de Campo suggestion:

pattern proxies have now an update condition. reset method, if stuck.

there is also an .endless method that will embed the proxy endlessly.

node proxy multichannel expansion with arrays of numbers works now more like expected

~x = [~a, ~b, ~c]; expands into 3 channels

~x[0..] = [~a, ~b, ~c]; expands into 3 slots (mixing the inputs)


networking: removed PublicProxySpace, added a Dispatcher class [Public]  that 

does the same for any EnvironmentRedirect.


pattern proxies: all can have an environment, and take functions as arguments as well.

Tdef/TaskProxy take also a pattern as argument (for time streams).

Tdef .fork: fork a thread.

defaults now end (no looping by default)

nodeproxy.clear and proxyspace.have a fadeTime argument now

nodeproxy / nodemap: mapEnvir now takes not an array of keys, but multiple arguments

(.mapEnvir(\a, \b, \c) instead of .mapEnvir([\a, \b, \c])


improved network classes, PublicProxySpace

added envir variable to pattern proxies, the respond to set / map now.


nodeproxy.source now returns the sources

added tutorial 



fixed a bug when loading node proxy if the server is fresh.

node proxy now removes its synthdefs from the server.

Pdef: quant can now have the form [quant, offset]


removed Router class. see BroadcastServer helpfile.

experimental network classes added, old ones changed.


fixed a bug in Tdef/Pdef where the clock wasn't passed in (.play) properly when it was set before.

NodeProxy is more efficient in building SynthDefs.

ProxySynthDef can be used independent of NodeProxy now


refactored Pdef: new subclasses

improvements in NodeMap and NodeProxy

added role scheme (helpfiles to come)


nodeProxy.mapn expands to multiple controls. (not by arrays of keys anymore!)

some small efficiency improvements


Pdef/Tdef: pause and resume are now beat quantized

embedInStream is more efficient now, fadeTime is only applied for transitions

added recursive phrasing event

corrected Client bundle size calculation

NodeProxy remove/stop now differentiated, to allow ressource freeing in future (mainly cx players)

nodeMap_( ) fixed (unmaps synth now)

filter method for node proxy


removed N / Debug class to reduce number of classes.


wrapForNodeProxy improved (Bus works now, NodeProxy more tolerant)

simplified object wrapping

added monitor class, separated monitoing from BusPlug

channel expansion works with .play now (converting number of channels)

removed toggle method. 

onClear, monitorGroup, vol slots are removed (monitorGroup, vol is in monitor)

node order in multi object node proxy works more efficiently

multiple put: a[2..5] = { ... }


added fadeTime

Pdefn default is 1.0 now, which is safer for use in time patterns.

avoid occasional duplicate notes when changing pattern

Tdef is more error proof.

ProxySpace has a parent. the proto slot is used to store the tempo proxy.


SynthDef-hasGateControl fixed

InBus static float index works now

bugfix in Order-detect

fix unset/unmap bug

supplementNodeMap also works for non functions.


loading large proxyspaces now works - no late messages anymore

fixed bug in NodeProxy.clear when using patterns

fixed group order

added crossfade support for Patterns (EventStreams)

added crossfaded input offset (using e.g. .ar(1, offset))

removed Channel ugen, added XIn Ugens

lineAt, xlineAt messages work now

fixed the read example in [jitlib_efficiency]

nodeProxy.send now sends all if no index is given

refactoring, readability improved.


fixed bug on ProxySpace-reduce that caused infinite recursion in some cases

fixed bug in BinaryOpPlug (account for function.rate returning \stream)

new version of Pdef/Pdefn/Tdef


added .storeOn, .document methods for ProxySpace. see [jitlib_asCompileString] 


fixed Pattern support for NodeProxy/ProxySpace due to change in Event implementation

fixed Prefn

removed Penvir, Sfin etc, Ensemble etc. (removed classes can be found on sc-swiki)



added garbage collector to ProxySpace

fixed unmap

control rate proxies do not wrap channels anymore.


Pref / Prefn are tested, update properly. I'm thinking of merging them with Pdef.

fixed wakeUp bug in NodeProxy.

fixed bug in load when no server is present

embed control proxies in streams as bus index, allow multichannel mapping in patterns

added possibility to use \offset key in event streams to have offset index in multichannel proxy

fixed bug in lazy init



Pdef, Tdef work now, also with NodeProxy.

NodeProxy-releaseAndFree is replaced by .end.


symbol input is assumed to represent a synthdef that has a gate and frees.

functions and synthdefs are searched for their inner envelopes and the appropriate

method of freeing / releasing is chosen accordingly.


input channels now wrap. so any number of channels can be set to any proxy.

ar and kr take a second argument for the channel offset within the proxy

checked all helpfiles

put now has a different arg order! a.put(0, obj) or a[0] = obj

prependargs were removed for now.

lag can be set by name a.lag(\freq, 1)

a shortcut was added to efficiently read from another proxy: a.read(b) or a.read([b, c])

added granular / xtexture functionality: gspawner / spawner (experimental, might change)

a.play now does not create multiple synths if evaluated repeatedly (unless multi: true)

lazy init works now.

bin/unops work fully now again like any math op.