SuperCollider 4: First Thoughts

Visions, ideas, concerns.

No vision but maybe of interest: discussions about SC4 go back to 2006 or earlier (there was a lecture by JMC at the SC symposium in Birmingham), search the mailing list archives (though, you’ll find posts mainly about the SC4 logo :slight_smile:)

https://www.listarc.bham.ac.uk/lists/sc-users-2006/msg04538.html

2 Likes

James Harkins offered that allowing custom syntax would be a great leap forward.

Small asks would be to be able to add classes without recompiiling and declare variables anywhere in a function.

1-bit synthesis would be good ( I know this is sort of possible now but…)

write uGens in language, no separate compilation.

I think there’s something to be said for re-rethinking the server/language split but I’m out of my depth there atm

My biggest dream would be a strong type system

4 Likes

Built-in oversampling ?
64 bits floats audio path and resolution for UGen parameters ?

1 Like

I wouldn’t mind a type system as long as the user has the option to ignore it. (I.e. please don’t let SuperCollider become Java).

hjh

2 Likes

Don’t tie it to a language, separate server was brilliant concept.

Otherwise,

  • agree: oversampling
  • in general arbitrary undersampling (variable block size. e.g. in powers of two perhaps).
  • parallel processing abstractions (don’t know if supernova’s pgroups solve this already?)
  • file-append mode for b_write
  • probably having dedicated integer signals could help solving various problems (although of course 64-bit floats “are ok”)

Just out of curiosity, what would be the advantage of a type system in SC?

I’m not a computer scientist, but from my experienced with Rust for example I’ve started dreaming about this. I think that if we had very strong types, a ton of complexity and problems could be avoided at compile/evaluation time for example and programs could be made safer at run time (making it impossible for example to send a string to something that expects an integer). And on that account get rid of nil (The worst mistake of computer science - Lucidchart). But I would probably just use Rust anyway, haha. This is my biggest issue with using SuperCollider for bigger / more advanced projects : Once you reach a certain size of project, errors become extremely hard to track down and I think a lot of this complexity would be removed with a strong type system.

That said, I think I agree with @Sciss that it shouldn’t be tied to a language or maybe any language at all, maybe the future is a pure sc4 server and no language and no IDE to go with it? this would reduce development needs significantly and I think we already see inklings of this future in the current use of SuperCollider - lots of people use it via Norns, TidalCycles, SonicPi etc etc.

Another thing I’m dreaming of for sc4 (and sc3 as well actually) is embeddability. Not sure how to do this in practice apart from an even more open licensing model but it would be really nice to make it super easy to embed anywhere (on the web, in game engines and, more importantly to me, inside of DAW’s like Reaper where it could run with native latency as any plugin). CSound and PureData have achieved this to some extent already I think but there must be some way of creating an easy to use unified API for this, maybe Faust inspired. And maybe even targetting bare metal embedded devices like Teensy’s and Arm chips.

Brian mentioned an idea before leaving the project that I also think was awesome: Making it easy to use arbitrary (C++/C) libraries with SuperColider.

3 Likes

I never thought about this before but maybe we can actually solve oversampling now in a UGen? I think I’m going to experiment with this idea!

I saw in the helpfile for the HouvilainenFilter filter:

https://github.com/esluyter/houvilainenfilter

he says he uses 4x upsampling. I guess that is inside the UGen. I haven’t looked at the source.

Sam

Since we’re daydreaming, I’d personally like to see:

  • Runtime class definition, not so much for workflow reasons as for metaprogramming reasons. I also think that SC as a whole would benefit from there being a more natural “onramp” to new users learning to formalize their ideas as classes. The right implementation (imo) would look at what many of them currently try to do instead (usually difficult to scale/maintain hacks involving dictionary-based “pseudo-objects”) and bridge the gap between that sort of thing and the “standard” process of writing compiled classes.

  • A more modular architecture for sc in general, with a smaller “core”. This would ideally make it easier to create “distributions” of sc for particular use cases, and done right, could also make the distinction between the “core” and “periphery” of sc clearer to new users than it currently is.

  • A move (back?) to a more editor-agnostic paradigm, maybe focusing on maintaining a language server rather than an IDE.

  • Improved package managment. In particular, I’d love to see a simple way to have packages include both class definitions and ugens, with some provision for build scripts, pre/post-install hooks, etc.

Beyond that, I agree that being able to over/undersample parts of a synthesis graph arbitrarily would be very useful, I think the client/server paradigm is correct and valuable, and I agree that stronger typing would be great as long as it’s optional – I’d imagine it working similarly to the way type annotations currently work in Python.

3 Likes

I would (again) just be cautious about a coercive type system. If there is a well-supported “variant” variable type, then users can decide for themselves when/how/to what extent to use compile-time type checking. If not, then users are effectively compelled to buy into strong typing, whether they like it or not. That seems counter to the general SC ethos. (Or, concretely, consider the way that NodeProxy sources can be functions, or patterns, or symbols, or role mapping associations. If strong typing is enforced, then we have to have method overloading (“yay, let’s write source_ five times”) and maybe Java interfaces, and my flesh is crawling just thinking about it.

I tend to think, rather than redoing work that other languages do well, it may be a more effective use of developer resources to write really good server etc abstractions in another language.

Also, realistically I don’t see us fixing the last few remaining really nasty interpreter bugs.

It would hurt if I had to reimplement my toys in another language, but we’re not language design specialists.

A more modular architecture for sc in general, with a smaller “core”.

Pure Data may be taken as a cautionary tale here, where the core is way too minimal. The Pd community has a curious ambivalence: otoh proud of the way that externals solve the limitations of minimal core, but also skeptical of reliance on externals.

hjh

If we are there to talk about our dreams concerning a future version of SC:

  • IDE improvement: better completion, Vim mode?
  • Shorter / more elegant syntax for the pattern system (I’ve tried to create my own methods but it ended up being a huge time sink). Inspiration taken from the wonderful live-coding interfaces that pigyback on SC.
  • Compiling classes without having to reload the Class library or restart anything.
  • Optional typing: type hints (Python tried something like this, I personnally think that it’s really fine and convenient without pushing people to use it if they don’t want to).
  • Opening the documentation to contributors! I am not currently aware if there is a way to contribute to the refinement of SC docs and there is currently no translation system.

The docs are part of the source on GitHub
https://github.com/supercollider/supercollider/tree/develop/HelpSource

All are welcome and encouraged to contribute
https://github.com/supercollider/supercollider/wiki

Cheers,
eddi
https://alln4tural.bandcamp.com

Class namespaces would be really really great. I get into such trouble designing medium-large programs trying to keep my class names sensible while also avoiding conflicts with the core library, sc3-plugins, and any quarks I might ever possibly want to install. I always wind up in prefix-gobbledygook land.

+1 for over/undersampling, 64 bit dsp, runtime class compilation, writing UGen dsp within the language, probably in that order.

Also, maybe this is a separate and less important topic, but I think there could be better structures in place for multi-level OSC handling. I recently made some trivial touchOSC button interface and wound up writing this monstrosity:

~cues = [
  [{..}, {..}, {..}, {..}, {..}, {..}, {..}, {..}],
  [{..}, {..}, {..}, {..}, {..}, {..}, {..}, {..}],
  [{..}, {..}, {..}, {..}, {..}],
  [{..}, {..}],
  [{..}, {..}, {..}, {..}, {..}, {..}, {..}, {..}],
  [{..}, {..}, {..}, {..}, {..}, {..}, {..}, {..}]
];
~cues.do { |list, i|
  list.do { |cue, j|
    OSCdef(("multipush" ++ i ++ j).asSymbol, { |msg|
      if (msg[1] == 1.0) {
        cue.value.postln;
      };
    }, "/1/multipush1/" +/+ (i+1) +/+ (j+1));
  };
};

where each entry in the ~cues array was a separate function to execute if that button was pushed…just to handle incoming messages in the form of “/1/multipush1/x/y”. I was pleased to have come up with that solution as opposed to writing each OSCdef by hand, but I also feel that this situation is probably common and shouldn’t warrant a headscratching solution. I would be happy to help work on a better interface, don’t feel well enough versed in OSC to spearhead one.

Yes I said it did, but actually I just noticed that it was only partially complete because of an errant return statement (input was upsampled, decimation was extremely naive). Should be fixed now, main difference I notice is better consistency with high resonance and high cutoff, especially on 24db LP filter. Slightly higher CPU usage as well. Upsampling/decimation (not written by me) happens here: houvilainenfilter/FilterHandler.h at master · esluyter/houvilainenfilter · GitHub I think this is what makes this filter so CPU costly. (from looking at the code it seems somewhere along the way Patrick Kunz decided hermite interpolation was inferior to basic linear interpolation, so that’s what it currently does. I have not done any sort of independent testing. The original csound opcode does some sort of 2x upsampling, but I haven’t really looked into it. – actually this is partly why it would be so helpful to have oversampling as part of the core project, wouldn’t have to worry so much about implementation on a piece by piece basis.)

1 Like

On my wishlisht:

  • readable stack traces including relevant line numbers
  • interactive debugging/stepping (at the very least through language side code)
  • assuming that SC4 can break backward compatibility: although I’m aware of how math operations work in sclang, I occasionally still fight with order of mathematical operations from time to time… so getting some sane defaults in that department would still be welcome
  • i would also enjoy some built-in support for using traditional note names (actually the Panola quark already does most of what I need, but maybe I should have chosen a subset of lilypond syntax instead so that the same spec can also be used for score generation - so maybe just having a quark is good enough. For sure I do not naturally think in midi note numbers.)
  • if a new architecture could prevent nasty hangup problems like FileDialog hangup in KDE · Issue #3807 · supercollider/supercollider · GitHub (i have it on every laptop I own - very weird that no one else seems to suffer from it) that 'd be great
  • support for jack-midi would be great too

I’m always telling people, outside of SC, to always use parentheses, always, so the intention is clear. Often, people fool themselves with suggestive formatting, or make wrong assumptions about the interpreter/compiler at hand’s precedence rules. This can be avoided, and universal peace achieved, with consistent use of parens …

Hence, I’m not troubled at all by sclang’s pure left-to-right processing, and wonder why this comes up every now and then. Perhaps I’m missing something. Can you give some examples where this has hurt or bothered you?

Cheers!
eddi
https://alln4tural.bandcamp.com

Sure. In my day job I need a bit of mathematics, and I program C++ and python all the time, and if you write something like a+b*c in maths, C++ or python it behaves like (a+(b*c)). Given this background, it is very easy, out of pure habit, to slip in an “a+b*c” in a supercollider program (which then behaves like ((a+b)*c) ). Given that such formulas tend to be used in inner loops or as part of a larger calculation, it can take quite some time to find out why an algorithm doesn’t work the way it’s supposed to work. Of course by now I’m aware of the pitfall and have less trouble with it, but during the first years of me trying to learn sc, I’ve cursed at the math conventions more than once. I now also try to use parentheses everywhere, but it adds a lot of visual noise to a program. Given that many people come from other programming languages this is an “unnecessary” problem we all bump into and it’s not at all trivial to guess what is wrong unless you already know how it works. Just my interpretation of the situation obviously :slight_smile:

1 Like

I think you have a very narrow idea on strongly typed languages (I think we’re talking about static typing here, SC is already strongly typed). Java would certainly be not in a category of a fancy static type system, and overloading is only one form in nominally typed systems. In more functional languages, you’d go for type classes or structural types if the language permits it (I guess like Haskell).

The reason I personally went from sclang to Scala was that static type systems allow you to build larger systems, creating and debugging them in dynamically typed languages (plus a rather non-existent IDE when it comes to development) is very wasteful and frustrating. Development also means not to write code once, but to be able to refactor it over time, which is definitely problematic with dynamically typed languages.

Static typing doesn’t have to get into your way. You can perfectly create systems in Scala, Haskell, etc. that don’t feel much different for a user than a dynamically typed language. I haven’t used Tidal, but from the look it, people would probably not suspect that it’s based on a statically typed language.

There was a bit of fad about gradual typing a few years ago, but I haven’t seen it going really anywhere. In the end, that’s why I think allowing different clients is the way to go, as the preferences for language are really very personal, and you won’t find the one language that everybody identifies with.