Is there an elegant way to do pseudo-OO stuff.

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

Is there an elegant way to do pseudo-OO stuff.

NateTG
I've been musing on ways to do object-oriented kinds of stuff in OpenSCAD and came up with the approach below, but it's pretty clunky.  Is there a more elegant method that someone can suggest?

To be clear, I'm asking about OpenSCAD syntax kind of stuff, and not about to implement a particular kind of data structure.

function last(list)=
   let(
      listcheck=assert(is_list(list))
   )
   len(list)-1
;

function index_list_find(list,index,i=0)=
   (i>last(list))?
      undef
   :(list[i][0]==index)?
      list[i][1]
   :
      index_list_find(list,index,i+1)
;

function index_list_from_pairs(
   filter=function(index) (is_string(index)),
   pairlist=[],
)=
   let(
      test=[for(item=pairlist) assert(is_list(item) && len(item)==2)]
   )
   [for (item=pairlist) if(filter(item[0])) item]
;

function list_to_pairs(list)=
   let(
      test=assert(0==len(list)%2,"odd length list")
   )
   [for(i=[0:2:last(list)-1]) [list[i],list[i+1]]]
;

function simple_struct(
   arg=undef,
   nlist=[],
   slist=[]
)=
   (is_string(arg))?
      index_list_find(list=slist,index=arg)
   :(is_num(arg))?
      index_list_find(list=nlist,index=arg)
   :(is_list(arg))?
      ("add_list"==arg[0])?
         function (list) (
            simple_struct(arg=["add_pairs"],nlist=nlist,slist=slist) (list_to_pairs(list))
         )
      :("add_pairs"==arg[0])?
         function(pairs) (
            function(arg) (
               simple_struct(
                  arg=arg,
                  nlist=concat(
                     nlist,
                     index_list_from_pairs(
                        filter=function(x) (is_num(x)),
                        pairlist=pairs
                     )
                  )
                  ,
                  slist=concat(
                     slist,
                     index_list_from_pairs(
                        filter=function(x) (is_string(x)),
                        pairlist=pairs
                     )
                  )
               )
            )
         )
      :("keys"==arg[0])?
         concat([for(n=nlist) n[0]],[for(s=slist) s[0]])
      :("values"==arg[0])?
         concat([for(n=nlist) n[1]],[for(s=slist) s[1]])
      :
         assert(false,str("unsupported command:",arg[0]))
   :
      assert(false,str("unexpected argument:",arg))
;

test=simple_struct(["add_pairs"])([ ["a",1],[1,"a"],["1",2]]);

echo(test("a"));
echo(test("1"));
echo(test(1));

test2=test(["add_list"])(["one","two","three","four"]);

echo(test2("one"));
echo(test2(["keys"]));
echo(test2(["values"]));


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Is there an elegant way to do pseudo-OO stuff.

caterpillar
This post was updated on .
The simple way is using a group of functions that share the same data, such as
the way I does with my  hashmap
<https://openhome.cc/eGossip/OpenSCAD/lib3x-hashmap.html>  .

Simulating class-based oo, however, is riveting and here is my attempt to do
it.

// require dotSCAD 3.0 https://github.com/JustinSDK/dotSCAD
use <util/map/hashmap.scad>;
use <util/map/hashmap_get.scad>;

function methods(mths) = hashmap(mths);
function _(instance, name) = hashmap_get(instance, name);

function clz_list(data) =
        methods([
            ["get", function(i) data[i]],
            ["append", function(n) clz_list(concat(data, [n]))]
        ]);

lt1 = clz_list([10, 20]);
assert(_(lt1, "get")(0) == 10);
assert(_(lt1, "get")(1) == 20);

lt2 = _(lt1, "append")(30);
assert(_(lt2, "get")(0) == 10);
assert(_(lt2, "get")(1) == 20);
assert(_(lt2, "get")(2) == 30);





-----
https://openhome.cc
--
Sent from: http://forum.openscad.org/
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Is there an elegant way to do pseudo-OO stuff.

caterpillar
This post was updated on .
You can encapsulate the instance even further. But the code is more complex
when defining a class.

use <util/map/hashmap.scad>;
use <util/map/hashmap_get.scad>;

function methods(mths) = hashmap(mths);
function _(name, instance) = hashmap_get(instance, name);

function clz_list(data) = function(name) _(name,
    methods([
        ["get", function(i) data[i]],
        ["append", function(n) clz_list(concat(data, [n]))]
    ])
);

lt1 = clz_list([10, 20]);
assert(lt1("get")(0) == 10);
assert(lt1("get")(1) == 20);

lt2 = lt1("append")(30);
assert(lt2("get")(0) == 10);
assert(lt2("get")(1) == 20);
assert(lt2("get")(2) == 30);



-----
https://openhome.cc
--
Sent from: http://forum.openscad.org/
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Is there an elegant way to do pseudo-OO stuff.

NateTG
caterpillar wrote
...
lt1 = clz_list([10, 20]);
assert(lt1("get")(0) == 10);
assert(lt1("get")(1) == 20);

lt2 = lt1("append")(30);
assert(lt2("get")(0) == 10);
assert(lt2("get")(1) == 20);
assert(lt2("get")(2) == 30);
....
Thanks for the answers.  That syntax still seems a little clunky, but I guess that's going to happen when pushing the language to do things it's not designed to.




Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]