I have bumped to line limits often, especially when storing/accessing numbers with PN x y z in SUBs so I would appreciate every improvement to make the code shorter. - unless we add another hundred new OPs which will make it more difficult to learn or read other peoples code

also

at one point I found myself wishing for an OP to report if the variable is greater/less than it was when last read.
keyboard shortcut to copy/paste entire script

my vote for the next big feature in TT would be though for ternary operators since it will give additional functionality to PREs and potentially make lines shorter.

Maybe he’s referring to the JEZ style ops, where you did suggest adding several, one for each variable it’s using.

I added the aliases. At the time I think he was against them, as were others.

Isn’t that a false equivalence though? ER is impossible to achieve on the Teletype without an OP, MZ isn’t, it’s just for convenience.


Regarding new OPs and OP names, we do have to be careful, once they’re added, they’re hard to remove or even change. And once the name is taken it’s hard to rename.

I also think there is a discussion to be had by all as to what direction we want the Teletype to go in.

My favoured option is the relative status quo for the language, with new ops for things that are really hard / impossible to do (e.g. scales and quantisation, which is what I’m trying to work on when I have free time for it). Plus various UI improvements (e.g. a calibration screen to the CV outputs).

Some seem to be in favour of more complex OPs (e.g. MZ, JEZ, etc).

But others would rather have longer lines, more lines in a script, and more scripts as an alternative to a more complex language.

All three options are eminently doable.

So where are we going?

(Also, can we also remember that whatever we do, we would like for @tehn to be able to sell lots of them.)

6 Likes

I’ll cop to the false equivalency and the irony of using it in the same digital breath as calling out hyperbole. :wink:

MZ is more than just convenience, though. It expands the language capability by permitting more complex operations in the same way EZ does.

3 Likes

full disclosure: there are only 300 TT in existence currently. it’s a much-loved module by a very small fraction of the modular market. we’re in the process of building a new edition of 100. they generally do not fly off the shelves.

so yes, i’m in favor of less obfuscation, but i don’t think there are clear lines as to what this means.

it was somewhat inevitable that we’d get to the point we’re at now-- constraints make the module and language accessible and fun to use and immediate-- the line length and chunky screen and ultra-simple syntax. i understand the desire to do more complex behaviors, and this extensibility would be easy with a larger screen and an established/pre-existing language.

basically the task at hand is making realistic goals that don’t detract from the original ease of entry. most people don’t even want to think about anything resembling code, yet this module has brought many people into scripting-- this is wonderful, and we need to keep that as the focus. but i do think there are many ways the system can be extended that won’t compromise that.

perhaps a compromise to the line-length issue is to wrap the command into two lines (with indention), and then reduce the possible max lines in the command. trade-off number of lines for line length. i really think it’s important to SEE the whole script at once.

will scrub through the other propositions later today with opinions, but i’ll lean towards consensus given it’s open-source and i massively appreciate all contributions.

EDIT: corrected number of TT in the wild from 200 to 300.

14 Likes

I think that the basic / power user dichotomy can be bridged with documentation. I’ll put my head to that grindstone for a while as community opinions roll in.

I think almost everyone can agree on AT being desirable. If we hammer out a finalized syntax (whose discussion is being held on the issue tracker), I can work on that one, too.

4 Likes

I was, slightly ironically, referring to the rate which is about 10 new OPs in 4 days.

I can see the use of aliases but I find the script much harder to understand then. One reason is that X + X Y looks more wrong to me than X ADD X Y due to the “normal” mathematical syntax/use of + and ADD looking more like a command. Another reason is that I cannot derivate the meaning of symbols like % or == in this context from their common meaning. Those things might have clear meaning for you coding people but I cannot grasp it.

Also I find it confusing to have symbols, shorted words and three letter acronyms as abbreviations for OPs in parallel.

What I would love to see though are more i2c commands to integrate Ansible apps better…

Maybe in the end the problem is that when you build a framework that is easy accessible you have to deal with users who need an easy access? :wink:

1 Like

dealing with this by having a “power user” language subset and a “basic user” language subset just feels wrong to me. one of the defining things for teletype is its community. exchanging scripts is an important part of that. i’m not saying we should keep the language “simple”, but we do need to consider that these decisions affect all users, even those who will never use new ops.

considering how it will benefit the community should be the first thing for any new ops, imo. if it’s a really special case that can be done (even though less efficiently) with existing ops, is it worth adding it? unless it’s something that is used often, scale for IN and PARAM being a good example.

another option is to make it less of a special case. say, if comparing a result of an arithmetic or logic operation to 0 or 1 is a common case, perhaps we could define a set of ops that would work consistently for all operations, making it easier to remember and more likely to be used often. how about %?1 or %?0 (not really suggesting these but as an example)

and all new ops should be considered from the point of future extensibility. the namespace is pretty limited, so whatever we add now means we can’t use it for something perhaps more suitable in the future (and i think we should avoid using special characters in op names in case we decide to use them as modifiers later on - which is why i particularly don’t like M! op - sorry @sam!).

4 Likes

10 discussed, maybe, but I’ve only implemented 5. This thread should contain brainstorming, so it’s natural that many bad ideas may be discussed.

Funny, because I’m sure most people would call 1 + 2 x 7 “normal” and 1 ADD 2 MUL 7 “strange”. The only thing different about TT syntax is that it’s prefix notation, whereas most of us learned infix notation, and some learned postfix.

I can understand being confused by the usefulness of the Modulo function, however. How often do you need to know the remainder of a division versus the quotient in the real world? You’re right that this function is much more familiar to a programmer because it’s very common to calculate offsets.

Short answer, MOD (%) (Modulo) is the remainder. It’s a handy thing to know, and in the context of rhythmic division, it’s handy to know when it’s zero. Consider:

A ADD A 1
IF EZ MOD A 4: TR.P 1

The second line, in English, reads: If there is no remainder when dividing A by 4, pulse trigger 1. Essentially, this is a clock divider that divides by 4, because every fourth integer divides by 4 evenly, and has a remainder of 0.

Warning: Tongue-in-cheek pedantry ahead.

I don’t agree and don’t advocate this, but it’s going to be a consequence when there are already highly complex and questionable features. Despite understanding and loving the concept of the stack, I have never once used it, and I wonder how many users do. Its usefulness is clearly limited, especially considering that you can’t execute a command stack without clearing it – at least then you could use it as a subroutine. Maybe people use it to buffer values or reverse the order of values, but these functions could be done in other ways with existing operators. Even its seemingly unique purpose – buffering commands – could be accomplished by just writing a script with a series of conditionals instead of one conditionally building a stack of commands to be executed in reverse. Additionally, you won’t have to rebuild the script every time you run it.

Complex :heavy_check_mark: Limited Utility :heavy_check_mark: Duplicates Functionality :heavy_check_mark: Other Commands Start With S :heavy_check_mark:

</tongue_in_cheek>


Consider a new operator, CHAOS, that returns numbers from a chaotic, yet deterministic formula. You could implement it entirely with existing ops, but you’d chew through dozens of operators and more of your available variables. You put it in a script, so it takes an execution stack slot. Then, you have to copy that one script to every place you want this new source of seemingly-random numbers, which is currently burdensome.

As a reference point, how do you think CHAOS would score as an operator?

I think MZ fits in well with the existing abstraction of EZ NZ, with the exception that MZ is a binary command, and EZ and NZ are unary.

A good point. I generally am ambivalent about the name with the exception of its verbosity, which should be low IMO.

Agreed, although ! was already taken as an alias for EZ.

P.S.: I appreciate everyone expressing their views in this thread!

4 Likes

As a side note here, this is already implemented for the TXi using the MAP operator:

TI.PARAM.MAP 1-n α β maps the PARAM values to the range α - β
TI.IN.MAP 1-n α β maps the IN values to the range α - β

I avoided the use of SCALE as the expanders also support quantization and the SCALE operator is used to set the current tuning.

I like this. Was thinking on similar lines when I implemented *.BPM operators for the TELEX independent metronomes.

TO.TR.M.BPM 1-n α time for TR.M; α in Beats Per Minute

Wonder if I should deprecate it.

Love the enthusiasm here; keep up the great work!!

3 Likes

I think MAP is a good, short name. I’ll implement it as such.

1 Like

not sure i agree on stack - i think it can lend itself to some interesting use cases, and could be used by people with no coding background. but i get it was a tongue in cheek example of existing ops that don’t necessarily follow the guidelines as outlined. the thing about existing ops though is that it’s hard to change them now - even more the reason to carefully consider any new ops.

CHAOS - i can totally see that being a useful op actually! i did say “unless it’s something that is used often” and a more powerful random generator with various algorithms would be totally useful imo. but an op for something like “take the value of A, increment it by 1 and store it to B” probably less so as it’s way too specific.

this can all be subjective, obviously, and something that appears obscure to me might be something a lot of people would use. that’s why i think it should be based on community input and specific use cases.

Thinking about this, I have to disagree because we are tokenizing with whitespace. If you had a truly unique namespace, it would still be pretty big. I think you could make a compelling case for expansive functionality using a language that only required tokens between numbers.

IFMZY4:TR.PLIM+Y-RAND1,1,4;XABSO

(32 characters, 16 operators)

I’m not saying that the current operator names could work, but I bet I could get a set that was reasonably close in name and identical in idiom and function to teletype script and retain human readability.

(Note: this fictional language is an illustrative device and does not represent my desire for teletype syntax.)

Adding whitespace tokenization vastly increases the universe of the identifiers in the syntax, so I don’t think this is really at issue.


That said, I certainly share the concerns of the group: the syntax should be unconfusing, the operators universally useful, and scripts easy-to-read.

That I write the code gives me undue, if unintended, influence in the design and naming process of the code I write. I will always hold that of the code that I may submit, any of it may be discarded or modified to meet the needs of the community as it sees fit. My goal is to enrich the community, and I hope that my work is to that end, but I don’t lament failure.

I apologize if I have seemed imposing, which is certainly not my intent. Now is as good a time as any to inform you all that I am autistic, and as such have difficulties communicating and “behaving normally”. I’m working on it. :slight_smile: Please send me a message and say hi if you’d like to introduce yourself.

I’ll shut up now and get back to the actual work at hand. :wink:

edit: Original post updated to include current status.

5 Likes

no apologies needed! if was just the rate of introducing new ops that seemed alarming :slight_smile: and i hope i didn’t come across as simply rejecting all your suggestions - there are several ops that i’d love to see, and for the rest i tried to understand the use case behind it - teletype is flexible enough to allow for many different styles, it’s always educating to see a different approach (i never thought of using all of the scenes for one composition - would love to see that if you have examples posted anywhere!).

teletype is quite possibly the most unique module in its approach, and i would love to see more people with no coding background try it. that’s really my main worry about making it into something that people might consider too difficult to use.

Btw, I had a quick look at the pull requests on Github and the ones for new operators (or rather their changes tab) are a good documentation for “how to make an operator”.

3 Likes

It seems that we have different ways of handling pattern recognition. So let me explain this again:

For me 1 + 2 x 7 looks as normal as 1 ADD 2 MUL 7 does. It is just swapping the common symbols against two intuitive names for them and I hardly notice any difference between both expressions. There is nothing strange in it for me.

What makes a big difference to me is indeed the prefix notation. This is what is breaking/changing the pattern, not if I use “+”, “ADD” or “plus” in the usual places.

Using an operator like ADD or MUL now generates a coding framework and leads my perception into this direction. When I now read X ADD Y Z I immediately know this means X shall be the sum of Y and Z.

Notating the very same thing with symbols as in X + Y Z does not generate this perceptual framework. At first it looks like a browser generated password suggestion to me, then I have to abstain from automatically adding X and Y.

Regarding the modulo function - I know what it does and I use it regularly. What I meant is that all the above is getting more difficult for me when symbols are used which already have a common meaning. % A 4 does not only look like a random string to me it also has nothing to do with percentage calculation. It’s the same with “==” btw…

On the other side, of course I often bump against the end of a line and would wish for more space or an additional line. And I can see that condensing the command set/syntax opens up more opportunities (I am very happy that we got rid of the empty space before a colon for example) - I am just advocating to do this cautiously to keep it accessible for everyone.

CHAOS made me realise how subjective individual needs can be. Is it supposed to take the formula as user input? If not, is it just a more repetitive RAND? (“TM” anyone?)
Im totally aware this was just an arbitrary example for reference. But to me personally, the MZ proposal (still think RZ could be a good alternative) would be much more useful in the command set. Which leads me to the question:

How can we determine what the community wants? Should we make polls for each proposal (with tehn as last instance)? Or is that too easy and prone to distortion and people should write down their opinions? Still I think there could be a silent majority that just trusts tehn and has no interest in crawling through threads like this. Not an easy undertaking (sam probably knows that best so far).

However, this discussion made me realise how excited I am about TT, and thankful to tehn for bringing it into our lives!

So how could we make it more attractive to new users? Making it multi modal? Say plug in usb midi -> configurable midi/cv (with one cv in/knob). Or an oscilloscope mode? Monome/Arc apps? Games? Of course I don’t want to bloat the firmware, but it could be a cool (and fun) way of gaining some attention, as separate firmware. A bit off topic sorry.

Just thinking out loud here.

1 Like

Some random thoughts here.

We have LIVE, EDIT and TRACKER modes already (I’ll ignore SCENE modes for simplicity).

How about a SCRIPT (or EXTENSION) mode, which is really just one long, scrollable page (up to the limits of the module) that can be used to write callable functions?

e.g. (Imagine something like this all on one mode/page)

FUNCTION MYRANDOM
RETURN RRAND 1 12
END FUNCTION

FUNCTION WHATEVER
DO SOMETHING INTERESTING
END FUNCTION

etc.

I can then call MYRANDOM and WHATEVER from other scripts.

This would be the one and only place that scrips could be longer than a screenful and scrollable.

People could write / share extension scripts as they decide they want to in order to extend the language, introduce aliases, etc. Or just completely ignore the whole thing to keep it simple.

I’ve only had one coffee, so this may be a bad idea, but on first blush it feels there’s something useful here.

1 Like

The problem here would re-usability between scenes. You would have to retype everything every time, basically.

As it is, individual scripts already kind of work like functions with no parameters, if I’m not mistaken.

1 Like

I’m imaging just one extra special script per scene, that is saved with the scene, that supports scrolling and some form of function syntax.

Alternatively it could be a “global script” or even “global scene” that other scripts could share.

why not just make the script edit mode so that the pages can scroll? Wouldn’t that serve the same purpose but keep the UI complexity lower?