## Are '(true nil) and '(true) is equal?

Q&A's, tips, howto's

### Are '(true nil) and '(true) is equal?

May be I don't understand recursive comparision doing by "=", but I see no logic in this:
Code: Select all
`newLISP v.10.7.1 32-bit on Windows IPv4/6 UTF-8 libffi, options: newlisp -h> (= '(true) '(true nil))nil> (= '(true nil) '(true))true`

And another case on numbers:
Code: Select all
`> (= '(1 0) '(1)) #-> true?nil>`

Bug or feature?
IVShilov

Posts: 17
Joined: Wed Apr 12, 2017 1:58 am

### Re: Are '(true nil) and '(true) is equal?

Looks like a bug to me. At the very least, I believe that it should be a desirable property for the `=` operator to act as a symmetric relation, that is, that `(= a b)` and `(= b a)` return the same boolean value (for any `a` and `b`).

More fundamentally, the manual says that for all the relational operators: "List expressions can also be compared (list elements are compared recursively)." Your example of `(= '(true nil) '(true))` evaluating to `true` contradicts that assertion.

Nice find, BTW!
(λx. x x) (λx. x x)
rickyboy

Posts: 582
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

### Re: Are '(true nil) and '(true) is equal?

Another way to exhibit the problem:

Code: Select all
`> (= '(1 2 3 nil nil) '(1 2 3))true> (= '(1 2 3 nil nil nil) '(1 2 3))true> (= '(1 2 3 nil nil nil nil) '(1 2 3))true> ;; and so on ...`

In nl-math.c, when the evaluation of any of the above expressions gets to `compareLists()` and `left` has the `nilSymbol`. `right` has the `nilCell` (because it's "bottomed out" already). Then when `compareCells(left, right)` is called, it happily reports "equal!" because `isNil(left)` (nl-math.c:1034) and `isNil(right)` (nl-math.c:1036) are both true. This is because, the `isNil()` macro doesn't distinguish between `nilSymbol` ("nil") and `nilCell` (the "end of a list" marker):

Code: Select all
`newlisp.h:450:#define isNil(A) ((A)->type == CELL_NIL || ((A)->type == CELL_SYMBOL && (A)->contents == (UINT)nilSymbol))`

Lutz, all the best fixing this, because I know you don't want the fix to break the behavior of the other comparison operators.
(λx. x x) (λx. x x)
rickyboy

Posts: 582
Joined: Fri Apr 08, 2005 7:13 pm
Location: Front Royal, Virginia

### Re: Are '(true nil) and '(true) is equal?

Thanks for the discovery of this bug.

Lutz

Posts: 5276
Joined: Thu Sep 26, 2002 4:45 pm

### Re: Are '(true nil) and '(true) is equal?

IVShilov

Posts: 17
Joined: Wed Apr 12, 2017 1:58 am

### Re: Are '(true nil) and '(true) is equal?

Lutz wrote:Thanks for the discovery of this bug.

Thank you for nifty tool, Lutz!
NL is my pet language.

Two more questions:
1. does
Code: Select all
`(letn (L '((1 2 3) (1 2 ))) (= L (transpose (transpose L)))) -> nil`

have the same roots? Because L is not two-dimensional matrix, there must be an exception error, no?

2. I'm newbie in compiling on Windows, so please point me to HOWTO make newlisp.exe from sources from "http://newlisp.nfshost.com/downloads/development/inprogress/". I need MinGW?
IVShilov

Posts: 17
Joined: Wed Apr 12, 2017 1:58 am

### Re: Are '(true nil) and '(true) is equal?

Code: Select all
`> (set 'L '((1 2 3) (1 2 )))((1 2 3) (1 2))> (transpose L)((1 1) (2 2) (3 nil))> (transpose (transpose L))((1 2 3) (1 2 nil))> (= L (transpose (transpose L)))nil> `

From the documentation of transpose :

"Any kind of list-matrix can be transposed. Matrices are made rectangular by filling in nil for missing elements, omitting elements where appropriate, or expanding atoms in rows into lists."

So this is on purpose and makes the function more usable but also will correctly make the double transposed list different from the original.

Ps: this is an 'unofficial' directory page, it might change before the actual release of v10.7.5.
Lutz

Posts: 5276
Joined: Thu Sep 26, 2002 4:45 pm

### Re: Are '(true nil) and '(true) is equal?

Ok, I understand and agree with you, add a nil to make args properly for transposition is right decision - I can filter this nil later.

But today I found that data lost because of args not matrix:
Code: Select all
`> (transpose '((1) (1 2)))((1 1))> (transpose (transpose '((1) (1 2))))((1) (1))`

transpose throw away "2".

On a 2d-matrix, transpose is reversible:
Code: Select all
`> (transpose (transpose '((1 nil) (1 2))))((1 nil) (1 2))`

May be some kind of "matrix?" predicate will be useful?

- thank you! Hope that QA-tests is up to date.
IVShilov

Posts: 17
Joined: Wed Apr 12, 2017 1:58 am

### Re: Are '(true nil) and '(true) is equal?

From the transpose documentation:

"Matrix dimensions are calculated using the number of rows in the original matrix for columns and the number of elements in the first row as number of rows for the transposed matrix."

Looking for the shortest row in a multidimensional list would take a much longer time. So this was intentionally.
Lutz

Posts: 5276
Joined: Thu Sep 26, 2002 4:45 pm

### Re: Are '(true nil) and '(true) is equal?

Ok, thanks, question was silly.
IVShilov

Posts: 17
Joined: Wed Apr 12, 2017 1:58 am