First time here? Check out the FAQ!
x

How do I create a 2 dimensional array of controls?

0 votes
1,140 views

I'm using this code to create a 2 dimensional grid of VCS controls:


(!Column of: (
    !Row of: (
    1 to: 4 collect: [:j |
        1 to: 4 collect: [:i |
            !Note suffix: (i printString, '_', j printString)
        ]
    ])
)) nn

 

If I put this code in a text file and compile it (ctrl-Y) I get:

 (!Column of: (!Row of: #( #( !Note1_1 !Note2_1 !Note3_1 !Note4_1 ) #( !Note1_2 !Note2_2 !Note3_2 !Note4_2 ) #( !Note1_3 !Note2_3 !Note3_3 !Note4_3 ) #( !Note1_4 !Note2_4 !Note3_4 !Note4_4 ) ))) nn

 

Which looks OK... I think. But when I put the code in the Frequency parameter of an Oscillator Sound, I get

"The message suffix: is being sent to something other than an EventVariable..."

If I follow the advice of the error message and put curly brackets around the code that makes the array then I get an error that 'j' is an undeclared variable.

asked Oct 19, 2017 in Capytalk & Smalltalk by alan-jackson (Virtuoso) (15,840 points)

2 Answers

+1 vote
 
Best answer

First of all suffix: only works in curly braces, use 'aString' asHotValue instead. Also the message of: can't return an array. You need to collect !Row of: anArray, like this:

(!Column of: (

1 to: 4 collect: [ :j |

!Row of: (

1 to: 4 collect: [ :i |

('Note'&i&'_'&j) asHotValue

])

])) nn

Sorry about the formatting, seems like tabs are not recognized... 

Hope that helps :)

 

 

answered Oct 20, 2017 by kymaguy (Virtuoso) (10,580 points)
selected Oct 20, 2017 by alan-jackson
That helps enormously! That works great... it also raises more questions for me.

I'm used to using {}'s, curly braces, in arrays to group the elements of an expression together so it's a single array item. But I realise I don't really know what {}'s mean. I've read all the bits for {}'s in the Kyma X book and still don't get it. Why does suffix: only work inside {}'s?

Also why can't of: return an array?

of: is capytalk isn't it and collect: is smalltalk? So I was surprised that you could put "!Row of:..." inside the collect: statement. I'm finding it hard to understand the interplay between smalltalk and capytalk.

Would it be fair to say that smalltalk is working like a macro doing a kind of text replacement in the capytalk? Except smalltalk is a full language not just a text processing macro language... nope, I'm not there yet.
Smalltalk is executed once at compile-time and the CapyTalk is continuously evaluated while the Sound is playing. You can use Smalltalk to write a CapyTalk expression. When you Play a Sound, the Smalltalk in the parameter field is executed, resulting (in this case) in a CapyTalk expression. Once the Sound is downloaded and running, that CapyTalk expression is evaluated whenever the receiver or one of its arguments changes (or in the case of some of the generator expressions, periodically once per millisecond).
That's great. I understand the different times of execution. I am used to using a mix of two languages in HTML templates but they usually look very different. Smalltalk and CapyTalk look the same which is maybe why I find it harder to understand where the boundaries of each language is and what's going on.

Here is a properly formatted version for anyone following this thread:

(!Column of: (

  1 to: 4 collect: [ :j |

    !Row of: (

      1 to: 4 collect: [ :i |

        !Note suffix: (i printString, '_', j printString)

        ])

    ]

)) nn

It is not necessary to use asHotValue here; suffix: works just fine.

That's brilliant thanks. Is there an advantage to using printString or '&'?
I don't think so...
One thing I want to add here is that I like to think of smalltalk as a constructor to build capytalk expressions (which is also happening here).
0 votes

This is really a question but I wanted to post up an image so I've made it as a answer.

In the formatted code snippet that SSC posted I've added colours to try and understand what is SmallTalk and what is CapyTalk. I've made CapyTalk blue and the SmallTalk on a white background. Have I got it right?

 

Am I right in thinking anything with []'s is SmallTalk?

What exactly does it mean to SmallTalk when it encounters CapyTalk? Does it mean "print this string into the final CapyTalk statement for execution at run time?". How does SmallTalk recognise a CapyTalk boundary when it gets to the use of the variable "i" in the "!Note suffix: (" expression?

answered Oct 23, 2017 by alan-jackson (Virtuoso) (15,840 points)
suffix: is also Smalltalk (suffix: is applied at compile time, not while the Sound is playing).
It can be interesting to select all and evaluate the Smalltalk using Ctrl+Y. That will evaluate the Smalltalk and print out the resulting Capytalk expression.
Ahhh, yes of course! I can suddenly see why Ctrl+Y is so useful. Thanks
...