-
Notifications
You must be signed in to change notification settings - Fork 1
File Format Versioning
Sometimes, it's necessary to break backwards compatibility to be able to provide improvements to OpenSCAD. We'll discuss ways of doing this, as well as enumerate some of the suggested breaking changes.
One way of versioning OpenSCAD files is to add a version tag, similar to e.g. GLSL or VRML
#openscad 2014.03
union() {
cube();
sphere();
}
This enables us to detect for which version of OpenSCAD a design was intended.
When creating new files with the built-in editor, we could automatically add a missing tag. When opening a file without a tag, we could issue a warning
Existing OpenSCAD designs shouldn't suffer from changes in the language. To handle old designs, we could
- Issue a warning and have people use an old version of OpenSCAD
- Offer to upgrade existing designs
- Have two built-in renderers and give users an option to use the old one
Alternatively, could have a 'base' version on preferences which is added to a new file, and used implicitly as the base for opened files missing a version spec (rather than adding text to an opened file - don't want to do changes to existing files). That way a user can work with a fixed version (of the language) while using updates (for bug fixes etc) without having to transition to the next language version/features etc, until they are ready.
See https://github.com/openscad/openscad/issues/522
As a sub section: Consider unification of variable, function and module namespaces.
The naming scheme and default values of the built-in OpenSCAD modules are not quite orthogonal and coherent. We should consider cleaning these up when doing a non-compatible language change. Examples:
-
linear_extrude
takes aheight
parameter, whilecylinder
takesh
-
sphere
is centered around the origin whilecube
andcylinder
is not.
We should consider making argument lists a bit stricter with positional arguments too. For example, not allowing positional arguments located after named ones.
Started by Oskar on the mailing list:
The sequential assignment semantics of the proposed let() should ideally be aligned with the future idea of having scoped variables, and I am interested in what the intention is here. The current behavior is (as has been discussed before) not ideal, and there may be a few different options of how to change that. Considering the following two cases (and their current behavior in the comment)
a=1; b=a; a=2; // b == 2
d=c; c=2; // WARNING: Ignoring unknown variable 'c', d == undef
The options I see are:
-
Introduce sequential assignment with reassignment. This will silently change b to 1 in the example above, which will cause silent breakage.
-
Introduce sequential assignment without allowing reassignment (i.e. make it an error). This will probably break some few cases of existing code, but not silently and with an easy way to fix.
-
Introduce recursive assignment disallowing reassignment. -> This will change d to 2 in the example above which theoretically could silently break some existing code, but quite unlikely.
-
Of course: Do nothing.
So: 1 -> silent breakage. 2 -> less breakage but not silent. 3 -> low risk of silent breakage. From an implementation point of view, 1 and 2 are quite a bit simpler to implement.
My suggestion would be to do 2, but start with a depreciation warning. That is also in line with the current let-syntax (especially if we disallow reassignment).
The use case of supplying variables on the command line with them just being appended to the current file could be handled in a special way to keep that support.
The following case is interesting too:
i = 1;
module foo() {
function f() = i;
echo(f());
a = f();
echo(a);
i = 2;
echo(f());
b = f();
echo(b);
}
foo();
Before testing, can you guess what it outputs? Should module calls be interleaved with expression evaluation?