member and strings in 8.9

For the Compleat Fan
Locked
cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

member and strings in 8.9

Post by cormullion »

In 8.9 (and the manual) we have this:

Code: Select all

(member "" "newLISP")     ? "newLISP")
Why is this true?

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

Hi Cormullion,

Actualy 'yes its a little confusing what is in the manual though its not
untrue ;-) Though I would expect also a 'nil

"In the second syntax member searches for str-key in str. If str-key is found all of str starting with str-key is returned. If nothing is found nil is returned."

(member "" "something") does return everything as "" is empty or all..

Norman.
-- (define? (Cornflakes))

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

Hi Norman!

I still don't get it! ;-( "something" doesn't contain "nothing" ... It's like saying my full glass of beer contains an empty glass and no beer, as well as some beer, and a glass... ! ;-)



newLISP: tomorrow's language with yesterday's memory requirements...

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

hahah ..well yes your right.. A full glass of nothing cant be compared against
an empty glass of someting.. ;-)

Lets see what Lutz has to say..
-- (define? (Cornflakes))

William James
Posts: 58
Joined: Sat Jun 10, 2006 5:34 am

Post by William James »

Code: Select all

> (member "f" "oo")
nil
> (member "f" (append "f" "oo"))
"foo"
> (member "" (append "" "oo"))
"oo"
Every string contains the empty string as a substring, so

Code: Select all

(member "" some-string)
is always true.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

William James wrote: Every string contains the empty string as a substring, so

Code: Select all

(member "" some-string)
is always true.
Hi William. Yes, this is what I understood the manual to mean, but I'm objecting to it on philosphical grounds! (Not that I'm qualified to, being neither a philosopher or any sort of programmer... :-)

Is it also true to say, by extension, that "every list contains the empty list as a sublist"? I hope not...




newLISP: the Apotheosis of the Parenthesis

eddier
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

As a mathematician I can definitely say two things are being confused here.

substring should act like subset in sets, i.e. {a} is a subset of {a,b}.
Also, {} is a subset of every set.
member should act like set membership, i.e. a is a member of {a,b}.
However, {a} is not a member of {a,b} and neither is {}.
{} is a member of {{}} the set with one element the emptyset.

Just my two cents.

Eddie

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

Hi Eddie. I am definitely one of the two things being confused, but it may be that I'm looking for the wrong type of consistency in the wrong place :-)

Are you saying that the following (the current behaviour) is consistent with mathematical set theory?

Code: Select all

> (member "" "this is a string")
"this is a string"
> (member '() '("this" "is" "a" "list"))
nil
> (find "" "this is a string")
nil
> (find '() '("this" "is" "a" "list"))
nil
If so, then that's cool. Mathematics is cool. Like most complicated things, as long as I can predict the outcome, I don't need to understand why they work... :-)

eddier
Posts: 289
Joined: Mon Oct 07, 2002 2:48 pm
Location: Blue Mountain College, MS US

Post by eddier »

Hi cormullion.

This is really a tough one in one sense, because NL doesn't have a character data type that would be an element of a string (list or array of characters). Membership should only be used to test to see if a character is in a string.

We should be able to almost treat "" as {}. Of course strings can't be nested like sets (or can they?) and strings have order to their elements and sets don't. Also, strings can have redundant elements (this may be imposed by having order?).

If we compare the string, list, and set operations, then the current implementation is probably inconsistent. That is,

(member "" "string")

should probably be nil. If we look at "" like {}, then its like saying
{} in {s,t,r,i,n,g} or (member "" "string") which is false. However, {} in {{},s,t,r,i,n,g} or (member "" "{}string") where {} is a nested string would be true. The catch is that in NL, member is treating "a" as both a chacter and a string. This is inconsistent in a pure mathematical sense. IMHO, the member function should not be used with strings but, Lutz should decide the semantics here.

On the other hand,
(substring "" "this") => true
is consistent because {} is a subset of {t, h, i, s}.

Let's see what Lutz has to say.

Eddie

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Eddie's reasoning is correct from a mathematical-logical point of view, but the 'member' function for strings is less trying to model mathematical member ship behaviour than that it tries to be practical for string handling purposes. It tries to offer a shorter coding for the frequently used idom:

Code: Select all

(slice str (find key str 0))
The function is modelled after the 'C' function strstr() which behaves the same way, returning a pointer to the entire string when searching for the empty string. When doing a regular expression search with 'find' then the 0 position is returned, also assuming that the empty string is part of the string.

When doing a non regular expression search with 'find', than 'nil' is returned, but 'find' without the regex option is rather a memory buffer search rather than it is a string search because it is made to also handle binary information.

Code: Select all

(member "" "abcd") => "abcd" => true

(find "" "abc") => nil

(find "" "abc" 0) => 0 => true

(regex "" "abc") => ("" 0 0) => true
Programming languages which force these kinds of decisions to be always mathematically consistent tend to be impractical. But even from a practicality point of view one could probably argue both ways. In this case the precedent of strstr() and the behaviour of regular expressions swayed the decision.

Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Note that there is also:

Code: Select all

(starts-with "abc" "") => true

(ends-with "abc" "") => true
perhaps all three functions 'member', 'starts-with' and 'ends-with' should loose their bool option and instead have a regex option. Then we could give them all the dual behaviour of 'find'.


Lutz

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

Thanks Lutz. Your explanations make sense. I usually appreciate newLISP's pragmatism rather than any intellectual 'purism', and the occasional confusion I experience is a small price to pay...!

The job of us software consumers is to tell you software designers what we find easy and what we find difficult - you can then decide how or whether to take notice of us (and whether to put it in the manual ;-)).




newLISP: making the complicated simple
(a quote from a musician to keep m i c h a e l happy)

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

.. and it is always good to listen to the pure mathematical logical viewpoint too, many times both can live in harmony together.

Lutz

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

I'm Happy!

Post by m i c h a e l »

cormullion wrote:(a quote from a musician to keep m i c h a e l happy)
:-)

Locked