Testing TUPLE! + CHAIN! + PATH! Structuring

Tuple and Chain and Path are all based on similar mechanisms. They're all immutable types, all have to have at least two elements, and they don't allow nesting into themselves. So you can't put a tuple-into-a-tuple or a chain-into-a-chain or path-into-a-path.

But you can put a tuple in a chain...just not vice versa. And you can put a chain in a path...just not vice-versa. They exist in a hierarchy, so things are unambiguous.

For instance: a.b:c/d:e.f is a 2-element path, containing two 2-element chains. The first chain is a tuple and a word, while the second chain is a word and a tuple.

And a/b/c.d/e/f is a 5-element PATH! whose third element is a TUPLE!.

I came up with a pretty cool and visually intuitive test dialect for making sure things are working correctly.

It's NEW-LINE?-sensitive, which is an interesting aspect of it.

Structural Equivalence Testing

Here are the two examples above shown in the test dialect. Each line contains a string, an arrow, and then one or more isomorphic structures, where PATH! is replaced with BLOCK!, CHAIN! is replaced with FENCE!, and TUPLE! is replaced with GROUP!:

"a.b:c/d:e.f"  ->  [(a {b c}) ({d e} f)]
"a/b/c.d/e/f"  ->  [a b (c d) e f]

So then what the test does is TRANSCODE the string, and transform its interstitial sequences into the lists on the right of the arrow.

Lists are legal in sequences. So if actual sequences are seen, a CHAIN! is used to mark them... (given that there are otherwise no chain/tuple/paths on the right, because they were all turned into lists!)

"[a].{b}.(c)"  ->  (:[a]: :{b}: :(c):)  ; tuple represented by outer group

To make it easier to see the BLANK!s, a similar choice is made for :_: to represent a BLANK! (otherwise they'd show up as commas). A plain _ represents a space RUNE!

Whitespace testing is important, to make sure it reacts correctly...which means you can get more than one value on the right:

"(a b)/c"  ->  [:(a b): c]
"(a b) /c"  ->  :(a b):  [:_: c]
"(a b) _/c"  ->  :(a b):  [_ c]

I decided it was a nice use of the NEW-LINE? to detect when a new test started. I still don't know exactly where on balance in dialecting it's good or bad to use line breaks, but it would be much noisier if each test had to be in a BLOCK! or if there had to be some explicit <new-test> tag.

I found that on a page full of tests, two spaces between things helped... and also, the ability to group a few similar tests together and then skip a line before another group of tests:

; all dots are exception, become WORD!
"."  ->  .
".."  ->  ..
"..."  ->  ...

"/a"  ->  [:_: a] 
"a/"  ->  [a :_:]
"//a"  ->  [:_: :_: a]
"a//"  ->  [a :_: :_:]
"/a/"  ->  [:_: a :_:]
"//a//"  ->  [:_: :_: a :_: :_:]

You can make some wacky things... just because you can doesn't mean you should. :slight_smile: But things are working pretty well.

"a.1.(x)/[a b c]/<d>.2"  ->  [(a 1 :(x):) :[a b c]: (<d> 2)]

"/./(a b)/./"  ->  [:_: (:_: :_:) :(a b): (:_: :_:) :_:]

But equally important to what kinds of wild paths and tuples you might create if you wanted, is the fact that mysteriously evil paths and tuples won't be able to exist. So don't fear the power... get ready to enjoy the coherence.

2 Likes

A post was merged into an existing topic: Idea for Naming Function Arguments Out of the Way