primitive function empty? could not accept array

Started by ssqq, July 16, 2016, 03:21:41 AM

Previous topic - Next topic

ssqq


> (empty? (array 2 '(1 2)))
ERR: list or string expected : (1 2)


I think any check function could accept any type of data.

rrq

#1
I'd agree that empty? should be defined for arrays. I don't use arrays much in newlisp, but in most other languages the empty array test (i.e., size==0) pops up very often.

Lutz

#2
There are no empty arrays ;-)

ssqq

#3
I think array should have empty array, Just like other language.



I think "Not empty array" is a design error.

TedWalther

#4
By default, we perceive an array as a special case of a list; so we expect it to act like a like in pretty much every way.  So, even if an array is never empty, it makes sense for every function that acts on a list, to also act on an array and do the sensible thing.  Even though under the hood, an array and list are very different.  Principle of Least Surprise.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

newBert

#5
Quote from: "TedWalther"By default, we perceive an array as a special case of a list; so we expect it to act like a like in pretty much every way.


Yes, but we can't effectively create an empty array :
newLISP v.10.7.1 32-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h

> (array 0)

ERR: wrong dimensions in function array : 0
>

If we'd like to consider an array as a special case of a list, we must think it's above all a non-empty list.

So, the use of empty? with an array seems to be  an incoherence, or even a nonsense... and it's not so bad that an error message reminds us of it :)
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>

rrq

#6
Again, I haven't really used arrays in newlisp, so I don't mind the lack of empty arrays once told :-)



But upon review it seems that ideally the functions like find and ref (with friends) should handle arrays as if lists. Intuitively that's needed in order to take some advantage of the (as advertised) faster element access by index.



And (while loitering at the wishing well), maybe there could also be a binary search lookup for sorted array, to take even more advantage of the speedier indexing.

rickyboy

#7
Quote from: "Lutz"There are no empty arrays ;-)

+1 for pithy, direct answer.  :)



... that unfortunately seemed to be ignored for a bit. :(
(λx. x x) (λx. x x)

TedWalther

#8
Since you can convert an array into a list, it is easy to overlook that there is no "list to array" function.  But array creation does let you use a list as an "initializer".  '() is a list... intuitively, until you try and fail, you wouldn't guess that the empty list isn't allowed as an array initializer.



The array-list function sets up a correspondance in the mind.  This creates the expectation that arrays are just another type or format of list; so all the list functions should apply to it.  Contexts are different enough from lists that you learn to treat them as their own data type from the beginning.  Arrays are similar enough to lists, that it is jarring when they don't act like lists.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

ssqq

#9
I need make array, hash, list use newLISP. SO i do like follows:

(define (is-blank-array x) (= x '()))

(define (is-list x) (list? x) (and (= (first x) "list") (list? (last x))))

(define (is-blank-hash x) (= x '(())))

(define (is-hash @x)
  (and (list? @x) (for-all is-pair @x)))

(define (is-pair @x)
  (and (list? @x) (= 2 (length @x)) (is-key (@x 0))))

(define (is-key @x) (or (string? @x) (number? @x)))

rickyboy

#10
Hi ssqq,



Let's take this one by one.


Quote from: "ssqq"I need make array, hash, list use newLISP. SO i do like follows:

(define (is-blank-array x) (= x '()))

The name `is-blank-array` belies what the procedure is actually doing which is checking that its input is an empty list.  In other words, it has nothing to do with arrays.  Also, recall that Lutz said that there are no empty arrays in newLISP.


Quote from: "ssqq"
(define (is-list x) (list? x) (and (= (first x) "list") (list? (last x))))

The `(list? x)` expression is superfluous (i.e., does nothing).  Moreover, this function doesn't do what its name seems to intend.  Witness:


> (is-list (list 1 2 3))
nil

This is due to the fact that lists in newLISP are not implemented as "sequences" where the first item is the string "list".  That's just wrong.



This doesn't even work.


> (is-list (list "list" 1 2 3))
nil

because `(list? (last x))` fails.


> (last (list "list" 1 2 3))
3

Lists like this will work:


> (is-list (list "list" 1 2 (list 3)))
true

but I think you intended a more general test.


Quote from: "ssqq"
(define (is-blank-hash x) (= x '(())))

(define (is-hash @x)
  (and (list? @x) (for-all is-pair @x)))

This doesn't "describe" a "hash" (i.e., hash table/map), but an association list.  Lispers have called this "alist" for short. So, your function names might be better expressed as `empty-alist?` and `alist?`.


Quote from: "ssqq"
(define (is-pair @x)
  (and (list? @x) (= 2 (length @x)) (is-key (@x 0))))

(define (is-key @x) (or (string? @x) (number? @x)))

In an alist, the keys can usually be more than just strings or numbers -- they can be whatever data in the language is comparable under certain equality operators; these operators will be the ones used in your alist lookup functions, by the way.  In hash tables/maps, keys are anything that is "hashable" (i.e., any data for which the hash function can produced a hash).
(λx. x x) (λx. x x)

rickyboy

#11
Quote from: "ssqq"I think array should have empty array, Just like other language.



I think "Not empty array" is a design error.

I disagree.  Why?  Do you have a good use case?
(λx. x x) (λx. x x)

rickyboy

#12
Hello Ted!


Quote from: "TedWalther"The array-list function sets up a correspondance in the mind.  This creates the expectation that arrays are just another type or format of list; so all the list functions should apply to it.

The subject of the action is incorrect here IMO.  It's not the `array-list` function that "sets up a correspondence"; it's your own mind that is doing this. My mind is not making the same correspondence. :D


Quote from: "TedWalther"Contexts are different enough from lists that you learn to treat them as their own data type from the beginning.  Arrays are similar enough to lists, that it is jarring when they don't act like lists.

In my mind, arrays are *different* enough from lists ... :)
(λx. x x) (λx. x x)

ssqq

#13
in newLISP, no "true" hash, is just assoc-list. I just want simulate Hash, Array use newlisp.



Just like no Hash, List and symbol in C, but Lautz could write newLISP use C.



I write Spp language implement with newLISP, it have Array, Hash, List, Rule:


> (my @array [])
[]
> (@array << :a)
[:a]
> (my %hash {1 : 2, 3 : 4})
{1 ; 2, 3 : 4}
> (%hash 1)
2
> (my @lst :(1 2 3))
(1 2 3)