-
Notifications
You must be signed in to change notification settings - Fork 0
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
Debate if we should add mutation to KCL #22
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Should KCL be imperative? | ||
|
||
Currently KCl tries to keep all its variables immutable. Should we allow mutation? | ||
|
||
## Why immutable | ||
|
||
- Fewer chances of bugs when variables cannot be updated | ||
- Encourages users to use higher-level constructs like patterns, that can be optimized in both KCL and the engine much more easily than a for loop. | ||
- Easy to map a specific geometric feature (e.g. a 2D polygon) to its definition in the IDE because a geometric feature is created once and then never changed, so it's fully defined at its source range. If geometry could be updated, we'd need the IDE to show where it was defined AND where the relevant change was made. | ||
- KCL is about defining geometry, not about modeling a changing system. Mutation doesn't seem necessary. | ||
|
||
## Why mutation | ||
|
||
- Mechanical engineers (MEs) will be coming from Python or JS. They will be used to imperative programming with loops and variables. The functional programming patterns (e.g. map and reduce) they'll need to engage with will be unfamiliar. | ||
- Given that we're already asking MEs to go outside their comfort zone (by coding rather than using the GUI), we should make the language as intuitive as possible. This probably means for loops. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #15 for a proposal for a 'for loop' construct which subsumes for_each, map, and reduce (in most cases) and works with immutability, and I believe is easy to teach to programmers coming from Python/JS (though the actual details of how it works are somewhat complex). |
||
- To keep KCL performant will require implementing persistant data structures. For example, to keep KCL immutable, Array.push currently clones the array into a new variable, and appends to the cloned array. It'd be much faster to just mutate the array in-place, but that'd require mutation. There are alternative high-performance immutable data structures but we'd need to understand and implement them. Certainly doable, but less immediately simple than reusing Rust's mutable datatypes. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once KittyCAD/modeling-app#1130 is fixed, I don't think adopting persistent data structures would be hard at all. There are only a few things that interact with arrays. Literals, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that in practice this shouldn't be a problem if we encourage using constructs like patterns rather than arrays. For performance, most variables would only require reference counting, not full persistent data structures. The latter could be layered on top of Rust data structures fairly easy (note that you don't really want a persistent data structure, which is emulating mutability in an immutable world, you want the opposite which is emulating immutability in a mutable but monotonic world. This is pretty easy - just use a Rust array and a variable which points to an earlier version of the array is a copy-on-write slice reference of the correct length, similarly for other data structures). |
||
- Currently the engine is mutable and KCL is not. This leads to mismatches like <https://github.com/kittycad/modeling-app/issues/2728> which will be complicated to solve if we keep the language immutable, and trivial if we allow mutation. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I commented here, I don't think it is that hard to fix (though certainly non-trivial to fix properly) |
||
- Many math formulae that MEs will try to implement are easier as imperative algorithms (citation needed) | ||
|
||
## Implementation problems | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fear that there would be a large knock-on effect of such a large change to the character of the language which would mean a lot of changes to existing and planned constructs, and std lib functions. |
||
|
||
- Should we allow any immutable variables? E.g. a difference between `const` and `var`? | ||
- Currently KCL doesn't require any variable declaration i.e. you can do `x = 2`. This is fine in an immutable language, but with mutation it means you can't tell if `x = 2` is reassigning `x` or creating a new variable named `x`. We should consider making `const` and `var` keywords meaningful again, so it's clear if you're creating a new variable or not (and whether it is mutable). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add that it makes a lot of analyses (e.g., for the IDE), optimisations, and other reasoning about the code, much, much easier. In particular, partial execution (for sketch mode) and code mods will be much harder to get right in the presence of mutation