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

Function notation: prefix character #67

Closed
aszs opened this issue Mar 10, 2022 · 5 comments
Closed

Function notation: prefix character #67

aszs opened this issue Mar 10, 2022 · 5 comments

Comments

@aszs
Copy link

aszs commented Mar 10, 2022

TOSCA is currently broken. There is no way to provide a value that happens to look like a function call. For example:

node_types:
  Server:
    properties:
      traits:
        type: map
        entry_schema:
          type: list
          entry_schema: string

service_template:
  node_templates:
    server:
      type: Server
      properties:
        trait:
          concat: [ this, is, supposed, to, be, a, value ]

In TOSCA 1.X, that last line will always be evaluated as a function call. It cannot be escaped in any way.

The proposal is to require all function calls (both intrinsic and custom) in TOSCA to begin with an escapable prefix character. This will solve the above bug, and also provide a more consistent parsing algorithm for functions (both for TOSCA processors and for the human eye scanning a TOSCA YAML file).

The proposed prefix character is $. It would not cause any problems with YAML parsing, and also it would be familiar to users of bash, Perl, Ruby, and many templating languages.

I think a programmatic definition makes the most sense:

(extracted from issue #123)

In TOSCA values, for any map of any nested depth:

  • Is the key a string starting with $ and with length > 1? If yes:
    • Is the second character $? If so, discard the first $ and stop here (escape). If yes:
      • Is this the only key? If not, emit a parsing syntax error ("malformed function"). If yes:
        • This is a function call!

Note that I am here assuming that the argument(s) of a function can be anything: a single string value (like get_input), a sequence (like all other intrinsic functions), or anything else (for custom functions). I think this is a good idea, as it allows for cleaner syntax, e.g. functions with single arguments (like get_input) but also functions with a map argument (compare to kwargs in Python):

{ $get_security_context: { env: staging, role: admin } }
@aszs aszs added the TOSCA 2.0 label Mar 10, 2022
@tliron
Copy link
Contributor

tliron commented Jul 12, 2022

An alternate proposal could be that all functions (both intrinsic and custom) must have a YAML seq for arguments (and the get_input function would have to be changed to match that):

  • Is the key a string starting with $ and with length > 1? If yes:
    • Is the second character $? If so, discard the first $ and stop here (escape). If yes:
      • Is this the only key? If not, emit a parsing syntax error ("malformed function"). If yes:
        • Is the value of the key a seq? If not, emit a parsing syntax error ("malformed function"). If yes:
          • This is a function call!

I am less in favor of this. I don't think there's any ambiguity in the original programmatic definition.

@tliron
Copy link
Contributor

tliron commented Jul 12, 2022

Also a clarification about escaping the $: you would only need to do this for map keys, not for any arbitrary string value. Examples:

properties:
  prop1: $myid # valid as is, no need to escape
  prop2: my_value

But here we do need to escape:

properties:
  $$prop1: myid # if we don't escape we will get a "malformed function" syntax error
  prop2: my_value

@tliron
Copy link
Contributor

tliron commented Jul 28, 2022

This has been accepted into the spec. Also implemented in Puccini.

@tliron tliron closed this as completed Jul 28, 2022
@lauwers
Copy link
Contributor

lauwers commented Jul 28, 2022

Actually, one more clarifying question: I assume function names can be namespaced, as in ubct:$sqrt

@tliron
Copy link
Contributor

tliron commented Jul 28, 2022

I don't assume that, at least not for built-in (including custom built-in) functions. It is something we should discuss for user-defined declared functions (#123).

Should the functions section work like the _types sections in that they are namespaced? If so, I would suggest this syntax:

$ubct:sqrt

because it wouldn't break the algorithm and wouldn't complicate escaping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

3 participants