The primary usecase of this is for working with case-sensitive strings (ex Criteria) & differentiating types that can coerce to Nil from values that are exactly Nil (To be used in some things we are working on)

(=== "a" "a") -> True
(=== "a" "A") -> Nil
(=== "1.0" 1.0) -> Nil
(=== "" Nil) -> Nil
(=== varWithEmptyMutableList Nil) -> Nil
(=== 0 Nil) -> Nil
(=== 0.0 Nil) -> Nil
(=== Nil Nil) -> True

64-bit Note:

Once PointerType is added (for 64bit) a pointer and an int/double should also fail to coerce to eachother and return Nil as well

wolfy 26 days ago:

WARNING: Since the usage of this in TAI is performance sensitive, it will not have an API version check. TAI (and other libraries like DDR) need to check for empty (mutable) lists. This means that you NEED to manually verify that you have updated your extension's API version to 55+, otherwise multiverse can download it to an older version and cause all sorts of problems as these functions will not exist there.

A note on why we want to check for empty lists not being Nil:

Despite Nil pretending to be an empty list, it is not mutable - it is an atom.

The reason this is important is the following:

;;normally attempting to make an empty list returns Nil instead
() -> Nil
(list) -> Nil
;;but making a list and removing everything from it leaves an empty mutable list instead of Nil
(lnkRemove (list 1) 0) -> ()

;;setup our atomic Nil example
(setq a Nil) -> Nil
(setq b a) -> Nil
(setq c a) -> Nil

;;setup our mutable list example
(setq x (list 1)) -> (1)
(lnkRemove x 0) -> ()
(setq y x) -> ()
(setq z x) -> ()

;;show the expected behavior of lnkAppend-ing to an empty mutable list
(lnkAppend y 1) -> (1)
x -> (1)
z -> (1)

;;show where everything goes wrong when you assume that Nil is actually an Empty list
(lnkAppend b 1) -> (1)
a -> Nil
c -> Nil

For performance reasons we should also have a function to generate an empty mutable list instead of a Nil. We may want to adapt (list) or () to do so? (normally you use Nil to get an atomic Nil). That will be a separate ticket.

giantcabbage 25 days ago:

BTW - in v1.9 and 2.0 alpha you can use (list) to produce an empty list:

(setq x (list))
(setq y x)
(setq z (list))

; x any y point to the same list object:
(lnkAppend x 1)
x -> (1)
(lnkAppend y 2)
y -> (1 2)
; z is a separate mutable list
(lnkAppend z 3)
z -> (3)

Empty brackets should be returning Nil, not an empty list, as you're actually calling a null function. Consider:

(cat 1 2) -> '12'
(1 2) -> ERROR "Function name expected [1]"
giantcabbage 25 days ago:

BTW - if you're checking if you have a real list then wouldn't it be better to use (! (isatom somevar)) Then you can accept both empty and non-empty lists

wolfy 25 days ago:

Ah! ok when we checked last night for some reason I guess we misread some of the line ordering in our tests and though (list) was returning Nil. I'll close that out.

Good point on the null function.

(!=== possiblyAListOrNil) -> True if its not Nil and only requires one function