discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

What happened to booleans?

JB
Jordan Brown
Fri, Jul 31, 2020 5:57 AM

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.  

Cool.

So if your program has an undef in its hands, is there a straightforward
way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.

On 7/30/2020 9:24 PM, Hans L wrote: > I've now implemented the capability for undef types to carry a reason > string.   Cool. So if your program has an undef in its hands, is there a straightforward way to say "what is the reason for this undef"? I don't know whether it's necessary to have a way to _retrieve_ the reason, or just a way to say "hey, I don't want an undef, this is an error, report the error with the reason for the undef". One really simple mechanism might be to have assert(undef) report the reason for the undef. That would be an exception to the general rule that undef is OK in a boolean context, but then again undef is false in a boolean context and assert(false) is an error, so it's not stretching the rule very much.
A
adrianv
Fri, Jul 31, 2020 10:36 AM

Another question:  is there a way to create an undef and associate a reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.  

Cool.

So if your program has an undef in its hands, is there a straightforward
way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

Another question: is there a way to create an undef and associate a reason, so for example undef("line_intersection: lines did not intersect") JordanBrown wrote > On 7/30/2020 9:24 PM, Hans L wrote: >> I've now implemented the capability for undef types to carry a reason >> string.   > > Cool. > > So if your program has an undef in its hands, is there a straightforward > way to say "what is the reason for this undef"? > > I don't know whether it's necessary to have a way to _retrieve_ the > reason, or just a way to say "hey, I don't want an undef, this is an > error, report the error with the reason for the undef". > > One really simple mechanism might be to have assert(undef) report the > reason for the undef. > > That would be an exception to the general rule that undef is OK in a > boolean context, but then again undef is false in a boolean context and > assert(false) is an error, so it's not stretching the rule very much. > > > _______________________________________________ > OpenSCAD mailing list > Discuss@.openscad > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Sent from: http://forum.openscad.org/
HL
Hans L
Fri, Jul 31, 2020 7:19 PM

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR to
only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might end
up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way where
you could copy/paste output back into a script and it should be parsed into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way to
inspect for reason strings though.

Another possibility is that the reason string could be a "member lookup" on
undef types, so e.g. ( some_undef_value.reason ) could return a string.
But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an actual
error?

For setting the string, I don't think calling undef() like a function is a
good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically) identifier of
the same name.  But perhaps a function named undefined() would be fine, for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv avm4@cornell.edu wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.

Cool.

So if your program has an undef in its hands, is there a straightforward
way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

No I haven't added any mechanism to query or set undefined strings programmatically from scripts, since I felt like that needed some more thought and planning around the interface, and wanted to limit this PR to only the least contentious changes. Adding either of those should be fairly quick and simple to implement though. For displaying the string, i considered that echo() and str() could possibly automatically show the undef strings if any. But this might end up with more verbose messages than people would like for general cases. Also as far as I know, echo() and str() generally work in such a way where you could copy/paste output back into a script and it should be parsed into the same literal values. So doing something like that should probably require that we first lock in how the string would be set programmatically (see below). Having assert() handle undef as a special case might be one good way to inspect for reason strings though. Another possibility is that the reason string could be a "member lookup" on undef types, so e.g. ( some_undef_value.reason ) could return a string. But then should an undef without any string return undef for that as well?(its undefs all the way down!) And would ".reason" on a non-undef type also be undef, or throw an actual error? For setting the string, I don't think calling undef() like a function is a good idea, since we don't want to mix up the default literal "undef" identifier with a new builtin function(constructor basically) identifier of the same name. But perhaps a function named undefined() would be fine, for example. On Fri, Jul 31, 2020 at 5:36 AM adrianv <avm4@cornell.edu> wrote: > Another question: is there a way to create an undef and associate a > reason, > so for example > > undef("line_intersection: lines did not intersect") > > > > JordanBrown wrote > > On 7/30/2020 9:24 PM, Hans L wrote: > >> I've now implemented the capability for undef types to carry a reason > >> string. > > > > Cool. > > > > So if your program has an undef in its hands, is there a straightforward > > way to say "what is the reason for this undef"? > > > > I don't know whether it's necessary to have a way to _retrieve_ the > > reason, or just a way to say "hey, I don't want an undef, this is an > > error, report the error with the reason for the undef". > > > > One really simple mechanism might be to have assert(undef) report the > > reason for the undef. > > > > That would be an exception to the general rule that undef is OK in a > > boolean context, but then again undef is false in a boolean context and > > assert(false) is an error, so it's not stretching the rule very much. > > > > > > _______________________________________________ > > OpenSCAD mailing list > > > Discuss@.openscad > > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
JB
Jordan Brown
Fri, Jul 31, 2020 9:29 PM

On 7/31/2020 12:19 PM, Hans L wrote:

For setting the string, I don't think calling undef() like a function
is a good idea, since we don't want to mix up the default literal
"undef" identifier with a new builtin function(constructor basically)
identifier of the same name.

It's a coin flip.  Having the two with the same name would be in a sense
confusing, but at the same time it makes the association between them be
really strong... and it should be really strong.

Of course, you can only ask this question in a language where variable
names[*] and functions are in different namespaces.  But OpenSCAD is
such a language.

[*]  Yeah, yeah, they aren't variables.
On 7/31/2020 12:19 PM, Hans L wrote: > For setting the string, I don't think calling undef() like a function > is a good idea, since we don't want to mix up the default literal > "undef" identifier with a new builtin function(constructor basically) > identifier of the same name. It's a coin flip.  Having the two with the same name would be in a sense confusing, but at the same time it makes the association between them be really strong... and it *should* be really strong. Of course, you can only ask this question in a language where variable names[*] and functions are in different namespaces.  But OpenSCAD is such a language. [*]  Yeah, yeah, they aren't variables.
NH
nop head
Fri, Jul 31, 2020 9:43 PM

Why does it need a different name? One of things I like about OpenSCAD is
modules, functions and variables all have their own namespace and it isn't
ambiguous which one is referred to.

On Fri, 31 Jul 2020 at 20:20, Hans L thehans@gmail.com wrote:

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR to
only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might end
up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way where
you could copy/paste output back into a script and it should be parsed into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way to
inspect for reason strings though.

Another possibility is that the reason string could be a "member lookup"
on undef types, so e.g. ( some_undef_value.reason ) could return a string.
But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an actual
error?

For setting the string, I don't think calling undef() like a function is a
good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically) identifier of
the same name.  But perhaps a function named undefined() would be fine, for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv avm4@cornell.edu wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.

Cool.

So if your program has an undef in its hands, is there a straightforward
way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

Why does it need a different name? One of things I like about OpenSCAD is modules, functions and variables all have their own namespace and it isn't ambiguous which one is referred to. On Fri, 31 Jul 2020 at 20:20, Hans L <thehans@gmail.com> wrote: > No I haven't added any mechanism to query or set undefined strings > programmatically from scripts, since I felt like that needed some more > thought and planning around the interface, and wanted to limit this PR to > only the least contentious changes. > > Adding either of those should be fairly quick and simple to implement > though. > > For displaying the string, i considered that echo() and str() could > possibly automatically show the undef strings if any. But this might end > up with more verbose messages than people would like for general cases. > Also as far as I know, echo() and str() generally work in such a way where > you could copy/paste output back into a script and it should be parsed into > the same literal values. So doing something like that should > probably require that we first lock in how the string would be set > programmatically (see below). > Having assert() handle undef as a special case might be one good way to > inspect for reason strings though. > > Another possibility is that the reason string could be a "member lookup" > on undef types, so e.g. ( some_undef_value.reason ) could return a string. > But then should an undef without any string return undef for that as > well?(its undefs all the way down!) > And would ".reason" on a non-undef type also be undef, or throw an actual > error? > > For setting the string, I don't think calling undef() like a function is a > good idea, since we don't want to mix up the default literal "undef" > identifier with a new builtin function(constructor basically) identifier of > the same name. But perhaps a function named undefined() would be fine, for > example. > > > > > On Fri, Jul 31, 2020 at 5:36 AM adrianv <avm4@cornell.edu> wrote: > >> Another question: is there a way to create an undef and associate a >> reason, >> so for example >> >> undef("line_intersection: lines did not intersect") >> >> >> >> JordanBrown wrote >> > On 7/30/2020 9:24 PM, Hans L wrote: >> >> I've now implemented the capability for undef types to carry a reason >> >> string. >> > >> > Cool. >> > >> > So if your program has an undef in its hands, is there a straightforward >> > way to say "what is the reason for this undef"? >> > >> > I don't know whether it's necessary to have a way to _retrieve_ the >> > reason, or just a way to say "hey, I don't want an undef, this is an >> > error, report the error with the reason for the undef". >> > >> > One really simple mechanism might be to have assert(undef) report the >> > reason for the undef. >> > >> > That would be an exception to the general rule that undef is OK in a >> > boolean context, but then again undef is false in a boolean context and >> > assert(false) is an error, so it's not stretching the rule very much. >> > >> > >> > _______________________________________________ >> > OpenSCAD mailing list >> >> > Discuss@.openscad >> >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
DM
Doug Moen
Fri, Jul 31, 2020 10:19 PM

A different name for the constant and the function is useful in the context of the new feature under development for function values, wherein functions can exist in the variable namespace.

On Fri, Jul 31, 2020, at 9:43 PM, nop head wrote:

Why does it need a different name? One of things I like about OpenSCAD is modules, functions and variables all have their own namespace and it isn't ambiguous which one is referred to.

On Fri, 31 Jul 2020 at 20:20, Hans L thehans@gmail.com wrote:

No I haven't added any mechanism to query or set undefined strings programmatically from scripts, since I felt like that needed some more thought and planning around the interface, and wanted to limit this PR to only the least contentious changes.

Adding either of those should be fairly quick and simple to implement though.

For displaying the string, i considered that echo() and str() could possibly automatically show the undef strings if any.  But this might end up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way where you could copy/paste output back into a script and it should be parsed into the same literal values.  So doing something like that should probably require that we first lock in how the string would be set programmatically (see below).
Having assert() handle undef as a special case might be one good way to inspect for reason strings though.

Another possibility is that the reason string could be a "member lookup" on undef types, so e.g. ( some_undef_value.reason ) could return a string.  But then should an undef without any string return undef for that as well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an actual error?

For setting the string, I don't think calling undef() like a function is a good idea, since we don't want to mix up the default literal "undef" identifier with a new builtin function(constructor basically) identifier of the same name.  But perhaps a function named undefined() would be fine, for example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv avm4@cornell.edu wrote:

Another question:  is there a way to create an undef and associate a reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.

Cool.

So if your program has an undef in its hands, is there a straightforward
way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

A different name for the constant and the function is useful in the context of the new feature under development for function values, wherein functions can exist in the variable namespace. On Fri, Jul 31, 2020, at 9:43 PM, nop head wrote: > Why does it need a different name? One of things I like about OpenSCAD is modules, functions and variables all have their own namespace and it isn't ambiguous which one is referred to. > > > On Fri, 31 Jul 2020 at 20:20, Hans L <thehans@gmail.com> wrote: >> No I haven't added any mechanism to query or set undefined strings programmatically from scripts, since I felt like that needed some more thought and planning around the interface, and wanted to limit this PR to only the least contentious changes. >> >> Adding either of those should be fairly quick and simple to implement though. >> >> For displaying the string, i considered that echo() and str() could possibly automatically show the undef strings if any. But this might end up with more verbose messages than people would like for general cases. >> Also as far as I know, echo() and str() generally work in such a way where you could copy/paste output back into a script and it should be parsed into the same literal values. So doing something like that should probably require that we first lock in how the string would be set programmatically (see below). >> Having assert() handle undef as a special case might be one good way to inspect for reason strings though. >> >> Another possibility is that the reason string could be a "member lookup" on undef types, so e.g. ( some_undef_value.reason ) could return a string. But then should an undef without any string return undef for that as well?(its undefs all the way down!) >> And would ".reason" on a non-undef type also be undef, or throw an actual error? >> >> For setting the string, I don't think calling undef() like a function is a good idea, since we don't want to mix up the default literal "undef" identifier with a new builtin function(constructor basically) identifier of the same name. But perhaps a function named undefined() would be fine, for example. >> >> >> >> >> On Fri, Jul 31, 2020 at 5:36 AM adrianv <avm4@cornell.edu> wrote: >>> Another question: is there a way to create an undef and associate a reason, >>> so for example >>> >>> undef("line_intersection: lines did not intersect") >>> >>> >>> >>> JordanBrown wrote >>> > On 7/30/2020 9:24 PM, Hans L wrote: >>> >> I've now implemented the capability for undef types to carry a reason >>> >> string. >>> > >>> > Cool. >>> > >>> > So if your program has an undef in its hands, is there a straightforward >>> > way to say "what is the reason for this undef"? >>> > >>> > I don't know whether it's necessary to have a way to _retrieve_ the >>> > reason, or just a way to say "hey, I don't want an undef, this is an >>> > error, report the error with the reason for the undef". >>> > >>> > One really simple mechanism might be to have assert(undef) report the >>> > reason for the undef. >>> > >>> > That would be an exception to the general rule that undef is OK in a >>> > boolean context, but then again undef is false in a boolean context and >>> > assert(false) is an error, so it's not stretching the rule very much. >>> > >>> > >>> > _______________________________________________ >>> > OpenSCAD mailing list >>> >>> > Discuss@.openscad >>> >>> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >>> >>> >>> >>> >>> -- >>> Sent from: http://forum.openscad.org/ >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
A
adrianv
Fri, Jul 31, 2020 10:28 PM

What is confusing about calling undef() like a function?  You say we don't
want to "mix up" the undef literal with an undef constructor, but what's the
difference really between

undef

and

undef("some reason text")

Isn't the first one basically the same as the second one only with the
argument missing, in some sense?  What's the problem or consequence of
"mixing up" these two things?  When there's no string associated with an
undef then what is there?  Empty string?  Another undef?  It's a bit
unclear what the advantage is of not having a string.  Shouldn't there
always be one?  (undef: "list index out of bounds", undef: "variable not
set", undef: "mismatched argument types for +".)  It seems like you'd want
to encourage users to supply the string any time they make an assignment.

I guess there's the question of what it means if you just write "foo=undef",
as in that case there's no string.  The string could be "direct assignment"
or something like that.

To me it seems like doing

foo = undef

but

foo = undefined("some reason")

is more confusing because now I have to remember when to use undef and when
to use undefined.  It looks like undef is already illegal as a function
name, so it wouldn't break any code, whereas undefined() is currently a
valid function, so using that could break code.

thehans wrote

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR to
only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might end
up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way where
you could copy/paste output back into a script and it should be parsed
into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way to
inspect for reason strings though.

Another possibility is that the reason string could be a "member lookup"
on
undef types, so e.g. ( some_undef_value.reason ) could return a string.
But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an actual
error?

For setting the string, I don't think calling undef() like a function is a
good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically) identifier
of
the same name.  But perhaps a function named undefined() would be fine,
for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv <

avm4@

> wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.

Cool.

So if your program has an undef in its hands, is there a

straightforward

way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context and
assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad

Discuss@.openscad

What is confusing about calling undef() like a function? You say we don't want to "mix up" the undef literal with an undef constructor, but what's the difference really between undef and undef("some reason text") Isn't the first one basically the same as the second one only with the argument missing, in some sense? What's the problem or consequence of "mixing up" these two things? When there's no string associated with an undef then what is there? Empty string? Another undef? It's a bit unclear what the advantage is of not having a string. Shouldn't there always be one? (undef: "list index out of bounds", undef: "variable not set", undef: "mismatched argument types for +".) It seems like you'd want to encourage users to supply the string any time they make an assignment. I guess there's the question of what it means if you just write "foo=undef", as in that case there's no string. The string could be "direct assignment" or something like that. To me it seems like doing foo = undef but foo = undefined("some reason") is more confusing because now I have to remember when to use undef and when to use undefined. It looks like undef is already illegal as a function name, so it wouldn't break any code, whereas undefined() is currently a valid function, so using that could break code. thehans wrote > No I haven't added any mechanism to query or set undefined strings > programmatically from scripts, since I felt like that needed some more > thought and planning around the interface, and wanted to limit this PR to > only the least contentious changes. > > Adding either of those should be fairly quick and simple to implement > though. > > For displaying the string, i considered that echo() and str() could > possibly automatically show the undef strings if any. But this might end > up with more verbose messages than people would like for general cases. > Also as far as I know, echo() and str() generally work in such a way where > you could copy/paste output back into a script and it should be parsed > into > the same literal values. So doing something like that should > probably require that we first lock in how the string would be set > programmatically (see below). > Having assert() handle undef as a special case might be one good way to > inspect for reason strings though. > > Another possibility is that the reason string could be a "member lookup" > on > undef types, so e.g. ( some_undef_value.reason ) could return a string. > But then should an undef without any string return undef for that as > well?(its undefs all the way down!) > And would ".reason" on a non-undef type also be undef, or throw an actual > error? > > For setting the string, I don't think calling undef() like a function is a > good idea, since we don't want to mix up the default literal "undef" > identifier with a new builtin function(constructor basically) identifier > of > the same name. But perhaps a function named undefined() would be fine, > for > example. > > > > > On Fri, Jul 31, 2020 at 5:36 AM adrianv &lt; > avm4@ > &gt; wrote: > >> Another question: is there a way to create an undef and associate a >> reason, >> so for example >> >> undef("line_intersection: lines did not intersect") >> >> >> >> JordanBrown wrote >> > On 7/30/2020 9:24 PM, Hans L wrote: >> >> I've now implemented the capability for undef types to carry a reason >> >> string. >> > >> > Cool. >> > >> > So if your program has an undef in its hands, is there a >> straightforward >> > way to say "what is the reason for this undef"? >> > >> > I don't know whether it's necessary to have a way to _retrieve_ the >> > reason, or just a way to say "hey, I don't want an undef, this is an >> > error, report the error with the reason for the undef". >> > >> > One really simple mechanism might be to have assert(undef) report the >> > reason for the undef. >> > >> > That would be an exception to the general rule that undef is OK in a >> > boolean context, but then again undef is false in a boolean context and >> > assert(false) is an error, so it's not stretching the rule very much. >> > >> > >> > _______________________________________________ >> > OpenSCAD mailing list >> >> > Discuss@.openscad >> >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> > Discuss@.openscad >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@.openscad > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Sent from: http://forum.openscad.org/
HL
Hans L
Fri, Jul 31, 2020 10:44 PM

As Doug points out, the situation is more complicated if you account for
function literals, which already exist as an experimental feature.
It's not necessarily an issue at the moment, but If we ever decided to make
builtin functions accessible as literals (personally i would like to see
this), then writing: foo = undef; would be ambiguous whether you want the
function literal value or the actual undef literal.

On Fri, Jul 31, 2020 at 5:29 PM adrianv avm4@cornell.edu wrote:

What is confusing about calling undef() like a function?  You say we don't
want to "mix up" the undef literal with an undef constructor, but what's
the
difference really between

undef

and

undef("some reason text")

Isn't the first one basically the same as the second one only with the
argument missing, in some sense?  What's the problem or consequence of
"mixing up" these two things?  When there's no string associated with an
undef then what is there?  Empty string?  Another undef?  It's a bit
unclear what the advantage is of not having a string.  Shouldn't there
always be one?  (undef: "list index out of bounds", undef: "variable not
set", undef: "mismatched argument types for +".)  It seems like you'd want
to encourage users to supply the string any time they make an assignment.

I guess there's the question of what it means if you just write
"foo=undef",
as in that case there's no string.  The string could be "direct assignment"
or something like that.

To me it seems like doing

foo = undef

but

foo = undefined("some reason")

is more confusing because now I have to remember when to use undef and when
to use undefined.  It looks like undef is already illegal as a function
name, so it wouldn't break any code, whereas undefined() is currently a
valid function, so using that could break code.

thehans wrote

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR to
only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might end
up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way

where

you could copy/paste output back into a script and it should be parsed
into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way to
inspect for reason strings though.

Another possibility is that the reason string could be a "member lookup"
on
undef types, so e.g. ( some_undef_value.reason ) could return a string.
But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an actual
error?

For setting the string, I don't think calling undef() like a function is

a

good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically) identifier
of
the same name.  But perhaps a function named undefined() would be fine,
for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv <

avm4@

> wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a reason
string.

Cool.

So if your program has an undef in its hands, is there a

straightforward

way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report the
reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context

and

assert(false) is an error, so it's not stretching the rule very much.


OpenSCAD mailing list

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad

Discuss@.openscad

As Doug points out, the situation is more complicated if you account for function literals, which already exist as an experimental feature. It's not necessarily an issue at the moment, but If we ever decided to make builtin functions accessible as literals (personally i would like to see this), then writing: foo = undef; would be ambiguous whether you want the function literal value or the actual undef literal. On Fri, Jul 31, 2020 at 5:29 PM adrianv <avm4@cornell.edu> wrote: > What is confusing about calling undef() like a function? You say we don't > want to "mix up" the undef literal with an undef constructor, but what's > the > difference really between > > undef > > and > > undef("some reason text") > > Isn't the first one basically the same as the second one only with the > argument missing, in some sense? What's the problem or consequence of > "mixing up" these two things? When there's no string associated with an > undef then what is there? Empty string? Another undef? It's a bit > unclear what the advantage is of not having a string. Shouldn't there > always be one? (undef: "list index out of bounds", undef: "variable not > set", undef: "mismatched argument types for +".) It seems like you'd want > to encourage users to supply the string any time they make an assignment. > > I guess there's the question of what it means if you just write > "foo=undef", > as in that case there's no string. The string could be "direct assignment" > or something like that. > > To me it seems like doing > > foo = undef > > but > > foo = undefined("some reason") > > is more confusing because now I have to remember when to use undef and when > to use undefined. It looks like undef is already illegal as a function > name, so it wouldn't break any code, whereas undefined() is currently a > valid function, so using that could break code. > > > > thehans wrote > > No I haven't added any mechanism to query or set undefined strings > > programmatically from scripts, since I felt like that needed some more > > thought and planning around the interface, and wanted to limit this PR to > > only the least contentious changes. > > > > Adding either of those should be fairly quick and simple to implement > > though. > > > > For displaying the string, i considered that echo() and str() could > > possibly automatically show the undef strings if any. But this might end > > up with more verbose messages than people would like for general cases. > > Also as far as I know, echo() and str() generally work in such a way > where > > you could copy/paste output back into a script and it should be parsed > > into > > the same literal values. So doing something like that should > > probably require that we first lock in how the string would be set > > programmatically (see below). > > Having assert() handle undef as a special case might be one good way to > > inspect for reason strings though. > > > > Another possibility is that the reason string could be a "member lookup" > > on > > undef types, so e.g. ( some_undef_value.reason ) could return a string. > > But then should an undef without any string return undef for that as > > well?(its undefs all the way down!) > > And would ".reason" on a non-undef type also be undef, or throw an actual > > error? > > > > For setting the string, I don't think calling undef() like a function is > a > > good idea, since we don't want to mix up the default literal "undef" > > identifier with a new builtin function(constructor basically) identifier > > of > > the same name. But perhaps a function named undefined() would be fine, > > for > > example. > > > > > > > > > > On Fri, Jul 31, 2020 at 5:36 AM adrianv &lt; > > > avm4@ > > > &gt; wrote: > > > >> Another question: is there a way to create an undef and associate a > >> reason, > >> so for example > >> > >> undef("line_intersection: lines did not intersect") > >> > >> > >> > >> JordanBrown wrote > >> > On 7/30/2020 9:24 PM, Hans L wrote: > >> >> I've now implemented the capability for undef types to carry a reason > >> >> string. > >> > > >> > Cool. > >> > > >> > So if your program has an undef in its hands, is there a > >> straightforward > >> > way to say "what is the reason for this undef"? > >> > > >> > I don't know whether it's necessary to have a way to _retrieve_ the > >> > reason, or just a way to say "hey, I don't want an undef, this is an > >> > error, report the error with the reason for the undef". > >> > > >> > One really simple mechanism might be to have assert(undef) report the > >> > reason for the undef. > >> > > >> > That would be an exception to the general rule that undef is OK in a > >> > boolean context, but then again undef is false in a boolean context > and > >> > assert(false) is an error, so it's not stretching the rule very much. > >> > > >> > > >> > _______________________________________________ > >> > OpenSCAD mailing list > >> > >> > Discuss@.openscad > >> > >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> > >> > >> > >> > >> > >> -- > >> Sent from: http://forum.openscad.org/ > >> > >> _______________________________________________ > >> OpenSCAD mailing list > >> > > > Discuss@.openscad > > >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> > > > > _______________________________________________ > > OpenSCAD mailing list > > > Discuss@.openscad > > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
A
adrianv
Fri, Jul 31, 2020 11:34 PM

I hadn't really thought about how function literals might be involved here.
But I'm a little puzzled.  Suppose builtin functions can be treated as
literals as shown below.  Then

foo = sin

is ambiguous about whether I mean the function "sin" or the variable "sin".
I would think that if you want to make regular functions (and built-ins)
available as literals---which is a really good idea because otherwise it
creates a confusing situation where some functions need to be redefined as
function literals for convenience---you should do something like what MATLAB
does and create a syntax for it.  In MATLAB you create a function literal
(they call them handles) from (any) function using "@".  So in MATLAB

foo = @sin

assigns a function literal into foo.  And the call

foo(@sin,@cos)

passes two function literals into the function foo.  Given how namespaces
work in OpenSCAD there's no way to assign a pre-existing function to a
variable or pass functions as literals without a new syntax that "converts"
the function into a literal.

But my point is that

foo=undef

is not any more ambiguous than

foo=sin

so it's not a problem that has to do with undef.  So I still don't see any
issue with using the functional form I proposed.

foo = undef;  // Plain undef without text
foo = undef("reason");  // undef with text
foo = @undef;  // or whatever new syntax....  the undef function...though
why would you ever want that?

Have I missed something?

thehans wrote

As Doug points out, the situation is more complicated if you account for
function literals, which already exist as an experimental feature.
It's not necessarily an issue at the moment, but If we ever decided to
make
builtin functions accessible as literals (personally i would like to see
this), then writing: foo = undef; would be ambiguous whether you want the
function literal value or the actual undef literal.

On Fri, Jul 31, 2020 at 5:29 PM adrianv <

avm4@

> wrote:

What is confusing about calling undef() like a function?  You say we
don't
want to "mix up" the undef literal with an undef constructor, but what's
the
difference really between

undef

and

undef("some reason text")

Isn't the first one basically the same as the second one only with the
argument missing, in some sense?  What's the problem or consequence of
"mixing up" these two things?  When there's no string associated with an
undef then what is there?  Empty string?  Another undef?  It's a bit
unclear what the advantage is of not having a string.  Shouldn't there
always be one?  (undef: "list index out of bounds", undef: "variable not
set", undef: "mismatched argument types for +".)  It seems like you'd
want
to encourage users to supply the string any time they make an assignment.

I guess there's the question of what it means if you just write
"foo=undef",
as in that case there's no string.  The string could be "direct
assignment"
or something like that.

To me it seems like doing

foo = undef

but

foo = undefined("some reason")

is more confusing because now I have to remember when to use undef and
when
to use undefined.  It looks like undef is already illegal as a function
name, so it wouldn't break any code, whereas undefined() is currently a
valid function, so using that could break code.

thehans wrote

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR

to

only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might

end

up with more verbose messages than people would like for general cases.
Also as far as I know, echo() and str() generally work in such a way

where

you could copy/paste output back into a script and it should be parsed
into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way to
inspect for reason strings though.

Another possibility is that the reason string could be a "member

lookup"

on
undef types, so e.g. ( some_undef_value.reason ) could return a string.
But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an

actual

error?

For setting the string, I don't think calling undef() like a function

is
a

good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically)

identifier

of
the same name.  But perhaps a function named undefined() would be fine,
for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv <

avm4@

> wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a

reason

string.

Cool.

So if your program has an undef in its hands, is there a

straightforward

way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is an
error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report

the

reason for the undef.

That would be an exception to the general rule that undef is OK in a
boolean context, but then again undef is false in a boolean context

and

assert(false) is an error, so it's not stretching the rule very

much.


OpenSCAD mailing list

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad

Discuss@.openscad

I hadn't really thought about how function literals might be involved here. But I'm a little puzzled. Suppose builtin functions can be treated as literals as shown below. Then foo = sin is ambiguous about whether I mean the function "sin" or the variable "sin". I would think that if you want to make regular functions (and built-ins) available as literals---which is a really good idea because otherwise it creates a confusing situation where some functions need to be redefined as function literals for convenience---you should do something like what MATLAB does and create a syntax for it. In MATLAB you create a function literal (they call them handles) from (any) function using "@". So in MATLAB foo = @sin assigns a function literal into foo. And the call foo(@sin,@cos) passes two function literals into the function foo. Given how namespaces work in OpenSCAD there's no way to assign a pre-existing function to a variable or pass functions as literals without a new syntax that "converts" the function into a literal. But my point is that foo=undef is not any more ambiguous than foo=sin so it's not a problem that has to do with undef. So I still don't see any issue with using the functional form I proposed. foo = undef; // Plain undef without text foo = undef("reason"); // undef with text foo = @undef; // or whatever new syntax.... the undef function...though why would you ever want that? Have I missed something? thehans wrote > As Doug points out, the situation is more complicated if you account for > function literals, which already exist as an experimental feature. > It's not necessarily an issue at the moment, but If we ever decided to > make > builtin functions accessible as literals (personally i would like to see > this), then writing: foo = undef; would be ambiguous whether you want the > function literal value or the actual undef literal. > > On Fri, Jul 31, 2020 at 5:29 PM adrianv &lt; > avm4@ > &gt; wrote: > >> What is confusing about calling undef() like a function? You say we >> don't >> want to "mix up" the undef literal with an undef constructor, but what's >> the >> difference really between >> >> undef >> >> and >> >> undef("some reason text") >> >> Isn't the first one basically the same as the second one only with the >> argument missing, in some sense? What's the problem or consequence of >> "mixing up" these two things? When there's no string associated with an >> undef then what is there? Empty string? Another undef? It's a bit >> unclear what the advantage is of not having a string. Shouldn't there >> always be one? (undef: "list index out of bounds", undef: "variable not >> set", undef: "mismatched argument types for +".) It seems like you'd >> want >> to encourage users to supply the string any time they make an assignment. >> >> I guess there's the question of what it means if you just write >> "foo=undef", >> as in that case there's no string. The string could be "direct >> assignment" >> or something like that. >> >> To me it seems like doing >> >> foo = undef >> >> but >> >> foo = undefined("some reason") >> >> is more confusing because now I have to remember when to use undef and >> when >> to use undefined. It looks like undef is already illegal as a function >> name, so it wouldn't break any code, whereas undefined() is currently a >> valid function, so using that could break code. >> >> >> >> thehans wrote >> > No I haven't added any mechanism to query or set undefined strings >> > programmatically from scripts, since I felt like that needed some more >> > thought and planning around the interface, and wanted to limit this PR >> to >> > only the least contentious changes. >> > >> > Adding either of those should be fairly quick and simple to implement >> > though. >> > >> > For displaying the string, i considered that echo() and str() could >> > possibly automatically show the undef strings if any. But this might >> end >> > up with more verbose messages than people would like for general cases. >> > Also as far as I know, echo() and str() generally work in such a way >> where >> > you could copy/paste output back into a script and it should be parsed >> > into >> > the same literal values. So doing something like that should >> > probably require that we first lock in how the string would be set >> > programmatically (see below). >> > Having assert() handle undef as a special case might be one good way to >> > inspect for reason strings though. >> > >> > Another possibility is that the reason string could be a "member >> lookup" >> > on >> > undef types, so e.g. ( some_undef_value.reason ) could return a string. >> > But then should an undef without any string return undef for that as >> > well?(its undefs all the way down!) >> > And would ".reason" on a non-undef type also be undef, or throw an >> actual >> > error? >> > >> > For setting the string, I don't think calling undef() like a function >> is >> a >> > good idea, since we don't want to mix up the default literal "undef" >> > identifier with a new builtin function(constructor basically) >> identifier >> > of >> > the same name. But perhaps a function named undefined() would be fine, >> > for >> > example. >> > >> > >> > >> > >> > On Fri, Jul 31, 2020 at 5:36 AM adrianv &lt; >> >> > avm4@ >> >> > &gt; wrote: >> > >> >> Another question: is there a way to create an undef and associate a >> >> reason, >> >> so for example >> >> >> >> undef("line_intersection: lines did not intersect") >> >> >> >> >> >> >> >> JordanBrown wrote >> >> > On 7/30/2020 9:24 PM, Hans L wrote: >> >> >> I've now implemented the capability for undef types to carry a >> reason >> >> >> string. >> >> > >> >> > Cool. >> >> > >> >> > So if your program has an undef in its hands, is there a >> >> straightforward >> >> > way to say "what is the reason for this undef"? >> >> > >> >> > I don't know whether it's necessary to have a way to _retrieve_ the >> >> > reason, or just a way to say "hey, I don't want an undef, this is an >> >> > error, report the error with the reason for the undef". >> >> > >> >> > One really simple mechanism might be to have assert(undef) report >> the >> >> > reason for the undef. >> >> > >> >> > That would be an exception to the general rule that undef is OK in a >> >> > boolean context, but then again undef is false in a boolean context >> and >> >> > assert(false) is an error, so it's not stretching the rule very >> much. >> >> > >> >> > >> >> > _______________________________________________ >> >> > OpenSCAD mailing list >> >> >> >> > Discuss@.openscad >> >> >> >> > >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> >> >> >> >> >> >> >> >> >> -- >> >> Sent from: http://forum.openscad.org/ >> >> >> >> _______________________________________________ >> >> OpenSCAD mailing list >> >> >> >> > Discuss@.openscad >> >> >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> > >> > _______________________________________________ >> > OpenSCAD mailing list >> >> > Discuss@.openscad >> >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> >> >> >> -- >> Sent from: http://forum.openscad.org/ >> >> _______________________________________________ >> OpenSCAD mailing list >> > Discuss@.openscad >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@.openscad > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Sent from: http://forum.openscad.org/
HL
Hans L
Sat, Aug 1, 2020 12:40 AM

The difference is that undef is an already established builtin constant
value
, but sin is not.
x = sin;
WARNING: Ignoring unknown variable 'sin', in file , line 1.

If builtin functions were treated as literals, then that would be fine with
no warning, and x would then hold a FunctionType value.

The user would of course be free to assign a value to their own variable
named "sin", and this would shadow our hypothetical builtin function
literal of the same name.
It would be a weird thing for the user to do, but not ambiguous.

On Fri, Jul 31, 2020 at 6:35 PM adrianv avm4@cornell.edu wrote:

I hadn't really thought about how function literals might be involved
here.
But I'm a little puzzled.  Suppose builtin functions can be treated as
literals as shown below.  Then

foo = sin

is ambiguous about whether I mean the function "sin" or the variable
"sin".
I would think that if you want to make regular functions (and built-ins)
available as literals---which is a really good idea because otherwise it
creates a confusing situation where some functions need to be redefined as
function literals for convenience---you should do something like what
MATLAB
does and create a syntax for it.  In MATLAB you create a function literal
(they call them handles) from (any) function using "@".  So in MATLAB

foo = @sin

assigns a function literal into foo.  And the call

foo(@sin,@cos)

passes two function literals into the function foo.  Given how namespaces
work in OpenSCAD there's no way to assign a pre-existing function to a
variable or pass functions as literals without a new syntax that "converts"
the function into a literal.

But my point is that

foo=undef

is not any more ambiguous than

foo=sin

so it's not a problem that has to do with undef.  So I still don't see any
issue with using the functional form I proposed.

foo = undef;  // Plain undef without text
foo = undef("reason");  // undef with text
foo = @undef;  // or whatever new syntax....  the undef function...though
why would you ever want that?

Have I missed something?

thehans wrote

As Doug points out, the situation is more complicated if you account for
function literals, which already exist as an experimental feature.
It's not necessarily an issue at the moment, but If we ever decided to
make
builtin functions accessible as literals (personally i would like to see
this), then writing: foo = undef; would be ambiguous whether you want the
function literal value or the actual undef literal.

On Fri, Jul 31, 2020 at 5:29 PM adrianv <

avm4@

> wrote:

What is confusing about calling undef() like a function?  You say we
don't
want to "mix up" the undef literal with an undef constructor, but what's
the
difference really between

undef

and

undef("some reason text")

Isn't the first one basically the same as the second one only with the
argument missing, in some sense?  What's the problem or consequence of
"mixing up" these two things?  When there's no string associated with

an

undef then what is there?  Empty string?  Another undef?  It's a bit
unclear what the advantage is of not having a string.  Shouldn't there
always be one?  (undef: "list index out of bounds", undef: "variable not
set", undef: "mismatched argument types for +".)  It seems like you'd
want
to encourage users to supply the string any time they make an

assignment.

I guess there's the question of what it means if you just write
"foo=undef",
as in that case there's no string.  The string could be "direct
assignment"
or something like that.

To me it seems like doing

foo = undef

but

foo = undefined("some reason")

is more confusing because now I have to remember when to use undef and
when
to use undefined.  It looks like undef is already illegal as a function
name, so it wouldn't break any code, whereas undefined() is currently a
valid function, so using that could break code.

thehans wrote

No I haven't added any mechanism to query or set undefined strings
programmatically from scripts, since I felt like that needed some more
thought and planning around the interface, and wanted to limit this PR

to

only the least contentious changes.

Adding either of those should be fairly quick and simple to implement
though.

For displaying the string, i considered that echo() and str() could
possibly automatically show the undef strings if any.  But this might

end

up with more verbose messages than people would like for general

cases.

Also as far as I know, echo() and str() generally work in such a way

where

you could copy/paste output back into a script and it should be parsed
into
the same literal values.  So doing something like that should
probably require that we first lock in how the string would be set
programmatically (see below).
Having assert() handle undef as a special case might be one good way

to

inspect for reason strings though.

Another possibility is that the reason string could be a "member

lookup"

on
undef types, so e.g. ( some_undef_value.reason ) could return a

string.

But then should an undef without any string return undef for that as
well?(its undefs all the way down!)
And would ".reason" on a non-undef type also be undef, or throw an

actual

error?

For setting the string, I don't think calling undef() like a function

is
a

good idea, since we don't want to mix up the default literal "undef"
identifier with a new builtin function(constructor basically)

identifier

of
the same name.  But perhaps a function named undefined() would be

fine,

for
example.

On Fri, Jul 31, 2020 at 5:36 AM adrianv <

avm4@

> wrote:

Another question:  is there a way to create an undef and associate a
reason,
so for example

undef("line_intersection: lines did not intersect")

JordanBrown wrote

On 7/30/2020 9:24 PM, Hans L wrote:

I've now implemented the capability for undef types to carry a

reason

string.

Cool.

So if your program has an undef in its hands, is there a

straightforward

way to say "what is the reason for this undef"?

I don't know whether it's necessary to have a way to retrieve the
reason, or just a way to say "hey, I don't want an undef, this is

an

error, report the error with the reason for the undef".

One really simple mechanism might be to have assert(undef) report

the

reason for the undef.

That would be an exception to the general rule that undef is OK in

a

boolean context, but then again undef is false in a boolean context

and

assert(false) is an error, so it's not stretching the rule very

much.


OpenSCAD mailing list

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad


OpenSCAD mailing list

Discuss@.openscad

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


OpenSCAD mailing list

Discuss@.openscad

Discuss@.openscad

The difference is that undef is an already established builtin *constant value*, but sin is not. x = sin; WARNING: Ignoring unknown variable 'sin', in file , line 1. If builtin functions were treated as literals, then that would be fine with no warning, and x would then hold a FunctionType value. The user would of course be free to assign a value to their own variable named "sin", and this would shadow our hypothetical builtin function literal of the same name. It would be a weird thing for the user to do, but not ambiguous. On Fri, Jul 31, 2020 at 6:35 PM adrianv <avm4@cornell.edu> wrote: > I hadn't really thought about how function literals might be involved > here. > But I'm a little puzzled. Suppose builtin functions can be treated as > literals as shown below. Then > > foo = sin > > is ambiguous about whether I mean the function "sin" or the variable > "sin". > I would think that if you want to make regular functions (and built-ins) > available as literals---which is a really good idea because otherwise it > creates a confusing situation where some functions need to be redefined as > function literals for convenience---you should do something like what > MATLAB > does and create a syntax for it. In MATLAB you create a function literal > (they call them handles) from (any) function using "@". So in MATLAB > > foo = @sin > > assigns a function literal into foo. And the call > > foo(@sin,@cos) > > passes two function literals into the function foo. Given how namespaces > work in OpenSCAD there's no way to assign a pre-existing function to a > variable or pass functions as literals without a new syntax that "converts" > the function into a literal. > > But my point is that > > foo=undef > > is not any more ambiguous than > > foo=sin > > so it's not a problem that has to do with undef. So I still don't see any > issue with using the functional form I proposed. > > foo = undef; // Plain undef without text > foo = undef("reason"); // undef with text > foo = @undef; // or whatever new syntax.... the undef function...though > why would you ever want that? > > Have I missed something? > > > thehans wrote > > As Doug points out, the situation is more complicated if you account for > > function literals, which already exist as an experimental feature. > > It's not necessarily an issue at the moment, but If we ever decided to > > make > > builtin functions accessible as literals (personally i would like to see > > this), then writing: foo = undef; would be ambiguous whether you want the > > function literal value or the actual undef literal. > > > > On Fri, Jul 31, 2020 at 5:29 PM adrianv &lt; > > > avm4@ > > > &gt; wrote: > > > >> What is confusing about calling undef() like a function? You say we > >> don't > >> want to "mix up" the undef literal with an undef constructor, but what's > >> the > >> difference really between > >> > >> undef > >> > >> and > >> > >> undef("some reason text") > >> > >> Isn't the first one basically the same as the second one only with the > >> argument missing, in some sense? What's the problem or consequence of > >> "mixing up" these two things? When there's no string associated with > an > >> undef then what is there? Empty string? Another undef? It's a bit > >> unclear what the advantage is of not having a string. Shouldn't there > >> always be one? (undef: "list index out of bounds", undef: "variable not > >> set", undef: "mismatched argument types for +".) It seems like you'd > >> want > >> to encourage users to supply the string any time they make an > assignment. > >> > >> I guess there's the question of what it means if you just write > >> "foo=undef", > >> as in that case there's no string. The string could be "direct > >> assignment" > >> or something like that. > >> > >> To me it seems like doing > >> > >> foo = undef > >> > >> but > >> > >> foo = undefined("some reason") > >> > >> is more confusing because now I have to remember when to use undef and > >> when > >> to use undefined. It looks like undef is already illegal as a function > >> name, so it wouldn't break any code, whereas undefined() is currently a > >> valid function, so using that could break code. > >> > >> > >> > >> thehans wrote > >> > No I haven't added any mechanism to query or set undefined strings > >> > programmatically from scripts, since I felt like that needed some more > >> > thought and planning around the interface, and wanted to limit this PR > >> to > >> > only the least contentious changes. > >> > > >> > Adding either of those should be fairly quick and simple to implement > >> > though. > >> > > >> > For displaying the string, i considered that echo() and str() could > >> > possibly automatically show the undef strings if any. But this might > >> end > >> > up with more verbose messages than people would like for general > cases. > >> > Also as far as I know, echo() and str() generally work in such a way > >> where > >> > you could copy/paste output back into a script and it should be parsed > >> > into > >> > the same literal values. So doing something like that should > >> > probably require that we first lock in how the string would be set > >> > programmatically (see below). > >> > Having assert() handle undef as a special case might be one good way > to > >> > inspect for reason strings though. > >> > > >> > Another possibility is that the reason string could be a "member > >> lookup" > >> > on > >> > undef types, so e.g. ( some_undef_value.reason ) could return a > string. > >> > But then should an undef without any string return undef for that as > >> > well?(its undefs all the way down!) > >> > And would ".reason" on a non-undef type also be undef, or throw an > >> actual > >> > error? > >> > > >> > For setting the string, I don't think calling undef() like a function > >> is > >> a > >> > good idea, since we don't want to mix up the default literal "undef" > >> > identifier with a new builtin function(constructor basically) > >> identifier > >> > of > >> > the same name. But perhaps a function named undefined() would be > fine, > >> > for > >> > example. > >> > > >> > > >> > > >> > > >> > On Fri, Jul 31, 2020 at 5:36 AM adrianv &lt; > >> > >> > avm4@ > >> > >> > &gt; wrote: > >> > > >> >> Another question: is there a way to create an undef and associate a > >> >> reason, > >> >> so for example > >> >> > >> >> undef("line_intersection: lines did not intersect") > >> >> > >> >> > >> >> > >> >> JordanBrown wrote > >> >> > On 7/30/2020 9:24 PM, Hans L wrote: > >> >> >> I've now implemented the capability for undef types to carry a > >> reason > >> >> >> string. > >> >> > > >> >> > Cool. > >> >> > > >> >> > So if your program has an undef in its hands, is there a > >> >> straightforward > >> >> > way to say "what is the reason for this undef"? > >> >> > > >> >> > I don't know whether it's necessary to have a way to _retrieve_ the > >> >> > reason, or just a way to say "hey, I don't want an undef, this is > an > >> >> > error, report the error with the reason for the undef". > >> >> > > >> >> > One really simple mechanism might be to have assert(undef) report > >> the > >> >> > reason for the undef. > >> >> > > >> >> > That would be an exception to the general rule that undef is OK in > a > >> >> > boolean context, but then again undef is false in a boolean context > >> and > >> >> > assert(false) is an error, so it's not stretching the rule very > >> much. > >> >> > > >> >> > > >> >> > _______________________________________________ > >> >> > OpenSCAD mailing list > >> >> > >> >> > Discuss@.openscad > >> >> > >> >> > > >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> >> > >> >> > >> >> > >> >> > >> >> > >> >> -- > >> >> Sent from: http://forum.openscad.org/ > >> >> > >> >> _______________________________________________ > >> >> OpenSCAD mailing list > >> >> > >> > >> > Discuss@.openscad > >> > >> >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> >> > >> > > >> > _______________________________________________ > >> > OpenSCAD mailing list > >> > >> > Discuss@.openscad > >> > >> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> > >> > >> > >> > >> > >> -- > >> Sent from: http://forum.openscad.org/ > >> > >> _______________________________________________ > >> OpenSCAD mailing list > >> > > > Discuss@.openscad > > >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >> > > > > _______________________________________________ > > OpenSCAD mailing list > > > Discuss@.openscad > > > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >