Giter Club home page Giter Club logo

Comments (10)

mflatt avatar mflatt commented on June 20, 2024

What if you switched the roles of () and [], so that parentheses are used in most places and [] is for grouping? Or what if {} was used for grouping and () and [] left more like shrubbery notation?

FYI, I changed the parser in the package implementing #163, because I think the pop quiz here pointed to a mismatch between the prose spec and the implementation. The point stands that the result is not obvious.

from rhombus-prototype.

michaelballantyne avatar michaelballantyne commented on June 20, 2024

What if you switched the roles of () and [], so that parentheses are used in most places and [] is for grouping? Or what if {} was used for grouping and () and [] left more like shrubbery notation?

Assuming a parsed representation that uses tags, neither of these deeply bothers me but I think they run counter to the most common associations of each delimiter.

from rhombus-prototype.

gus-massa avatar gus-massa commented on June 20, 2024

I think that Mathematica use a similar system, where scare brackets are used for function definition and application, and parenthesis are used only in math expressions.

from rhombus-prototype.

mflatt avatar mflatt commented on June 20, 2024

I'm trying to figure out how essential it is to equate a group with one item and that item. It seems like the sort of representation choice that usually goes wrong in subtle ways. For example, suppose a macro f rewrites f [X, Y] to X + Y. If X in a us turns out to be an identifier that is implemented by a macro, then X + Y ends up meaning that X receives + and Y. Writing the result template as (X) + (Y) doesn't do anything if (X) is the same as X at the reader level. Something like values [X] + values [Y] would mean the right thing, but you wouldn't want values [X] as macro boilterplate. Those problems are resolved if grouping is always reflected in the representation, even for single-item groups, but I'm not sure whether that creates other problems. Is representing a single-item group with a basic goal here, so that extra parentheses can be wrapped around any group whether or not its in an expression position, or is it less important than that overall?

It looks like the area several bugs in the parsing of fib. Here's an attempt to repair:

 (define fib [n]
   {(cond
     {{(n == 0 {0})}
      {(n == 1 {1})}
      {(else {(fib [(n - 1)] + fib [(n - 2)])})}})})

from rhombus-prototype.

michaelballantyne avatar michaelballantyne commented on June 20, 2024

Thanks for the repair to fib; I've updated the text.

The problem with dropping parens is interesting. The goal of normalizing parens was to avoid situations where macros break due to extra parens that are used to disambiguate. For example, writing cond on one line requires parens, and I'd like to make sure all these parse the same:

cond | (x < 5: #t) | (else: #f)

cond
| (x < 5: #t)
| (else: #f)

cond
| x < 5: #t
| else: #f

That way the cond macro doesn't have to have additional cases for an explicitly-parenthesized alternative body.

The idea of x + y and (x) + y both successfully parsing but with different answers bothers me. This gets back to my other comment on enforestation. I would prefer a more structured system in which a macro never consumes a variable amount of syntax, and where parsing an undelimited region can be accomplished using information about operator arities and argument contexts before macros expand. But I'd need to read your enforestation and Rhombus syntax proposals more deeply to understand how compatible that goal is with the rest of the design.

from rhombus-prototype.

mflatt avatar mflatt commented on June 20, 2024

Thanks for the clarification.

I can appreciate the goal of allowing parentheses to group without interfering with matching. I expected that kind of interference with shrubbery parentheses, but for what it's worth, it hasn't turned out to be a problem. Implementing parentheses as a specific expression, binding, etc., form has worked well. I also consider it a feature that (fun) (x): x and fun ((x)): x are not equivalent to fun (x): x. The only place where I remember extra parentheses as a problem was in an intermediate ad hoc attempt at propagating static information; the problem was resolved there by an approach that's less ad hoc.

A similar grouping idea might be applied to shrubbery notation by removing the ability of{} to create blocks, but still allow them as extra wrappers to delimit blocks. The old rules about removing redundant blocks had the same goal, but I can see how splitting the role of {} from : and | might make things simpler and better.

from rhombus-prototype.

michaelballantyne avatar michaelballantyne commented on June 20, 2024

for what it's worth, it hasn't turned out to be a problem

In that case, the parenthesis-dropping idea isn't essential. I'm not really sure I like

lambda ([x]): 1 + 2

parsing the same as

lambda [x]: 1 + 2

anyway.

So if we set that aside, as well as the goal of having orthogonal grouping and sequencing forms and its big tradeoffs, I think there are still two ideas in here I'd like to make sure come across:

  1. There is only one major lexical syntax for a given parsed syntax. I like the idea of removing {} as a way to create blocks in Shrubberies. I could see them functioning either in the way you describe as an optional delimiter for the extent of blocks:
cond | x > 5: { #t } | x < 5: { #f }

or as another grouping / sequencing form like () and [], which could be useful for things like dictionary and set literals.

  1. The notation is described not in terms of individual punctuation syntaxes, but in terms of bigger concepts. I think the Shrubbery proposal could adopt this idea. Right now the headings of the Shrubberies proposal are:
  • Grouping by lines
  • Grouping by opener-closer, including blocks
  • Group separators ; and ,
  • Grouping by indentation
  • Grouping by :
  • Grouping by |
  • Continuing a line with \

I think a syntax very similar to Shrubberies (especially if you drop {} blocks) could be described with this outline:

  • Groups
    • Whitespace-separated elements.
  • Nested groups
    • Opener-closer pairs can bracket nested groups.
  • Sequences
    • Commas within brackets form a sequence of groups contained by the bracketing form.
  • Blocks
    • : introduces a block.
    • ; or newlines separate groups in blocks
    • \ continues a group across newlines
  • Alternatives
    • | introduces alternatives.

If you keep {} blocks, they would be described as a second syntax in the blocks section rather than the sequences section.

I would find that description much easier to follow.

from rhombus-prototype.

mflatt avatar mflatt commented on June 20, 2024

I like the idea of completely separating {} from block notation. The connection between : and {} was the main idea in tonyg's racket-something, which was a starting point of shrubbery notation. But maybe because of other parts of shrubbery notation, {} hasn't been especially useful for blocks in the Rhombus experiment prototype.

The main use of {} has been for macros that consume or return definition sequences, such as implementations of binding forms. Patterns and templates for those macros used to be written as ?{ .... }, sometimes in the middle of a group. It works to change each macro protocol to use a layer of parentheses, so block patterns and templates are written as ?(: .... ). That's not as nice as ?{ .... }, but it's close, and since contexts that manipulate blocks are relatively rare, it seems like a fine tradeoff. My experiment so far haven't imposed the rule that a block must have something before it, otherwise more would be needed between ( and :.

I tried going entirely without a delimiting form for shrubbery blocks, but then there's no way to render some shrubberies that are naturally constructed through templates. For example, if t | x | y might be spliced in place of EXPR in if a | EXPR | b. (A template splice would produce the correct shrubbery structure; it's just a question of representing that structure as text.) Delimiting is rarely needed, though, so my current experiment uses « ... » for delimiting blocks, leaving {} potentially for sets and maps. A delimiting « ... » pair is allowed for the three block-creating positions: just after :, just after |, and around a sequence of |s:

x: y:« a; b »; c
if t | «if f | a | b» | y
x: if t «| a | b»; y

from rhombus-prototype.

michaelballantyne avatar michaelballantyne commented on June 20, 2024

Hmm. Now that I better understand the situations where {} is useful I feel more ambivalent. Thanks for the explanation, in any case!

from rhombus-prototype.

michaelballantyne avatar michaelballantyne commented on June 20, 2024

These do seem like situations where Square's idea of having extra parentheses be insignificant works well, however. In Square I think the first two examples would be:

x: (y: a; b); c
if t | (if f | a | b) | y

I can see how in expansion it would be useful to manipulate blocks and alts separately from their surrounding group. Perhaps Square should make (: a; b) parse as {a b} and (| a | b) parse as {{a} {b}}. Then a ?(: ... ) pattern would make sense without needing extra parens in the protocol.

from rhombus-prototype.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.