There’s two notions at play here, one is object-oriented programming (which 
javascript handles quite well), the other is a static typing system (which 
javascript being a dynamic language doesn’t natively support). 

It’s important to understand that you can do object-oriented programming 
without static typing, classes, explicit interfaces, or inheritance. 
Similarly, just because you are using classes, interfaces, or inheritance 
doesn’t mean your code is object-oriented. 

I understand why you are troubled by the notion that you shouldn’t just be 
able to trust an object implements the correct interface simply because it 
has methods with the right names. Technically speaking, you are absolutely 
correct. The push method of an object I pass in might very well just do a 
window.alert('I'm 
not pushing').

However, what you have to realize is that there is always an implicit 
contract between methods and API’s you write, and the people who use those 
API’s. When you write a function, you have to document or show examples of 
what it does, what parameters it expects and what it will return. A 
statically typed language provides some tools to help document and enforce 
*some* of that contract at compile time. However, static typing can only go 
so far to enforce a contract, so you still have to trust the caller. For 
example, even with static typing I can create a group and have it implement 
a “List” interface but there is nothing preventing me from implementing the 
list interface incorrectly, or even purposefully not behaving as a faithful 
implementation of a list contract (i.e. I can still “push” persons off a 
cliff rather than add them to my group). 

Duck-typing can be a useful tool in dynamically typed languages, as long as 
your contracts is documented. For example, in your method you would say: 
“if the first parameter proviides a push method it will be interpreted as 
an array-like object and the method used to add items to it”. While this 
contract is not enforced by the language itself or the compiler, it is 
still a contract nonetheless. If the user of your method chooses to pass in 
an object with a push that does something other than what the contract 
requires, they should not expect it to work correctly. 

We use these kind of contracts all the time in angular and don’t think much 
of them. Take for example controller definitions, they take a string and a 
constructor, but the constructor could be a function, or it could be an 
array where where each element is a string and the last element is a 
function (for dependency injection). So the following two are valid ways of 
defining a controller:

app.controller('myController', function($scope){
});

app.controller('myController', ['$scope', function($scope){ 
}]);

This is a contract we are all familiar with, but it’s not enforced by the 
language, I could pass an array of integers as the second parameters but it 
would not really work because I’m violating the contract in the 
documentation. I could pass a list of strings that don’t actually match any 
services in my module and angular would throw me an exception because the 
contract states that these strings should be the names of valid services. 

My point is that the contract is between a method and those who use the 
method. Static typing can only help partially document and enforce some 
aspects of the contract, but often not the entire contract, so there will 
always be a level of trust that the objects passed in to your function 
behave as specified in the contract (even when using static typing). 

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to angular+unsubscr...@googlegroups.com.
To post to this group, send email to angular@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to