Daniel Lemire's blog

, 18 min read

Duck Typing, Artificial Intelligence and Philosophy

15 thoughts on “Duck Typing, Artificial Intelligence and Philosophy”

  1. Arugula says:

    You are committing a sophomore error: Turing did not propose “specific
    Turing tests”. He proposed one particular test for general-purpose
    intelligence.

    You confuse “performing at the same level as a human” with “performing
    similarly to a human, foibles and all”. You obviously don’t mean the
    latter — but Turing’s “imitation game” most certainly did.

    You also confuse different uses of the word “intelligent”. Turing
    proposed his test as a way, in principle, to decide if a computer
    was intelligent in a general-purpose sense that included things like
    creativity, language use, arithmetic ability, humor, etc.

    When we talk about “intelligent spam filters”, or “intelligent
    backtracking”, or even “intelligent toasters”, we mean “intelligent”
    in the sense of performing a particular task well.

    And your comment that creating an intelligent computer is secondary to
    utility is amusing: you poo-poo what would be the greatest invention
    in human history in favor of short-term grantsmanship? Small dreams
    means small disappointment, I guess.

  2. Arugula: Please calm down. This post was designed to start discussions. No insults are warranted at this point. I don’t poo-poo anything.

  3. Peter Turney says:

    In other words, how long must the machine fool the human being before we conclude that the Turing test is a success?

    Yes, time is very important. This point has been made many times. Search on Google for “time limit” “turing test”.

    Hence, Computer Science should focus on usefulness criteria and reject other criteria.

    I agree that usefulness is very important. Other criteria (e.g., perplexity in NLP) are generally substitutes for usefulness when usefulness is difficult to measure. If you look at papers by AI researchers, the motivation is almost always some concrete application. Most AI researchers do not take the Turing test seriously. Joseph Weizenbaum’s Eliza program showed how easy it is to fool people (at least for a short time). His 1976 book Computer Power and Human Reason probably turned many researchers away from the Turing test. The vast majority of papers on the Turing test are not written by AI researchers.

    This has very concrete consequences if you accept my ideas. Research in Computer Science should therefore be focused on making machines useful.

    You won’t get much argument from computer scientists. This is already the majority view in computer science. My own focus is on making machines useful.

    On the other hand, a general-purpose artificial intelligence is likely to be very useful, compared to a highly specialized artificial intelligence.

  4. Arugula says:

    Daniel: It is cute how you talk down to me, as if I am one of your students.

    I certainly did discuss your posting — I think the most interesting thing about it is that you are making common beginners errors that lead you to what I think are very foolish conclusions.

    I have no interest in tip-toeing around a professor’s ego, so I will not be bothering you again.

  5. alex says:

    I enjoyed your post, and Arugula’s reply even more, a shame that you saw insults in it.

  6. Peter Turney says:

    You are committing a sophomore error

    Small dreams means small disappointment, I guess.

    In my opinion, these comments are somewhat insulting. I think it was appropriate for Daniel to request cooler, less emotional discussion.

  7. At best, I though that Arugula demonstrated the point: we don’t really know what “intelligence” means.

    I’m behind the notion of focusing on the criteria of useful. I strive for that in my own work. Coming up with a general “intelligence” may or may not be attainable, but perhaps the best way to get there is just keep doing useful things and see if some pattern emerges.

    I’ve been studying programming languages for my graduate work and I get the feeling that “useful” is not on in the minds of those trying to advance the field. There’s this urge to try and come up with the “be all and end all” tool instead of a “not quite perfect, but beneficial” tool. It’s never sat well with me.

  8. I think you misrepresent the concept of duck typing.

    Take java. I think, if you ask any programmer familiar with a number of languages, if java has ‘duck typing’, your poll will come up with a resounding NO, java doesn’t have it.

    And yet by your description here, java does; any two objects with both implement, say, “Comparator” (an interface), can be fed into a sort routine. The sort code in the JVM doesn’t care beyond the notion that it’s a Comparator, after that all’s fair.

    The elephant in the corner here is what duck typing really means in common discussions on programming languages:

    The idea that attribute names alone are enough. In other words, the very fact that an object happends to have an attribute named ‘compareTo’ is enough; that is (in python/JS/ruby style languages) basically the definition of being a Comparator.

    In java/C# and company, that’s not enough – you need to implement Comparator (and that forces you to have that compareTo method). The major advantage is namespacing:

    ‘compareTo’ has no namespace. This isn’t an obvious problem for a method named ‘compareTo’, but if we start playing with ‘shoot()’ then accidentally shooting my Gun instead of my Camera could cause some nasty surprises. Even if the intent is the same, the implementation details (e.g. do I feed it a list and does that get updated in place, or do I feed it a tuple and do I get a new tuple back?) of the interface definition may still preclude actually mixing and matching to your heart’s content.

    On the other hand, all those interface definitions are a whole lotta typing.

    Personally I prefer the typing, not so much for the Gun/Camera thing (though a nice bug-preventing bonus in rare circumstances), but for the ability to ctrl+click on any interface name in my IDE and read all about what it means to be a Comparator. Do I return a negative number to indicate a is larger than b, or smaller than? I never remember.

    What you are talking about is completely different: You’re just talking about OOP.

  9. Reinier: I do mean duck typing and I don’t think Java has duck typing. I actually link to wikipedia for those who want to learn more about the concept. But you are right that my explanation is incomplete. I have edited my post accordingly. Thanks.

  10. Peter Turney says:

    I’ve been studying programming languages for my graduate work and I get the feeling that “useful” is not on in the minds of those trying to advance the field.

    Those of us in computer science who are trying to invent new programming languages are in a minority. Most computer scientists, being practical people, will use whatever existing programming language is most suitable for the task at hand.

  11. Static typing is not the same idea as static methods (http://en.wikipedia.org/wiki/Static_typing). With polymorphism in Java, it is trivial to determine whether an object has the right interface. A simple “instanceof” will determine, in constant time, whether you can plug this object in this function. In Python or Ruby, determining whether a given object can be used inside a given function is much harder… and in practice, you only care whether it works *within the scope of your code*. Python and Ruby are not the only such languages… JavaScript might even be a better example because it is weakly typed too!

    I agree you can make Java use duck typing, but that’s now how 99.999% of the code out there works, so that’s a tiny technical issue.

  12. But isn’t the difference between instanceof and if ( object.methodName ) in the end only a minor technicality?

    Maybe, depends on what you consider to be technical.

    In Python/Ruby/JavaScript, if an object has *all* of the methods that are ever used in a function, then it is safe to use to pass this object in the function. However, there are many other objects with an incomplete interface that will also do. The interpreter has no easy way to know whether your code will fail because of a missing method… so it just runs the code… and thousands of programmers live happily with this model. These languages use a “fail late” approach: try your best to succeed and fail only when you have to.

    In Java, if your object has an incomplete interface, and you try to pass it to a function, then it wil not compile! That’s because the designers of the Java language think that it is better to catch “possible errors” as earlier as possible. These languages use a “fail early” approach.

    Now, if you look at what happens with experimental sciences… we are in a fail late approach: you run experiments and if you learn as late as is possible that you have failed.

    I’d in fact argue that the JS view fails because it doesn’t step back and
    take an abstract view of the concept of polymorphism; just because an object
    has a shoot() method it doesn’t mean what you think it might (english has
    homonyms, e.g. shoot with a camera or shoot with a gun, and there are
    implementation differences; basically a method stands for something, it is
    supposed to do something. It’s not always possible or even desirable to put
    all the details in the name itself, it can help to stuff the details in a
    comment, or maybe in the parameter list definition, etcetera.

    You argue not only for a fail early approach, but in fact for a “fail super early” approach by introducing semantics. I hold the view that more semantics than is absolutely necessarily is evil because it makes systems more complex.

    In any case, fail early goes against the point of my post, I think.

  13. Experiments are fail super early.

    Physical laws are falsifiable, but not provable. This is why, even if you have tested a law 100,000 times, you must still test it, again and again and again and you stop only in case of a failure. You have no way of stopping your experiments early unless you encounter a failure in the course of an experiment.

    Which is why I’m, again, correct, in asserting that that’s taking it way too
    far: The idea that polymorphism is inherent in AI discussions is an
    interesting one, the moment you take it beyond this metaphor and start
    trying to assign it to specific implementations of the idea of polymorphism,
    it becomes a pointless tirade.

    If determining machine intelligence was like Java’s polymorphism, then to check whether a machine is intelligent, we would do “machine instanceof intelligentbeing”. This can be done in constant time. On the other hand, validating duck typing is equivalent to the halting problem and that is a very hard problem.

  14. Okay, but now the article doesn’t make any sense. The comparison you make between programming principles and the turing test is interesting, but certainly not so specific as to have a restriction like not including static methods make any sort of sense.

    Not to mention that static methods cannot be polymorphed in java; you can’t stuff them in interfaces, and a class with a static method can’t be ‘extended’ meaningfully (you can redefine the method, but this won’t result in objects of the subtype linking to the new method). Basically, this definition still doesn’t cover what’s ordinarily meant with duck typing.

    More importantly:I think the key IS polymorphism here, and not a specific implementation of it. Duck typing is one way to pull it off. (the existence of duck typing in e.g. python also explains why there is no such thing as an ‘interface definition’ in those languages; the duck typing is their way of doing it. Java and C# and the like have no duck typing (Actually they do, it’s called proxy classes, but that’s “cheating”, I guess) but they do have interface definitions – that’s their way of doing it.

    As long as your programming language offers a way of doing polymorphism, is what I’m saying.

  15. Joe says:

    Let me say that the first poster could certainly have phrased his particular insight with a little more compassion and clarity.

    Next, I want to commend you. Your question here is quite interesting. How many (and what kind of) tests do we need to show this machine can think? If we’re strict dualists, there’s nothing that show this — just as there’s no gesture we can perform to prove God exists, or that gravity will *always* function as we conceive it currently.

    I think the important step to take is denying this dualism — that there’s no difference between language and the actions and passions of bodies. The question is substratum, material, construction methodology. Who’s to say a computer won’t ‘think’ if we build a recursive network of self-organizing social agents? What indeed would be the difference, if a robot was *acting* wise and compassionate, responding as necessary to the situation?