# Plans to change variable behavior ?

91 messages
12345
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 In reply to this post by rickan This is all about philosophy. The argument "All programming languages I have used do it differently" is irrelevant. Of the many languages I have used, all have some features you learn to live with. OpenSCAD has a very valid reason for doing what it does. My vote is to leave it alone. Larry
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 Here is my attempt at explaining functional programming to myself. https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/General_%28by_c.t.chin%29#Basic_ConceptsI'm with kintel here.  While I find declarative programming to very restrictive and inconvenient, I can sense that catastrophe awaits if the development team agrees to change to or allow even limited procedural computation.   My solution to enable iterative computation or logic in OpenSCAD is to use Matlab (you could do VC, perl, Python whatever) for the computation and "export" the answer(s) to OpenSCAD by generating OpenSCAD code.   Matlab may not be a well-known language, but its code is easy enough to understand, following generate an OpenSCAD polyhedron module from Matlab: ```function outstr = openscad(fid, modname, objs); fprintf(fid, 'module %s() { union() {\n', modname); for o = objs; // for each object o nv = size(o.verts, 1); nf = numel(o.faces); fprintf(fid, 'polyhedron(\n points = [\n'); for kv = 1:nv fprintf(fid, ' [%g, %g, %g],\n', o.verts(kv,1), o.verts(kv,2), o.verts(kv,3)); end; fseek(fid,-2,0); % remove the last comma and newline fprintf(fid, '\n ],\n'); fprintf(fid, ' faces = [\n'); for kf = 1:nf; m = sprintf('%d, ', o.faces(kf).vi-1); m = m(1:end-2); fprintf(fid, ' [%s],\n',m); end fseek(fid,-2,0); % remove the last comma and newline fprintf(fid, '\n ]\n);\n'); end fprintf(fid, '} } \n'); ```
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 In reply to this post by L Boyd In the instance which aroused my desire to vote against immutable variables, the location of my primitive call, cube(), in the inner of 3 nested for ops, is ideal for calculating various properties of the cube for that specific call and for counting the numbers of cubes with the same properties, etc. The reasons, in addition to immutable variables, I can't to that is that modules do not return anything and modules cannot be called within functions. I can do it by writing other functions to be called on the list equivalent of the three nested for ops with the same conditionals resulting in horrible code proliferation with it's attendant pitfalls. Or I can just write it in Perl which spews huge volumes of module calls generated in the 3 nested for loops in which case features of the OpenSCAD language such as immutable variables are irrelevant. I read parts of your OpenSCAD 2 proposal with interest. Most relevant is that the only distinction between functions and modules is what they return, i.e. functions return anything at all and modules return geometrical objects. (Please correct any error in my understanding.) I would like to suggest that modules return objects which contain the geometrical object in addition to a user definable, user settable, set of key => value pairs, i.e. user definable meta-data the module produces. It might make sense that some of the keys would be standard e.g. the key for the geometrical object itself, the parameters passed to the call including children objects, the coordinate transform matrix of the call, the color, etc.; but whether or not that is done, the user should be able to augment the set. If this were done, then aggregation of the meta-data could be accomplished by calling functions on lists of these module produced objects. What I'm calling meta-data here is, I think, a very important part of solid modeling. Here's my specific case: Wallis.scad inserted here for convenience: ```// Copyright 2015 Richard Kandarian http://kandarian.com/ function mkp(p, n, m) = n>m ? p : mkp(concat(p, [p[len(p)-1]*(2*n-1)/(2*n-2)]), n+1, m); function mka(a, n, m) = n>m ? a : mka(concat(a, [a[len(a)-1]*(2*n-1)/(2*n)]), n+1, m); function shift(o, v) = [for(i=[o:len(v)-1]) v[i]]; function hsv2rgb(h, s, v) = let(hs=h/60, f=hs-floor(hs), p=v*(1-s), q=v*(1-s*f), t=v*(1-s*(1-f))) h>=0 && h<60 ? [v, t, p] : ( h>=60 && h<120 ? [q, v, p] : ( h>=120 && h<180 ? [p, v, t] : ( h>=180 && h<240 ? [p, q, v] : ( h>=240 && h<300 ? [t, p, v] : [v, p, q] ) ) ) ); m = 50; hollow = 1; thick = 1; p = mkp([1], 2, m); pl = len(p)-1; a = concat([1], shift(1, mka([1], 1, m-1))); al = len(a)-1; //echo(pl, p); //echo(al, a); module octant(){ for(zi = [0:pl]){ zm = pl-zi; z = zm<1 ? 0 : p[zm-1]; h = a[zm]; // hv1 = zm/m*360+(zm%2)*120; // hv = hv1 > 360 ? hv1-360 : hv1; for(yi = [0:zi]){ ym = zi-yi; y = ym<1 ? 0 : p[ym-1]; l = a[ym]; for(xi = [0:yi]){ xm = yi-xi; x = xm<1 ? 0 : p[xm-1]; w = a[xm]; if(!hollow || abs(xm+ym-zi) < thick){ hv1 = (xm+ym)/m*360+(zm%2)*120; hv = hv1 > 360 ? hv1-360 : hv1; translate([x, y, z]){ color(hsv2rgb(hv, .3, 1)){ cube([w, l, h], center=false); }; }; } } } } } module hemi(){ octant(); rotate([0,0,90]) octant(); rotate([0,0,180]) octant(); rotate([0,0,270]) octant(); } //hull(){ hemi(); rotate([180,0,0]) hemi(); //} ```
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 Hmmm, Seems I hit the wrong reply button. I meant to reply to Doug Moen.
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 It's okay, I got the message. And I'll try to respond.On 16 November 2015 at 13:53, rickan wrote:Hmmm, Seems I hit the wrong reply button. I meant to reply to Doug Moen. -- View this message in context: http://forum.openscad.org/Plans-to-change-variable-behavior-tp9647p14558.html Sent from the OpenSCAD mailing list archive at Nabble.com. _______________________________________________ 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
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 Doug Moen said: > rickan, again: > > I would like to suggest that modules return objects which contain the > > geometrical object in addition to a user definable, user settable, set of > > key => value pairs, i.e. user definable meta-data the module produces. It > > might make sense that some of the keys would be standard e.g. the key for > > the geometrical object itself, the parameters passed to the call including > > children objects, the coordinate transform matrix of the call, the color, > > etc.; but whether or not that is done, the user should be able to augment > > the set. > > That is pretty much how the OpenSCAD2 design already works. > I have not made any attempt to define "standard keys", and in the present design, > primitive shapes like the ones returned by cube() and sphere() don't have any keys. > All keys within a geometric object are user defined. > But otherwise, it works as you have described. > > Here is the section that describes "geometric objects": > https://github.com/doug-moen/openscad2/blob/master/rfc/Objects.mdIt doesn't look that way to me because I only see how parameters are input to the object, not how the object creates values (meta-data) and stores them for later use as a result of the module call or object instantiation, e.g, volume or moment of inertia calculated from the input parameters. In my code example where the cube() is called inside if{!hollow... if I were to take that if block and put it in a module or object with all the required input parameters, I could, in that module, calculate and store the volume of the cube, it's moment of inertia, and I could store the color for access and analysis in some other part of my program.
Open this post in threaded view
|

## Re: Plans to change variable behavior ?

 Okay, let me explain how it works.In OpenSCAD2, an object is delimited by {...}. It may contain definitions, like 'zm = pl-zi;' from your octant module, and it may contain geometry statements, like 'translate(..) color(..) cube(..)' from your octant module. Definitions add key-value pairs to the object, while geometry statements add geometry.Now lets consider your octant module:```module octant(){ for(zi = [0:pl]){ zm = pl-zi; z = zm<1 ? 0 : p[zm-1]; h = a[zm]; for(yi = [0:zi]){ ym = zi-yi; y = ym<1 ? 0 : p[ym-1]; l = a[ym]; for(xi = [0:yi]){ xm = yi-xi; x = xm<1 ? 0 : p[xm-1]; w = a[xm]; if(!hollow || abs(xm+ym-zi) < thick){ hv1 = (xm+ym)/m*360+(zm%2)*120; hv = hv1 > 360 ? hv1-360 : hv1; translate([x, y, z]){ color(hsv2rgb(hv, .3, 1)){ cube([w, l, h], center=false); }; }; } } } } } ```There are lots of {...} object literals in this module, so the result will be a nested tree of objects.L0: the top level object contains a list of objects generated by 'for (zi=...)'L1: the objects in L0 each contain 3 fields named zm, z, h, plus the objects generated by 'for (yi=...)'L2: the objects in L1 each contain 3 fields named ym, y, l, plus the objects generated by 'for (xi=...)'L3: the objects in L2 each contain 3 fields xm, x, w, plus zero or one objects generated by the if, depending on whether the if condition is false or true.L4: the optional object in L3 contains 2 fields, hv1, hv, plus the shape 'translate(..) color(..) cube(..)'.So if I write    oct = octant();then 'oct' is a object tree, nested 4 levels deep.    len(oct) is the number of L1 objects in oct    oct[0] is the first L1 object in oct    oct[0].zm is the value of the zm field of oct[0], which is a numberOkay?On 16 November 2015 at 14:53, rickan wrote:Doug Moen said: > rickan, again: > > I would like to suggest that modules return objects which contain the > > geometrical object in addition to a user definable, user settable, set > of > > key => value pairs, i.e. user definable meta-data the module produces. > It > > might make sense that some of the keys would be standard e.g. the key > for > > the geometrical object itself, the parameters passed to the call > including > > children objects, the coordinate transform matrix of the call, the > color, > > etc.; but whether or not that is done, the user should be able to > augment > > the set. > > That is pretty much how the OpenSCAD2 design already works. > I have not made any attempt to define "standard keys", and in the present > design, > primitive shapes like the ones returned by cube() and sphere() don't have > any keys. > All keys within a geometric object are user defined. > But otherwise, it works as you have described. > > Here is the section that describes "geometric objects": > https://github.com/doug-moen/openscad2/blob/master/rfc/Objects.md It doesn't look that way to me because I only see how parameters are input to the object, not how the object creates values (meta-data) and stores them for later use as a result of the module call or object instantiation, e.g, volume or moment of inertia calculated from the input parameters. In my code example where the cube() is called inside if{!hollow... if I were to take that if block and put it in a module or object with all the required input parameters, I could, in that module, calculate and store the volume of the cube, it's moment of inertia, and I could store the color for access and analysis in some other part of my program. -- View this message in context: http://forum.openscad.org/Plans-to-change-variable-behavior-tp9647p14567.html Sent from the OpenSCAD mailing list archive at Nabble.com. _______________________________________________ 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