Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in spec/data-model-errors.json #995

Open
mihnita opened this issue Jan 31, 2025 · 4 comments
Open

Error in spec/data-model-errors.json #995

mihnita opened this issue Jan 31, 2025 · 4 comments

Comments

@mihnita
Copy link
Collaborator

mihnita commented Jan 31, 2025

The last test case is

    {
      "src": ".local $star = {star :string} .match $star |*| {{Literal star}} * {{The default}}",
      "exp": "The default"
    }

I think this is an error.

Why?

Because there is no difference between |*| and *.
So there should be a data model error,

It is the same as the test a bit above:

    {
      "src": ".input {$var :string} .match $var * {{The first default}} * {{The second default}}",
      "expErrors": [
        {
          "type": "duplicate-variant"
        }
      ]
    },

And the fact that it is included in data-model-errors.json also seems to confirm that the intention was for this to be an error, and the missing "expErrors": [{ "type": "duplicate-variant" }] is just an unintentional mistake.

@eemeli
Copy link
Collaborator

eemeli commented Feb 1, 2025

Because there is no difference between |*| and *.

There is a difference: * is the catch-all selector which is handled specially in Pattern Selection, while |*| represents a literal key. With the default functions, the latter would only match something like {|*| :string}, and not e.g. {star :string}.

@mihnita
Copy link
Collaborator Author

mihnita commented Feb 1, 2025

And I argue that it is wrong to have that difference.

Everything is a string, we refused again and again to allow for any kind of types:

|a| = string
a = string
|1| = string
1 = string
|*| = string
* = NOT A STRING

It also has the side-effects that the keys in a "selector map", or the "cases in a switch" (however we want to think about the selection) end up being different types.
Which is not a problem for programming languages with a dynamic typing, but introduces unnecessary friction for static typing languages.


In ABNF the * looks like a string:

key               = literal / "*"

By this logic the _ are also different:

".match $var
   _   {{The first default}}
   |_| {{The first default}}
   *   {{The second default}}",

Because

name-start = ALPHA / "_"

I mean, "_" is "the keyword _".


Looks like * is different because we use "catch-all key '*'" 3 times without even explaining what it means.

@mihnita
Copy link
Collaborator Author

mihnita commented Feb 1, 2025

The description of Key in the data model (syntax.md):

#### Key

A **_<dfn>key</dfn>_** is a value in a _variant_ for use by a _selector_ when ranking
or excluding _variants_ during the _matcher_ process.
A _key_ can be either a _literal_ value or the "catch-all" key `*`.

The **_<dfn>catch-all key</dfn>_** is a special key, represented by `*`,
that matches all values for a given _selector_.

The value of each _key_ MUST be treated as if it were in [Unicode Normalization Form C](https://unicode.org/reports/tr15/) ("NFC").
Two _keys_ are considered equal if they are canonically equivalent strings,
that is, if they consist of the same sequence of Unicode code points after
Unicode Normalization Form C has been applied to both.

So:

  • |*| is a key
  • * is "catch-all" key, but it is also a key, right?
  • Two _keys_ are considered equal if they are canonically equivalent strings

So the "*" (key, literal) and "*" (catch-all key) are not "canonically equivalent strings"?

@eemeli
Copy link
Collaborator

eemeli commented Feb 2, 2025

Ah, good catch! The key equality text is a bit misleading, so I filed #996 to improve the text.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants