Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port environments.js to @flow. #862

Merged
merged 2 commits into from Sep 10, 2017
Merged

Conversation

marcianx
Copy link
Collaborator

@marcianx marcianx commented Sep 9, 2017

Fixes #859.
Sits on top of PR 860, which needs to be submitted first!

@marcianx marcianx changed the title Flow environment Port environment.js to @flow. Sep 9, 2017
@marcianx marcianx changed the title Port environment.js to @flow. Port environments.js to @flow. Sep 9, 2017
envName: string,
parser: Parser,
positions: number[],
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 4 space tab.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oi! Time to change my vim defaults. I keep forgetting to set it to 4 spaces in every new session. ;)

* List of ParseNodes followed by an array of positions.
* Returned by `Parser`'s `parseArguments`.
*/
type ParseResult = (ParseNode | number[])[] | ParseNode;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do we return a result with type number[][]?

Copy link
Collaborator Author

@marcianx marcianx Sep 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parser's parseArgument always returns the list of positions as the last element.
So it returns something of the format [ParseNode, ParseNode, ..., ParseNode, number[]]. So this happens any time you see a defineFunction with code like

    res = parseArray(context.parser, res, "display");
    return res;

We need to refactor this at some point, but I'd rather do it right before or during ParseNode being ported. It would help to have maximal support from type-safety while doing this since ParseResult is simply stored here and used various places (including possible buildHtml, but I haven't read that part of the code base yet).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, it's documented in the comment above.

We need to refactor this at some point, but I'd rather do it right before or during ParseNode being ported.

Sounds good.

allowedInText: boolean,
numOptionalArgs: number,
handler: EnvHandler,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks suspiciously similar to how functions are typed. We might be able to dedupe in future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: Looking at defineFunction.js I don't currently see any benefit in coalescing.

  1. We don't really need any subtype relationship.
  2. For object/struct types, there's not really an extends type behavior AFAICS (please correct me if I'm wrong), so we would need to repeat the fields anyway when defining it.

* - numArgs: (default 0) The number of arguments after the \begin{name} function.
* - argTypes: (optional) Just like for a function
* - allowedInText: (default false) Whether or not the environment is allowed
* i nside text mode (not enforced yet).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i nside => inside

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

pregap?: number,
postgap?: number,
};
type EnvNodeData = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArrayEnvNode or ArrayNode would be better as this type is specific to arrays. For consistency ArrayColSpec could be AlignNode and we could even introduce a SeparateNode type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArrayEnvNode is more descriptive. So I'm using that.
Is AlignNode the most appropriate name? It's not a ParseNode.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, per ArrayEnvNode, it's not a ParseNode, but the data stored in the ParseNode. Would you still prefer to call it ArrayEnvNode? Or would ArrayEnvNodeData (a little long, I know) be more appropriate to avoid confusion?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the currently-pushed version, I went with AlignSpec and ArrayEnvNodeData. I'm very open to changing per your feedback.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a need to differentiate parse nodes from environment nodes as they end up being part of the same tree at the end of the day. I think eventually we'll types for each of the different nodes the parser can generate and eventually ParseNode will become:

ParseNode = FracNode | ExpNode | ... | ArrayNode | AlignNode | ... 

Environments are just one type of thing that the parser parses as it does its work, it just happens that the environment parsing code is in a separate file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I didn't quite understand this comment and the future evolution you intend. What I meant was: for result: ArrayEnvNodeData, we have

    return new ParseNode(result.type, result, parser.mode);

So the ParseNode instance contains a payload that is of type ArrayEnvNodeData struct, which is why I was thinking about the Data suffix.

So did you mean that the payload would become a union type (e.g. ParseNodeData or something briefer)?
I'm guessing you didn't mean that the ParseNode class would be dissolved in favor of a union type (given that we still want to encapsulate the common tokenizer metadata for error reporting)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that eventually we'd have a union type to specify the different types in the tree. It's possible that ParseNode wraps these data nodes and adds additional data like error reporting. I have spent any time thinking trough the details. The high-level goal is for nodes with in the parse tree to be more regular and for all them to be statically typed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so what you're saying is that the payload of ParseNode is still considered an undecorated "Node". And hence we should use the Node suffix rather than NodeData?
Is that your preference?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see that you merged it. Please LMK what nomenclature you had in mind. I'm happy to update these as we continue in the future.

let row = [];
const body = [row];
const rowGaps = [];
while (true) {
for (;;) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that was just to get rid of the eslint suppression at the top (personally a fan of maximal linting). However, that's not my favorite lint anyway; and I can revert this if you like.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. This is fine. We can re-evaluate lint rules separately.

parser: Parser,
result: EnvNodeData,
style: StyleStr,
) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

*/
function defineEnvironment(names, props, handler) {
function defineEnvironment(
names: string | string[],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We updated defineFucntion to only take an array of strings. We should probably do the same here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

function defineEnvironment(names, props, handler) {
function defineEnvironment(
names: string | string[],
props: EnvProps | number,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defineFunction doesn't support taking a number for props, we should do the same here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@kevinbarabash kevinbarabash merged commit 1c344ed into KaTeX:master Sep 10, 2017
@kevinbarabash
Copy link
Member

@marcianx thanks for the PR. It's exciting to see all of these implicit types being made explicit.

@marcianx marcianx deleted the flow-environment branch September 10, 2017 00:32
marcianx added a commit to marcianx/KaTeX that referenced this pull request Sep 10, 2017
* Port environment.js to @flow.

* Updated per comments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants