OK, I think I'm starting to wrap my mind around what you're thinking of,
and if I'm right then it's neither what I would call a module reference
nor exactly geometry.
When you say:
x = module cube([1,2,3]);
I have two mental models of what that might mean:
Neither of those quite align with what you seem to want to do.
If it's an unnamed module, in non-trivial cases you can't say anything
interesting about "members", because they might have values that can't
be known until the module is evaluated.
If it's a representation of the object created, you also can't say
much about the "members", because all of the interesting values may have
been lost in the evaluation.
I think that maybe what you're thinking is that you are going to
capture the name of the (one) module being invoked, and you're going to
evaluate its arguments and capture them. You could then access the
argument values, and you could invoke the module with those arguments
(and no others).
Let's look at a more complex example. Here's a module that creates a
wide-screen television based on its diagonal and its thickness.
module television(diagonal, thickness) {
// Ratio for a wide-screen TV
nominal_h = 9;
nominal_w = 16;
nominal_diagonal = sqrt(nominal_h^2 + nominal_w^2);
// Multiplier for *this* TV
ratio = diagonal/nominal_diagonal;
// Resulting height and width
h = nominal_h * ratio;
w = nominal_w * ratio;
cube([w, thickness, h]);
// add some feet
translate([0,0,-1]) cube([1,thickness,1]);
translate([w-1,0,-1]) cube([1,thickness,1]);
echo(h=h, w=w, diagonal=diagonal);
}
Now, how would this fit into your scheme?
x = module television(55, 2);
What can you say about x? What are the "members" of x? When would the
echo() happen?
If I'm understanding correctly, you're suggesting that x.diagonal=55 and
x.thickness=2, and the echo() has not yet happened, and will happen when
and if x() happens.
And I think x() always creates a 55-unit-diagonal television, 2 units thick.
Is that what you intend?
Over the last few years, a number of people have been working on ideas
related to this.
You can find some of the thinking at
https://github.com/openscad/openscad/pull/3077 (function
literals/references)
https://github.com/openscad/openscad/pull/3087 ("object literals")
https://github.com/openscad/openscad/issues/3088 (various related topics)
https://github.com/openscad/openscad/pull/3956 (rendering geometry into
data)
I tried to pull some of those concepts together into a coherent whole at
https://docs.google.com/document/d/14siqbr9CyGuA2tY6dvTqiF3Hf9zFMyefk7YdaUJSn3Q
That doc focuses on geometry-as-data, but has a brief discussion of
module references (sometimes maybe called module literals) toward the
bottom - mostly to point out that they are an orthogonal concept.
I've only just started to push that model, and so I can't claim that I
have buy-in, but based on some conversations today I think maybe there's
interest.
I don't think anything in there is precisely aligned with what you're
thinking of, but I think it's close and might be close enough.
Just in case it is not clear, Andy Little is kwikius of the GitHub https://github.com/openscad/openscad/issues/4336 Issue.
From: Jordan Brown [mailto:openscad@jordan.maileater.net]
Sent: Fri, 2 Sep 2022 10:33
To: Andy Little via Discuss
Cc: kwikius@yahoo.com
Subject: [OpenSCAD] Re: Making modules first class without breaking existing Openscad code
OK, I think I'm starting to wrap my mind around what you're thinking of, and if I'm right then it's neither what I would call a module reference nor exactly geometry.
When you say:
x = module cube([1,2,3]);
I have two mental models of what that might mean:
Neither of those quite align with what you seem to want to do.
If it's an unnamed module, in non-trivial cases you can't say anything interesting about "members", because they might have values that can't be known until the module is evaluated.
If it's a representation of the object created, you also can't say much about the "members", because all of the interesting values may have been lost in the evaluation.
I think that maybe what you're thinking is that you are going to capture the name of the (one) module being invoked, and you're going to evaluate its arguments and capture them. You could then access the argument values, and you could invoke the module with those arguments (and no others).
Let's look at a more complex example. Here's a module that creates a wide-screen television based on its diagonal and its thickness.
module television(diagonal, thickness) {
// Ratio for a wide-screen TV
nominal_h = 9;
nominal_w = 16;
nominal_diagonal = sqrt(nominal_h^2 + nominal_w^2);
// Multiplier for this TV
ratio = diagonal/nominal_diagonal;
// Resulting height and width
h = nominal_h * ratio;
w = nominal_w * ratio;
cube([w, thickness, h]);
// add some feet
translate([0,0,-1]) cube([1,thickness,1]);
translate([w-1,0,-1]) cube([1,thickness,1]);
echo(h=h, w=w, diagonal=diagonal);
}
Now, how would this fit into your scheme?
x = module television(55, 2);
What can you say about x? What are the "members" of x? When would the echo() happen?
If I'm understanding correctly, you're suggesting that x.diagonal=55 and x.thickness=2, and the echo() has not yet happened, and will happen when and if x() happens.
And I think x() always creates a 55-unit-diagonal television, 2 units thick.
Is that what you intend?
Over the last few years, a number of people have been working on ideas related to this.
You can find some of the thinking at
https://github.com/openscad/openscad/pull/3077 (function literals/references)
https://github.com/openscad/openscad/pull/3087 ("object literals")
https://github.com/openscad/openscad/issues/3088 (various related topics)
https://github.com/openscad/openscad/pull/3956 (rendering geometry into data)
I tried to pull some of those concepts together into a coherent whole at
https://docs.google.com/document/d/14siqbr9CyGuA2tY6dvTqiF3Hf9zFMyefk7YdaUJSn3Q
That doc focuses on geometry-as-data, but has a brief discussion of module references (sometimes maybe called module literals) toward the bottom - mostly to point out that they are an orthogonal concept.
I've only just started to push that model, and so I can't claim that I have buy-in, but based on some conversations today I think maybe there's interest.
I don't think anything in there is precisely aligned with what you're thinking of, but I think it's close and might be close enough.
--
This email has been checked for viruses by AVG antivirus software.
www.avg.com
Not quite sure why my email address is appearing instead of my name. Probably going to get a ton of spam! Anyway to disable that feature?
Let's look at a more complex example. Here's a module that creates a
wide-screen television based on its diagonal and its thickness.
module television(diagonal, thickness) {
// Ratio for a wide-screen TV
nominal_h = 9;
nominal_w = 16;
nominal_diagonal = sqrt(nominal_h^2 + nominal_w^2);
// Multiplier for \*this\* TV
ratio = diagonal/nominal_diagonal;
// Resulting height and width
h = nominal_h \* ratio;
w = nominal_w \* ratio;
cube(\[w, thickness, h\]);
// add some feet
translate(\[0,0,-1\]) cube(\[1,thickness,1\]);
translate(\[w-1,0,-1\]) cube(\[1,thickness,1\]);
echo(h=h, w=w, diagonal=diagonal);
}
x = module television(55,2);
What are the "members" of x?
diagonal = x.diagonal; // (55)
thickness = x.thickness; // (2)
nominal_h = x.nominal_h; //(9)
nominal_w = x.nominal_w; // (16)
nominal_diagonal = x.nominal_diagonal (18.3576)
ratio = x.ratio; //(2.99604)
h = x.h; //(26.9644)
w = x.w; //(47.9367)
When would the echo() happen?
x();
(since echo(...) is actually a single_module_instantiation. see https://github.com/openscad/openscad/blob/master/src/core/parser.y#L314
If I'm understanding correctly, you're suggesting that x.diagonal=55 and
x.thickness=2, and the echo() has not yet happened, and will happen when
and if x() happens.
Yes !
And I think x() always creates a 55-unit-diagonal television, 2 units thick.
Is that what you intend?
Yes !
Over the last few years, a number of people have been working on ideas
related to this.
You can find some of the thinking at
https://github.com/openscad/openscad/pull/3077 (function
literals/references)
Very nice and also working in current openscad. The module_alias feature is intended to do something similar for modules. Perhaps module_alias should be renamed to module_literal ?
https://github.com/openscad/openscad/pull/3087 ("object literals")
The module alias is complimentary. You can use a module_alias in the body of an object_literal I think or seee no reason why not.
https://github.com/openscad/openscad/issues/3088 (various related topics)
you could presumably use a module_alias in a script also
https://github.com/openscad/openscad/pull/3956 (rendering geometry into data)
fun and potentially very useful but doesn’t really interact with the module_alias since it transfoms a module_instantiation into pure data. A quick read of the implementation suggest it instantiates module(s) and then removes them from the AST. That might be a little hairy!
Anyway I don't think it has an effect on the module_alias feature
I tried to pull some of those concepts together into a coherent whole at
https://docs.google.com/document/d/14siqbr9CyGuA2tY6dvTqiF3Hf9zFMyefk7YdaUJSn3Q
That doc focuses on geometry-as-data, but has a brief discussion of
module references (sometimes maybe called module literals) toward the
bottom - mostly to point out that they are an orthogonal concept.
I've only just started to push that model, and so I can't claim that I
have buy-in, but based on some conversations today I think maybe there's
interest.
I don't think anything in there is precisely aligned with what you're
thinking of, but I think it's close and might be close enough.
from the doc
m = module(parameters) {...};
m is a reference to that module, can be invoked like so:
m(arguments);
looks like an alternative syntax for defining modules? but how do you refer to already defined modules?
you could probably extend the module_alias syntax to parameters
m = module(height) cube([1,1,height]);
m(20); // --> cube([1,1,20]);