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

"{c| |c}" does not supported nested use case #6856

Closed
vicuna opened this issue May 5, 2015 · 20 comments
Closed

"{c| |c}" does not supported nested use case #6856

vicuna opened this issue May 5, 2015 · 20 comments

Comments

@vicuna
Copy link

vicuna commented May 5, 2015

Original bug ID: 6856
Reporter: @bobzhang
Status: closed (set by @alainfrisch on 2016-01-27T08:25:00Z)
Resolution: suspended
Priority: normal
Severity: feature
Target version: 4.03.0+dev / +beta1
Category: ~DO NOT USE (was: OCaml general)
Monitored by: @gasche @hcarty

Bug description

for example
{c| {c| |c} |c} is an invalid syntax

{c| {i| {c| |c} |i} |c} still invalid

This makes the quote less useful(especially when you want antiquot, or string interpolation), I will help implement it if people are happy with this change

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @alainfrisch

It's the purpose of {id|...|id} that nothing is recognized specially within the string content except the closing delimiter |id}. In particular, we don't want to tokenize the content. It would be quite weird to support inner quoted strings, but not normal ones:

{c| "|c} "..."

To avoid the problem, you could simply use a different delimiter.

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @bobzhang

using a different delimiter is ugly, but not scalable, so if I want nested depth to be three, I need three delimiters.

For me it's natural that
{c| {c| |c} |c} is valid

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @alainfrisch

And what about:

{c| (* |c} *) |c}
{c| " |c} " |c}

?

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @lpw25

using a different delimiter is ugly, but not scalable, so if I want nested depth to be three, I need three delimiters.

It is scalable, you can use a delimiter of any length and therefore support nesting of any depth.

Note that ppx transformers should not be using the delimiter of quotes to recognise their syntax. They should instead be used with a syntax like:

[%c {| ... |}]

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @bobzhang

@Frisch,
Actually, that's something I think should all be valid for least surprise, I did implement fan's quasiquotation that way.

@lpw25, [%c{| |} ] is heavy weight, how do you get nested quote work in your case, for example, depth 3? I don't think users like to change the name of delimiter ..

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @bobzhang

you mean something like this ?
[%c{| ... {a| {i| |i} |a}|} ]

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @alainfrisch

The {| |} is really an alternative form of string literals, intended to inject foreign syntax without "suffering" from normal lexical convention of string literals, in particular the presence of special characters that require escaping, hence the explicit choice of the "delimiter", which avoids the need for any special character (at the cost of having to pick a proper delimiter which is not part of the content). It's an important feature that a double quote can appear in the content without being interpreted in a special way, so supporting

{| "|}" |}

is really not an option.

Can you give your intended use case? Could a simple extension node, with the content being parsed with OCaml grammar, be an option for you?

@vicuna
Copy link
Author

vicuna commented May 5, 2015

Comment author: @lpw25

you mean something like this ?
[%c{| ... {a| {i| |i} |a}|} ]

Basically, with nested quotation/anti-quotation I guess it would be something like:

[%quote {| ... [%antiquote {x| ... [%quote {xx| ... |xx}] ... |x}] ... |}]

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @bobzhang

@Frisch, you can still have " inside {| |}, the only requirement is that it should be paired.
{| "|}" |} -- valid
{| "ghsoghso" |} -- valid
{| " |} -- invalid
I think this covers most use cases, having unpaired " will also make syntax highlighting not working, user should do something like this
{| " |}

@lpw it is too heavy weight, correct me if I am wrong

  1. you can not prevent user write [%c xxx {| |} ]
  2. [%c ] still uses ocaml syntax..

Take ruby for example(which is normal behavior I believe):

~>irb
irb(main):001:0> %Q[ %Q[ ] ]
=> " %Q[ ] "
irb(main):002:0> %Q[ ] ]
SyntaxError: (irb):2: syntax error, unexpected ']', expecting $end
from /opt/swt/bin/irb:12:in `

'

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @alainfrisch

An explicit goal of {|...|} is to allow injecting arbitrary foreign syntax without requiring any escaping. One could write for instance:

let js = {| alert(' Double-quote: " '); |} in
...

Not that even with OCaml code, " can be unmatched (e.g. because of the character literal '"').

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @lpw25

you can still have " inside {| |}, the only requirement is that it should be paired.

The whole point of {| ... |} is to avoid that kind of crap. Why should " always have to be paired for all DSLs?

@lpw it is too heavy weight, correct me if I am wrong

  1. you can not prevent user write [%c xxx {| |} ]
  2. [%c ] still uses ocaml syntax..

Just emit an error if the extension node contains something other than a string literal.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @bobzhang

it's not arbitrary syntax, you always have to make trade off
let js = {| alert (' {| |}'); |} -- invalid
I think ruby's way is more intuitive and well thought, there is an easy walk around for unmatched '"' which is not common, but the workaround for nested quotes is not acceptable(too verbose, and changing delimiters)

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @lpw25

it's not arbitrary syntax, you always have to make trade off

It is arbitrary syntax. For any arbitrary piece of syntax, that syntax can be included as an OCaml string without modification. This is not true of any other scheme, based on ad-hoc rules for counting pairs of delimiters and escaping arbitrary characters.

I think the point you are missing is that many things which are useful to quote are not OCaml syntax -- and restricting them to respect OCaml's lexical conventions (e.g. " must be matched, unless within a pair of ') is painful.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @bobzhang

do you see my example?
let js = {| alert (' {| |}'); |} -- invalid

it's not ocaml's convention, it's convention for most languges. I think the most benefit for {| |} is that you can write
{| "nice" |} instead of " "nice" " which is available under both solutions.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @lpw25

do you see my example?
let js = {| alert (' {| |}'); |} -- invalid

let js = {x| alert (' {| |}'); |x} -- valid

I think the most benefit for {| |} is that you can write
{| "nice" |} instead of " "nice" " which is available under both solutions.

The main benefit of {| ... |} is being able to produce any string without having to change anything about the string itself. This is not available in any solution which treats other delimiters (e.g. ", ') specially.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @lpw25

The main benefit of {| ... |} is being able to produce any string without having to change anything about the string itself. This is not available in any solution which treats other delimiters (e.g. ", ') specially.

It is worth noting that this does not preclude treating the delimiter itself as special. For example,

{x| {x| |x}

could be treated as a syntax error, since:

{y| {x| |y}

can be used in that case. In other words, nesting can be supported but must ignore other delimiters.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @gasche

hongboz: the way i think of it is that if you want to make some string $FOO a string literal, you need to find a (possibly-empty) word "bar" such that "|bar}" does not appear in $FOO, and then use {bar|$FOO|bar}.

That is, you should not think like

I just wrote {| |}, am I allowed to put (alert ('{| |}')) inside?
(in which case you feel restricted) but rather
I want to write (alert ('{| |}')), which delimiters should I choose?
(there is always an infinite number of possible choices)

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @bobzhang

I understand changing delimiters have more coverage, however, if you write quote/antiquote a lot, such heavy syntax is very disappointing. another thing, delimiters means some semantics, here we have to treat all delimiters in the same way.

If we only used {| |} for convenient string literals, it's ok. but if we want to use {||} for delimited domain specific languages, I found current syntax support was lacking.

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @bobzhang

for example, if I have a delimited dsl called x,
{x| |x}
if I want to use dsl x inside x, then I have to change it another name y, then if I want depth 3, I should give it three names....

{||} seems only suffice to replace ""

@vicuna
Copy link
Author

vicuna commented May 6, 2015

Comment author: @lpw25

for example, if I have a delimited dsl called x,
{x| |x}
if I want to use dsl x inside x, then I have to change it another name y, then > if I want depth 3, I should give it three names....

As mentioned previously, the intention is to use [%x {| |}] in that situation.

@vicuna vicuna closed this as completed Jan 27, 2016
@vicuna vicuna added this to the 4.03.0 milestone Mar 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant