Forth: test cases for definitions that use built-in words

I’d like to propose two new cases for the forth canonical data. I opened a PR for this before discussing it here, which was the wrong order, sorry. This thread is the proposal.

The gap

The suite checks that a definition keeps the meaning its words had when it was defined, but only when those words are user-defined:

: foo 5 ;
: bar foo ;
: foo 6 ;
bar foo        → [5, 6]

Nothing checks the same rule when the body uses a built-in word. A solution that expands user-defined words at definition time, but leaves built-ins as names to be looked up when the word runs, passes every current test.

I hit this as a student on the Scala track: all tests passed, and a mentor pointed out the bug. I then found the same bug in my older AWK solution, which had been passing too.

Proposed cases

Both would go under “user-defined words”:

{
  "uuid": "3ce7a6d1-8a01-48f3-9ee8-66ae48a7dac6",
  "description": "can use built-in words as they were when the word was defined",
  "property": "evaluate",
  "input": {
    "instructions": [": sum + ;", ": + * ;", "2 3 sum"]
  },
  "expected": [5]
},
{
  "uuid": "9972320e-dc7c-496e-a880-f09ea5009559",
  "description": "can define word that uses built-in word with the same name",
  "property": "evaluate",
  "input": {
    "instructions": [": dup dup dup ;", "1 dup"]
  },
  "expected": [1, 1, 1]
}

With the bug, the first case gives [6] and the second never terminates.

What they cost

  • Existing solutions with this bug will start failing. I don’t know how many there are.
  • With the bug, the second case does not fail an assertion: dup keeps expanding into itself, so tracks see a timeout. If that is a problem, the first case alone already covers the rule, and I’m happy to propose only that one.
  • No existing case changes.
  • Neither case requires an error for an undefined word inside a definition. That was the contested point in the 2024 thread, and I’m leaving it out on purpose.

Solutions that keep built-ins and user-defined words in one dictionary are fine, as long as the body is resolved when the word is defined, which the existing foo/bar case already requires.

For reference: the closed PR with the exact diff is problem-specifications#2702, and the older issue on the same gap is problem-specifications#1800.

I suspect those tests will break a whole lot of solutions! The introduction of a test likely to trigger infinite loops in many solutions may have a financial/compute cost associated with it. Is this something we should take into consideration here, @iHiD ?

1 Like

Can the Exercism API tell us the total number of completions for a given exercise per track? That might be useful in cases like this since we can aggregate the total number of completions site-wide as a theoretical maximum impact.

1 Like

If exists MCP for Exercism we can just ask this question :)