Creating a NGUI

For want of a better term, I’m working on a piece of code/composition that has grown to the point of complexity where it’s hard to manage all the variables interspersed within the code, leading to my desire to create a ¨non-graphical user interface¨, to make working with the code easier. By NGUI I mean an interface made from code that does not require knobs, sliders, buttons, or other forms of interaction derived from traditional synths and other forms of hardware. The desire to not create a GUI is not just laziness, I’m finding a charm to working in code, and seeing my thinking represented in it, and I don’t intend for this particular code to be used by others, so it only has to be intelligible to me.

My first question is: is this an existing field of thought? While I know there are ways for arranging code in general, in the specific field of ¨creative coding¨ and, more specifically, music composition and instrument design, does something exist?

The second question is: are there any working principles that people on this forum have developed in their own practice?

My plan currently is to create a section at the top of the code where I can turn all the important variables into global variables and use comments to arrange and clarify their use. I have some trepidation about this however, as by making lots of global variables that do not currently exist, I’m worried I might muddy the code that’s already there, and sacrifice the clarity of its workings for the clarity of interaction.

I’m curious to know how other people deal with this problem: keeping one’s code intelligible and interactive as a project grows in complexity. I have an uncle who is a very good journalist, and I remember him saying to me good writing is just clear thinking, my guess is the same applies to code.

It depends on the form of interaction you want your user to have.

So it could be something as simple as declaring environmental variables like:

(
//make some synths
~MakeAwesomeSynth = {|awesomeness(10000000)| Synth(\mas, [\awesomeness, awesomeness])};
)

~makeAwesomeSynth.(inf); //infinitely awesome synth

Or you could put instructions about ways you want someone who isn’t familiar with SC to use you code. I often try to write code that only need be evaluated once if I know the user isn’t familiar with SC (about 98% of the time).

Or you can just make a GUI with a text field and then just have SC evaluate those functions. Or you could define custom classes (or functions, which I do frequently as a planning stage for times I might make a class or method from my function later).

It really just depends on the context, but it’s a great launchpad for discussion.

I like making GUI. I avoided it and then I felt it was a weakness and now I use it for animations and making games. I understand the draw of code though. Including a readme is another useful practice. I think that sometimes people can get overwhelmed with text because there are so many things that can go wrong. Typos happen ALL the time. If you forget a parenthesis it can break your program. Just different considerations/food for thought. Sometimes it may be just better to ask of the user that they have some basic knowledge of SC to use your code so you’re not reinventing the wheel.

So questions of audience/user, context, functionality/scope, are probably prerequisite before implementation.

Hope this helps and sorry for the non-answer,
Josiah

Hi Josiah,

Thanks for the reply. Very interesting. A Readme is a good idea. Even as a letter to a future self that won’t remember all the nuanced thoughts that went into the development.

In my own case I’m not writing the code for an audience, which in some respects is liberating, as there’s not a need for it to be intelligible for others. But I suppose the danger is for it to become excessively idiosyncratic.

I think if I was writing for an audience I would be far more likely to go for a GUI, and to arrange the program in a context that is concordant with tradition, so it’s more intuitive to use.

Thanks for sharing your thoughts.

I think what you’re getting at here is how to write readable code, and create some form of library - which itself invites a set of actions.

Readable code is quite hard to define, but generally: don’t use acronyms, have minimal indentation, short lines, and having a simple syntax - often passing functions can help with a lot of this.

Having the code invite a set of actions is very hard. It’s heavily tied into the tooling the language has. I. Supercollider we only have classes. I would recommend you build classes that way the ide can auto-complete many methods for you or you can use the documentation as normal to learn how the code might be used. Building good libraries is VERY hard.

I take a little exception to this. The problem is that thought takes place in language, as I’m writing this post I am thinking in English. However when I write code, I do not think in code, I think in English. Supercollider, in particular, is multiparadimatic (read has many dialects). So even if I was to be to translate my thought directly to code, it isn’t guaranteed the reader (or even myself when I learn more) will be able to understand it.

Ultimately I think you’ve just described a million (or perhaps billion) :pound: question… How do you write something complex simply. I’d recommend this video on the subject ( Complecting Made Easy - Tony Van Eerd [CppNow 2021] - YouTube ) which says that reaching for the easy option leads to the messy complex code, i.e., easy + time = complex.
One good design principle to follow is ‘correct by design’, meaning you should try to write code that can’t be used incorrectly, however supercollider (and other small talks) make this quite difficult.
Another current trend is functional programming, this involves having immutable variables, and pure functions. I personally like this approach when applied sensibly (not universally) and supercollider oddly supports it reasonably well, dispute being object oriented (and very out of fashion).

Good luck!

Fascinating response Jordan.

I would recommend you build classes that way the ide can auto-complete many methods for you or you can use the documentation as normal to learn how the code might be used. Building good libraries is VERY hard.

This is good advice, but also intimidating. I suppose one important aspect to all of this is to read other people’s code? The temptation is to write code, because watching your ideas take form is fun, but I realise I have learned a lot when looking at clean, concise, and thoughtful code. A library seems a bit further down the road of my development.

I take a little exception to this. The problem is that thought takes place in language, as I’m writing this post I am thinking in English. However when I write code, I do not think in code, I think in English.

This is a valid criticism. And not only English, but logic, maths, physics, algorithms. I find the latter thinking music easier, and the coding part feels a bit like getting my hands dirty. It’s not yet reached a point where there is much of an alignment between the ´human thinking´ and the ´machine thinking´.

I’m going to watch the video you shared, thanks for sending it on. ‘Correct by design’ is a nice concept to hold onto.

I’m still slightly holding onto my original question though. If for instance one has a program with 300 lines of code, what would the definition of ´readable code´ be? For instance, if there is one variable at line 50 that’s important, and another at line 250, that strikes me as impractical, but perhaps not unreadable.

I think the reason this interests me is coming from a instrumental background ergonomics is drilled into me. Move 5cm too much in any given movement during a long practice session and you waste a huge amount of energy. Similarly if one variable is at line 50 and another at line 250 that is poor ergonomics - you literally use more physical and mental energy when using the program. Instead the most ergonomic thing - all things being equal - would be to have them at line 1 and line 2. Unless of course you want to build a whole GUI. But I want to avoid that, and I don’t think it’s SC strong point either.

Thanks for the input Jordan! As ever, very interesting.