KittyCAD / modeling-app

The KittyCAD modeling app.
https://kittycad.io/modeling-app/download
MIT License
403 stars 35 forks source link

KCL desugaring #3415

Open adamchalmers opened 2 months ago

adamchalmers commented 2 months ago

Background

Some KCL features are just syntactic sugar. E.g. pipeline expressions are basically a more convenient way to do normal function evaluation:

f |> g(%) |> h(%) is equivalent to h(g(f()))

Problem

It's nice to add syntactic sugar, it helps users. But it comes at a cost: these sugars add more types of AST node, which complicates the executor. If we had a "smaller" language with less syntactic sugar, the language would be less pleasant for users, but the executor would be simpler.

Solution

Other languages get the best of both worlds with a "desugaring" step. Basically, they convert the user-friendly language into a very similar but smaller language, with the syntactic sugar from the nice language converted into repetitive constructs in the lower-level one.

KCL could do this! Right now we parse the AST and then execute it directly. Instead, we could add a desugaring step between parsing and executing. The desugaring step would convert pipeline expressions into a series of function applications. Then the KCL executor wouldn't need any node for PiplineExpression -- it could use fewer node types and be a smaller, simpler language.

This might not really be worth it right now, but I have idea of more syntactic sugar I'd like to add:

jtran commented 2 months ago

Yes.

A caveat with KCL is that I don't think we can just parse the sugar away. I believe we need to actually parse it into a data structure so that it can be unparsed back to a string. So we just have to be careful that any operations that we need are available.

The frontend does code transformations. So would that work on the complete, concrete syntax tree or the abstract, desugared one? I think it has to work on the complete tree so that it doesn't lose information.

jtran commented 1 month ago

Another benefit is that we could refactor the intermediate language (IL) for performance or other reasons without affecting the frontend.

From the interpreter's perspective, the tree that the frontend modifies (currently called the AST) is a public interface that is a pain to change. I know we're a long way from this, but if we ever allowed third-party packages to have their own AST modifiers, we'd need to worry about backward compatibility. The more I think about it, the more I think we would benefit from a concrete syntax tree that the frontend knows how to modify, which is separate from what we execute.

I tried to make a list of things that could be simplified in an IL.

Other benefits

I'm sure there will be others as we add conveniences.