Bundling module parameters

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Bundling module parameters

OpenSCAD mailing list-2
This time I have an interesting syntax question. I'm building a small library
of bits I find useful and in the manner of such libraries more complex parts
build on simpler parts.

Even the simple part may have a good few parameters. For example:

module simple_thing(p1, p2, p3, p4, p5, p6) { }

Now I want to build on that, create a richer model of something bigger and
more complicated and I want to bundle these parameters into a vector
something like this:

module bigger_thing(simple_thing_ps, pp11, pp2) { }

where:

simple_thing_ps = [p1, p2, p3, p4, p5, p6]

that is, the simple thing parameters bundled up. In this bigger module now I
can include a simple thing like so quite easily:

module bigger_thing(simple_thing_ps, pp11, pp2) {

        simple_thing(simple_thing_ps[0],
simple_thing_ps[1],simple_thing_ps[2],
simple_thing_ps[3],simple_thing_ps[4], simple_thing_ps[5]);

        // do more stuff
}

But wow that is clumsy. Now I'm familiar with Python and it has a beautiful
syntax for unpacking lists like this, so that I could write something like:

module bigger_thing(simple_thing_ps, pp11, pp2) {

        simple_thing(unpack(simple_thing_ps));

        // do more stuff
}


Not only terser and nicer, the new module no longer needs to know how long
simple_thing_ps is. In Python that unpack operarator is just *, such that
the if the v = [p1, p2, p3], then *v = p1, p2, p3 and I'd call
simple_thing(*v) to have the list unpacked into individual parameters that
simple thing sees.

Of course one solution is to write simple_thing so it takes a single vector
parameter which it unpacks internally into parameters. But that too is
clumsy, as it means anyone using simple_thing has an odd syntax to contend
with.

I've had a look at "each" which tantalisingly close and may even be able to
do this, I just haven't figured outhow yet.

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/List_Comprehensions#each

All the examples are generating lists, rather than unpacking them. There's a
solid chance that unpack simply isn't possible.

Perhaps one smart flexible way to write it is to have simple_thing check if
it has only one vector as a parameter, and if so unpack it internally else
use the parameters themselves.

module simple_thing(p, p2, p3, p4, p5, p6) {
  if (is_list(p) && is_undef(p2)  
                    && is_undef(p3)  
                    && is_undef(p4)  
                    && is_undef(p5)
                    && is_undef(p6) ) {
        p1 = p[0];
        p2 = p[1];
        p3 = p[2];
        p4 = p[3];
        p5 = p[4];
        p6 = p[5];
   } else {
       p1 = p
    }
}


While a little wordy it's contain in simple_thing and allows using it
normally and tersely in bigger things. It just gets a little hairier if some
or all of the parameters have default values and if p is expected to be a
list anyhow etc.

Wonder if there's a more elegant solution?

Regards,

Bernd.



--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
rew
Reply | Threaded
Open this post in threaded view
|

Re: Bundling module parameters

rew
On Tue, Apr 28, 2020 at 09:26:25PM -0700, ThumbOne via Discuss wrote:
> Wonder if there's a more elegant solution?

I'd make a

module simple_thing_v (pv)  // simple thing with a vector for the parameters.
{
  simple_thing (pv[1], pv[2], pv[3], pv[4], pv[5]);
}

        Roger.

--
** [hidden email] ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Bundling module parameters

Ronaldo
In reply to this post by OpenSCAD mailing list-2
Functions with alternative parameter sets are harder to write and clumsy to read. When possible, avoid it. If needed, define clear precedence rules.

What would be the result of your last code for a call like:

simple_thing([1, 2], 3)  ;



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Bundling module parameters

adrianv
Ronaldo wrote
> Functions with alternative parameter sets are harder to write and clumsy
> to
> read. When possible, avoid it. If needed, define clear precedence rules.

Harder to write, absolutely.  Careful parameter checking is necessary.  In
the posted example I would check that either all five parameters are defined
or only the first one is defined.  Otherwise, issue an error.  And then if
you have one parameter, split it with a recursive call.  

But clumsy to read?  I disagree.  What's clumsy to read (and write in my
code) are a bunch of calls where you have to use double delimiters so you
have

foobar([v1,v2,v3]);
baz([v2,v3]);

instead of simply

foobar(v1,v2,v3);
baz(v2,v3);




--
Sent from: http://forum.openscad.org/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Bundling module parameters

Ronaldo
But clumsy to read?  I disagree.  What's clumsy to read (and write in my
code) are a bunch of calls where you have to use double delimiters so you
have

I understand your point but I was referring to the function code reading not its call.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Bundling module parameters

nophead
I prefer to represent objects by named lists of properties and pass that as the first parameter to all functions and module that operate on them. That keeps the code clean and backwards compatible. I.e. I can add more properties to the list and it does not affect clients of the library as they still pass the same named object, with no care of what it is.

The only advantage of using module parameters is they can be set by name and have defaults, whereas my lists are all initialised by position. That could be solved by having a separate constructor function with an argument per property to make the lists. However since the lists are hidden away in the library, each in their own file, there would be little benefit.

There are a few objects that are defined in the client code. Mainly customisable printed objects like cases. This discussion has prompted me to think they should have constructor functions to better isolate the client code from changes to the library.

On Wed, 29 Apr 2020 at 12:26, Ronaldo Persiano <[hidden email]> wrote:
But clumsy to read?  I disagree.  What's clumsy to read (and write in my
code) are a bunch of calls where you have to use double delimiters so you
have

I understand your point but I was referring to the function code reading not its call.
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org