OO patterns in OpenSCAD

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

OO patterns in OpenSCAD

NateTG
Recently, I've been thinking that it would be nice if there were some syntax hack that made:

> function.text

equivalent to something like

> function($dot="text")

for function literals in openSCAD.

That would allow for the creations of things like color triplets in user space:

>function rgbtriplet($dot=undef,r=undef,g=undef,b=undef)=
>   ($dot=="new")?
>      function($dot) rgbtriplet($dot=$dot,r=r,g=g,b=b)
>   :($dot=="r" || $dot=="R" || $dot=="red")?
>      r
>   :($dot=="g" || $dot=="G" || $dot=="green")?
>      g
>   : // ($dot=="b" || $dot=="B" || $dot=="blue")?
>      b
>;
>
>my rgb=rgbtriplet.new(r=128,g=64,b=255);
>echo(rgb.r);

Function literals already allow this kind of programming pattern, but the existing syntax for doing it is pretty awkward.

We already have the dot notation for lists.  So "dot syntax" isn't out of line for OpenSCAD. On the other hand, it might be that the way that dot notation for lists is implemented makes this kind of thing much harder to do to.

Regardless, I'm wondering whether:

1. People think this is a terrible idea or not in principle.

2. People think that this kind of thing is hard to implement or not.



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: OO patterns in OpenSCAD

JordanBrown
There is some related commentary in the "Discuss Function literals & Objects etc" issue at https://github.com/openscad/openscad/issues/3088 .


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

Re: OO patterns in OpenSCAD

doug.moen
In reply to this post by NateTG
There has been a separate forum discussion about adding syntax for record literals, which might look something like this:

 rgb =  {r: 128, g: 64, b: 255};

and then you can use expressions like 'rgb.r'. I think this approach is simpler and more ergonomic than requiring people to encode records using functions.

On Sat, Apr 3, 2021, at 12:01 PM, NateTG wrote:
Recently, I've been thinking that it would be nice if there were some syntax hack that made:

> function.text

equivalent to something like

> function($dot="text")

for function literals in openSCAD.

That would allow for the creations of things like color triplets in user space:

>function rgbtriplet($dot=undef,r=undef,g=undef,b=undef)=
>   ($dot=="new")?
>      function($dot) rgbtriplet($dot=$dot,r=r,g=g,b=b)
>   :($dot=="r" || $dot=="R" || $dot=="red")?
>      r
>   :($dot=="g" || $dot=="G" || $dot=="green")?
>      g
>   : // ($dot=="b" || $dot=="B" || $dot=="blue")?
>      b
>;
>
>my rgb=rgbtriplet.new(r=128,g=64,b=255);
>echo(rgb.r);

Function literals already allow this kind of programming pattern, but the existing syntax for doing it is pretty awkward.

We already have the dot notation for lists.  So "dot syntax" isn't out of line for OpenSCAD. On the other hand, it might be that the way that dot notation for lists is implemented makes this kind of thing much harder to do to.

Regardless, I'm wondering whether:

1. People think this is a terrible idea or not in principle.

2. People think that this kind of thing is hard to implement or not.



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

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



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

Re: OO patterns in OpenSCAD

MichaelAtOz
Administrator
doug.moen wrote
 rgb =  {r: 128, g: 64, b: 255};
Please not curly brackets in another context.
OpenSCAD Admin - email* me if you need anything, or if I've done something stupid...
* on the Forum, click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain;
to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


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

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
OpenSCAD Admin - email* me if you need anything, or if I've done something stupid...
* on the Forum, click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain;
to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.
Reply | Threaded
Open this post in threaded view
|

Re: OO patterns in OpenSCAD

RevarBat
In reply to this post by NateTG
For consideration, I’ve created a function-literal pseudo-class for implementing hashmaps, where the arguments used specify the action taken:

hm = hashmap(items=[for (i=[0:9999]) [str("foo",i),i]]);
a = hm("foo37");  // Returns: 37
hm2 = hm("Blah", 39);  // Adds entry "Blah" with val 39.
b = hm2("Blah");  // Returns: 39
hm3 = hm2(additems=[["bar",39],["qux",21]]);  // Adds "bar" and "qux"
hm4 = hm3(del="Blah");  // Deletes entry "Blah".
for (kv = hm4()) {  // Iterates over all key/value pairs.
   echo(key=kv[0], val=kv[1]);
}


function simple_hash(x) =
    let( m = 0.5 * (sqrt(5) - 1) )
    is_num(x)? floor(m*x*256) :
    is_list(x)? let(
        l = len(x),
        a = function(i,v) i>=l? v : a(i+1, m*v + simple_hash(x[i]))
    ) floor(a(0,0)*4096) : let(
        s = str(x),
        l = len(s),
        a = function(i,v) i>=l? v : a(i+1, m*v + ord(s[i]))
    ) floor(a(0,0)*4096);

function idx(l) = [0:1:len(l)-1];  // Simplified from BOSL2 code.

// Declaring group_data() in terms not requiring BOSL2 is a lot more complicated
// and will not be included here.  It's only used for `items=` and `additems=`.

function hashmap(hashsize=127,items,table) =
    let(
        table = !is_undef(table)? table : [for (i=[0:1:hashsize-1]) []]
    )
    items != undef? hashmap(hashsize=hashsize, table=table)(additems=items) :
    function(k,v,del,additems)
        additems!=undef? let(
            hashes = [for (item = additems) simple_hash(item[0]) % hashsize],
            grouped = list_pad(group_data(hashes, additems), hashsize, []),
            table = [for (i=idx(table)) concat(table[i],grouped[i])]
        ) hashmap(hashsize=hashsize, table=table) :
        del!=undef? let(
            bnum = simple_hash(del) % hashsize,
            bucket = [for (item=table[bnum]) if (item[0]!=del) item],
            table = [for (i=idx(table)) i==bnum? bucket : table[i]]
        ) hashmap(hashsize=hashsize, table=table) :
        k==undef && v==undef? [for (bucket=table, item=bucket) item] :
        let(
            bnum = simple_hash(k) % hashsize,
            bucket = table[bnum],
            fnd = search([k], bucket)
        )
        k!=undef && v==undef? (fnd==[]? undef : bucket[fnd[0]][1]) :
        let(
            newtable = [
                for (i=idx(table))
                i!=bnum? table[i] :
                !fnd? [[k,v], each bucket] :
                [[k,v], for (j=idx(bucket)) if (j!=fnd[0]) bucket[i]]
            ]
        ) hashmap(hashsize=hashsize, table=newtable);


- Revar


On Apr 3, 2021, at 9:01 AM, NateTG <[hidden email]> wrote:

Recently, I've been thinking that it would be nice if there were some syntax hack that made:

> function.text

equivalent to something like

> function($dot="text")

for function literals in openSCAD.

That would allow for the creations of things like color triplets in user space:

>function rgbtriplet($dot=undef,r=undef,g=undef,b=undef)=
>   ($dot=="new")?
>      function($dot) rgbtriplet($dot=$dot,r=r,g=g,b=b)
>   :($dot=="r" || $dot=="R" || $dot=="red")?
>      r
>   :($dot=="g" || $dot=="G" || $dot=="green")?
>      g
>   : // ($dot=="b" || $dot=="B" || $dot=="blue")?
>      b
>;
>
>my rgb=rgbtriplet.new(r=128,g=64,b=255);
>echo(rgb.r);

Function literals already allow this kind of programming pattern, but the existing syntax for doing it is pretty awkward.

We already have the dot notation for lists.  So "dot syntax" isn't out of line for OpenSCAD. On the other hand, it might be that the way that dot notation for lists is implemented makes this kind of thing much harder to do to.

Regardless, I'm wondering whether:

1. People think this is a terrible idea or not in principle.

2. People think that this kind of thing is hard to implement or not.



Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]


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

Re: OO patterns in OpenSCAD

RevarBat
In reply to this post by MichaelAtOz
More entertaining things to do with function literals.  Making function generators to optionally pre-fill out arbitrary arguments of existing functions that take 1 to 3 args:

f_add = f_2arg(function(a,b) a+b);
f_mul = f_2arg(function(a,b) a*b);
f_lt = f_2arg(function(a,b) a<b);

fn_lt = f_lt();    // = function(a,b) a<b;
fn_lt3 = f_lt(3);    // = function(a) a<3;
fn_3lt = f_lt(a=3);    // = function(b) 3<b;
fn_3lt4 = f_lt(a=3,b=4); // = function() 3<4; Not very useful, but symmetric.

lt10 = function(list) filter(f_lt(10), list);
inv = function(list) map(f_div(a=1), list);
sum = function(list) reduce(f_sdd(), list);
prod = function(list) reduce(f_mul(), list);
cumul_prod = function(list) accumulate(f_mul(), list);

function map(func, list) = [for (x=list) func(x)];

function filter(func, list) = [for (x=list) if (func(x)) x];

function reduce(func, list, init=0) =
    let(
        l = len(list),
        a = function (x,i) i<l? a(func(x,list[i]), i+1) : x
    ) a(init,0);

function accumulate(func, list, init=0) =
    let(
        l = len(list),
        a = function (x, i, out)
            i >= l ? out :
            let( x=func(x,list[i]) )
            a(x, i+1, [each out, x])
    ) a(init, 0, []);

function f_1arg(func) =
    function(a)
        a==undef? func :
        function() func(a);

function f_2arg(func) =
    function(b,a)
        a==undef && b==undef? func :
        a==undef? function(x) func(x,b) :
        b==undef? function(x) func(a,x) :
        function() func(a,b);

function f_3arg(func) =
    function(a,b,c)
        a==undef && b==undef && c==undef? func :
        a==undef && b==undef? function(x,y) func(x,y,c) :
        a==undef && c==undef? function(x,y) func(x,b,y) :
        b==undef && c==undef? function(x,y) func(a,x,y) :
        a==undef? function(x) func(x,b,c) :
        b==undef? function(x) func(a,x,c) :
        c==undef? function(x) func(a,b,x) :
        function() func(a,b,c);

- Revar




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

Re: OO patterns in OpenSCAD

NateTG
In reply to this post by doug.moen
doug.moen wrote
There has been a separate forum discussion about adding syntax for record literals, which might look something like this:

 rgb =  {r: 128, g: 64, b: 255};

and then you can use expressions like 'rgb.r'. I think this approach is simpler and more ergonomic than requiring people to encode records using functions.
...
Thank you for the feedback.

I see that that's more convenient and legible than something like:

include<dict.scad>
....
rgb=dict( [ ["r",128],["g",64],["b",255] ]);

How well does what you proposed fit with the existing OpenSCAD syntax?

Is there some philosophical guideline about whether stuff should be done "in OpenSCAD" or "in userspace"?  (I'm not sure whether that's the right terminology.)

Should "r","g", and "b" have been in quotes in the example that you gave? Are you looking for something that effectively just adds "rgb.r", "rgb.g" and "rgb.b" as variables to the current scope, or do you care about things like iterating over key value pairs, or code-generated keys?

When you write "simpler" do you mean "easier for me to use and read" or something else?


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: OO patterns in OpenSCAD

NateTG
In reply to this post by RevarBat
RevarBat wrote
For consideration, I’ve created a function-literal pseudo-class for implementing hashmaps, where the arguments used specify the action taken:
...
Thank you.

Do you have any opinion about whether something like "function dot" syntax in OpenSCAD would be a good idea or not?

Do you have any sense about whether "function dot" syntax would be hard to implement?


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: OO patterns in OpenSCAD

mondo
In reply to this post by NateTG

On 05/04/2021 13:43, NateTG wrote:
> How well does what you proposed fit with the existing OpenSCAD syntax?

Is there a 'formal definition' of the syntax anywhere, or has it just
evolved, bit's added as needed?
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: OO patterns in OpenSCAD

NateTG
mondo wrote
On 05/04/2021 13:43, NateTG wrote:
> How well does what you proposed fit with the existing OpenSCAD syntax?

Is there a 'formal definition' of the syntax anywhere, or has it just
evolved, bit's added as needed?
I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything.

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there.


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: OO patterns in OpenSCAD

mondo

I think, if a list of definitions was available, we would find a few anomalies. For example [] to indicate a list or vectors. Is [] used elsewhere? Then there is a dot notation for the first three values. Why? Other than saving a key stroke, what is the purpose? And, does vector in openscad mean more than a vector elsewhere, like a cube in openscad is not a cube in the outside world. Yes, and, I think therein lies a fundamental problem. New concepts/notations can be introduced, and later on there is too much complexity and broken rules in what is a fairly succinct language.

However, if using a dot notation, then I would hope it would be in a very broad sense, applied to modules within include files, down to subset's of vectors, (not just the first three). However, instead of adding bells and whistles, I would prefer more emphasis on improving what is already there, error reporting/highlighting, etc. I realise that it is all dependant on volunteer work, so I'm grateful for whatever happens.

Best wishes,

Ray

On 05/04/2021 16:29, NateTG wrote:
mondo wrote
On 05/04/2021 13:43, NateTG wrote:
> How well does what you proposed fit with the existing OpenSCAD syntax?

Is there a 'formal definition' of the syntax anywhere, or has it just
evolved, bit's added as needed?
I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything.

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there.


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

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

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

Re: OO patterns in OpenSCAD

RevarBat
In reply to this post by NateTG
Here’s the latest revision of my dictionaries proposal, which includes provisions for dot notation,

// Dictionaries proposal, v3.

// Dictionary declaration.
a = "fee"; b = "fie";
dict1 = {
    "foo": 23,    // KEY : VALUE
    "bar": 77,    // String key.
    undef: 34,    // undef key.
    false: a,     // Boolean key.
    99   : 34,    // Numeric key.
    56   : "AZ",  // Value can be any type.
    "bar": 65,    // Overwrites previous "bar" key entry.
    .qux : 29,    // Key literal syntax.  Same as "qux"
    str("c","a","t") : b  // Expressions usable for keys or values.
    a>b?a:b : a>b?5:8  // If you have a '?' then the next ':' is part of the ternary expression,
                       // not a separator.  This should always be unambiguous.  If not, use parens.
    .func = function(self,a,b) self.foo*(a+b)}  // Pseudo OOP?
};

// Dictionary comprehension.
dict2 = {
    for (i=[0:100])
    if(i%2==0)  // `if` works as expected.
    each {      // `each` will expand sub-dictionaries, but only in a dictionary comprehension
        i:i*5,  // Using `each` on a dictionary in a list comprehension expands into [key,val] items.
        i+0.5:i*5+1
    }
};

// Extending/merging dictionaries. Later duplicated keys overwrite previous ones.
// Lists merge into dictionaries using numeric positions as keys.
dict3 = concat(dict1, dict2, {"flee":0});

// Getting dictionary values.
w = dict3["bar"];
x = dict3.baz;   // Same as dict3["baz"].  Lets you make structures.
u = dict3.func(dict3, 3, 8);  // Calling a function literal pseudo-method.
y = dict3[a];
z = dict3["fit"];   // Returns undef for nonexistent keys.

// Iterating a dictionary.  Iterate keys in original declared order?
for (kv = dict3) {
    echo(key=kv[0], val=kv[1]);
}

// If we ever have mutable dictionaries, then you can set items like:
dict3.foo = 17;   // Key literal syntax
dict3["bar"] = 12;

// Otherwise with immutable dictionaries, we end up doing
dict4 = concat(dict3, {"foo":17});
dict5 = {each dict4, .bar:12};

- Revar


On Apr 5, 2021, at 8:29 AM, NateTG <[hidden email]> wrote:

mondo wrote
On 05/04/2021 13:43, NateTG wrote:
> How well does what you proposed fit with the existing OpenSCAD syntax?

Is there a 'formal definition' of the syntax anywhere, or has it just
evolved, bit's added as needed?
I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything.

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there.


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]


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

Re: OO patterns in OpenSCAD

JordanBrown
In reply to this post by mondo
On 4/5/2021 11:04 AM, Ray West wrote:

For example [] to indicate a list or vectors. Is [] used elsewhere?


Ranges.

Then there is a dot notation for the first three values. Why? Other than saving a key stroke, what is the purpose?


I think it's to make the semantics clearer.  "foo.x" more clearly refers to the X coordinate than "foo[0]" does.

That notation is currently special cased for x/y/z and begin/step/end for ranges.  There's some discussion of extending it to be more general-purpose.  I'm experimenting with it to support rich return values from my "text metrics" work.

And, does vector in openscad mean more than a vector elsewhere,


It maps pretty well to a list/array/vector in languages like Python and JavaScript, in that it's an ordered and indexed list of values, where each value can be any of the data types.

New concepts/notations can be introduced, and later on there is too much complexity and broken rules in what is a fairly succinct language.


And that's why the core developers are rightly very careful about what they add.


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

Re: OO patterns in OpenSCAD

MichaelAtOz
Administrator
In reply to this post by RevarBat

 

>     "bar": 65,    // Overwrites previous "bar" key entry.

 

> // Iterating a dictionary.  Iterate keys in original declared order?

> for (kv = dict3) {

>     echo(key=kv[0], val=kv[1]);

 

Re declared order, does "bar":65 overwrite "bar" in position 2, or does the position 2 get removed and "bar":65 added to the end?

 

 


From: Revar Desmera [mailto:[hidden email]]
Sent: Tue, 6 Apr 2021 07:39
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: OO patterns in OpenSCAD

 

Here’s the latest revision of my dictionaries proposal, which includes provisions for dot notation,

 

// Dictionaries proposal, v3.

 

// Dictionary declaration.

a = "fee"; b = "fie";

dict1 = {

    "foo": 23,    // KEY : VALUE

    "bar": 77,    // String key.

    undef: 34,    // undef key.

    false: a,     // Boolean key.

    99   : 34,    // Numeric key.

    56   : "AZ",  // Value can be any type.

    "bar": 65,    // Overwrites previous "bar" key entry.

    .qux : 29,    // Key literal syntax.  Same as "qux"

    str("c","a","t") : b  // Expressions usable for keys or values.

    a>b?a:b : a>b?5:8  // If you have a '?' then the next ':' is part of the ternary expression,

                       // not a separator.  This should always be unambiguous.  If not, use parens.

    .func = function(self,a,b) self.foo*(a+b)}  // Pseudo OOP?

};

 

// Dictionary comprehension.

dict2 = {

    for (i=[0:100])

    if(i%2==0)  // `if` works as expected.

    each {      // `each` will expand sub-dictionaries, but only in a dictionary comprehension

        i:i*5,  // Using `each` on a dictionary in a list comprehension expands into [key,val] items.

        i+0.5:i*5+1

    }

};

 

// Extending/merging dictionaries. Later duplicated keys overwrite previous ones.

// Lists merge into dictionaries using numeric positions as keys.

dict3 = concat(dict1, dict2, {"flee":0});

 

// Getting dictionary values.

w = dict3["bar"];

x = dict3.baz;   // Same as dict3["baz"].  Lets you make structures.

u = dict3.func(dict3, 3, 8);  // Calling a function literal pseudo-method.

y = dict3[a];

z = dict3["fit"];   // Returns undef for nonexistent keys.

 

// Iterating a dictionary.  Iterate keys in original declared order?

for (kv = dict3) {

    echo(key=kv[0], val=kv[1]);

}

 

// If we ever have mutable dictionaries, then you can set items like:

dict3.foo = 17;   // Key literal syntax

dict3["bar"] = 12;

 

// Otherwise with immutable dictionaries, we end up doing

dict4 = concat(dict3, {"foo":17});

dict5 = {each dict4, .bar:12};

 

- Revar

 



On Apr 5, 2021, at 8:29 AM, NateTG <[hidden email]> wrote:

 

mondo wrote

On 05/04/2021 13:43, NateTG wrote:
> How well does what you proposed fit with the existing OpenSCAD syntax?

Is there a 'formal definition' of the syntax anywhere, or has it just
evolved, bit's added as needed?

I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything.

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there.


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]

 


Virus-free. www.avg.com

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
OpenSCAD Admin - email* me if you need anything, or if I've done something stupid...
* on the Forum, click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain;
to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.
Reply | Threaded
Open this post in threaded view
|

Re: OO patterns in OpenSCAD

RevarBat
As yet dictionary key order is undefined in this spec.  It’s viable to make key order the same as add order, or just hash value order.

- Revar



On Apr 5, 2021, at 4:12 PM, MichaelAtOz <[hidden email]> wrote:

 
>     "bar": 65,    // Overwrites previous "bar" key entry.
 
> // Iterating a dictionary.  Iterate keys in original declared order?
> for (kv = dict3) {
>     echo(key=kv[0], val=kv[1]);
 
Re declared order, does "bar":65 overwrite "bar" in position 2, or does the position 2 get removed and "bar":65 added to the end?
 
 

From: Revar Desmera [[hidden email]] 
Sent: Tue, 6 Apr 2021 07:39
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: OO patterns in OpenSCAD
 
Here’s the latest revision of my dictionaries proposal, which includes provisions for dot notation,
 
// Dictionaries proposal, v3.
 
// Dictionary declaration.
a = "fee"; b = "fie";
dict1 = {
    "foo": 23,    // KEY : VALUE
    "bar": 77,    // String key.
    undef: 34,    // undef key.
    false: a,     // Boolean key.
    99   : 34,    // Numeric key.
    56   : "AZ",  // Value can be any type.
    "bar": 65,    // Overwrites previous "bar" key entry.
    .qux : 29,    // Key literal syntax.  Same as "qux"
    str("c","a","t") : b  // Expressions usable for keys or values.
    a>b?a:b : a>b?5:8  // If you have a '?' then the next ':' is part of the ternary expression,
                       // not a separator.  This should always be unambiguous.  If not, use parens.
    .func = function(self,a,b) self.foo*(a+b)}  // Pseudo OOP?
};
 
// Dictionary comprehension.
dict2 = {
    for (i=[0:100])
    if(i%2==0)  // `if` works as expected.
    each {      // `each` will expand sub-dictionaries, but only in a dictionary comprehension
        i:i*5,  // Using `each` on a dictionary in a list comprehension expands into [key,val] items.
        i+0.5:i*5+1
    }
};
 
// Extending/merging dictionaries. Later duplicated keys overwrite previous ones.
// Lists merge into dictionaries using numeric positions as keys.
dict3 = concat(dict1, dict2, {"flee":0});
 
// Getting dictionary values.
w = dict3["bar"];
x = dict3.baz;   // Same as dict3["baz"].  Lets you make structures.
u = dict3.func(dict3, 3, 8);  // Calling a function literal pseudo-method.
y = dict3[a];
z = dict3["fit"];   // Returns undef for nonexistent keys.
 
// Iterating a dictionary.  Iterate keys in original declared order?
for (kv = dict3) {
    echo(key=kv[0], val=kv[1]);
}
 
// If we ever have mutable dictionaries, then you can set items like:
dict3.foo = 17;   // Key literal syntax
dict3["bar"] = 12;
 
// Otherwise with immutable dictionaries, we end up doing
dict4 = concat(dict3, {"foo":17});
dict5 = {each dict4, .bar:12};
 
- Revar
 


On Apr 5, 2021, at 8:29 AM, NateTG <[hidden email]> wrote:
 
mondo wrote
On 05/04/2021 13:43, NateTG wrote: 
> How well does what you proposed fit with the existing OpenSCAD syntax? 

Is there a 'formal definition' of the syntax anywhere, or has it just 
evolved, bit's added as needed? 

I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything. 

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there. 


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
 

Virus-free. www.avg.com
<a href="x-msg://5/#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width="1" height="1" style="color: blue; text-decoration: underline;" class="">
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]


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

Re: OO patterns in OpenSCAD

MichaelAtOz'

You can sort to hash value order, but you can't recreate original add order, so the later would probably be more useful.

 


From: Revar Desmera [mailto:[hidden email]]
Sent: Tue, 6 Apr 2021 10:01
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: OO patterns in OpenSCAD

 

As yet dictionary key order is undefined in this spec.  It’s viable to make key order the same as add order, or just hash value order.

 

- Revar

 

 



On Apr 5, 2021, at 4:12 PM, MichaelAtOz <[hidden email]> wrote:

 

 

>     "bar": 65,    // Overwrites previous "bar" key entry.

 

> // Iterating a dictionary.  Iterate keys in original declared order?

> for (kv = dict3) {

>     echo(key=kv[0], val=kv[1]);

 

Re declared order, does "bar":65 overwrite "bar" in position 2, or does the position 2 get removed and "bar":65 added to the end?

 

 


From: Revar Desmera [[hidden email]] 
Sent: Tue, 6 Apr 2021 07:39
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: OO patterns in OpenSCAD

 

Here’s the latest revision of my dictionaries proposal, which includes provisions for dot notation,

 

// Dictionaries proposal, v3.

 

// Dictionary declaration.

a = "fee"; b = "fie";

dict1 = {

    "foo": 23,    // KEY : VALUE

    "bar": 77,    // String key.

    undef: 34,    // undef key.

    false: a,     // Boolean key.

    99   : 34,    // Numeric key.

    56   : "AZ",  // Value can be any type.

    "bar": 65,    // Overwrites previous "bar" key entry.

    .qux : 29,    // Key literal syntax.  Same as "qux"

    str("c","a","t") : b  // Expressions usable for keys or values.

    a>b?a:b : a>b?5:8  // If you have a '?' then the next ':' is part of the ternary expression,

                       // not a separator.  This should always be unambiguous.  If not, use parens.

    .func = function(self,a,b) self.foo*(a+b)}  // Pseudo OOP?

};

 

// Dictionary comprehension.

dict2 = {

    for (i=[0:100])

    if(i%2==0)  // `if` works as expected.

    each {      // `each` will expand sub-dictionaries, but only in a dictionary comprehension

        i:i*5,  // Using `each` on a dictionary in a list comprehension expands into [key,val] items.

        i+0.5:i*5+1

    }

};

 

// Extending/merging dictionaries. Later duplicated keys overwrite previous ones.

// Lists merge into dictionaries using numeric positions as keys.

dict3 = concat(dict1, dict2, {"flee":0});

 

// Getting dictionary values.

w = dict3["bar"];

x = dict3.baz;   // Same as dict3["baz"].  Lets you make structures.

u = dict3.func(dict3, 3, 8);  // Calling a function literal pseudo-method.

y = dict3[a];

z = dict3["fit"];   // Returns undef for nonexistent keys.

 

// Iterating a dictionary.  Iterate keys in original declared order?

for (kv = dict3) {

    echo(key=kv[0], val=kv[1]);

}

 

// If we ever have mutable dictionaries, then you can set items like:

dict3.foo = 17;   // Key literal syntax

dict3["bar"] = 12;

 

// Otherwise with immutable dictionaries, we end up doing

dict4 = concat(dict3, {"foo":17});

dict5 = {each dict4, .bar:12};

 

- Revar

 




On Apr 5, 2021, at 8:29 AM, NateTG <[hidden email]> wrote:

 

mondo wrote

On 05/04/2021 13:43, NateTG wrote: 
> How well does what you proposed fit with the existing OpenSCAD syntax? 

Is there a 'formal definition' of the syntax anywhere, or has it just 
evolved, bit's added as needed? 

I'm not aware of any formal design documents.  I looked through the usual documentation a bit to see what the restrictions on variable identifiers are at ( http://www.openscad.org/documentation.html) as part of thinking about this question and didn't come up with anything. 

In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there. 


Sent from the OpenSCAD mailing list archive at Nabble.com.
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]

 

 

Virus-free. www.avg.com

<a href="x-msg://5/#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2" width=1 height=1>

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

 


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

Re: OO patterns in OpenSCAD

NateTG
In reply to this post by RevarBat
RevarBat wrote
As yet dictionary key order is undefined in this spec.  It’s viable to make key order the same as add order, or just hash value order.

- Revar
...
I'm certainly used to "if you care about the order use a list" thinking.  It's probably a good idea for there to be consistent behavior, but I'm not sure having people rely on it is a good thing to encourage.

I can certainly see first beats the second, second beats the first, and assert(false) as desired behaviors for key collision, and I don't think there's a perfect solution for that.  I can even see some utility in retaining multiple (key,value) pairs for a single given key.

It seems like we should expect dict["key"] to evaluate to undef for unset values, which leads to the question whether there should be a difference between setting a value to undef and not setting the value in the first place.


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: OO patterns in OpenSCAD

MichaelAtOz
Administrator

> the question whether there should be a difference between setting a value to undef and not setting the value in the first place.

 

Perhaps NAN is unfound, thus undef is the returned matched found value?

 

 

 


From: NateTG [mailto:[hidden email]]
Sent: Tue, 6 Apr 2021 22:46
To: [hidden email]
Subject: [OpenSCAD] Re: OO patterns in OpenSCAD

 

RevarBat wrote

As yet dictionary key order is undefined in this spec.  It’s viable to make key order the same as add order, or just hash value order.

- Revar
...

I'm certainly used to "if you care about the order use a list" thinking.  It's probably a good idea for there to be consistent behavior, but I'm not sure having people rely on it is a good thing to encourage.

I can certainly see first beats the second, second beats the first, and assert(false) as desired behaviors for key collision, and I don't think there's a perfect solution for that.  I can even see some utility in retaining multiple (key,value) pairs for a single given key.

It seems like we should expect dict["key"] to evaluate to undef for unset values, which leads to the question whether there should be a difference between setting a value to undef and not setting the value in the first place.


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


Virus-free. www.avg.com

_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to [hidden email]
OpenSCAD Admin - email* me if you need anything, or if I've done something stupid...
* on the Forum, click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain;
to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.
Reply | Threaded
Open this post in threaded view
|

Re: OO patterns in OpenSCAD

NateTG

> Perhaps NAN is unfound, thus undef is the returned matched found value?

That seems like it's just changing the question from "what happens if a value gets set to undef?" to "what happens if a value gets set to NaN?"  Am I missing something?


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: OO patterns in OpenSCAD

JordanBrown
In reply to this post by NateTG
On 4/5/2021 8:29 AM, NateTG wrote:
In another sense, the language grammar is formally defined in the src/lexer.l and src/parser.y files.  So, for example, it looks like identifiers follow the regexp:  $"?[a-zA-Z0-9_]+ based on line 256 of lexer.l.   I'm not sophisticated enough to figure out where the ".x" stuff is in there.

It's in parser.y at line 473:
        | call '.' TOK_ID
where a "call" is a constant, variable, array, range, function call, array reference, or parenthesized expression.

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