To try to explain it simply (assuming I understand it correctly): you don't check that an object is of a given type, just that it can do what you want. You tell it to go over there, and you don't care if it's a duck and flies there, or a cat and walks there. The idea being that you don't need to know about all the different types of objects there are; you just assume they have a "go_there" method, and if not, either you do something else or you complain that you can't use this object. "If it quacks like a duck, that's good enough for me."
For a real life example: you're given a data source and you use its `read` method to get data. It doesn't matter if that source is a file, a socket, a function, etc; all that matters is that you can call its `read` method and get some data back. If you explicitly check that it's a file, then I can't use a socket instead, even if it would have worked just fine.
In more strictly typed languages, this would be done by accepting any object that inherits from some base class or implements some interface, which guarantees it has a `read` method. In a dynamically typed language like Lua, you don't get the advantage of type safety (you might receive an incompatible object), but the code can be much simpler (you don't have to import class definitions and try to fit your object into them).
The one major gotcha is if you're given an object that seems compatible but isn't; eg the object has a `read` method, but it doesn't take the same parameters as you expect, or does something different (maybe tells you "yes, this message has been read"). This isn't very common but is something to watch out for.
(Aside: you can certainly implement a class/interface system using metatables, but you'll still have to check at runtime that you've received the right kind of object. It helps prevent the above mentioned problem, but does add complexity.)