Some observations

I can agree with some of the general criticism, e.g., debugging in SC can be hard.
Often it’s hard to debug SynthDefs that pass compilation. In the language, I think, it comes from the absence of a step-debugger.

Non-strict typing makes the workflow smooth, I disagree that this is a main reason for trouble. Also, typically, in SC you’d rather write many short instead of fewer lengthy Functions where strict typing might give more advantage. I think that the wish to use return (which, by the way, you can do with the block construct) also appears when you mainly have lengthy Functions.
I remember that when starting with SC, I was often writing lengthy Functions, a habit which I dropped meanwhile.

However, the specific examples you mention can very well be done with SC. It’s just that it needs approaches that you might not be used to.

Not true, I do something like this quite frequently:

b = [... paths ...].collect { |p| Buffer.read(s, p) }

SynthDef(\xy, { |bufOffset, bufIndex ... | ...

Synth(\xy, [\bufOffset, b[0].bufnum ...]) 

synths using language structures are an exceptional case anyway. If you could name a concrete application maybe an alternative approach could be found.

Besides it often helps to regard the Task Function instead of the Task itself, because Functions are re-usable.

I’d say (though not all might agree), Patterns are the more idiomatic way to do sequencing in SC and that might be the reason that there’s less documentation about Tasks and Routines.

You definitely can do logical operations server-side, e.g. with the if UGen or Select, also with combinations of ‘*’ and ‘+’ and bitwise operations. However, it’s often not the best way.

A few possibly scattered comments:

  1. It’s completely fair to prefer strictly typed languages. What is not fair is to suggest that those who are working in (or who have created or are maintaining) duck typed languages are only cutting corners in language design.

  2. “I think that a compiler/interpreter should force you to be as explicit as possible” – that’s fine – but e.g. the field of live coding suggests that programming may have purposes and contexts that are very different from those of enterprise programming. In live coding, flexibility and immediacy are higher priorities than stability and future maintainability. If your position is that any/every compiler should enforce stability and maintenance, this implies that these are the only valid priorities in programming and that live coding is an invalid practice. That would be… an exceptionally bold statement.

  3. You can, today, start using the SC audio engine with a compile-time type-checked language (using libraries, created by members of this community, for existing languages) – so it may be more productive to look into those libraries (e.g. ScalaCollider) than to spend time telling users of this language that we are doing it wrong :laughing: One thing to note here is that SuperCollider isn’t “a language” – it’s language + audio engine + editor, and you can use the pieces of it as you see fit. If you’re interested in the audio engine but don’t like the language – that’s perfectly fine, as there are other languages that interface with the audio engine. Nobody will take offense if you use one of those.

hjh

1 Like

I wonder how well this applies to various sclang users… My own experience, using the language mostly for artistic exploration, is more like 20% trying to make something specific / 80% let’s see what happens – for that 80%, the line between bug and feature is pretty hard to make out.

Developing full applications I’ve felt a lot of pain points that come up on forum/mailing list – static class library, lack of namespaces, opaque debugging – on the other hand sclang’s solid implementation of midi, osc, and timing/clocks in general has probably saved me more days of debugging than I’ve lost to dealing with the language quirks. A little unrelated, but another time consideration – commercial live performance software has crashed far more often than SC for me during live performance, I can’t remember a SC related crash in the past few years.

It took me a while to realize that Functions (i.e. { whatever } ) behave like functions in a functional language, which is to say philosophically allergic to return statements, but class methods have an explicit return value which allows multiple points of exit, just like return statements in C etc. If I want to use return statements in a Function, I take it as an indicator that it could be time to write a class. (There’s a whole lot of I think smalltalk-y weirdnesses about writing classes that I also find annoying, btw…)

Anyway, I have come to find pleasure and grounding in sclang’s idiosyncrasies in a way that’s difficult to explain or justify. I am inspired by the developers’ care and attention to the needs of the community. I value conversations like this about how to improve the language, and I am really intrigued by this dialectic of SC as practical artistic tool and sclang as ideal programming language.

Late night thoughts…

Looking at the replies I got on my previous post I think I should have said that I’m new to SC ( only a few weeks) and that I really like the system. It is just not what I expected. As a synthesizer aficionado I expected to be able to program a SynthDef with all the logic that comes with a hardware synth (like switching waveforms, filtertypes, etc). You can do this in SC, just not in a SynthDef. The Server is clearly focussed on streaming data. That’s ok, I just had to find out.
In respect to strict typing: I do believe that a strict language makes for better code and less time spent on debugging. But, like some of the responders noted, the programs people write in SC are probably only tens of lines of code long, not hundreds of thousands, as you find in professional software, so it really doesn’t matter that much.
What I do object to is the fact that the Interpreter allows multiple, slightly different, ways to express the same thing. You can either say “squared(8)” or “8.square”, for instance. “\freq: 440” or “freq, 400”, “arg counter” or “|counter|” (which saves you only one keystroke). This is just confusing, it doesn’t add anything useful. In fact, it is easier to learn that “square” is a method/message of a number and that named arguments should be of the form “\freq:”

This is probably the result of the evolutionary development of the Interpreter, but it also gives the impression that the developers want to show how clever they are by making the Interpreter too flexible for its own good. Really clever developers choose the best way to express something and stick with it. It makes the Interpreter less complex and the language easier to learn.

Well, they are still sensible thoughts. I agree with all of them. I’m new to SC and my instinct is to compare it with the tools I am used to. SC is a marvelous environment for creating music and I realize it isn’t useful or fair to compare it to professional generic software development tools.
But my impression is that the language is overcomplicated and trying to be too smart. That’s unnecessary imho. A simpler language would mean a simpler Interpreter/Compiler and would be easier to learn. Like the Germans say: “In die Beschrenkung zeigt zich erst der Meister”

You have to calm down. I’m not saying you are wrong. I’m just saying that a language that gives you too much liberty in the way you write your code, will give you a hard time debugging that code. If you’re ok with that, be my guest. But the Interpreter/Compiler is more complex than it needs to be because the rules are more vague than they need to be, which makes it harder to learn SC. There is simply no reason to allow both “\freq:440” and “freq, 440”. I understand that the first has to do with named arguments, and the second with a collection of [argument, value] pairs. The problem is that SC tries to hide (for no reason) this difference. To save some keystrokes? The SC language is simply trying to be too smart for its own good.

just 3 weeks experience here,

:slight_smile:

May I…?

“Without expectations there are no disappointments”

regarding multiple ways of doing a “thing” and debugging etc. Pick your road, high or low, and stick to it.

If you like ‘returns’, ‘var return = theresultofthethingivebeendoingafewlinesabovethis’ as the last line in your functions.

In general, ‘excuse the wording’, every language sux. None of them work the way I think they should.

I’m not a programmer. My main experience is an other DSL, POV-Ray SDL. There you have render time functions. I still don’t get that completely, despite maintaining the documentation for a small decade.

Have fun,

Cheers.

1 Like

After a few discussions I’d like to take back my statement about lazy SC developers. They aren’t lazy but seem to be eager to create the most versatile and user friendly SC language as possible. I just think they focus on the wrong thing. User friendliness can be achieved by allowing the user to express their wishes in a lot of different ways. This requires a very sophisticated Compiler.

Another way is to define a set of clear rules that enable users to do what they ultimately want to do: create music.

The problem with SC is that it tries to be the ultimate programming language, and not the ultimate music programming language. SC developers may be proud of the fact that you can use both \freq:440 and freq, 440 as a parameter, but musicians don’t care. They are just confused.

There is no reason for a music oriented system to have all kinds of esoteric object oriented niceties and a hyper flexible compiler. It only makes SC hard to use.

I’ve actually been in the position of criticizing a programming environment, rather recently… bear with me, I have a point to this :wink:

A few months ago, it occurred to me what is the big problem with graphical patching systems (Max, Pure Data). Suppose you need an iterator over a list. In Pd, list iteration isn’t exactly hard, as long as the result is going to one place in the patch: a subpatch or abstraction encapsulates the behavior and the outlet is connected to the place where you want it to go. But… what if you need the output to go to different places at different times, as in a state machine? In SC, you simply create a stream (CollStream(list) or Pseq(list, 1).asStream). Anywhere in the code can call next on the stream, and the result comes back to the caller: easy. In Pd, the result goes to one predetermined location (via patch cable). To work around it, you could either use [send] / [receive] pairs with the send target set at runtime (exposing the guts of something that is basic in text languages) or make the list and index storage global (breaking encapsulation).

So I went onto the Pd forum and started laying out the case: that there are some computational problems that are clumsy to address in patchers because of the lack of function call/return, and that this discourages users of patchers from taking on creative projects that would benefit from that, and that this limits what is conceivable in these environments (to such an extent that both Max and Pd eventually just gave up and added scripting objects).

The outcome of the discussion was basically twofold: 1. I should restructure the computation so that I don’t need call/return; 2. Because I’m “fixated” on call/return, I may be missing other strengths of patchers.

Well, I’m still convinced that no call/return is a serious limitation – but one thing I learned from that discussion is that the user base of a programming environment is a living culture that is unlikely to change radically based on one person’s input. In that sense, both of those outcomes were right about one thing: “it is what it is,” both good and bad.

Which leads to the question for this thread: What is the outcome that you would hope to get from this discussion? In my Pd thread, I had hoped they would think about it and perhaps open a feature request for Pd to implement a call/return mechanism that’s idiomatic to patchers. This didn’t happen (and tbh I didn’t really expect it to). Or, even more basically, I hoped they would admit that I was right and that the software they love is flawed. This didn’t happen either (huh, I wonder why :thinking: ).

I’d just suggest again that live coding is a different beast. When you’re onstage, with a few dozen/hundred people potentially getting bored because the music isn’t changing fast enough, you do actually want the system to do something sensible with a wide range of input. For this specific example, the baseline syntax for a synth argument list is an array, [\name, value, \name2, value2]. But the syntax for a UGen argument list using keywords, or for an event, is (name: value, name2: value2). When live coding under time pressure, you don’t want to have to think about which is allowed in which context.

Or, more fundamentally: there is no way to disallow [\name, value] (it’s just an array), and method call argument lists can’t follow array syntax (because you couldn’t disambiguate symbols as values vs symbols as argument keywords). I think it’s a stretch to say that there is no reason for the language to be forgiving in this case.

Edit: On second thought, there’s a very interesting conversation to be had about the places in SC where an “argument list” appears, and the different syntaxes for these. It is indeed a rough edge. Part of the static is that Synth and Group are probably too low-level as abstractions – probably we should wrap up the concept of Synth, Event and Pbind arguments into a higher-level abstraction that gets translated differently where needed. But… another day, I’ve got other work for the afternoon.

hjh

These arguments make no sense. You’ve complained about SCLang having too many ways to do the same thing: C++ has many ways to do the same thing. For-loop syntax being an obvious example. “typedef” vs “using”; “function pointers”, “functors”, “lambdas”, etc. Python “used only in academic environments” couldn’t be further from the truth either. Nowadays, practically all companies doing something with deep learning (and there are VERY many at the moment) use python. I’ve been using both C++ and python for over 15 years at the company I work in.

Having said that, I fully agree that SCLang has some rough edges. For me some pain points include:

  • hard to interpret backtraces without file/line number information
  • order of mathematical operations (although I understand why it works the way it works)
  • difference in syntax (e.g. for returning a value) between methods and functions
  • it has a steep learning curve, because although at first sight it looks a bit like a C-style language, it’s actually a bit of a different beast.

Over time, I’ve come to realize that SCLang is actually much more powerful than I originally imagined and as I learn more I keep being amazed at what it is capable of in only a few lines of code. To say that SCLang tries to be “general purpose” and “is not specialized for music production” may also just indicate you haven’t fully understood the power of the language and the abstractions it offers yet.

1 Like

In a way several aspects feel like blend of macro’s (Token substitution, macro substitution) as seen in other languages and ‘real’ functions.

I did try to learn SC last year and I’m now starting with C++. SC gives me the feeling that I’ve to know a lot myself. The names of certain messages to get things done. I don’t have the feeling that I easily can use logic to accomplish things. It’s not easy to see the logic for me at least. I guess I do miss the ‘for-loops’ ‘while’ ‘case’ ways of doing things in C++. Those ways for doing things in C++, makes perfectly sense to me.

All though C++ is not easy to learn, it gives me a feeling that it is robust and logic. That it has strict rules. It gives me a feeling of confidence and trust in it. Following a book of the creator of c++ Stroustrup, he constantly tells the reader that the compiler is picky, for a reason. That otherwise it would becomes messy very soon.

I think you wouldn’t like it though, if you could do things in C++ in only one way, all though multiple ways doesn’t make it easier to use and read. I see how being able to things in different ways for doing the same thing can make you faster or make you code easier to read, but I don’t really see how it can make you more creative. At the end the building blocks are exactly the same and you can build the same creative things with those building blocks.

I realize that this is a (very) bit of a naive view towards both languages, but my ‘feeling’ towards SC is ‘messy, unclear’ and towards C++, ‘very strict, but clear and logic’. I do miss the logic building blocks in SC, from where you can start working, without having to dive into the help files or some example code constantly. Getting a bunch of audio files in a buffer? Grab your example file or go to your favorite Fieldsteel tutorial. I wished I could do this kind of things more easily based on logic basic principles. I assume these principles are there, but the syntax/logic of C++ seems to be much easier for me to grasp.

I hope and I think that programming experience with C++, will help me to see the logic of SC better in the future.

I would say SC is “multiple”, more than “messy”.
As said earlier, each if us has to find his way. And it ain’t easy. Because they are some many possible ways. And alas not a single paved one for beginners. That’s what’s taking the most energy.

Same for me. And that’s the frustrating point.

My feeling is that learning SC is like learning to play violin. Hours, months, years before you get a decent sound.

I am not a dev nor a computer scientist, but the big question I would like to ask to computer music experts is:

Tons of new computer music programming languages have been created over the past decade, specially those focused on livecoding and running on a browser. Are we going to see unification, only the best solutions will survive or the pulverized scenario will remain ?

E.g. would it be possible to have this on SC? Desirable? Feasible? Better just use another language?

My experience is also the same as Eric’s, but I see that as a chance rather than a deficit. I never start a new musical project with a clear vision of the final result. Just the opposite, I appreciate being surprised (by the sounding result, not by the syntax). I think this fundamentally distinguishes an artistic endeavor from a pure engineering, scientific or other “certain purpose” programming project (though, also in science, many findings happen by accident). On the road, there might be some clearly defined building blocks that I’d have to engineer. For this purpose, SC serves my needs extraordinarily well.
That said, I had my struggles with the SC language for quite a while. Coming from Lisp, the frequent mix of different kinds of brackets looked odd to me. That can be overcome, though, with indentation and dropping unnecessary brackets (e.g. do { } instead of do({ })).

Concerning the topic of exploration vs. specific purpose, I have collected some thoughts about that last year:

https://www.researchcatalogue.net/view/921059/922503

1 Like

SC is hard to learn because the syntax is not clear. It is the result of evolutionary development. A language like C++ is very easy to grasp (perhaps with the exception of pointers) because there is only one way to do things. The compiler immediately shows you where you are going wrong. SC is more like Python: it allows you do to anything, but there is no guarantee that you get what you want. It is hard for me to understand that people feel that this is the right way to go.

You are right. I’ll find my way. I just don’t like the way the developers of SC are trying to create the Ultimate Programming Language, while SC is supposed to be a music oriented language. SC is far too complex for its purpose. That makes it harder for musicians to use it.

These abstractions are useless when they don’t have musical implementations. Things like parameter lists and classes are useful in organizing your code, but they do not necessarily have musical meaning. SC should provide abstractions that are enabling users to generate music, not abstractions that just make the language more fancy.

Music is fairly simple: notes, timing and timbres. SC should concentrate on that. You can have all kinds of structures to generate these notes, timings and timbres, but there is no reason to have a general purpose language that makes it hard to create these musical parameters. I’m a c++ developer, for me it is easy to grasp the concepts, but for people who just want to create music, SC is unnecessarily difficult to master.
My suggestion is that the people who develop SC create a library of classes that encapsulate the power of the system and present users with a music oriented interface. Notes, timings and timbres.