Skip to content

Type safety in the reducer #190

@bakkot

Description

@bakkot

Currently the reducer has methods which look like

public State reduceClassDeclaration(
  ClassDeclaration node,
  State name,
  Maybe<State> _super,
  ImmutableList<State> elements
)

where of course ClassDeclaration is shaped like

class ClassDeclaration(
  BindingIdentifier name,
  Maybe<Expression> _super,
  ImmutableList<ClassElement> elements
)

There is a guarantee provided by the director, but not the type system, that the fields of the node and the noninitial arguments of the method line up, in the sense that node._super.isJust() == _super.isJust(), node.elements.length == elements.length, etc.

The fact that this isn't enforced by the type system leads to a lot of unchecked .fromJust()s. We could avoid this by defining, for each node type, a node-with-associated-data type along the lines of

<T> class ClassDeclarationWithT(
  Pair<BindingIdentifierWith, T> name,
  Maybe<Pair<Expression, T>> _super,
  ImmutableList<Pair<ClassElementWith, T>> elements
)

and then making the signature of methods in Reducer<State> be

public State reduceClassDeclaration(
  ClassDeclarationWithT<State> state
)

This does have the downside that you don't get a reference to the original node, which the LazyCloneReducer among other interfaces wast - for example, you need the original node to look up its location in the data structure provided by ParserWithLocation. I suppose it could always be passed as a second argument for those cases.

You can of course automatically convert between reducers of this type and reducers of the existing type, though going from reducers of the existing type to reducers of this type requires having all those unchecked .fromJust()s.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions