FH
Father Horton
Wed, Feb 16, 2022 12:55 AM
Maybe leave “search” alone and give the new function a new name? Is “find”
taken?
On Tue, Feb 15, 2022 at 6:38 PM Torsten Paul Torsten.Paul@gmx.de wrote:
On 16.02.22 01:03, Patrick Callahan wrote:
Replacement or perhaps renaming. Several have suggested
that there are valid use cases for the search function as
written.
Right, maybe it will stay forever, it certainly has seen
lots of interesting uses and made feature possible that
would not have worked otherwise.
But we also need to consider, there's new features that
maybe just need to be made easier to use, e.g. some of
the "search in array" cases can be done without any new
core feature:
find_index = function(v, pred)
[ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
first_in_vector = function(v) function(e) e[0] == v;
last_in_vector = function(v) function(e) e[len(e) - 1] == v;
a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
echo(find_index(a, first_in_vector("M4")));
// ECHO: [1]
echo(find_index(a, last_in_vector(false)));
// ECHO: [0, 2]
ciao,
Torsten.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Maybe leave “search” alone and give the new function a new name? Is “find”
taken?
On Tue, Feb 15, 2022 at 6:38 PM Torsten Paul <Torsten.Paul@gmx.de> wrote:
> On 16.02.22 01:03, Patrick Callahan wrote:
> > Replacement or perhaps renaming. Several have suggested
> > that there are valid use cases for the search function as
> > written.
>
> Right, maybe it will stay forever, it certainly has seen
> lots of interesting uses and made feature possible that
> would not have worked otherwise.
>
> But we also need to consider, there's new features that
> maybe just need to be made easier to use, e.g. some of
> the "search in array" cases can be done without any new
> core feature:
>
> find_index = function(v, pred)
> [ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
>
> first_in_vector = function(v) function(e) e[0] == v;
> last_in_vector = function(v) function(e) e[len(e) - 1] == v;
>
> a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
>
> echo(find_index(a, first_in_vector("M4")));
> // ECHO: [1]
> echo(find_index(a, last_in_vector(false)));
> // ECHO: [0, 2]
>
> ciao,
> Torsten.
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
AM
Adrian Mariano
Wed, Feb 16, 2022 1:13 AM
Everything that search() does can be done without search() in
userspace, and without function literals. The whole reason for the
existence of search is that it is fast. For example, the searchAtomic
posted earlier in the thread is about 500 times slower on a long list
when the item to find is near the beginning, because search() stops
when it finds the item. The example using find_index with the
function literal is 50 times slower than native search().
Perhaps the idea of first_in_vector() and similar searching functions
would be useful if it were implemented natively in OpenSCAD and ran
really fast, with short circuiting when the item is found.
I tried looking in the BOSL2 source to see what uses of search() I
could find. Most of them are to find all hits of entire list entries,
it appears. There are a few that look for first hit, and one or two
that look for first entry of a list of lists. Some of the "first hit"
uses are just to supply this capability to users---that is, I don't
know if it's actually useful. Overall I think "find all" entries of a
plain list is the most typical use case.
On Tue, Feb 15, 2022 at 7:38 PM Torsten Paul Torsten.Paul@gmx.de wrote:
On 16.02.22 01:03, Patrick Callahan wrote:
Replacement or perhaps renaming. Several have suggested
that there are valid use cases for the search function as
written.
Right, maybe it will stay forever, it certainly has seen
lots of interesting uses and made feature possible that
would not have worked otherwise.
But we also need to consider, there's new features that
maybe just need to be made easier to use, e.g. some of
the "search in array" cases can be done without any new
core feature:
find_index = function(v, pred)
[ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
first_in_vector = function(v) function(e) e[0] == v;
last_in_vector = function(v) function(e) e[len(e) - 1] == v;
a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
echo(find_index(a, first_in_vector("M4")));
// ECHO: [1]
echo(find_index(a, last_in_vector(false)));
// ECHO: [0, 2]
ciao,
Torsten.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Everything that search() does can be done without search() in
userspace, and without function literals. The whole reason for the
existence of search is that it is fast. For example, the searchAtomic
posted earlier in the thread is about 500 times slower on a long list
when the item to find is near the beginning, because search() stops
when it finds the item. The example using find_index with the
function literal is 50 times slower than native search().
Perhaps the idea of first_in_vector() and similar searching functions
would be useful if it were implemented natively in OpenSCAD and ran
really fast, with short circuiting when the item is found.
I tried looking in the BOSL2 source to see what uses of search() I
could find. Most of them are to find all hits of entire list entries,
it appears. There are a few that look for first hit, and one or two
that look for first entry of a list of lists. Some of the "first hit"
uses are just to supply this capability to users---that is, I don't
know if it's actually useful. Overall I think "find all" entries of a
plain list is the most typical use case.
On Tue, Feb 15, 2022 at 7:38 PM Torsten Paul <Torsten.Paul@gmx.de> wrote:
>
> On 16.02.22 01:03, Patrick Callahan wrote:
> > Replacement or perhaps renaming. Several have suggested
> > that there are valid use cases for the search function as
> > written.
>
> Right, maybe it will stay forever, it certainly has seen
> lots of interesting uses and made feature possible that
> would not have worked otherwise.
>
> But we also need to consider, there's new features that
> maybe just need to be made easier to use, e.g. some of
> the "search in array" cases can be done without any new
> core feature:
>
> find_index = function(v, pred)
> [ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
>
> first_in_vector = function(v) function(e) e[0] == v;
> last_in_vector = function(v) function(e) e[len(e) - 1] == v;
>
> a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
>
> echo(find_index(a, first_in_vector("M4")));
> // ECHO: [1]
> echo(find_index(a, last_in_vector(false)));
> // ECHO: [0, 2]
>
> ciao,
> Torsten.
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
M
MichaelAtOz
Wed, Feb 16, 2022 5:22 AM
existence of search is that it is fast.
Exactly, so adapting existing search() is warranted rather than userspace solutions.
IFF it is a simple fix & doesn't break backward compatibility.
A new find() (e.g.) will not materialise in a hurry.
Function search() should not have a default value for index_col_num.
Unfortunately that would be breakage.
I would say that the basic search behavior would be that search([x],list) returns exactly those
indices, i, such that list[i]==x is true. I think that's what Ronaldo meant by "matching full
list entries". No special behaviors relating types or whether things are or are not vectors or
lists. You never search inside vectors. You just perform a simple equality test.
That is not how it was first designed, for better or worse. It can't do that without breakage.
So a parameter exact=true,
search([x],list,exact=true) -> indices, i where list[i]==x, up to num_returns_per_match,
by implication the two must be matching type.
Noting search([x,y],list,exact=true) -> indices i where list[i]==x and list[i]==y, up to
num_returns_per_match
if instead you want to find '[x,y]' you'd do search([[x,y]],list,exact=true) as per the current
usage.
Alternatively, index_col_num=-1, does NOT look inside sublists
search([5], [3,4,[5,6],3,5],,-1) -> [4]
search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that implies
num_returns_per_match=0)
-----Original Message-----
Sent: Wed, 16 Feb 2022 12:14
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: search function is broken
Everything that search() does can be done without search() in
userspace, and without function literals. The whole reason for the
existence of search is that it is fast. For example, the searchAtomic
posted earlier in the thread is about 500 times slower on a long list
when the item to find is near the beginning, because search() stops
when it finds the item. The example using find_index with the
function literal is 50 times slower than native search().
Perhaps the idea of first_in_vector() and similar searching functions
would be useful if it were implemented natively in OpenSCAD and ran
really fast, with short circuiting when the item is found.
I tried looking in the BOSL2 source to see what uses of search() I
could find. Most of them are to find all hits of entire list entries,
it appears. There are a few that look for first hit, and one or two
that look for first entry of a list of lists. Some of the "first hit"
uses are just to supply this capability to users---that is, I don't
know if it's actually useful. Overall I think "find all" entries of a
plain list is the most typical use case.
On 16.02.22 01:03, Patrick Callahan wrote:
Replacement or perhaps renaming. Several have suggested
that there are valid use cases for the search function as
Right, maybe it will stay forever, it certainly has seen
lots of interesting uses and made feature possible that
would not have worked otherwise.
But we also need to consider, there's new features that
maybe just need to be made easier to use, e.g. some of
the "search in array" cases can be done without any new
find_index = function(v, pred)
[ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
first_in_vector = function(v) function(e) e[0] == v;
last_in_vector = function(v) function(e) e[len(e) - 1] == v;
a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
echo(find_index(a, first_in_vector("M4")));
echo(find_index(a, last_in_vector(false)));
> The whole reason for the
> existence of search is that it is fast.
Exactly, so adapting existing search() is warranted rather than userspace solutions.
IFF it is a simple fix & doesn't break backward compatibility.
A new find() (e.g.) will not materialise in a hurry.
Function search() should not have a default value for index_col_num.
Unfortunately that would be breakage.
I would say that the basic search behavior would be that search([x],list) returns exactly those
indices, i, such that list[i]==x is true. I think that's what Ronaldo meant by "matching full
list entries". No special behaviors relating types or whether things are or are not vectors or
lists. You *never* search inside vectors. You just perform a simple equality test.
That is not how it was first designed, for better or worse. It can't do that without breakage.
So a parameter exact=true,
search([x],list,exact=true) -> indices, i where list[i]==x, up to num_returns_per_match,
by implication the two must be matching type.
Noting search([x,y],list,exact=true) -> indices i where list[i]==x and list[i]==y, up to
num_returns_per_match
if instead you want to find '[x,y]' you'd do search([[x,y]],list,exact=true) as per the current
usage.
------
Alternatively, index_col_num=-1, does NOT look inside sublists
search([5], [3,4,[5,6],3,5],,-1) -> [4]
search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that implies
num_returns_per_match=0)
> -----Original Message-----
> From: Adrian Mariano [mailto:avm4@cornell.edu]
> Sent: Wed, 16 Feb 2022 12:14
> To: OpenSCAD general discussion
> Subject: [OpenSCAD] Re: search function is broken
>
> Everything that search() does can be done without search() in
> userspace, and without function literals. The whole reason for the
> existence of search is that it is fast. For example, the searchAtomic
> posted earlier in the thread is about 500 times slower on a long list
> when the item to find is near the beginning, because search() stops
> when it finds the item. The example using find_index with the
> function literal is 50 times slower than native search().
>
> Perhaps the idea of first_in_vector() and similar searching functions
> would be useful if it were implemented natively in OpenSCAD and ran
> really fast, with short circuiting when the item is found.
>
> I tried looking in the BOSL2 source to see what uses of search() I
> could find. Most of them are to find all hits of entire list entries,
> it appears. There are a few that look for first hit, and one or two
> that look for first entry of a list of lists. Some of the "first hit"
> uses are just to supply this capability to users---that is, I don't
> know if it's actually useful. Overall I think "find all" entries of a
> plain list is the most typical use case.
>
> On Tue, Feb 15, 2022 at 7:38 PM Torsten Paul <Torsten.Paul@gmx.de> wrote:
> >
> > On 16.02.22 01:03, Patrick Callahan wrote:
> > > Replacement or perhaps renaming. Several have suggested
> > > that there are valid use cases for the search function as
> > > written.
> >
> > Right, maybe it will stay forever, it certainly has seen
> > lots of interesting uses and made feature possible that
> > would not have worked otherwise.
> >
> > But we also need to consider, there's new features that
> > maybe just need to be made easier to use, e.g. some of
> > the "search in array" cases can be done without any new
> > core feature:
> >
> > find_index = function(v, pred)
> > [ for (i = 0;i < len(v);i = i + 1) if (pred(v[i])) i];
> >
> > first_in_vector = function(v) function(e) e[0] == v;
> > last_in_vector = function(v) function(e) e[len(e) - 1] == v;
> >
> > a = [["M3", 3, false], ["M4", 4, true], ["M5", 5, "x", false]];
> >
> > echo(find_index(a, first_in_vector("M4")));
> > // ECHO: [1]
> > echo(find_index(a, last_in_vector(false)));
> > // ECHO: [0, 2]
> >
> > ciao,
> > Torsten.
> > _______________________________________________
> > OpenSCAD mailing list
> > To unsubscribe send an email to discuss-leave@lists.openscad.org
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
--
This email has been checked for viruses by AVG.
https://www.avg.com
RP
Ronaldo Persiano
Mon, Feb 21, 2022 6:34 PM
Function search() should not have a default value for index_col_num.
Unfortunately that would be breakage.
,,,
Alternatively, index_col_num=-1, does NOT look inside sublists
search([5], [3,4,[5,6],3,5],,-1) -> [4]
search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that
implies num_returns_per_match=0)
Why wouldn't index_col_num=-1 also be a breakage ?
Currently (in version 2021.1), all the following calls return [[2,4]] :
search([5], [3,4,[5,6],3,5],0,0)
search([5], [3,4,[5,6],3,5],0,-1)
search([5], [3,4,[5,6],3,5],0,0.5)
search([5], [3,4,[5,6],3,5],0,"a")
search([5], [3,4,[5,6],3,5],0,undef)
search([5], [3,4,[5,6],3,5],0)
Many last year changes broke several existing codes and library functions
as it has been reported here. They were justifiable because they avoided a
spread of undef. So change without breakage is not an unbreakable rule.
What special case requires the current behavior of search of looking at
atomic and vectors when index_col_num=0?
Em qua., 16 de fev. de 2022 às 02:23, MichaelAtOz <oz.at.michael@gmail.com>
escreveu:
> Function search() should not have a default value for *index_col_num*.
>
>
>
> Unfortunately that would be breakage.
>
>
>
> ,,,
>
> Alternatively, index_col_num=-1, does NOT look inside sublists
>
> search([5], [3,4,[5,6],3,5],,-1) -> [4]
>
> search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
>
> search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that
> implies *num_returns_per_match=0)*
>
Why wouldn't index_col_num=-1 also be a breakage ?
Currently (in version 2021.1), all the following calls return [[2,4]] :
search([5], [3,4,[5,6],3,5],0,0)
search([5], [3,4,[5,6],3,5],0,-1)
search([5], [3,4,[5,6],3,5],0,0.5)
search([5], [3,4,[5,6],3,5],0,"a")
search([5], [3,4,[5,6],3,5],0,undef)
search([5], [3,4,[5,6],3,5],0)
Many last year changes broke several existing codes and library functions
as it has been reported here. They were justifiable because they avoided a
spread of undef. So change without breakage is not an unbreakable rule.
What special case requires the current behavior of search of looking at
atomic and vectors when index_col_num=0?
M
MichaelAtOz
Tue, Feb 22, 2022 12:11 AM
In the first case (not having a default), it is changing the specification, breaking code written to use it the way it is documented.
In the second, because -1 is not documented anywhere as a usable value, it is not a sensible value.
Passing a value that doesn't make sense as a parameter should be expected to produce undefined (not undef) outcomes.
(passing undef is equivalent to not passing anything so is defined behaviour)
If a new specification is produced which uses a particular value, then that undefined outcome is now defined.
But yes, someone could have used some variable as a flag with -1 for some purpose, then casually passed it to search().
However search([5], [3,4,[5,6],3,5],0,-1) returns [ [] ], so in effect -1 is do not match anything. That is not specified behaviour.
It is a fuzzy line, but I don't consider that breakage.
I chose -1 as the less worse option.
Current atomic/vector behaviour was intended by the author, if you read the history. The author does concede it could have been better.
Remember this was proposed as a readily doable fix in the near term, v's the time it would take to gestate a new find().
From: Ronaldo Persiano [mailto:rcmpersiano@gmail.com]
Sent: Tue, 22 Feb 2022 05:35
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: search function is broken
Em qua., 16 de fev. de 2022 às 02:23, MichaelAtOz oz.at.michael@gmail.com escreveu:
Function search() should not have a default value for index_col_num.
Unfortunately that would be breakage.
,,,
Alternatively, index_col_num=-1, does NOT look inside sublists
search([5], [3,4,[5,6],3,5],,-1) -> [4]
search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that implies num_returns_per_match=0)
Why wouldn't index_col_num=-1 also be a breakage ?
Currently (in version 2021.1), all the following calls return [[2,4]] :
search([5], [3,4,[5,6],3,5],0,0)
search([5], [3,4,[5,6],3,5],0,-1)
search([5], [3,4,[5,6],3,5],0,0.5)
search([5], [3,4,[5,6],3,5],0,"a")
search([5], [3,4,[5,6],3,5],0,undef)
search([5], [3,4,[5,6],3,5],0)
Many last year changes broke several existing codes and library functions as it has been reported here. They were justifiable because they avoided a spread of undef. So change without breakage is not an unbreakable rule.
What special case requires the current behavior of search of looking at atomic and vectors when index_col_num=0?
--
This email has been checked for viruses by AVG.
https://www.avg.com
In the first case (not having a default), it is changing the specification, breaking code written to use it the way it is documented.
In the second, because -1 is not documented anywhere as a usable value, it is not a sensible value.
Passing a value that doesn't make sense as a parameter should be expected to produce undefined (not undef) outcomes.
(passing undef is equivalent to not passing anything so is defined behaviour)
If a new specification is produced which uses a particular value, then that undefined outcome is now defined.
But yes, someone could have used some variable as a flag with -1 for some purpose, then casually passed it to search().
However search([5], [3,4,[5,6],3,5],0,-1) returns [ [] ], so in effect -1 is do not match anything. That is not specified behaviour.
It is a fuzzy line, but I don't consider that breakage.
I chose -1 as the less worse option.
Current atomic/vector behaviour was intended by the author, if you read the history. The author does concede it could have been better.
Remember this was proposed as a readily doable fix in the near term, v's the time it would take to gestate a new find().
_____
From: Ronaldo Persiano [mailto:rcmpersiano@gmail.com]
Sent: Tue, 22 Feb 2022 05:35
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: search function is broken
Em qua., 16 de fev. de 2022 às 02:23, MichaelAtOz <oz.at.michael@gmail.com> escreveu:
Function search() should not have a default value for index_col_num.
Unfortunately that would be breakage.
,,,
Alternatively, index_col_num=-1, does NOT look inside sublists
search([5], [3,4,[5,6],3,5],,-1) -> [4]
search([[5,6]], [3,4,[5,6],3,5]) -> [2] as it does now,
search([[5,6]], [3,4,[5,6],3,5],,0)) -> [[2]] ditto (as I think that implies num_returns_per_match=0)
Why wouldn't index_col_num=-1 also be a breakage ?
Currently (in version 2021.1), all the following calls return [[2,4]] :
search([5], [3,4,[5,6],3,5],0,0)
search([5], [3,4,[5,6],3,5],0,-1)
search([5], [3,4,[5,6],3,5],0,0.5)
search([5], [3,4,[5,6],3,5],0,"a")
search([5], [3,4,[5,6],3,5],0,undef)
search([5], [3,4,[5,6],3,5],0)
Many last year changes broke several existing codes and library functions as it has been reported here. They were justifiable because they avoided a spread of undef. So change without breakage is not an unbreakable rule.
What special case requires the current behavior of search of looking at atomic and vectors when index_col_num=0?
--
This email has been checked for viruses by AVG.
https://www.avg.com
JB
Jordan Brown
Tue, Feb 22, 2022 12:16 AM
On 2/21/2022 4:11 PM, MichaelAtOz wrote:
Remember this was proposed as a readily doable fix in the near term,
v's the time it would take to gestate a new find().
search() is difficult to understand at the best of times... gluing on an
additional bit of complexity will make it incrementally worse.
It seems like it should be possible to come up with a find() that's
more understandable and as powerful, or at least nearly as powerful.
(It would start with treating strings as atomic data items, not as
arrays of characters, at least by default.)
But I admit that I haven't tried to write down what the specification
for such a function would be.
On 2/21/2022 4:11 PM, MichaelAtOz wrote:
> Remember this was proposed as a readily doable fix in the near term,
> v's the time it would take to gestate a new find().
search() is difficult to understand at the best of times... gluing on an
additional bit of complexity will make it incrementally worse.
It *seems* like it should be possible to come up with a find() that's
more understandable and as powerful, or at least nearly as powerful.
(It would start with treating strings as atomic data items, not as
arrays of characters, at least by default.)
But I admit that I haven't tried to write down what the specification
for such a function would be.
AM
Adrian Mariano
Tue, Feb 22, 2022 12:31 AM
Is it consistent to treat strings as atomic data types? Right now, if
you want to search for 5 you need to write search([5],...) and if you
want to search for "hello" you do search (["hello"],...) so the
behavior is consistent.
I actually think there's no value in being able to search for multiple
things, and just extra confusion. There are two reasons for this.
One is that in practice it just never seems to be needed. In BOSL2 we
never use search() to search for more than one item. The second
reason is that there is no computational advantage to providing this
feature. If you really need to search for multiple items you can
use a list comprehension, and the run time is identical. Instead we
always write search([item],....)[0]. Of course, there's the other
issue that we often might be interested in searching for approximate
matches (within epsilon), which points towards a find function that
looks for a function to be satisfied instead of just simple equality.
I don't know if this ends up being a big enough efficiency gain to
make it worthwhile. But if we had a find that took a predicate and
returned the entries on which the predicate is true (like was
suggested a ways up) and it ran as fast as search() does right now
with a default predicate of simple equality testing, that seems like
it would be pretty useful, and if you really want to look at the 17th
position in a vector your predicate can do it, so it provides all the
power and more compared to search() without any interface complexity.
Perhaps it could be: find(search_target, list, num_matches)
where if search_target is a function, it returns all i such that
search_target(list[i]) is true, and otherwise it returns all i such
that list[i]==search_target.
Of course, this is only worthwhile if it's fast the way the current
search() is. if list can also be a range then you have the
possibility of testing a predicate on a list of values without having
to construct the list first. Not sure if that gives a speed advantage
or not.
On Mon, Feb 21, 2022 at 7:16 PM Jordan Brown
openscad@jordan.maileater.net wrote:
On 2/21/2022 4:11 PM, MichaelAtOz wrote:
Remember this was proposed as a readily doable fix in the near term, v's the time it would take to gestate a new find().
search() is difficult to understand at the best of times... gluing on an additional bit of complexity will make it incrementally worse.
It seems like it should be possible to come up with a find() that's more understandable and as powerful, or at least nearly as powerful. (It would start with treating strings as atomic data items, not as arrays of characters, at least by default.)
But I admit that I haven't tried to write down what the specification for such a function would be.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
Is it consistent to treat strings as atomic data types? Right now, if
you want to search for 5 you need to write search([5],...) and if you
want to search for "hello" you do search (["hello"],...) so the
behavior is consistent.
I actually think there's no value in being able to search for multiple
things, and just extra confusion. There are two reasons for this.
One is that in practice it just never seems to be needed. In BOSL2 we
never use search() to search for more than one item. The second
reason is that there is no computational advantage to providing this
feature. If you *really* need to search for multiple items you can
use a list comprehension, and the run time is identical. Instead we
always write search([item],....)[0]. Of course, there's the other
issue that we often might be interested in searching for approximate
matches (within epsilon), which points towards a find function that
looks for a function to be satisfied instead of just simple equality.
I don't know if this ends up being a big enough efficiency gain to
make it worthwhile. But if we had a find that took a predicate and
returned the entries on which the predicate is true (like was
suggested a ways up) and it ran as fast as search() does right now
with a default predicate of simple equality testing, that seems like
it would be pretty useful, and if you really want to look at the 17th
position in a vector your predicate can do it, so it provides all the
power and more compared to search() without any interface complexity.
Perhaps it could be: find(search_target, list, num_matches)
where if search_target is a function, it returns all i such that
search_target(list[i]) is true, and otherwise it returns all i such
that list[i]==search_target.
Of course, this is only worthwhile if it's fast the way the current
search() is. if list can also be a range then you have the
possibility of testing a predicate on a list of values without having
to construct the list first. Not sure if that gives a speed advantage
or not.
On Mon, Feb 21, 2022 at 7:16 PM Jordan Brown
<openscad@jordan.maileater.net> wrote:
>
> On 2/21/2022 4:11 PM, MichaelAtOz wrote:
>
> Remember this was proposed as a readily doable fix in the near term, v's the time it would take to gestate a new find().
>
>
> search() is difficult to understand at the best of times... gluing on an additional bit of complexity will make it incrementally worse.
>
> It *seems* like it should be possible to come up with a find() that's more understandable and as powerful, or at least nearly as powerful. (It would start with treating strings as atomic data items, not as arrays of characters, at least by default.)
>
> But I admit that I haven't tried to write down what the specification for such a function would be.
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
M
MichaelAtOz
Tue, Feb 22, 2022 6:21 AM
I actually think there's no value in being able to search for multiple
things, and just extra confusion.
Perhaps, other may think differently, including the original author.
In 2015 clothbot, the author said:
"A few comments/history behind my original writing of search():
When I wrote it (in 2012):
1. The 'undef' didn't exist as a return option so I settled on returning empty lists which
could be detected (list of length 0) as 'no match' conditions - it predated the Value rewrite of
the code-base.
2. The 'concat' list construction operator didn't exist; I needed a way to search for a
string-of-characters (aka. an ordered list of character values) and get the results back in order,
as a list.
3. The 'let' operator didn't exist.
4. Lists were statically defined; [ for() . ] dynamically generated lists weren't possible.
5. Function recursion was (and still is to some degree) dog-slow for more 'elegant' list
construction approaches.
6. The text() module didn't exist.
- See example023.scad combined with MCAD/fonts.scad for insight into how I was
generating text, and the original motivation behind coding up search().
7. The no-match warnings are gone as of last week; you'll have to build from source to see
that.
It's not buggy, just written within the constraints of the time. ;-)"
search() is a legacy of its time.
However, changing search() to not match on multiples/sub-vectors, is IMHO too much of a breakage.
There is 10 odd years of search() usage in the wild.
My suggestion provides a means to do atomic search, without breaking 'normal' past usage.
It does not make search simpler, that requires something new, but it give you built-in speed,
likely sooner.
I don't particularly need this, so I'm not wasting my breath any further.
-----Original Message-----
Sent: Tue, 22 Feb 2022 11:32
To: OpenSCAD general discussion
Subject: [OpenSCAD] Re: search function is broken
Is it consistent to treat strings as atomic data types? Right now, if
you want to search for 5 you need to write search([5],...) and if you
want to search for "hello" you do search (["hello"],...) so the
I actually think there's no value in being able to search for multiple
things, and just extra confusion. There are two reasons for this.
One is that in practice it just never seems to be needed. In BOSL2 we
never use search() to search for more than one item. The second
reason is that there is no computational advantage to providing this
feature. If you really need to search for multiple items you can
use a list comprehension, and the run time is identical. Instead we
always write search([item],....)[0]. Of course, there's the other
issue that we often might be interested in searching for approximate
matches (within epsilon), which points towards a find function that
looks for a function to be satisfied instead of just simple equality.
I don't know if this ends up being a big enough efficiency gain to
make it worthwhile. But if we had a find that took a predicate and
returned the entries on which the predicate is true (like was
suggested a ways up) and it ran as fast as search() does right now
with a default predicate of simple equality testing, that seems like
it would be pretty useful, and if you really want to look at the 17th
position in a vector your predicate can do it, so it provides all the
power and more compared to search() without any interface complexity.
Perhaps it could be: find(search_target, list, num_matches)
where if search_target is a function, it returns all i such that
search_target(list[i]) is true, and otherwise it returns all i such
that list[i]==search_target.
Of course, this is only worthwhile if it's fast the way the current
search() is. if list can also be a range then you have the
possibility of testing a predicate on a list of values without having
to construct the list first. Not sure if that gives a speed advantage
On Mon, Feb 21, 2022 at 7:16 PM Jordan Brown
On 2/21/2022 4:11 PM, MichaelAtOz wrote:
Remember this was proposed as a readily doable fix in the near term, v's the time it
would take to gestate a new find().
search() is difficult to understand at the best of times... gluing on an additional bit
of complexity will make it incrementally worse.
It seems like it should be possible to come up with a find() that's more
understandable and as powerful, or at least nearly as powerful. (It would start with
treating strings as atomic data items, not as arrays of characters, at least by default.)
But I admit that I haven't tried to write down what the specification for such a
> I actually think there's no value in being able to search for multiple
things, and just extra confusion.
Perhaps, other may think differently, including the original author.
In 2015 clothbot, the author said:
"A few comments/history behind my original writing of search():
When I wrote it (in 2012):
1. The 'undef' didn't exist as a return option so I settled on returning empty lists which
could be detected (list of length 0) as 'no match' conditions - it predated the Value rewrite of
the code-base.
2. The 'concat' list construction operator didn't exist; I needed a way to search for a
string-of-characters (aka. an ordered list of character values) and get the results back in order,
as a list.
3. The 'let' operator didn't exist.
4. Lists were statically defined; [ for() . ] dynamically generated lists weren't possible.
5. Function recursion was (and still is to some degree) dog-slow for more 'elegant' list
construction approaches.
6. The text() module didn't exist.
- See example023.scad combined with MCAD/fonts.scad for insight into how I was
generating text, and the original motivation behind coding up search().
7. The no-match warnings are gone as of last week; you'll have to build from source to see
that.
It's not buggy, just written within the constraints of the time. ;-)"
search() is a legacy of its time.
However, changing search() to not match on multiples/sub-vectors, is IMHO too much of a breakage.
There is 10 odd years of search() usage in the wild.
My suggestion provides a means to do atomic search, without breaking 'normal' past usage.
It does not make search simpler, that requires something new, but it give you built-in speed,
likely sooner.
I don't particularly need this, so I'm not wasting my breath any further.
> -----Original Message-----
> From: Adrian Mariano [mailto:avm4@cornell.edu]
> Sent: Tue, 22 Feb 2022 11:32
> To: OpenSCAD general discussion
> Subject: [OpenSCAD] Re: search function is broken
>
> Is it consistent to treat strings as atomic data types? Right now, if
> you want to search for 5 you need to write search([5],...) and if you
> want to search for "hello" you do search (["hello"],...) so the
> behavior is consistent.
>
> I actually think there's no value in being able to search for multiple
> things, and just extra confusion. There are two reasons for this.
> One is that in practice it just never seems to be needed. In BOSL2 we
> never use search() to search for more than one item. The second
> reason is that there is no computational advantage to providing this
> feature. If you *really* need to search for multiple items you can
> use a list comprehension, and the run time is identical. Instead we
> always write search([item],....)[0]. Of course, there's the other
> issue that we often might be interested in searching for approximate
> matches (within epsilon), which points towards a find function that
> looks for a function to be satisfied instead of just simple equality.
> I don't know if this ends up being a big enough efficiency gain to
> make it worthwhile. But if we had a find that took a predicate and
> returned the entries on which the predicate is true (like was
> suggested a ways up) and it ran as fast as search() does right now
> with a default predicate of simple equality testing, that seems like
> it would be pretty useful, and if you really want to look at the 17th
> position in a vector your predicate can do it, so it provides all the
> power and more compared to search() without any interface complexity.
>
> Perhaps it could be: find(search_target, list, num_matches)
>
> where if search_target is a function, it returns all i such that
> search_target(list[i]) is true, and otherwise it returns all i such
> that list[i]==search_target.
>
> Of course, this is only worthwhile if it's fast the way the current
> search() is. if list can also be a range then you have the
> possibility of testing a predicate on a list of values without having
> to construct the list first. Not sure if that gives a speed advantage
> or not.
>
>
>
>
> On Mon, Feb 21, 2022 at 7:16 PM Jordan Brown
> <openscad@jordan.maileater.net> wrote:
> >
> > On 2/21/2022 4:11 PM, MichaelAtOz wrote:
> >
> > Remember this was proposed as a readily doable fix in the near term, v's the time it
> would take to gestate a new find().
> >
> >
> > search() is difficult to understand at the best of times... gluing on an additional bit
> of complexity will make it incrementally worse.
> >
> > It *seems* like it should be possible to come up with a find() that's more
> understandable and as powerful, or at least nearly as powerful. (It would start with
> treating strings as atomic data items, not as arrays of characters, at least by default.)
> >
> > But I admit that I haven't tried to write down what the specification for such a
> function would be.
> >
> > _______________________________________________
> > OpenSCAD mailing list
> > To unsubscribe send an email to discuss-leave@lists.openscad.org
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
--
This email has been checked for viruses by AVG.
https://www.avg.com
M
MichaelAtOz
Tue, Feb 22, 2022 6:37 AM
I don't particularly need this, so I'm not wasting my breath any further.
Except to note, I thought I had used search() for something I did a long time ago.
Turns out I used lookup() - key/value match, based on the structured data mechanism in
MCAD/stepper.scad
As long as you work-around* the 'linearly interpolate if there's no exact match' bit, it is another
built-in speed option.
- e.g. using predefined variables as in stepper.scad as the keys.
I never tested performance.
But it is not a generalised search.
--
This email has been checked for viruses by AVG.
https://www.avg.com
> I don't particularly need this, so I'm not wasting my breath any further.
Except to note, I thought I had used search() for something I did a long time ago.
Turns out I used lookup() - key/value match, based on the structured data mechanism in
MCAD/stepper.scad
As long as you work-around* the 'linearly interpolate if there's no exact match' bit, it is another
built-in speed option.
* e.g. using predefined variables as in stepper.scad as the keys.
I never tested performance.
But it is not a generalised search.
--
This email has been checked for viruses by AVG.
https://www.avg.com
RW
Rob Ward
Tue, Feb 22, 2022 7:27 AM
Why is important to not break code that uses clumsy syntax in the first place? Why not just get it right?
Cheers, RobW
On 22 February 2022 5:37:29 pm AEDT, MichaelAtOz oz.at.michael@gmail.com wrote:
I don't particularly need this, so I'm not wasting my breath any further.
Except to note, I thought I had used search() for something I did a long time ago.
Turns out I used lookup() - key/value match, based on the structured data mechanism in
MCAD/stepper.scad
As long as you work-around* the 'linearly interpolate if there's no exact match' bit, it is another
built-in speed option.
- e.g. using predefined variables as in stepper.scad as the keys.
I never tested performance.
But it is not a generalised search.
--
This email has been checked for viruses by AVG.
https://www.avg.com
Why is important to not break code that uses clumsy syntax in the first place? Why not just get it right?
Cheers, RobW
On 22 February 2022 5:37:29 pm AEDT, MichaelAtOz <oz.at.michael@gmail.com> wrote:
>> I don't particularly need this, so I'm not wasting my breath any further.
>
>
>
>Except to note, I thought I had used search() for something I did a long time ago.
>
>Turns out I used lookup() - key/value match, based on the structured data mechanism in
>MCAD/stepper.scad
>
>
>
>As long as you work-around* the 'linearly interpolate if there's no exact match' bit, it is another
>built-in speed option.
>
>* e.g. using predefined variables as in stepper.scad as the keys.
>
>I never tested performance.
>
>
>
>But it is not a generalised search.
>
>
>
>--
>This email has been checked for viruses by AVG.
>https://www.avg.com