links-lang / links

Links: Linking Theory to Practice for the Web
http://www.links-lang.org
Other
320 stars 42 forks source link

Use inline records instead of nested tuples in AST nodes #533

Open SimonJF opened 5 years ago

SimonJF commented 5 years ago

In much of the Links AST, we use long tuples to describe information attached to nodes. Take TableLit as a (random) example:

  | TableLit         of phrase * (Datatype.with_pos * (Types.datatype *
                           Types.datatype * Types.datatype) option) *
                          (name * fieldconstraint list) list * phrase * phrase

It would be more descriptive to have these as named inline records:

  | TableLit         of { tlit_table_name: phrase
                             ; tlit_record: (Datatype.with_pos * 
                                  (Types.datatype *  Types.datatype * Types.datatype) option)
                             ; tlit_field_constraints: (name * fieldconstraint list) list
                             ; tlit_table_keys: phrase
                             ; tlit_database: phrase
                             }
jstolarek commented 5 years ago

One random thought regarding this. I have mentioned in one of the comments how nicely inline records work in GHC source code. However, Haskell allows to match record fields based on their positions, e.g.:

data F = A { a :: Int, b :: String    }
       | B { a :: Int, c :: Maybe Int }

foo :: F -> Int
foo (A x _) = x
foo (B _ (Just y)) = y
foo (B z Nothing ) = z

As far as I know OCaml does not have such a feature. We can rely on field punning to some extent, but some pattern matches are still likely to become very verbose, e.g.:

foo (TableLit { tlit_table_name; tlit_record = Some (pos, ty1, ty2, ty3)
              ; tlit_field_constraints = []; tlit_table_keys; _ }) = ...

instead of:

foo (TableLit ( name; Some (pos, ty1, ty2, ty3); []; keys; _ )) = ...
jstolarek commented 5 years ago

I wonder whether we could make a first step towards this by having someone who actually understand the whole AST to write comments in the code detailing what each of the fields does, e.g.:

  | Conditional      of phrase * (* if condition *)
                        phrase * (* then branch  *)
                        phrase   (* else branch  *)