Structs (data structures)

SC has no structs? If so, why not?

SC has hash tables (dictionaries).

hjh

1 Like

Classes are also basically structs, if you want fixed field names.

SomeStruct {
   var <>name, 
       <>age, 
       <>location;
}
2 Likes

I’m now curious about GADTs. Maybe deal with variants that are data-dependent, using a dictionary to map keys to behaviors or data structures? Just a thought experiment…))

When does one use dictionaries and when events? Or is there some rule, like the higher in hierarchy (from Object class downwards) the more stable?

So one can also define classes as datastructures in classes?

For what you want to do, you should use an Event of Symbols to things…

(
   \foo: 1,
   \bar: {|self, car| self[\foo] + car }  
)

Dictionary is a more generic structure that uses equality rather than identity. TLDR, its slower but more flexible.

A little warning about this pattern, which is called object prototyping by the way and there are help files on it…

You can access the fields like this

var objA = ( \foo: 1 );
objA.foo.postln; // prints 1!

Function, when accessed in this way, pass the event as the first argument.

var objA = (
   \foo: 1,
   \bar: {|self, car| self[\foo] + car }  
);

objA.bar(2); // returns 3

However, because of Object bloat, things like

var objA = (\numChannels: 4);
objA.numChannels; 

Will not work, you need to ensure all the field names are not names in the Object class. One easy way to do this is to change the name from numChannels, to num_channels, as sc doesn’t use snake case.

A little opinion about design…
Rather than making a constructor or ‘init’ method, it is often easier to create a factory function for the type of thing you wish to make, this way, you always get your objects in a valid state.

~mkMyObj = {|whatever_you_want|
   var obj = (); //create it
   obj.foo = 1;  // initialise it.
   obj;          // return it
}
5 Likes

structs are much more low level/efficient. As someone says below, classes are basically structs

The trade-off is expansion of the method lookup table (the size of which is every distinct method name * every class name * 2).

So I think it depends on context. If you just want to associate data with names and it isn’t a structure that you’re going to use often, adding permanent weight to the class library may not be ideal. If it’s a structure that you need all the time, and especially if there are frequently-used operations belonging to it, then a class makes more sense. Point and Rect are good examples of the latter.

IdentityDictionary lookup is extremely fast – slower than an object instance’s getter method, but well efficient enough for most cases.

hjh

Good to remember that Algebraic data types can have strict fields (call-by-value evaluation) or lazy fields (call-by-need). It varies according to the language, and some languages encourage one over the other.

May not seem, but that’s important.