lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great William Ahern once stated:
> On Fri, Aug 01, 2014 at 06:19:26PM -0400, Sean Conner wrote:
> > It was thus said that the Great William Ahern once stated:
> <snip>
> > > I'm not a C++ programmer, but there's a parallel with the ranking of
> > > implicit conversions when dealing with overloaded functions.
> > > 
> > > Because of Lua's metamethod devices it's important to always be in the habit
> > > of generating a loose hierarchy of types in your mind when implementing
> > > function overloading. Otherwise they go to waste. If implicit coercions
> > > didn't have significant value, neither would metamethods.
> > 
> >   I don't think that way.  I don't use metatables for tables, I use them for
> > userdata, and for all the userdata interfaces I've written, I've found one
> > that overrides something other than __call, __index, __newindex, __gc,
> > __tostring or __len [7], that's how rarely I do overloading. [8]
> 
> If somebody is checking the type of a method argument and does X if the
> argument is an integer and Y if the argument is a string, that's
> overloading.

  Technically true, but I feel there's a qualitative difference between
overloading __index and __add.

> > > I feel like the obsession with stricter typing is turning into an
> > > anti-pattern.
> > 
> >   I've checked the source control logs and over the past month, I've logged
> > 50 bugs in a work related project written in Lua [1].  Four of the bugs are
> > work arounds to bugs in other components I have no control over; two were
> > reverted (found not to be a bug or the wrong fix for a bug); 31 were logic
> > or misunderstandings (in other words, a compiler would not have caught
> > these) and the remaining 13 were bugs that a compiler or stricter typing
> > would have caught. [3]
> > 
> <snip>
> > [3]	Now, one might reasonably ask why 13 typos got into the source
> > 	control reposity.  I might answer as that's the only way to get the
> > 	code to the target machine for interoperability testing [4].  This
> > 	is also the first time I've seen actual SIP messages from the wild
> > 	[5].
> 
> But were any of those bugs caused by string-number coercion? Or the lack
> thereof?

  None where caused by coercion in this case.  But I have been bitten by
lua_isstring() in another project. 

> I'm not questioning whether strict typing _generally_ helps to mitigate
> bugs. I'm arguing that it's not clear to me that string-number coercions
> _specifically_ are hiding real bugs. And the potential risk, if any, should
> be weighed against the tremendous convenience.

  I looked for places where I called lua_isstring(), and in every case the
assumption is the user passed in a string.  In some cases, a number would
eventually call an error (because it didn't match anything I was expecting);
some other cases it wouldn't do anything bad per se, but it would still
fail to do anything meaningful (in other words, it becomes an expensive
no-op) and in one case the user would get something horribly different from
what they expected [1]:

	> uuid = require "org.conman.uuid"
	>
	> x = uuid.parse("2D69069E-DCE0-4FCA-9039-FA8D36ED3D8D")
	> print(x)
	2D69069E-DCE0-4FCA-9039-FA8D36ED3D8D
	> x = uuid.parse(222222222220000)
	> print(x)
	322E3232-3232-3232-3232-3232652B3134

  Okay, here's what's going on.  In the code to uuid.parse(), I call
luaL_checklstring().  If the string length is 36, then we get the first case
as shown above with "2D69069E-DCE0-4FCA-9039-FA8D36ED3D8D".

  But, because I also have to deal with raw UUIDs (16 bytes), I also check
the length of the string against 16, and if so, I assume it's a raw UUID
[1].  But, if you pass in a number that converts to a string that is 16
characters long, you'll get a spectacular failure as in the second example
[2][3].  Any other length of string or type is rejected as a failure.

  Granted, the chance of this happening is very small, but it's not 0.

  -spc (Will probably avoid the use of lua_isstring() in the future ... )

[1]	You know, being lenient with what I accept and all that.

[2]	And yes, it took a few minutes to find a number that ends up being
	16 characters long when converted to a string.

[3]	That is not a valid UUID according to RFC-4122.