Tinderbox Forum

Still grappling with Functions - A request

Due to the way my brain is aligned (3% off azimuth) - I’m STILL having problems getting my head around creating my own functions, and getting them to work. I think I have the syntax all wrong.

Is there an advanced user who could kindly generate a sample file with 3-4 very basic functions, and a couple of test Notes/Containers? Stuff like $Color, $Text changes, and a Move Action perhaps.

I went through the example projects that are on the forum and accompanying the tutorial video, but these functions are complex and contain things like ‘var’ that is a whole new concept to me and is getting some internal resistance.

Just so I can study a very basic function, watch its moving parts, and get a handle on how to roll my own.

Thanks!

Try this one:

function double(x) {
     return 2*x;
     }

Let’s start here. Can you think of a few Rules or Stamps that would test this?

1 Like

Ah, I can understand it! So this is the boilerplate format for a function, correct? In the sense that the syntax for ALL functions follows a form:

<Line 1> function nameOfFunction ( <either enter a variable that will be the target of the result of your function’s calculation, or leave blank if you are going to follow with a “var”> ) {

<Line 2> <argument/formula>;
<Line 3> <more arguments/formulae>;
}

(Please bear with me, I acknowledge that what I just did here looks way more complicated now, lol…)

how about this one:
TestArt.tbx (118.2 KB)

1 Like

This is sweet!! Thank you :slight_smile:

I’m by no means an expert, but perhaps this will help.

The basic form of a function definition is:

  • the word function
  • the name of the function followed by parentheses (which may or may not be empty)
  • a series of actions, separated by ;, all enclosed in brackets
  • optionally you can have the keyword return, which is the way the function passes information back to you – so you can use it in an $Attribute, for example.
  • var simply means that you’re going to use the identified variable within the brackets – it’s temporary information which can’t be used outside the function.

So, some examples. The simplest type of function just acts on the selected notes – it doesn’t expect you to give it any more information and it won’t return any to you.

e.g., the following just sets the selected note’s $Color to blue:

function makeNoteBlue() {
   $Color = blue;
}

Notice that the brackets are empty and there’s no return statement, because you don’t need to give the function any information and you don’t want any back in return.

You could call this function in a Stamp with the code makeNoteBlue(): apply the stamp and the selected note will turn blue immediately.

This isn’t very useful so far, because it’s hardwired to blue. So let’s extend it so we can choose the colour when we call the stamp.

function makeNoteColour(aColour) {
   $Color = aColour;
}

This can be read as colour the selected note with the colour “aColour”, which is a placeholder for the real colour I’ll tell you when I call the function.

You could call this with the stamp makeNoteColour("Red") or makeNoteColour("Blue") or whatever. i.e. you don’t have to change the function definition to get different colours, you just have to change the placeholder (technically known as the function’s parameters) when you use it.

(NB: it’s your job to ensure that the info you pass to the function (e.g. “Red”) is the correct type – in this case it needs a String, and you must pass it the right number of parameters. If you pass it a number, or if you only it pass it one parameter instead of two, the results may not be what’s expected…)

If you want the function to give you back information, then you’d use the return statement. E.g. this function gives you the map coordinates of the current note in a string.

function getCoordinates() {
   var coordinates = "";
   coordinates = "(" + $Xpos + ",  " + $Ypos + ")";
   return coordinates;
}

Note, this function uses the temporary variable coordinates to build the string which will be passed back in the return statement.

You could then use this function to populate an attribute. For example:

$Subtitle = getCoordinates()

If you put this in the note’s $Rule, the subtitle will update to show the note’s position on the map as you move it.

If you wanted to move the note on the map, you could use the following function, which is in some way the ‘inverse’ of the last one:

function setCoordinatesTo(x, y) {
   $Xpos = x;
   $Ypos = y;
}

Call this with the stamp setCoordinatesTo(0, 0) and this will move the selected note to the position 0, 0 on the current map (and the $Rule we created previously will display the new coordinates as a subtitle…).

Finally, you’ll notice that however we call a function (via Stamp or in a Rule etc) you need to include the parentheses, even if they’re empty. E.g. getCoordinates(), not getCoordinates.

This test project contains these functions, so you can experiment with it. Have a look at these to see how it’s put together.

  1. Hints/Library container for the functions
  2. A Note’s $Rule
  3. The Stamps inspector

Test functions.tbx (115.2 KB)

I’d start by changing the values of the parameters in the Stamps, then perhaps write a function which returns the $Color of the selected note, with a $Rule which uses the function to populate the attribute $MyString.

Slightly more advanced (but only using the above techniques), write a function which nudges the note one unit at a time, with the direction to be specified when you call the function. (e.g. moveNoteOneUnit(left)).

As I said, I’m not an expert so none of this is particularly advanced – you can do a lot more! But I hope it helps get a sense of how functions work.

5 Likes

Thanks so much, @brookter - this is AMAZING, and completely clarified my exact uncertainties!!
Could we pin the explanation somewhere on the forum for future reference?

You’re very welcome, Art, and I’m really glad it helped!

I don’t know how you’d go about pinning it, perhaps the moderators can help? (And assuming the real experts don’t think it’s got too many errors for that…)

1 Like

@archurhh here is more that may help you. Three examples

  1. Function simply processes action code
  2. Function passes an output
  3. Function ingest and input

[TBX L - Simple Functions Demo-3 Methods Action Code, Input Variables, and Output Variables).tbx (115.6 KB)

What I’m not clear on is how a function can call another function. Perhaps someone can explain this.

1 Like
function emphatic(s) {return s+"!";}

function friendly(s) {return "Hi, "+emphatic(s);}

$MyString=friendly("Mark");  // Hi, Mark!

composing.tbx (111.5 KB)

1 Like

Makes total sense, thanks.

Awesome! Thanks, will play with it @satikusala :slight_smile:

This is scary, I actually understood that.

Micheal,
a simple question from your file , how to apply 3 functions highlighted on a new /existing note.

To call a function you place it anywhere action code can be called ($Rule, $Stamp $Edict, link action, etc.).

Example 1: here the function is specifies what attribute is affected.

Example 2: Here the output is being sent to text.

Example 3: Here the input is being sent to the function, e.g $MyNumber (Note: it could be an array, like in my linking example), and the function determines the output

2 Likes

Not explicitly covered is the relation of function and var. There isn’t a relationship as such! But a real-work’ function may get long and complex whereas most most examples are simple. If a discrete attribute were needed to hold the value of intermediate stages, you need a lot of extra attribute. Not that Tinderbox makes adding more attributes a problem, but you do need to zero-out the attributes when done, at least if they are holding large lists or texts.

By using a var, you have a variable, just that, and one that have no scope outside the functions and destroys itself when not in use (i.e. when done).

Very simple example, with attributes and no vars:

function getCoordinates() {
   $CoOrdinates = "";
   $CoOrdinates = "(" + $Xpos + ",  " + $Ypos + ")";
   return $CoOrdinates;
   $CoOrdinates = "";
}

With variables replacing attribute values

function getCoordinates() {
   var coordinates = "";
   coordinates = "(" + $Xpos + ",  " + $Ypos + ")";
   return coordinates;
}

I’ve also updated my aTbRef section on Functions. The notes in the full action code listing for function and return are stubs pointing to the functions articles as the subject is too large for a sensibly sized article for a single operator.

I’d welcome some feedback on that set of articles is useful or insufficient (noting that aTbRef doesn’t link in articles to demo files and such. But, I hope the description and code examples are enough to cover the subject (noting they are descriptive and not—by design—a tutorial). If not, I’d like to know the weak spots. Please!

1 Like

Super-amazing… I was, in fact, wondering whether var could be used in this manner! Glad you clarified, @mwra.

1 Like
function getCoordinates() {
   $CoOrdinates = "";
   $CoOrdinates = "(" + $Xpos + ",  " + $Ypos + ")";
   return $CoOrdinates;
   $CoOrdinates = "";
}
  1. There’s no guarantee that statements after a return statement will be executed. So the last line may not have the intended effect.

  2. It makes sense to for functions to clean up after themselves. That said, assuming the Xpos and Ypos as strings are 10 characters long, the memory occupied by $CoOrdinates(this) is only ~14 bytes. OK: there’s some overhead: say 32 bytes. Your computer has multiple gigabytes — that’s a thousand million bytes — of RAM, and even more virtual memory which, these days, is probably stored in a fast solid-state disk. Don’t worry too much about the stray 32 bytes. (Let me do that.)

  3. The worry, really, is the something else will use the value of $CoOrdinates that you left behind. So, var is much neater.

  4. There’s nothing wrong with saying

var:string coordinates="(" + $Xpos + ",  " + $Ypos + ")";

in the function, which saves a line and (I think) makes your intent clearer.

3 Likes

Thanks for the clarification. I think it vindicates a general suggestion, especially for the learner, to use variables for storing/crystallising in-process values: i.e. something we need to store before doing something to that data in a later step. I will revisit my Functions explanations and add a note on use of variables vs attributes. I also ought to add a note about commenting. Functions are exactly the sort of place where comments are useful even if only for oneself, months or years later, trying to recall one’s original idea when making the function.

I will also clarify the point about passing return an (expression) rather than a value representing the evaluated result of the expression expression.

I can also see a separate need for some added description of why we have variables (var) and at what point they are useful replacement for using attribute values for storing interim results.

1 Like