patty icon indicating copy to clipboard operation
patty copied to clipboard

Simple macro to make some variants that have same fields

Open loloicci opened this issue 5 years ago • 7 comments

We want simple syntax (macro) to make some variants that have same fields.

like

variant Shape:
  Circle(radius: float)
  Square(diagonal: float)
  Rectangle, Ellipse (width: float, height: float)

?

Originally posted by @Quelklef in https://github.com/andreaferretti/patty/issues/17#issuecomment-417893450

loloicci avatar Nov 13 '18 05:11 loloicci

This causes invalid indentation. So, another form of macro is needed if we implement this.

 Hint: this [Processing]
 Hint: macros [Processing]
 Hint: sequtils [Processing]
 this.nim(6, 12) Error: invalid indentation

loloicci avatar Nov 13 '18 05:11 loloicci

If it's complaining about invalid indentation, then it's a syntax error and there's nothing that can be done. Macros don't work on the same level as the parser and cannot affect parsing. I had only posted that snippet as an example, not as a proposal for actual syntax.

Quelklef avatar Nov 13 '18 12:11 Quelklef

Yes, and I make this issue for discussing what syntax is suit to represent the wanted object type.

loloicci avatar Nov 13 '18 13:11 loloicci

Ah, sorry, I misunderstood.

It would be nice to just allow

variant Shape:
  ...
  Rectangle(width: float, height: float)
  Ellipse(width: float, height: float)

but I imagine that this would be difficult to implement since you would have to detect and combine equivalent variants.

Also, this would come with some surprises. If I then wanted to add

  Cylinder(radius: float, height: float)

this would seem reasonable to a user but can't be done due to Nim restraints on variant types.

Quelklef avatar Nov 13 '18 13:11 Quelklef

I don't see why the example with cylinder could not be done. It would share radius with Circle and height with Rectangle and Ellipse. It would be a little tedious to group all variables correctly, but I think it can be made to work

It would need to generate

type
  ShapeKind = enum
    Circle, Square, Rectangle, Ellipse, Cylinder
  Shape = object
    case kind: ShapeKind
    of Circle, Cylinder:
      radius: float
    of Square:
      diagonal: float
    of Rectangle, Ellipse:
      width: float
    of Rectangle, Cylinder:
      height: float

I did not test that but I believe it's valid Nim

andreaferretti avatar Nov 13 '18 16:11 andreaferretti

Uhm , actually it gives in.nim(12, 8) Error: duplicate case label in the Nim playground

If I recall correctly there was a discussion on the Nim issue tracker just about this case

andreaferretti avatar Nov 13 '18 16:11 andreaferretti

Here is the discussion. @Araq mentions a possible improvement that could be used to make this work, but which is not inside Nim yet

andreaferretti avatar Nov 13 '18 16:11 andreaferretti