duck typing

Difference between version 11 and 12 - Previous - Next
In [object orientation%|%object-oriented] programming, '''duck typing''' means
orienting on what interface an object exposes rather than on what its class is.


** Description **


'''If it walks like a duck, and talks like a duck, it's a duck'''.  With
'''duck typing''' one does not specify what type of object an argument to a
routine should be.  Rather, one specifies what methods it must support, and
what those methods do.  Any object, regardless of type, can be passed to the
routine if it provides the required methods.  Traditionally, a
statically-compiled object-oriented language is not conducive to duck typing
because at compile time the compiler must know the type of the object.  [Java]
works around this constraint and provide duck typing via the concept of
'''interfaces'''. 

Tcl is an odd duck.  An argument to a routine does not provide any methods
because it is not an object.  In Tcl there are no objects.  There are only
[EIAS%|%values].  In languages like [Python], there are no values.  There are
only objects that can be used as values. 

Duck typing is yet another case where a term simply doesn't apply to Tcl, at
least not in its commonly-understood sense.  Tcl simplifies the criteria:
'''If it looks like a duck, it's a duck.'''


** Discussion **


[AMG]: In Tcl, each value's data type is implicitly determined by the operations performed on the value.  This is called "duck typing" [http://en.wikipedia.org/wiki/Duck_typing].

===
set data {1 2 3 4}     ;# $data is a [string]
llength $data          ;# $data is a [list]
dict size $data        ;# $data is a [dict]
set data 42            ;# $data is a string
expr $data             ;# $data is an [expr]ession (beware of side-effects through nested commands)
expr {$data}           ;# $data is an [integer]
regexp $data 4242      ;# $data is a [regexp]
set data [expr 99]     ;# $data is an integer
string length $data    ;# $data is a string
===

and so on.

Beware of [shimmering]!

----

[AMG] (conversation moved from [Wikipedia], 2014-05-28): Tcl pretty much wrote the book on duck typing.

[PYK] 2014-05-28: I sorta thought [Python] wrote the book on duck typing.  I
think expanding the presence of [Tcl] on Wikipedia is a very useful activity,
and hope someone finds the time to expand the duck typing article there.

''[MSH] 2015-11-27: It appears there are no references to TCL at all on the "duck typing" [http://en.wikipedia.org/wiki/Duck_typing] page.  [AMG]: That is a shame.  But when I said the conversation was moved from [Wikipedia], I meant it was moved from the Tcl Wiki page on Wikipedia, not from the Wikipedia page on Duck Typing.''

[AMG]: Not at all.  In Python, types are intrinsic in values, whereas in Tcl, types exist only within the program's interpretation of values.

Python sees `"2"`, `2`, and `(2,)` as distinct, and they cannot be +'ed (added or string/list concatenated) without the programmer explicitly begging that one be converted from str to int, or vice versa, plus don't forget about unpacking single-element tuples or lists.

Tcl sees no distinction between the three, though it renders the single-element tuple `(2,)` as simply `2`.  The determination between adding or string/list concatenation is made not by the inherent type (a concept foreign to Tcl), but rather by having adding and string/list concatenation being separate operations.

With Tcl, the type is inferred according to the operations being performed on the value, and the type can freely change from moment to moment with no need for explicit conversions.  The interpreter figures out the type based on what the programmer is trying to do.

======
set operands {"2" 2 {2}}
tcl::mathop::+ {*}$operands   ;# 6
join $operands {}             ;# 222
list {*}$operands             ;# 2 2 2
======

With Python, the type is explicitly declared according to how the value was constructed.  Surround it in quotes, and it's a string.  Put it in brackets, and it's a mutable list.  Put it in parentheses with commas, and it's an immutable tuple.  Put it in braces, and it's a dict.  And so forth.  Conversions are not automatic, and the programmer has to explicitly ask for them.

======none
operands = ("2", 2, (2,))
def collapse(x):
    while isinstance(x, (list, tuple)):
        x = x[0]
    return x

reduce(lambda x, y: x + y, operands)                                   # cannot concatenate 'str' and 'int' objects
reduce(lambda x, y: int(collapse(x)) + int(collapse(y)), operands, 0)  # 6
reduce(lambda x, y: str(collapse(x)) + str(collapse(y)), operands, "") # '222'
reduce(lambda x, y: x + (int(collapse(y)),), operands, ())             # (2, 2, 2)
reduce(lambda x, y: x + (str(collapse(y)),), operands, ())             # ('2', '2', '2')
======

[PYK]: OK, I see where you're coming from now , and how the concept of duck
typing could be applied to Tcl values , but Tcl's [EIAS] wonderfulness isn't
what Python programmers have in mind at all by "duck typing" . They are
primarily thinking about the interfaces of the objects they pass around , and
the fact that clients of those objects need not inspect the type of the object
, but instead can inspect the interface (method) in order to decide whether or
not to work with it .  I still think it would be great for the Wikipedia
article to have an section about Tcl , perhaps with the title "And now for
something completely different ..." ;)

[AMG]: Yes, Python does have duck typing in the sense that object properties or methods or whatever are late-bound and can be added, modified, or removed throughout the object's lifetime.  But that's a rather limited view because the types are still bound to the objects, even if the interfaces can be changed around.  In Tcl, types are purely a notational thing, and the interfaces are wholly separate from the objects (values).  The [EIAS] section of my [Brush] paper summarizes Tcl's relationship with types.


** Page Authors **

   [PYK]:   

<<categories>> Concept