RUN IN TURBO MODE for the fastest experience. It has long been the case that Scratch lacks an in-built ability for functions to 'report,' or, in typical programming terms, 'return,' values. Custom blocks can only be executed as mere subroutines, and there is no way to convert custom block calls - which are Stack blocks - to Reporter blocks, and even then, the overarching absence of returnable data would invalidate the purpose of doing that. That is still not possible through this project. However, I have developed a small library of functions (which support recursion) that add values to a 'return' list, from where they can then be utilized for whatever purpose. Read below for technicalities. There is not much to really do in this project, but feel free to look inside and deconstruct the contents to your heart's content. I made a chintzy GUI that you can use if you so please, but it's pretty pointless. I'd honestly recommend just looking inside and running the custom blocks yourself. There are not many functions, although I do intend to create more; for the time being, why not enjoy access to substrings, string counting, and splitting strings into arrays? == Functions available so far == [Process Number] : [Description] 1: get a substring from a to b of a string. E.g. substring(1, 3, "the world") will give "th", as index #3 is not included. Returns: string 2: count the occurrences of a substring within a larger string, e.g. countOf("abab", "a") is 2. Returns: integer number 3: splits a string at characters corresponding to a given delimiter-character, e.g. split("the world", " ") gives two list elements, "the", and "world"; it also returns the number of elements that were just returned, so that the user can determine how many elements were in the returned array. Final output: [0]: the [1]: world [2]: 2 Returns: list elements<string>, integer number
The return list is a local variable that called functions 'return' values to. Because lists are not a first-class data type in Scratch, returning lists into said list is impossible, but I have considered an alternative mechanism: adding each value of the list to be returned into the return list successively before returning the list's length, which then provides enough information to reconstruct the original list that the function intended to return. As for the way functions are called, it's simple: they consist of independent custom blocks with adjustable arguments. There important mechanism is that a clone is generated whenever a function needs to be executed; this clone inherits the parent's properties, including a 'process number'. Depending on the process number, the newly-spawned clone will execute one of various subroutines, returning its values into another list called 'global bus'. This is a global list allowing communication between clones and their parents. Then, the custom block (e.g. the 'substring from a to b of string' block) will transfer this value from 'global bus' to 'return', discarding the global bus value. From there, the return value is accessible to the clone/sprite that called the subroutine. Because it uses cloning for the inheritance of values, each function has its own 'scope', meaning the same variable can be used in multiple functions, even if they both use that variable at the same time. The final point is that the project uses an 'args' list, which decomposes a string of comma-separated arguments and puts them into an array for the clones to use once the subroutine is spawned. This prevents the need to create distinct variables for each value that needs to be inherited from a custom block parameter, as they can instead be lumped into a single array.