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

String type hint #10099

Open
hugosenari opened this issue Feb 27, 2024 · 3 comments
Open

String type hint #10099

hugosenari opened this issue Feb 27, 2024 · 3 comments
Labels
feature Feature request or proposal language The Nix expression language; parser, interpreter, primops, evaluation, etc

Comments

@hugosenari
Copy link

Is your feature request related to a problem? Please describe.

In Nix, it isn't uncommon to embed other languages (mostly bash, but not always bash), with Nix Language as string.
But those strings have no type hint to help editor, formatter, and other tools.

Describe the solution you'd like

This is an issue but should be an RFC, because any solution would evolve to one anyway.

I Would like to have some language feature for that, like info string (lang name after backticks) from markdown.

ie:

{ 
  # ... 
  myCode = '''python
    def myPythonCode():
      print("helloWorld")
  ''';
}

Suggested 3 single quotes instead of two, but needs to be discussed.

Not sure how that could conflict with #228

Describe alternatives you've considered
An RFC to increment RFC 0145 (Doc-comments) to include some kind of special comment

ie:

{ 
  # ... 
  myCode = /*** python */ ''
    def myPythonCode():
      print("helloWorld")
  '';
  myOther = ''
    def myPythonCode():
      print("helloWorld")
  '';/** python */ 
}

Additional context
I vaguely remember someone commented something similar to this in Nix Forum.

It is a usability issue, for best usability it should be a lang feature, for best compatibility it should be a doc comment extension (if we follow that path, close this).

Priorities

Add 👍 to issues you find important.

@hugosenari hugosenari added the feature Feature request or proposal label Feb 27, 2024
@roberth
Copy link
Member

roberth commented Feb 27, 2024

Another alternative is to add an erasable annotation operator, e.g. e1 % e2, which evaluates to e1, and adds no other semantics (e.g. no primops that use e2).

This can also be polyfilled by defining lib.annotate = x: ann: x;. I consider that to be a temporary solution. An operator is desirable because it is easier to read, and it can be parsed unambiguously as an annotation.

The practical contents of e2 would not have to be enforced, but we could set some rules. In this instance we could informally declare string1 % string2 to mean string1 % { lang = string2; }: a string language hint.

@hugosenari
Copy link
Author

and adds no other semantics (e.g. no primops that use e2).

Now that you say that, I was thinking could be a good use to annotated strings, ie:

options.your-script = mkOption { type = lib.annotatedString };
config.your-doc = ''
  ``${builtins.getAnnotation cfg.your-script}
  ${cfg.you-script}
  ``
'';
config.your-cmd = ''
  #!/usr/bin/env ${builtins.getAnnotation cfg.your-script}
  ${cfg.you-script}`
'';

But this is less important, only thinking out loud.

An operator is desirable because it is easier to read

My problem with function is that some constructs may require parentheses. Is undesirable from usability and readability.

ie.

[
  # annotate as function
  (annotate ''
    def myPythonCode():
      print("helloWorld")
  '' "python3")
]
[
  # annotate as function (first line remover)
  (annotated ''python3
    def myPythonCode():
      print("helloWorld")
  '')
]
[
  # annotate as operator
  (''
    def myPythonCode():
      print("helloWorld")
  '' %  "python3")'
]
[
  # annotate as unary operator (first line remover)¹
  (% ''python3
    def myPythonCode():
      print("helloWorld")
  '')
  #if it doesn't require parentheses.
  % ''python3
    def myPythonCode():
      print("helloWorld")
  ''
]
[
  # annotate as comment before
  /*** python3 */
  ''
    def myPythonCode():
      print("helloWorld")
  ''
]
[
  # annotate as comment after
  ''
    def myPythonCode():
      print("helloWorld")
  ''  /*** python3 */'
]
[
  # use per language comments
  ''#python3
    def myPythonCode():
      print("helloWorld")
  ''
]
[
  # nix language native
  ''python3
    def myPythonCode():
      print("helloWorld")
  ''
]

Unrelated point, this could fix something that is strange to me, the first and the last \n of double single quote are parsed. Creating an unexpected new line before and after.

[
  # nix language native
  ''python3
    def myPythonCode():
      print("helloWorld")
    OMG_WHY?'' # Means the string could be pre AND (not only OR) post fixed.
  # unary operator
  % ''python3
    def myPythonCode():
      print("helloWorld")
    OMG_WHY?''
]

Thoughts:

  • For usability, having more syntax variations ain't good;
  • For retrocompatibity, changing current syntax semantics ain't good;
  • For readability, having more function ain't good;
  • For integration, having comments are only useful to external tools.

¹ current not operator inside an array requires parentheses. Testes with nix repl 2.18.1

@hugosenari
Copy link
Author

Linking nixpkgs project and RFC related to this missing feature.

@roberth roberth added the language The Nix expression language; parser, interpreter, primops, evaluation, etc label Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request or proposal language The Nix expression language; parser, interpreter, primops, evaluation, etc
Projects
None yet
Development

No branches or pull requests

2 participants