Multidemensional dictionary

You raise good points. I’ll re-visit the examples in aTbRef.

The more Action code becomes like a language and less like scripting, the more—and more complex—the potential usage. At the same time Action code doesn’t give failure messages and logging intermediate stages of a process only gets one so far. An internal failure, i.e. where something which it seems should work, doesn’t, it is hard to investigate further. This makes for something of a headache when trying to document things!

For aTbRef, my notes always start with the—often very brief—announcements of new features. I work on the assumption that any code samples have been tested, though if I have time (and understand the use case) I will try and test myself. For code-related notes, I turn them into aTbRef’s own standardised syntax. The later might be verbose for expert coders, but feedback suggests its consistency does make it easier for non-coders to understand how to use action code.

As regards lists (Set, List, Dictionary) these are still semicolon-delemited strings—that should be one’s base assumtion. One of the reasons for the [ ] listing syntax was to allow dictionaries (a list of key:value string) to have key values that are lists. Consider this dictionary:

$MyDictionary = dictionary("Types:fast;slow;Distance:234;"); // WRONG!!
//but
$MyDictionary = dictionary("Types:[fast;slow];Distance:234;");
//or  -  using newer {} dictionary markup
$MyDictionary = "{Types:[fast;slow];Distance:234;}";
// which for those who object to extra keystrokes is 
$MyDictionary = {Types:[fast;slow];Distance:234;};

But, in the case of the altter there is no unambiguous statement as to the use of ‘bare’ [ ] or { } values. IOW, we assume the parser sees these as strings of a List or Dictionary type. And yet, we don’t know because there is no release note to lean on, in terms of design intent.

It might be a while before I change existing aTbref notes in this context as updating one (now ambiguous) example for another doesn’t help. Some careful fine-grained testing is needed and I’m short on spare time ATM. If anyone does/has done tests in this area, by all means let me know (a PM or email is also fine) so I can update examples with confidence they are correct.

†. Although Tinderbox had Set-type before List-type, I think Sets are now better thought of as a special type of list, especially since v8 (v9?) actually started doing the long-forecast outcome of arbitrarily re-sorting the list order of Set items.

I should add, comma-delimited lists are only used for listing arguments of action & export code operators.

(whereas, JavaScript & JSON, use commas for lists)

1 Like

Hi Mark,

we are running into a philosophical debate :slight_smile:

I like how Python implemented it:

List: thislist = [“apple”, “banana”, “cherry”]
Dictionary: thisdict = {“brand”: “Ford”,“model”: “Mustang”,“year”: 1964}

But the way TBX is doing it is very usable for me.

A debugger: I don’t need one for TBX (I would use it if it were there)
A kind of log with error message: yes, please :wink:

Detlef

Well. I’m just a user. All I’m documenting is what is known to work in Tinderbox, I’ve zero interest in whether it similar to language X or Y (not least as I don’t use them).

For the philosophy of underlying design choices, you’d need to talk to the developer. :wink:

†. Disclaimer. I do use Python occasionally, out of necessity, bit its atypical importance of whitespace in code is far more difficult to remember in the moment than functional syntax. Indeed, that’s the point of documentation, as an occasional user if I don’t know I can look it up. I do have issue with the general usability of documentation of Python, but that’s a separate debate :slight_smile: .

show() is actually quite effective for simple cases.

Appending to a /log note is good for complex cases, which one always hopes to avoid but which do happen sometimes. That’s a bit of work, but even so it’s easier than using (say) os_log() on the Mac.

2 Likes

I’m all for taking responsibility, but the list question actually started with this post:

1 Like

RE this earlier example:

FWIW, this does work:

var:list myMatrix = "[[0;1;2];[3;4;5];[6;7;8];[9;10;11]]";
$Text = myMatrix[1]; // returns "[3:4;5]"

N.B. this fails—i.e. if the outer quotes omitted. This suggests the true intent of [ ] ({ } for dictionaries) is as a type wrapper for individual items rather than—as in some programming languages—a signal as to the data type of the whole. To summarise:

// these are good
$AList = "ant;bee" // good
$AList = list("ant","bee"); // good (but really for if list items are variable or expressions
$AList = "[ant;bee]"; // good but the [] are redundant
//but
$AList = [ant;bee]; // WRONG. Do not use

… and similarly with {} dictionaries. I’m still working through the ambiguities before I update aTbRef as my last quick update seems to added—unintentionally–to the confusion as to correct syntax/usage.

Certainly, I would urge not assuming behaviour based on how that character is used in [some other programming language]. For instance, though [ ] is used in relation to Tinderbox lists, it doesn’t mean lists can use comma delimited lists. So, not like—for example—JavaScript, that does use comma-delimited lists.

†. In first-posted form this omitted the inter-item semicolons, since fixed in the original post. Either way, their omission wasn’t the cause of the test’s failure.

Hi Mark,

thanks for testing all the options.

A syntax like (I found no reference for list(…) on your pages):

$AList = list("ant,bee");
$AList = "ant;bee";
$ADict = dictionary("key1:val1;key2:val2");

is what looks OK for me. I would expect the following patterns to be valid too:

$AList = ["ant";"bee"];
$ADict = {"key1":123};
$ADict = ["key1":123];

and I don’t like patterns like:

$AList = "[ant;bee]";
var:list myMatrix = "[[0;1;2];[3;4;5];[6;7;8];[9;10;11]]";
$MyDictionary = dictionary({cat:animal; dog:animal; rock:mineral});

A string is a string and no list or dictionary. That looks weird to me. Why should I use curly brackets when using the dictionary method? The method expects a string?!
You wrote dictionary({dictionaryStr}) but in dictionary({cat:animal; dog:animal; rock:mineral}); there is no string inside the brackets! What if I had done this:

var:string cat = "dog";
$MyDictionary = dictionary({cat:animal; dog:animal; rock:mineral});

Yes I did, because based on available source info this was all we had to go on as correct syntax. bear in mind that I am—as others here—just a user of the app. I’ve no internal access and can’t tell the design intent the code parser. Nor to I have unlimited time to (re-)test code in Release Notes (which I assume to be correct). I use the latter verbatim unless ambiguity for the learner implies further experimentation is needed to reveal how an operator works.

I think the background disconnect here is the assumption that Tinderbox action code is either a deliberate full programming language—it isn’t—or came out fully formed: it didn’t, it’s been 21 years in the making.

Let’s revisit some of the (mis-)assumptions at play here. In Tinderbox, lists i.e. multi-value data forms are semicolon delimited strings. You can’t use:

$MyList = ant;bee;cow

The result is “ant” as the semicolon closes the expression. IOW, the above is the same as typing:

$MyList = ant

But we know, if we read the docs, that the norm is to define a list (List or Set) using a quote_enclosed semi-colon delimited (string of text):

$MyList = "ant;bee;cow";

This is where a formal programming knowledge is unhelpful as it cause one to assume rather than check the correct syntax. Consider ‘strings’ and quoting. Quoting and using explicit expression (line-)end semi-colon markers came in in c.4.5 in 2008 (but are still not formally policed), six years into Tinderbox’s life. v4.6 (2009) brought dot-operators and more implicit formalisation. v5 (2010-2013) increased this without deprecation of the older looser forms. So can you can still write an action as:

Color = blue

and $Color will be set to the ‘blue’ defined colour. Less likely to do that for new code but plenty of users have very old documents and so old code still works. For more complex code, such certainty is less the case.

Until v5.0 (2009) the only multi-value data type was a Set: v5 added Lists. It wasn’t until v9.0 (2021) that the auto-sorting of Sets got enforced (12 years later) and the difference between a Set and List was more than whether duplicates are allowed.

Annoying as it may be for programmers to read, dictionaries—from a Tinderbox perspective—are a string (as in quote enclosed text) holding a semicolon delimited list of key:value pairs. Those arrived in Tinderbox v9 (2021).

The issue of nesting lists or actually the problem of dictionary values that were lists was address in v9.5.0 (2022) with the addition of [] for nested lists and {} for nested dictionaries. I think this caused people with experience of non-Tinderbox coding to assume a Tinderbox list suddenly suddenly == an array as in formal programming or {} defined a Tinderbox dictionary. Wrong, just plain wrong.

So the wrong question to ask is “Why doesn’t Action code work like [your favourite code language]?”. Instead, ask “how is [thing] defined in Tinderbox action code?”. It simply doesn’t matter how C++ or JavaScript does this—it’s just not helpful or relevant to understanding action code in Tinderbox. If the confusion is that Action code isn’t a normal programming language, the error is simple: it’s not a programming knowledge. Change the flawed assumptions when phrasing the questions.

If anyone finds an error or ambiguity in aTbRef (or app Help) please report it: post in the form, forum direct message or email—all are fine. It’s hard to fix unknown errors—so don’t rely the mysterious ‘somebody else’ to report it. In simple cases, I can normally fix aTbRef typos instantly. Errors in Help persist until the next release.

Anyway, please, please, don’t read this as implied criticism of @webline, whose questions arise quite reasonably from all their hard work in trying to resolve interesting problems and sharing all that hard work with fellow users for free. I also accept that aTbRef can always be improved (I try!)

So, in summary, I’d ask the community to avoid phrasing questions like “Why isn’t Tinderbox like [ X ]…?” but instead ask the more helpful “How do I do [ Y ] in Tinderbox?”. In part, the former phrasing doesn’t help the community respond as not all—indeed few, if any, other users—may use or even know of ‘X’ so it’s not a reference that helps the community help the questioner. Remember too, Action code is not a deliberately designed programming language, is a long evolved macro language and it’s oddities are more easily understood from that perspective…

I believe these are currently handled correctly.


Why should I use curly brackets when using the dictionary method? The method expects a string?!

Tinderbox tries to coerce types whenever type coercion is needed. So, any type that can be created may be created from a string; you can write

$MyNumber="3.1415927";

and Tinderbox will perform the conversion implicitly.

The […] notation for lists and {…} notation for dictionaries helps avoid ambiguous expressions.

This confuses me as whilst possible it’s not very consistent usage with lists to date

$AList = ["ant";"bee"];

where a normal Tinderbox approach would be:

$AList = "[ant;bee]'; // FWIW this works, the above doesn't 
//or
$AList = ["ant;bee"]; // this doesn't

or

$AList = "ant;bee";

As the [] are not needed as they don’t define a list. The only explanation that makes sense is that [] and {} are not for defining lists or dictionaries but for indicating that a list item or dictionary key’s value is a list or dictionary. Thus

$AList = "ant;[bee;cow];dog";
//not
$AList = ["ant;[bee;cow];dog"];

Why? Because the [] marks a nested list.

But we are going is circles here as the design intent, by which I mean the app code creator’s intended limits of use, of the feature are unclear. I say that without rancour, but it’s clear enough from this thread that different people are making different wrong guesses due to differing experiential PoVs and none of us knows the ground truth. Well-intentioned, but actually false, assumptions based on experience using formal programming languages only make things worse.

This is where a very system permissive (where the app infers user intent) works against being able to guess (minimum working) syntax. Easier would be to state the full syntax and document allowed elisions. Knowing what you can leave out is easier than guessing what you must not leave out. :slight_smile:

This ought to work. I believe it does.

$MyList=[1;2];

This ought to work; I believe it does.


$MyList=[ant;bee];

The tokens ‘ant’ and ‘bee’ might be interpreted as strings by analogy with the archaic $Color=red;. But we agree this is bad practice, and if it fails, that’s ok. ant is not a number, or a string. "ant" is.

$AList = ["ant;[bee;cow];dog"];

This should be a list that contains one string. I believe this is, in fact, what happens.

A hazard is that Tinderbox can easily be led (or misled) into converting a string like “ant;[bee;cow];dog” into a list of three elements.

1 Like

I think you are putting this discussion on too big a horse. The programming language behind TBX has certainly grown over many years, but it is still a powerful and thoroughly structured and understandable solution. I would have a hard time writing down the difference to a “full programming language”. :smiling_face_with_three_hearts:
As I said, this discussion is far too big for me. I just don’t find the syntax for lists and dictionaries logical and consistent. On the other hand, I really like other things.
The dot syntax is a great extension of the language in TBX. Why shouldn’t lists and dictionaries change as well? I don’t have to question the whole concept behind the language for that - do I? :woozy_face:
Regarding your concrete example: sure, a semicolon ends an expression. That’s why some languages use commas for lists. But without type binding, that’s not so bad. It’s all just a string in TBX for the time being. But quotes and a square bracket for a list are just too much of a good thing for my taste and doesn’t bring any added value IMHO. It currently works in TBX - those are the rules. But I would like to see the use of semantics behind the brackets - no need for quotes anymore. :disguised_face:
I try to keep to the syntax behind TBX. But my memories of other languages and thus my experience make life difficult for me here. When solving a problem in TBX, I can’t start without this experience - whether I want to or not. So why can’t I at least whine and moan a little bit here?
Besides, my first post here was not a criticism of anything. I just wanted to know what the Tinderbox way is to deal with dictionaries. I wanted a different view on things and to detach myself from my experiences - and then it was as if I had said Jehovah :crazy_face:

2 Likes

First, feel free to email me with what specifically you have in mind.

Big overview: we have two requirements.

  1. Currently, dictionaries are maps from keys, which are strings, to values, which are also strings.

  2. That means, values that are lists or dictionaries must distinguish themselves lexically.

coordinates: [43;90]
synonyms:  {dialogue:dialogue,conversation,talk;  }

This is essentially Javascript, which (I believe) adopted the notation from Python as it was back then. The underlying ideas are LISP, but everybody’s been trying to fix the syntax of LISP from the beginning.

My first concern right now is the specter that things that ought to work, don’t. I’m not sure how many of those have been found.

Your point, if I follow correctly, is that

  1. We know that the key is a string, and so should not require keys to be quoted.

  2. We know that the value is going to be stored as a string and coerced into whatever type is needed, ands so we should not require values that are [lists] or {dictionaries} to be quoted, either.

My concerns are

  1. Javascript is not a well-designed language, but lots of brainpower has gone into making it good. Javascript still requires keys to be strings, explicitly. So (I think) does Swift. Smalltalk-80 too, as I recall. I like languages, but they’re not my specialty, and the budget for nesting dictionaries and lists is necessarily small until we establish this is useful. So, I tend to emulate other languages.

  2. The challenge for keys is straightforward. For values: this feels like it might be a messy extension of the hand-built recursive-descent parser.

A view from the wings. Fro supporting this community over the years, users of Tinderbox automation fall into two groups with a different beef. Those with coding experience complain either/both that TB code is not like whatever they are more used to or that they object to typing any character that might be omitted. A separate group is those who struggle and give up because the ‘rules’ are so inconsistent.

In the documentation, I tend to think of and write for the latter. If something can’t be clearly described except to people who already understand, it makes for a difficult learning environment. Part of the unseen labour in resources like aTbRef is reviewing existing examples to ensure they reflect current practice. It feels like make-work but feedback shows it’s important to maintaining guidance open to other than experts. By comparison it is then easy to signal what might be omitted.

I’d also recognise the challenge we give the developer here. For better or worse, Tinderbox’s various codes (action, export, and now-defunct query) were very much in the manner of AppleScript where the idea was you wrote in close to natural language and the parser figured out the rest. But, now we have a very reduced export code and a massively more powerful action code whose range of possible variations simply doesn’t gel with the original loose approach. Plus, and something not credited enough, is that the app is still very forgiving of older code syntax as occasional users don’t want to keep re-writing code as things change.

If I must, for example, create a JavaScript array (i.e. list) using ["ant',"bee","cow"], so why is it so hard to accept that the Tinderbox syntax for this is shorter, simpler, "ant;bee;cow"? I don’t understand the seeming zero-sum game here.

Where this links to the above is debate about quoting text ‘strings’, mainly it seems for the convenience of making Tinderbox code closer to [something else], or save the ennui of having to use a few extra keystrokes. Currently, the rubric—even if ignored by seasoned TB coders, is that we quote (paired double or single) text inputs or arguments that aren’t a boolean value or a number (to be used arithmetically). Otherwise, enquote text and nothing will (should!) go wrong based on Tinderbox misreading your intent.

1 Like
var:list myMatrix = [[0;1;2];[3;4;5];[6;7;8];[9;10;11]];
$Text = myMatrix[1];

failed because the logic that performs indexed references was removing brackets too aggressively. This will be fixed in the next backstage release.

Note that the correct way to represent a list of lists is the one above:

[ item1; item2; item3; item4 ]
item1: [0;1;2]
item2: [3;4;5]
1 Like

OK, so we quote lists except if using outer square braces?

//Existing norm
var:list myOldMatrix = "item1; item2; item3; item4";
// optional new syntax
var:list myNewMatrix = [item1; item2; item3; item4];
// or is it
var:list myNewMatrix2 = ["item1"; 2; "item3"; False]; // to indicate different data types as ist items

Does this mean that the two forms should not mix. IOW, if nested lists (or dictionary objects) mix, do we use outer square brackets instead of the old method.

I’m still confused as how to explain till the options to a learner who just wants a simple explanation of syntax that will work. “Use quotes unless you don’t need to” is where we seem to be, as it appears we’ve fixed things for the expert but made it more confusing for the general user, unless we do a hard scrub though existing documentation to use the new syntax.

  1. A list is enclosed in brackets […].

  2. A dictionary is enclosed in braces {…}

  3. A string is enclosed in quotes “…” or ‘,’

  4. A dictionary is a list of key:value pairs. When in doubt, each are strings.

1 Like

I think it would be helpful if we can discuss these syntax elements in context.

For example,
[ ] are used to retrieve keys.
{ } are used to help with add operators

I’d love to see examples, especially nested list/set and dictionary examples. I’m still quite confused and would love to understand the nested use case, as noted above.

1 Like

… and where or where not, per best/simplest-rule practice, that quotes should or should not be used. I’m a bit lost with these changes as to how to describe things simply so newer users can bootstrap themselves from basic, consistent, examples.

1 Like