Hacker News new | past | comments | ask | show | jobs | submit login

Here's an article I've submitted before that makes a case for considering Squirrel instead of Lua:

http://computerscomputing.wordpress.com/2013/02/18/lua-and-s...

The best reason against using Lua in my mind is that undefined variables in Lua return nil, which can lead to typo bugs and therefore unintentional sparse arrays, which screws up the result returned by the length operator. It also has inconsistent boolean expression evaluation:

  while 0 do print("Loops forever") end
  while not 1 do print("Does nothing") end
  while 1 do print("Loops forever") end
  while not 0 do print("Does nothing") end
It's nice having real classes in Squirrel with type introspection and corresponding C APIs. In Lua, I have to juggle metatables in the registry to construct a class system, and my system will differ slightly from someone else's. Squirrel's other niceties like compile-time constants, 0-based arrays, and automatic reference counting for predictable memory management overhead make it a quite nice alternative to Lua.

It sounds like I'm bashing Lua here, though I still find it fun to program occasionally. But I do wonder how long Lua can remain as popular as it is with an unconventional syntax, inconsistent behavior, and a minimal built-in library in the face of richer alternatives like Squirrel, mruby, and even Tcl, which has improved much in recent years. There must have been a reason Valve Software chose to use Squirrel in L4D2 and Portal 2 instead of using Lua as most apparently do.




It's not inconsistent at all. In Lua, only nil and false are not true. Everything else is true, including all integer values, strings "0", "false", "", etc.

I'd rather say Lua is one of the most consistent and logical languages when it comes to truth values. You don't ever have to worry about arbitrary value evaluating to false.

http://www.lua.org/pil/3.3.html


Lua's treatment of boolean expression does lead to inconsistencies. For example:

  function Func1() return 1; end
  function Func2() return true; end

  if(Func1() == Func2()) then
    print "They're both the same!"
  else
    print "They're different!"
  end
In Lua, even though 1 and true evaluate to true, they're not the same thing and so comparisons between them evaluate to false!


1 and 2 both evaluate to true, yet they're not the same thing, so the comparison `1 == 2` is false. Is that equally problematic to you?

There's no way to avoid this problem in any language that allows coercing a number to a boolean. There are two possible boolean values, and many more possible numeric values. Therefore, numbers that are different and compare unequal will still both evaluate to true. Pigeonhole principle.

It seems you were surprised by the fact that Lua doesn't consider 0 false. Fair enough, that behavior's different from many other programming languages. But there's nothing inconsistent about it.


You're explaining the implementation, which I understand. There are reasons behind everything in the infamous "Wat!" video. The inconsistency is in conceptual expectations: (0) is true, (not 0) is false, yet (0 == true) is false. These are unexpected "gotchas" familiar to experienced Lua programmers.

It's not a dealbreaker. It's just a Lua quirk that often surprises newcomers. I was pointing out that Squirrel uses more conventional boolean evaluation that script authors coming from other languages may be more comfortable with. If you're exposing a scripting API, the language you use is essentially a part of your user interface.


As long as (0) and (not 0) are opposites; and (1) and (not 1) are opposites, there is nothing wrong, inconsistent or surprising.

But I think I see what you are trying to say. You want the == operator to coerce its operands to the same type before comparing (like JavaScript's == operator), but Lua's == operator doesn't do that, it simply compares. And that's why other languages need an === operator and Lua does not.

(JavaScript, by the way is the inconsistent one in this regard: the == operator does coerce its operands, but if(something == true) doesn't do the same thing as if(something). Try it with an empty array)


Lua's behavior here is identical to Ruby's, where 0 is also a truthy value:

    $ irb
    irb(main):001:0> if 0 then puts "0 is truthy!" end
    0 is truthy!
    => nil
    irb(main):002:0> if (not 0) then puts "(not 0) is truthy" end
    => nil
    irb(main):003:0> if (0 == true) then puts "0 is equal to true" end
    => nil
Many things about many programming languages are surprising to newcomers. However, the rule is very simple (in Lua): In a boolean context, every value besides nil and false is treated as though it were true. It is absolutely consistent. (a == b) is not a boolean context, or else 2 == 3 would be true.


Are you confusing (1==true) with (1 and true)? The value 1 is a number while true is a Boolean. Why should apple==orange ever be true?


If I understood your comments in this thread correctly what you are calling an inconsistency is that there are many values x for which

    if x then print "OK" end
prints "OK" but for which

    x == true
returns false. Is that right? If it is, then this is completely normal for languages that allow non-booleans in if statements. For example, x=2 is "inconsistent" in very many languages such as C, Python, Ruby, Perl, most Lisps, etc. I've never heard of this Squirrel language before, but if I read the docs correctly, x=2 is also "inconsistent" in Squirrel. In fact I'd be very surprised by a language that had no "inconsistent" values of x and that didn't achieve this by simply restricting x to be Boolean in an if.


One more language with a C syntax, how so exciting. If for nothing else, I love Lua for taking all the good simplicity out of Python and meshing it with a functional approach and everything is a table. Arguing over syntax aesthetics might be superficial, but I welcome some variety thank you very much, same as I would be bored as a writer if I could only use one style.


Correct me if I'm wrong, but what's inconsistent there is not boolean evaluation, it's number to boolean conversion. 1 == true and 0 == false are pretty standard, but that doesn't mean 0 and 1 are booleans.


Only nil and false evaluate to false. Because there's no distinction between nil and non-existent elements, checking the existence of an element with a value of 0 requires that 0 evaluates to true, so you get this situation:

  while 0 do print("loops forever") end
  while not 0 do print("does nothing") end


What you're saying is just that in Lua, 0 is truthy. Ruby is the same way, not a big deal.


Thanks for posting that link. I've been interested in Squirrel myself and will check it out.

I do like Lua and - per the discussion below - I don't see any problem in Lua's concept of truthiness. It's different from other languages like C or JavaScript, but similar to others like Ruby. Just something you have to get used to if you program in multiple languages.

But the other things you mentioned do sound worthwhile, so thanks!


That's not inconsistent. Unintuitive maybe.


You don't consider it an inconsistency for (1) and (not 0) to evaluate to different results?


(1) is a number. (not 0) is (false), a boolean. How could they be the same? They must be different because they are different types.


Obviously there are reasons for the behavior, but it's still inconsistent to users who are exposed to your scripting API to have:

  if 1 then print "true" end
  if 1 == true then print "never prints" end
Not a reason to avoid the language. But it may be a reason to consider an alternative with more conventional behavior.


If you replace 1 with 2 this is an argument against using a vast number of languages, including Squirrel, I think. So maybe you're really saying that languages should forbid non-Boolean values in if statements. Maybe I agree with that.


Would you consider that an inconsistency if you weren't coming from the C paradigm of 0 == false?


Yes, because it's not just a C paradigm. Additionally, even though 1 is true, comparing 1 and true returns false!


1 is not the same value as true. Just as in the case I commented on a couple of messages above, 1 and true are two different types.

The == operator does not compare the "truthiness" of two values. It compares the values, and if those values are two different types, they are always unequal.

http://www.lua.org/pil/3.2.html


I'm aware of the reasons why. It's still inconsistent to users. Remember that Lua is targeted at non-professional programmers.


In my opinion, having (1==true) evaluated to true, but (2==true) evaluate to false is more inconsistent. Even non-professionals should follow logic if they are going to program.


0 isn't false.


It's also not true:

  > if 0 then print "true" end
  true
  > 0 == true
 => false
I know why this is the case. But it's a logical inconsistency for users of the language.


Stop trolling please. You are advocating for `==` doing type coercion of arguments and that is almost always a misfeature in any language that has that (and the fix usually involves adding an ugly `===` operator after the fact)


In the case of Lua rules of what is truthy and why (as I read here) I'd expect (not 0) to be a type error. That's the case in OCaml for example and I think it would be good in Lua.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: