OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

tosca message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: New syntax for function calls


We discussed this proposal in the ad hoc today. We generally agree that going with a prefix is the best choice, and that perhaps "$" would be the best prefix, as it would be least likely to cause conflicts. See YAML 1.2 and YAML 1.1, specifically the "Indicators" section in the Index, as well as "Example 5.10" and "Example 5.9" (the grave character was added in YAML 1.2 as reserved for future use). YAML already stole all the best characters, so "$" remains. :)

We discussed two approaches to parsing:

"BROAD" PROPOSAL

Any string value that begins with an unescaped "$" would be considered an "_expression_". This includes map keys, including a-map-with-a-single-string-key-that-has-a-list-as-its-value, which is our conventional function format. But this also leaves the door open to other kinds of special values, such as magic words and other special features.

There's a lot of flexibility in this approach in that it can allow implementations based on anything you can do in YAML, including notations that we do not currently use in TOSCA. A few examples:

# Using our current function signature
my-property: { $get_env: [ USER ] }

# A custom function signature: string argument
my-property: { $get_env: USER }

# A custom function signature: map argument
my-property: { $get_env: { local: USER } }

# A custom string
my-property: $env.USER

# A custom key
my-property:
 key1: value1
 key2: value2
 $sorted: ascending

# A custom list element
my-property:
 - value1
 - value2
 - { $sorted: ascending }

It might also be a good idea to disallow node template names from beginning with an unescaped "$". The reason is that a common use case for the "custom string" might be for "modelable entity names" in functions like $get_property and $get_attribute, namely the built-in $self, $source, and $target. This rule would thus avoid potential ambiguities.

The pros of this "broad" approach are:
  1. Lots of flexibility! Many cool syntax varieties and features are possible.
  2. Straightforward parsing: any string beginning with an unescaped "$" is an _expression_ (meaning that it will not be treated as a string value).
  3. This does mean that users will have to pay attention and escape any actual string value beginning with "$". Though note that if they make a mistake they should get a clear error.
The major con of this approach is the lack of a specified function syntax. The fact that TOSCA's built-in functions are all a-map-with-a-single-string-key-that-has-a-list-as-its-value would simply become our convention. However, it's really more than a convention in TOSCA right now, because TOSCA supports nested function calls:

my-property: { $concat: [ { $get_property: [ $self, name ] }, -suffix ] }

If we let "$" be entirely implementation-specific then the TOSCA parser won't know to look into the values (function arguments in this case) and parse them first and somehow embed that _expression_ evaluation.

The workaround would be to say that the TOSCA parser *will* parse "$" values even if they are embedded inside other "$" values. This might sound obvious, but it's non-trivial: it means that custom implementations will not actually have complete control over their values. To me that's a reasonable compromise, even if it limits the flexibility a bit.

"NARROW" PROPOSAL

This is more conservative. The idea is to keep the current TOSCA syntactic conventions for function calls. So, the "$" prefixed strings would only apply to a-map-with-a-single-string-key-that-has-a-list-as-its-value. Additionally, we are assuming that every argument in the list is itself a value, which in turn could also be a "$" function call.

We can furthermore specify that an unknown function name is *not* an error. This will ensure better portability than the "broad" proposal. A TOSCA parser encountering an unrecognized function can just assume that it returns a value of the correct type. It can go further and insert a function call stub (this is what Puccini does), which could then be implemented by the runtime environment itself.

There is additionally another variant of this proposal that would allow for "special words". This is just syntactic sugar for function calls with no arguments, the ability to make these two equivalent:

my-property: { $get_property: [ { $host: [] }, name ] }
my-property: { $get_property: [ $host, name ] }

Note that there's a risk with this variant of turning it into the "broad" proposal above, because this means that any bare string value (but not a map key) needs to be checked for the "$" prefix. The workaround is to restrict this syntactic sugar to be *only* for function arguments. So the following would *not* be a function call, because it's not a function argument:

my-property: $host

Also, again node template names should be disallowed from beginning with an unescaped "$".

Pros:
  1. Keep TOSCA from becoming too weird.
  2. Better portability, as noted above.
  3. Clearer error messages.
Cons:
  1. Not very straightforward parsing. The "broad" approach is straightforward.
  2. Too narrow. Why not allow the freedom that the "broad" approach allows?
"COMBINED" PROPOSAL

Bear with me here, this might sound complex but it really isn't very. :)

The idea is to allow the use of "$" everywhere, just like the "broad" proposal. However, if the "$" is structured as a-map-with-a-single-string-key-that-has-a-list-as-its-value then will consider it specifically to be a function call, meaning that again unrecognized function names do not have to emit and error and can be implemented as stubs.

This does mix some of the pros and cons of both approaches.

MY THOUGHTS

Implementations will do whatever they want anyway. However, I do think the idea of recognizing function calls, specifically, is an important and portable feature. Thus I am leaning on the "combined" proposal.


On Tue, Apr 6, 2021 at 10:35 AM Tal Liron <tliron@redhat.com> wrote:
As a corollary to my proposal for a prefix character for function names, I would add that we would need a prefix character for our "magic names", too, and for many of the same reasons. Here's a simple example that shows the problem:

topology_template:
 node_templates:
  SELF:
ÂÂÂÂÂ type: ServerPool
ÂÂÂÂÂ properties:
ÂÂÂÂÂÂÂ name: mypool

ÂÂÂ IMPLEMENTATION:
ÂÂÂÂÂ type: Server
ÂÂÂÂÂ properties:
ÂÂÂÂÂÂÂ name: nyname
ÂÂÂÂÂÂÂ additional_name: { @get_property [ SELF, name ] } # here we mean ourselves
ÂÂÂÂÂÂÂ pool_name: { @get_property [ SELF, name ] } # here we mean the node template named 'SELF'

The above is obviously broken in TOSCA. Basically all the magic keywords cannot be used as template names. This doesn't sound like a big deal, but certain edge cases can be problematic, e.g. a TOSCA code generator. Let's fix this by using a prefix (which is again escapable by doubling):

topology_template:
 node_templates:
  SELF:
ÂÂÂÂÂ type: ServerPool
ÂÂÂÂÂ properties:
ÂÂÂÂÂÂÂ name: mypool

ÂÂÂ IMPLEMENTATION:
ÂÂÂÂÂ type: Server
ÂÂÂÂÂ properties:
ÂÂÂÂÂÂÂ name: nyname
ÂÂÂÂÂÂÂ additional_name: { @get_property [ @self, name ] } # no ambiguity, magic name is prefixed
ÂÂÂÂÂÂÂ pool_name: { @get_property [ SELF, name ] } # no ambiguity, it's a template name

The escaping rule is very clear (use "@@" for anything that needs to begin with "@") and is deterministically possible to algortihmize into things like TOSCA generators without them having to be hardcoded with a list of forbidden magic names.

Another aspect to this -- if we want to talk about allowing TOSCA to be extended by adding custom functions, it's very useful in the same context to talk about extending via custom magic names. From an implementation perspective they really are the same, there's just a simpler syntax allowed here for a zero argument function call. E.g. you can think of the "@self" magic name as syntactically equivalent to this:

 value: { @self: [] }

I think it's worth allowing this if we already want to allow custom functions, as it can lead to cleaner syntax. For example, there would be a way here to recreate the Simple Profile's "HOST" magic name. This is a feature we removed from TOSCA 2.0 for good reasons -- it's extremely implementation-specific. Well, then, specific implementations of TOSCA could allow for such useful features by such grammatical extensions.



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]