Skip to content

Change the syntax of the #open and /close function calls #398

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

Closed
wants to merge 3 commits into from

Conversation

stasm
Copy link
Collaborator

@stasm stasm commented Jun 19, 2023

This is an alternative to #397, which I'd like to collect feedback on. It's an attempt to find a pair of convenient single-char-long prefixes which don't conflict with signed number literals.

The opening syntax, \func, is inspired by TeX. The closing syntax, /func, is inspired by HTML.


July 2 Update

I've morphed this PR to propose {#open}...{/close}. See #398 (comment).

main: {+button title=|Click me!|}Submit{-button}
#397: {::button title=|Click me!|}Submit{:/button}
this: {#button title=|Click me!|}Submit{/button}

This is an alternative to unicode-org#397, which I'd like to collect feedback on.

	main: {+button title=|Click me!|}Submit{-button}
	unicode-org#397: {::button title=|Click me!|}Submit{:/button}
	this: {\button title=|Click me!|}Submit{/button}

It's an attempt to find a pair of convenient single-char-long prefixes which don't conflict with signed number literals.

The opening syntax, `\func`, is inspired by TeX. The closing syntax, `/func`, is inspired by HTML.
@stasm stasm force-pushed the open-close-slashes branch from eeae91d to a8894f9 Compare June 19, 2023 09:04
@aphillips aphillips added the Agenda+ Requested for upcoming teleconference label Jun 19, 2023
@eemeli eemeli mentioned this pull request Jun 19, 2023
@stasm
Copy link
Collaborator Author

stasm commented Jun 26, 2023

If \open is considered problematic, e.g. due to troubles of escaping it, we could also consider #open.

There's also prior work of using {#foo} ... {/foo} for block content in at least two templating languages:

@eemeli
Copy link
Collaborator

eemeli commented Jun 30, 2023

If \open is considered problematic, e.g. due to troubles of escaping it, we could also consider #open.

I would consider \open as problematic, given that we're using \ as an escape character, and that we've otherwise taken pains to avoid characters like " that often require escaping in whatever container MF2 syntax content is placed.

There's also prior work of using {#foo} ... {/foo} for block content in at least two templating languages:

Looking at these examples, the sense I get is that there's well-established precedent in templating languages for something like {#foo} ... {/foo} to be denoting parts of content that may appear in the result 0, 1, or N times depending on some condition.

This seems like a completely different meaning than our intended use for "open" and "close" indicators?

@stasm
Copy link
Collaborator Author

stasm commented Jun 30, 2023

If \open is considered problematic, e.g. due to troubles of escaping it, we could also consider #open.

I would consider \open as problematic, given that we're using \ as an escape character, and that we've otherwise taken pains to avoid characters like " that often require escaping in whatever container MF2 syntax content is placed.

You're right, we made an effort to avoid certain characters, and \open would bring back some of the issues that we wanted to prevent. I'm going to close or morph this PR.

@stasm
Copy link
Collaborator Author

stasm commented Jun 30, 2023

There's also prior work of using {#foo} ... {/foo} for block content in at least two templating languages:

Looking at these examples, the sense I get is that there's well-established precedent in templating languages for something like {#foo} ... {/foo} to be denoting parts of content that may appear in the result 0, 1, or N times depending on some condition.

This seems like a completely different meaning than our intended use for "open" and "close" indicators?

Hmm, can you elaborate why you think it's different? In both of the use-cases you described (repetition and open/close) there's need for something that denotes the beginning of a block and the end. I see {#foo} ... {/foo} as yet another syntax for blocks: other languages achieve this as { ... }, begin ... end, or <foo> ... </foo>.

@eemeli
Copy link
Collaborator

eemeli commented Jun 30, 2023

With the existing meanings of {#foo} ... {/foo}, the start and end tags are not at all included in the output, and the body between them may or may not be included; possibly more than once as a result of some iteration. In our output, we would like each of the start, body, and end to be processed separately, and to each nominally produce something for the output.

So while the syntax is roughly similar, the existing usage of this particular start/end pair carries a clear pre-existing semantic meaning for the tags.

Our usage is more like the <foo> ... </foo> example you give, which one would expect to produce a foo element in the output.

@stasm
Copy link
Collaborator Author

stasm commented Jul 2, 2023

I pushed a commit to this PR which changes the placeholder-open syntax from \open to #open. After consideration, I agree that using the backslash could cause escaping problems. Let's continue discussing the {#open}...{/close} syntax here.

@stasm stasm changed the title Change the syntax of the \open and /close function calls Change the syntax of the #open and /close function calls Jul 2, 2023
@stasm
Copy link
Collaborator Author

stasm commented Jul 2, 2023

So while the syntax is roughly similar, the existing usage of this particular start/end pair carries a clear pre-existing semantic meaning for the tags.

There are different semantics: condition, repetition, nesting, overlapping, etc. All of them can be expressed in writing with some sort of a "block" syntax. I don't see {#foo}...{/foo} suggesting one particular semantic stronger than others. It's a block syntax with a semantic of our choosing.

@aphillips
Copy link
Member

We spent a long time previously discussing open/close semantics, including the ability to have only open or only close placeholders (unpaired) in a message. Where we arrived is that :, +, and - are really just synonyms (notwithstanding the text in the spec about +/- being for paired use). We have not yet specified if functions that share names but not sigils such as :foo and +foo and -foo are synonyms or are somehow distinct.

If we don't define rules for pairing (perhaps in the registry), we aren't really changing this. Each placeholder only controls the content of its expression (that is, the space between the {/}).

If we want block-like syntax or required-to-be-paired placeholders, maybe they should have separate identifiers. I think I'd prefer not to invent a large variety of sigils for different uses (:foo, #open, /close, +openPaired, -closePaired, %block, etc.).

Maybe a question would be: Should we provide function signatures that are required to be paired (as a convenience to function authors)? I understand that there can be messages that contain only an open or close tag for a markup language, but what if the output you're trying to make is an attributed string rather than markup? Should there be a way to make some (not all) unpaired functions an error?

Perhaps instead of a zoo of sigils, would it make sense to establish naming conventions for pairing (perhaps with corresponding description in the registry)? What about:

{This has a simple placeholder {:function}}
{This has a standalone {:#openFunction}} // which could be named :openFunction??
{ while this has the standalone {:/closeFunction}} // it's name would probably actually be :/openFunction
{This has required-to-be-paired placeholders {:+open}around{:-open} text or expressions}

@stasm
Copy link
Collaborator Author

stasm commented Jul 2, 2023

I don't think we want to express the notion of required-to-be-paired placeholders in the syntax. Instead, I was under the impression that we wanted three kinds of placeholder "markers" (standalone, open, close) without defining the semantics of what "open" or "close" mean. Each custom function which chooses to have an open/close variant can choose what it means for the message content.

I'd like to approach the whole problem space holistically: write down what sort of different placeholder types we want and what requirements for identifier names and unquoted literals we have, and then design the syntax from that. Right now we have a few related discussions in flight: #399, #403, #404, and they could benefit from an up-leveling of the conversation.

I'm also happy to discuss a single sigil + a set of naming conventions based on the same requirements as above.

@stasm stasm marked this pull request as ready for review July 3, 2023 09:49
@eemeli
Copy link
Collaborator

eemeli commented Jul 3, 2023

There are different semantics: condition, repetition, nesting, overlapping, etc. All of them can be expressed in writing with some sort of a "block" syntax. I don't see {#foo}...{/foo} suggesting one particular semantic stronger than others. It's a block syntax with a semantic of our choosing.

@stasm Can you point to any prior usage of {#foo}...{/foo} where the #foo or /foo itself shows up in any way in the result? In all the uses I'm aware of, it's dropped out. To me, it seems more like it's filling a role like our let and match statements, kinda like this if we were to invert our initial state:

{#match $count :number}
{#when 1}You have one notification.
{#when *}You have {$count} notifications.
{/match}

@stasm
Copy link
Collaborator Author

stasm commented Jul 3, 2023

@stasm Can you point to any prior usage of {#foo}...{/foo} where the #foo or /foo itself shows up in any way in the result? In all the uses I'm aware of, it's dropped out.

I'm not trying to argue that there is a prior usage of {#foo}...{/foo} that matches our semantics precisely. I'm only saying that there's prior art in using {#foo}...{/foo} to represent start-close syntax.

To me, it seems more like it's filling a role like our let and match statements, kinda like this if we were to invert our initial state:

{#match $count :number}
{#when 1}You have one notification.
{#when *}You have {$count} notifications.
{/match}

Thanks for this example, I think I understand your point of view better now. If this was indeed our syntax today, then I think I'd agree with you in that I'd expect {#foo}...{/foo} to also have control flow semantics. However — and also crucially — our syntax is different and I see no conflict in using {#foo}...{/foo} for open and close placeholders.

@gibson042
Copy link
Collaborator

#399 (comment) (emphasis added):

If XML Nmtoken is sufficiently important to use as a foundation for unquoted literals, then having overlap between it and function prefix sigils seems like an unnecessary misstep. Without dragging this too far into the weeds, I will note that most ASCII punctuation characters are excluded from NameChar and therefore available for that use in MF2, particularly all of those that are currently included in reserved-start = "!" / "@" / "#" / "%" / "^" / "&" / "*" / "<" / ">" / "?" / "~". Accordingly, of the three PRs relating to unquoted negative number operands, I think {#open}...{/close} of #398 heads in the best direction (although it would still need to replace {:functionName} with something like {!functionName} so that valid Nmtoken instances like ":functionName" can be used as unquoted operands).

@stasm
Copy link
Collaborator Author

stasm commented Jul 12, 2023

I'm going to close this for now, while I prepare a document about a more holistic sigil design.

@stasm stasm closed this Jul 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Agenda+ Requested for upcoming teleconference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants