(Teletype) Pre-2.1 Operators and Features

I hear you. Thanks for your input!

It would have a built-in formula (or a few) and some parameters, and it doesn’t necessarily repeat. Check out the logistic equation for an example.


since a lot of this is driven by length limitations perhaps that’s where we should start? i also like being able to see the whole script at once, so how about just extending the number of scripts to 16? (or some other number).

this would work well if we also introduced a way to pass parameters into scripts. this is already doable in a way since all variables are global but having proper parameters would make them behave more like proper functions. we could have special variable names P1, P2 etc (maybe a different letter to avoid confusion with patterns) and then if you call a script like this: SCRIPT 1 123 456 in the script P1 would have the value of 123 and P2 would have the value of 456. if a parameter was not passed it can default to 0.

also what if we introduced a way to define aliases dynamically, with the scripts themselves. this should probably be limited to expressions only, so you couldn’t define an alias for something like L 1 4: - this wouldn’t be feasible for several reasons, but if we limit it to expressions it means we could evaluate an alias for correctness right when it’s defined. such expressions would be calculated whenever the alias is used. as an example: FI: SUB MUL I 2 1 defines an alias FI which is I*2-1 which then can be used like this: L 1 4: CV 1 N FI. basically, these aliases would serve as inline functions. this could partially address not having MZ as you could just define an alias MZ: EZ MOD A B (assuming it’s MOD A B you need).


I had an idea where this could be simplified.

Currently, we have SCRIPT x, which calls x Script on the current Scene. It would be cool to have something like SCRIPT y x as well, which calls x Script from y Scene. That way, you could keep Scenes of commonly used scripts without having to create yet another mode.

However, this idea assumes things about Teletype RAM that I am gleefully ignorant of :slight_smile:

1 Like

I was, too (although not gleefully), and it has way more than we’re using. I can’t imagine this thing becoming RAM-limited with the current scope.

It’s more of a design question of how many scripts there should be.

I have a soft spot for the high level sequencing commands in SuperCollider’s pattern library. How would the community feel about something akin to

PSEQ num_0,.. num_k

where the k numbers are limited by the line length, and there is no explicit time interval. Every time the command executes, it spits out the next num_j in line?

I imagine using this for instance like this:

X PSEQ 0 3 5 7
If TOSS: Y ADD X PSEQ 12,5,7
ELSE: Y ADD X PSEQ 11 13 17

Or other ways for creative pattern composition.

I realize this can already be done using the tracker and a combination of commands. The point of this would be the convenience of having high level commands available (same way that CHAOS can be done with a combo of commands, but having it as an OP promotes its usage), and immediate visual feedback on the pattern values, instead of going back and forth between the tracker and script modes.

I would offer to do it myself. But I’m not well versed in C.


aliases are something i’ve considered. it’d need a special character.



and then #DEC could be used anywhere instead of X SUB X 1

figuring out a UI for definition and listing is a whole different issue. ie, the INIT script would just get clogged with defines. so it’d need to go somewhere else. but the # is important to provide an entire namespace, and call out to the user that the alias is a different/weird/other thing.

absolutely not enough RAM. it’d require grabbing that data from flash, which may or may not be a reasonable request at fast runtimes


First, I really love the Teletype as it is. For me, it is the most beautifully elegant thing that @tehn has designed so far. Both its capabilities and limitations are extremely inspiring. The device and its integrated language extend each other’s metaphors beautifully.

I also think that @sam has done a wonderful job shepherding that design philosophy in the 2.0 enhancements. When I imagine useful extensions for the thing, I challenge myself to be as mindful of those ideas as they have been. “To make everything as simple as possible, but no simpler.” (Not necessarily an Einstein quote: https://quoteinvestigator.com/2011/05/13/einstein-simple/.)

Here is where my head has been at with this stuff, if you are interested. :slight_smile:

  1. Love the idea of passing parameters to scripts that @scanner_darkly - almost did it a while back on a lark and restrained myself to keep focus on the TELEX. It feels natural and could be really helpful.

  2. Really like @tehn’s timeline proposal as well. I think of it like an event view in a sequencer - give an event time (in MS or triggers or beats or …) and a command / script to run at that moment. With the ability to pass values to scripts (from #1 above), this would get even more powerful. (This would be appropriate to scroll in the context of the Teletype, I think, as its metaphor seems to invite it.)

  3. I like the runtime aliases / scriptlets ideas above as well (with parameter passing). This would clear up one of the problems that I’ve caused for myself and others by making some of the TELEX commands on the long side for intelligibility. If I want to use one a lot (or in a loop where I’m running out of space) - boom, make a runtime alias.

  4. I’ve gone back and forth on this, but I don’t think scripts should wrap lines and I don’t think that they should extend beyond the screen. This limitation is one of the things that “just works” in the design and actually inspires creativity. I don’t think we should mess with it as it will add confusion when visually parsing scripts when commands are wrapping and/or falling off the view.

  5. Memory aside (not sure where our limits are), I think having some more available scripts would be nice - but I feel like they should extend the metaphor of the device. Right now, scripts map to trigger inputs … they relate to a physical thing. There is something magic about the way that works in your brain when you are interacting with the instrument. The best way I can think of to add more scripts would be to add “shadow” or “alternate” scripts that sit under each of the individual 8. This way - you still would only be paginating through 8 scripts in general use. The complexity of the additional scripts would be out of the general path of usage for a novice user - or advanced user doing something light. You could cycle into a script’s alternate using another set of keys. You could call the alternate script using a designator - something like SCRIPT 1A - though I loathe using a variable designator there that could be visually confused. You could even swap alternates in for the primary script if you want - creating new trigger behaviors that can be programmatically introduced into the patch. (INIT could also have alternates that you could “chain” in at script startup to handle additional commands/aliases/etc.)

Anyway - still lots to think about - but, that is where my brain is at the moment. :slight_smile: :slight_smile:


A selective script load combined with a prescan at scene load shouldn’t be too bad, though, should it?

I’m seriously thinking about writing a Debug / Profile screen to assist with development questions like this.

1 Like

some way to expand I script would definitely help, regardless of any other proposed changes. even just another I script.

@bpcmusic - agreed on all points!

re: calling scripts from other scenes - the problem i see with this is that it breaks the flow. it would work okay for functions that are not likely to ever change, but if you have to go back and forth it’ll be a hassle - you have to save the scene, select the other scene, edit, save, select the first one etc.

Why not a “Library” scene, where you put common routines?

e: Super easy solution is to allow scripts to import scripts from other scenes (e2: in the editing process)

remember you can use semicolons for multiple assignments. ie

x 3; y 8; z 9;

i’d prefer not to scroll the init screen. an extreme init could also use the TL. i’ve considered TL as a super-long scratchpad as well as a sequential execution system.

i don’t like the idea of calling scripts from other scenes-- i would discourage pursuing this. primarily for the reason that for scenes to inter-read one another they’d all need to have static indexes, ie script 1 of scene 3 called by script 3 of scene 5. ugh. this is unmanageable and unshare-able. if someone wants to share a scene, it should be possible as a single elegant little bundle. cross-scene communication would be a mess in many ways-- require scenes to be loaded at specific index positions in order to function. so, again, there are better ways.

for those on the fence about TL: imagine another screen, like TRACKER. it scrolls. lines start with a number.

200 TR 1 1
200 X ADD X 1
200 M.ACT 0
300 TR 2 1

so, for example, you want to extend script 1:

A 1
B 2
C 3
D 4
X 3

TL.CALL would execute the TL at the given position. when it hits BREAK it’ll quit.

thinking while typing, sorry: the BREAK might not even be needed, as the idea for TL was to be operated from a timer. but perhaps explicit CALLs would make the system clearer. ie:

0 TR.P 1
100 TR.P 1
100 TR.P 2
150 TR.P 1

X MOD X 200

so this is a manual execution, but it lets you do some interesting things. anyway, i should sit down and work with the design. any comments welcome.

and to clarify, each scene has their own TL script.

i don’t like this idea because again it makes it so scenes have dependencies.

this is a spectacular idea. it’s an editor feature, not a language issue. it keeps scenes atomic.


Still wrapping my head around this but…first impression? This is a very elegant solution to extend the functions w/o adding additional (individual) scripts

My fav part of the core tt design is the universal access to tracker data and this feels like it fits the spirit of teletype

Right, just some quick technical interludes… I don’t have too much time to read through everything.

  • Reading from flash. Not that slow actually (writing is much slower). Takes 1 CPU cycle to read the data. Remember a lot of the look up tables are stored as constants in flash.

  • User defined functions, labels, etc… currently the tables to convert names to functions is done at compile time. Doing it at runtime will add a lot of complexity. As an alternative consider us having say, 4 slots available for saved commands, FN1FN4. The following would be extremely easy to code (as is not that different to how DEL works):

    FN1: ADD X X
    SCRIPT 1:
    Y FN1.CALL 2

    Y would end up containing 4. Each FNx could be redefined multiple times in a single script (to interesting effect), and would return either the last value or 0 if there is none. (FYI I have literally made these up on the spot and not really thought it through…)

  • Increasing the script count would be easy, but as I mention frequently the USB disk code needs a total rewrite first! If space is an issue we can just reduce the number of scenes available.

  • @Pampalini unfortunately PSEQ would not work as the Teletype parser requires there to be a fixed number of arguments. I am currently experimenting with the following OPs on my own Teletype:

    ARP3 0 5 7 T            # return the Tth value from the 3 long array, wrapped, a bit like an arpeggiator
    SCL7 0 2 4 5 7 9 11 X   # take X as a scale degree and return the note in the given scale 
                              (I think that's the major scale) 

    Plus a few other variations. All of them under the theme of ‘inline arrays’. Each OP is defined multiple times for each length, e.g. ARP2, ARP3, etc, etc

  • @sliderule, ones of things I wanted to do with the 2.0 update was adjust the scene load mode to not only show the text, but also show the script contents too. The clipboard code was updated to be global, so you could easily modify the scene load mode to allow copying a line of a script to the clipboard.

Anyway will try to chip in more when I have some free time.


just posted in the github issues about AT. very much looking forward to that one.

1 Like

Quoting myself here… I think this is very similar to what @scanner_darkly suggested, but with fixed names.

Reasons why letting users define their own names is bad…

  1. A lot of booking keeping in the code required to keep a track of them.

  2. What happens when you load a new scene, do the old definitions stick around (as we do for variables).

  3. How many should we allow to be defined? And what happens when that limit is reached?

  4. What happens when firmware 2.5 comes out and it uses a name that someone is already using as a defined function…

1 Like

for all the reasons you state, i don’t think defines should happen dynamically, by scripts as your example shows.

if there’s another screen (defines) that has a list, and each define is preceded by a special character (ie #), then this would get saved with the scene and the whole thing would remain a package. scene switching would clear/reload the define table.



I’m kinda feeling like have some new variables that can hold expressions instead of numbers might be quite a lot of fun. And it would be so so easy to code up.

They’d have to be set using a mod, as that’s how the parser works at present. But internally it’s no different that using DEL or S. I particularly like that if you can change the saved expression at runtime.

Alternative syntax

FN x: <cmd>    # save <cmd> to function slot x
FN.CALL x      # run function x, returning it's output if it has one, or 0

I also think that it’s in keeping with the language, as the usage is very similar to DEL and S too.



SCL4 0 5 7 10 ARP5 0 1 2 3 4 T

looks to be a very handy equivalent of this

Pbind(\scale, [0,5,7,10], \degree, Pseq([0,1,2,3,4],inf))

Is there any chance I could get access to your fork to experiment with ARP and SCL?

this is a brilliant compromise. i love the execution-- super elegant. the only downside is that the user needs to remember functions by number, but i think it may be a worthy compromise. how many functions would we allow?


What is the conceptional difference between the FN x command and allowing 4 to 8 more scripts that are not connected to a trigger input but free to use with the SCRIPT command? They could be used for more complex operations or extended initial settings. I wonder if this would be easier to understand and to use.

Also wanted to say that II like the timeline concept very much!