Skip to content

[RFC][Relay] Text Format Part 2 #3016

Description

@joshpoll

The following RFC is for more bikeshedding about syntax of the Relay text format not covered by #1782.

The guiding principles for syntax choices are

  • readability: Syntax should be easy to read and parse visually.
  • internal consistency: Syntax choices should be similar to each other (e.g. function definitions and function types should have similar syntax).
  • external consistency: We should strive to reuse existing syntax choices from other languages so users that are familiar with those languages have less to learn. Also existing syntax choices are usually well-thought-out.

Please provide feedback on the syntax choices below or other syntactic features you think should be discussed that weren't already agreed on in #1782.

References

RefCreate

Existing languages:
OCaml

ref 5

ReasonML

ref(5)

Relay Proposal

ref(5)

RefWrite

OCaml

r := v

ReasonML

r := v

Relay Proposal

r := v

RefRead

OCaml

!r

ReasonML (adopted because ! is already used for not)

r^

It may be temping to use &x, but this implies that any expression has a reference, whereas in ML-like languages references must be created explicitly.
Relay Proposal

!r

Prefixes seem better than postfixes, but we need to avoid ! do to ambiguity. I'm open to other suggestions.

ADTs

ReasonML

type myVariant =
  | HasNothing
  | HasSingleInt(int)
  | HasSingleTuple((int, int))
  | HasMultipleInts(int, int)
  | HasMultipleTuples((int, int), (int, int))

Rust

enum myVariant {
  HasNothing,
  HasSingleInt(int),
  HasSingleTuple((int, int)),
  HasMultipleInts(int, int),
  HasMultipleTuples((int, int), (int, int)),
}

Relay Proposal

type myVariant =
  | HasNothing
  | HasSingleInt(int)
  | HasSingleTuple((int, int))
  | HasMultipleInts(int, int)
  | HasMultipleTuples((int, int), (int, int))

Pattern Matching

ReasonML

switch (x) {
  | HasNothing => 0
  | HasSingleInt(x) => 0
  | HasSingleTuple((x, y)) => 0
  | HasMultipleInts(x, y) => 0
  | HasMultipleTuples((x, y), (q, r)) => 0
}

Rust

match x {
  HasNothing => 0,
  HasSingleInt(x) => 0,
  HasSingleTuple((x, y)) => 0,
  HasMultipleInts(x, y) => 0,
  HasMultipleTuples((x, y), (q, r)) => 0,
}

Relay Proposal

match (x) {
  | HasNothing => 0
  | HasSingleInt(x) => 0
  | HasSingleTuple((x, y)) => 0
  | HasMultipleInts(x, y) => 0
  | HasMultipleTuples((x, y), (q, r)) => 0
}

case is also a viable alternative keyword.

Generics (i.e. type arguments)

Rust

enum Option<T> {
    Some(T),
    None,
}

fn takes_anything<T>(x: T) {
    // do something with x
}
let x: Option<i32> = Some(5);
let x: Option<i64> = Some(5);

ReasonML

type Option('a) =
    | Some('a)
    | None

Scala

Some[A](a : A)

Python

Option[A] = Union[A, None]

Relay Proposal

type Option[A] =
  | Some(A)
  | None

fn takes_anything[T](%x: T) {
    // do something with %x
}

let x = Some[i32](5);
let x = Some[i64](5);

TupleGetItem

ReasonML

("foo",2,true).0 // "foo"

Rust

("foo",2,true).0 // "foo"

Scala

("foo",2,true)._1 // "foo"

Python

("foo",2,true)[0] # "foo"

Relay Proposal

("foo",2,true).0 // "foo"

Semicolons

We need to consider whether or not to use semicolons as separators in sequence operations. The pros of using semicolons is they're easier to implement and allow us to ignore newline characters when writing and parsing programs. The cons are they are more cumbersome and make the text format less python-like.

Attributes

Python

def foo(a, b, c=None, d=None):

Relay Proposal

@foo(%a, %b, %c=None, %d=None)

when the attrs type index matches the operator's attrs type index

@foo(%a, %b, BarAttrs={%c: None, %d: None})

when it doesn't.
I'm not as certain about this syntax piece, so I'm very open to suggestions here.

cc @tqchen @MarisaKirisame @jroesch @wweic @vinx13 @junrushao1994 @nhynes

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions