+ 7
Why is [] (empty Array or list) falsey in Python but, truthy in JavaScript?
I'm having a little confusion about "emptyness" of lists and Arrays When I do: console.log(!![]); // then, it logs "true" but, when I do: print(not not []) // it print "False" ??? But, why these two languages have different implementation of the same concept? Is there any logic behind their implementation or are Arrays different from lists?
38 Answers
+ 8
From the official docs (https://docs.python.org/3/library/stdtypes.html#truth-value-testing):
Truth Value TestingĀ¶
Any object can be tested for truth value, for use in anĀ ifĀ orĀ whileĀ condition or as operand of the Boolean operations below.
By default, an object is considered true unless its class defines either aĀ __bool__()Ā method that returnsĀ FalseĀ or aĀ __len__()Ā method that returns zero, when called with the object.Ā [1]Ā Here are most of the built-in objects considered false:
constants defined to be false:Ā NoneĀ andĀ False.
zero of any numeric type:Ā 0,Ā 0.0,Ā 0j,Ā Decimal(0),Ā Fraction(0,Ā 1)
empty sequences and collections:Ā '',Ā (),Ā [],Ā {},Ā set(),Ā range(0)
Operations and built-in functions that have a Boolean result always returnĀ 0Ā orĀ FalseĀ for false andĀ 1Ā orĀ TrueĀ for true, unless otherwise stated. (Important exception: the Boolean operationsĀ orĀ andĀ andĀ always return one of their operands.)
+ 7
Gordon š
Arrays in Java are 'true' , first-class objects.
The elements of an array of objects are references to the objects, not actual instances of the objects.
The default value of each element is thereforeĀ 'null' , until we assign instances of appropriate objects.
In Java, a newly allocated array of objects actually contains only reference variables, each with the valueĀ 'null'.
Thatās not to say that there is no memory associated with an empty array - there is memory needed to hold those references
(the empty "slots" in the array).Ā
Default assigned array values in Java :
ā¢ boolean : false
ā¢ int : 0
ā¢ double : 0.0
ā¢ String : null
ā¢ User Defined Type : null
// I have an example, I'll send when I find! š»
+ 6
In JS, an array is an object and objects are always true.
+ 6
HonFu LoL...š probably š
Gordon I hope, my previous answer was satisfactory! š
but here it is,
I would ask sir John Wells to correct me if I'm wrong!
In Kotlin,
This can be done using the Array constructor which accepts a size parameter and a function to do the initialization:
Array(size, intializer)
The type of the array is determined by the type the initializer returns. The function is passed a single Int, the index, and the value it returns is stored in that element. For example:
var a = Array(10, { i -> i * 2 })
creates an array of 10 Ints initialized so that a[i]=2*i. The initialization function can be as complicated as you like but the most common is:
var a = Array(10, {Ā 0 })
which zeros the array.
Notice that the function simply returns zero and doesn't need the value of the parameter!
https://code.sololearn.com/cHLMQG31PxdI/?ref=app
+ 5
In python, it is implemented that way to allow for more compact code. At least that's what I read somewhere. Instead of "if len(list) == 0:" or even "if not len(list):" you can just write "if not list:" (or "if list:" instead of "if len(list) >= 1:"). Of course that doesn't answer the question why it is the other way round in JS.
+ 5
Thanks Anna! ;)
+ 5
HonFu right! I'd previously thought that programming languages would be the most logical thing as they run on mathematics. But, it's not really true.
Nevertheless, programming is my favorite subject ;)
+ 5
That's a big problem with weakly typed languages in general. Arrays shouldn't be "falsy" or "truthy", because they are not booleans.
Ideally, `![]` should just throw a TypeError. You never need `![]` in practice, and it prevents you from doing that sort of stuff by accident (which does happen in practice).
JS in particular is one of those languages that doesn't (didn't?) like errors at all and tried chugging along at all costs, so it tries to make sense of things like `![]`. I guess they didn't know better in the 90s, but weak typing has lead to many bugs and inefficiencies.
([9,10,11].sort() == [10,11,9] is my favourite example)
If we all programmed in Haskell none of this would even be a topic of dicussion :P
+ 5
Gordon Floating point numbers have a sign bit in their binary representation, 0 for positive, 1 for negative. The remaining bits are the number itself.
Awkwardly that means that there is both +0 and -0!
It's a minor thing. They behave the same almost all of the time and so are identical as far as the average programmer is concerned.
+ 4
Anna, Jonathan, HonFu: Sorry, if I responded late, I'm learning on the web.
Thanks for your answers :)
@Jonathan nice explanation. An object can never* be false. But, I need a similar explanation for Python also...
* See Gordon's answer
+ 4
Like Anna explained, in Python null objects are zero/false. Empty string, empty list, empty set--you name it! It's more natural, and is convenient in doing stuff like "if my_list:".
[Hardcore]
In set theory, we even define 0 as the empty set.
0={}, 1={0}, 2={0,1}...
https://en.m.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers
+ 4
rv7 here's a sample code to confuse you even more.
https://code.sololearn.com/WoS1qQ8nSejv/?ref=app
On a serious note, I suggest you read this to get a good grasp of some JS quirks.
https://codeburst.io/understanding-null-undefined-and-nan-b603cb74b44c
+ 4
HonFu I figured you'd bring this up, nice :D
C is a special case, because C has no booleans. So `if` kind of has to work on numbers. There is the <stdbool.h> header but I think it defines `true` as 1 and `false` as 0 or something. (It also wasn't in the standard library from the very beginning I think)
It's numbers all the way down and C is totally reasonable in that regard I think!
+ 4
HonFu As to C, I think it goes from Assembly. You don't usually have boolean type at the level of processor instructions. Just comparison with 0. And if(n) is just something like jump-if-zero.
+ 3
Hey Gordon, I'm confused š«, why null is a false object?
+ 3
LoL. Objects are the most confusing part of JS.
+ 3
Just like honfu has said, "because we(the designer of the language) decided to" š
And we have to remember these special cases as special cases.
+ 3
Thing is: Like real languages they don't live in isolation.
People are using them and have been using them before and there is code that needs to continue to run properly, so one could not arbitrarily 'tidy up the place'.
So when old decisions (mistakes?) remain in a language to ensure backward compatibility, all our teachers can do is say: 'Don't use these old features, use the newer, safer ones instead!'
And since humans are humans, some will do that and some won't and it all becomes a mess with different 'styles' and all.
(That's at least my impression.)
+ 3
rv7 this sharing is further to Jonathan Pizarra 's example of NaN and for your enrichment :
https://www.sololearn.com/post/42147/?ref=app
To check equality of NaN, we need to use isNaN()