The Artima Developer Community
Sponsored Link

Weblogs Forum
Implicit versus Explicit Dynamic Typing

95 replies on 7 pages. Most recent reply: Apr 17, 2006 11:09 AM by Isaac Gouy

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 95 replies on 7 pages [ « | 1 ... 2 3 4 5 6 7 | » ]
Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Well trodden path Posted: Sep 21, 2005 9:15 PM
Reply to this message Reply
Advertisement
> > Because you can't compare apples to oranges? Why do
> you
> > think this is hard?
>
> Not necessarily that it's hard, but that you still have to
> explain types. In fact it is proponents of loosely-typed
> systems that claim typing is a hard concept. But you
> can't get around teaching it, you just have to say "oh,
> and you don't have any way to enforce it."
>
> I say this because Perl was the first language I learned.
> I understood the dynamic type system pretty easily, until
> l I started working on bigger projects and ran into
> trouble precisely because of the loose typing.
>
This thread is about dynamic typing, not weak typing.

Python is dynamically typed, but it's hella strongly typed.

The issue of enforcing or not a type is therefore irrelevant.

Terje Slettebø

Posts: 205
Nickname: tslettebo
Registered: Jun, 2004

Re: Well trodden path Posted: Sep 22, 2005 4:21 AM
Reply to this message Reply
> > Really? If these are related by inheritance, there's no
> > problem handling this situation in a statically typed
> > language, such as Java:
>
> And if they are not related by inheritance, then you can't
> substitute one for another, even if they happen to
> implement the same protocol.

This is a separate argument. You originally said:

Terje:

> Static typing
> eliminates the need for type testing.

Todd:

> Until you support inheritance in the language, and then it
> doesn't.

I argued that if you have a lot of need for downcasts, your design may have a problem.

What you say above is an argument for "duck typing"; it doesn't have to do with static typing and inheritance, which you started with.

> > I think
> > "duck typing" is very useful; what I meant was that the
> > problem is the lack of _support_ for it, in languages
> like
> > C++, as well as in dynamically typed languages
>
> Dynamically typed languages usually only implement duck
> typing.

Yes, but they usually lack support for checking type constraints on function boundaries (which you get with support for "concepts").

> > The problem I speak of is that there's typically _no_
> type
> > checking at function boundaries, when "duck typing" is
> > used.
>
> Why should you check there? In a duck typing system, you
> are only in trouble when you ask something to quack that
> can't. This is the point of error. Not the function call
> boundary.

If you call a sort function with a an object that doesn't conform to the requirements of the comparator (such as having the less-than operator defined), then you'll get an error message pointing to where the function tries to use the unsupported feature. Normally, you'd then think the problem is in the sort function (since that's where the error message points to), when in reality, the problem is that you're calling it with parameters that don't conform with the requirements. Agree?

If you could specify the "duck typing constraints" on the function declaration, then you could get a type-error at the call site, where the error is.

As mentioned, this - the effect of "duck typing" without support for "concepts", is what can make debugging template-code, _and_ dynamically/undeclared typed code, difficult, because you may get an error message from a very different place than where the error actually is (when you consider that a function or module may have certain requirements on its parameters).

> > Therefore, any type-related problems may manifest
> > themselves as incomprehensive error messages deep into
> the
> > implementation (and in the case of a dynamically typed
> > language, you may not get any error at all, unless you
> > ensure that all possible cases are covered with tests.
>
> I seldom find the errors caused by type errors cryptic.
> They are usually obvious and straight forward. I also
> o find that we spend way too much time guarding against
> this error considering how often it actually occurs in
> practice.

I've several years of experience with developing applications in PHP, and my experience (as well as my coworkers), is that type-related errors stand for a large part of our bugs, as well as the difficulty in finding the correct place the error originates.

For this reason, we've developed some "manual" type-checking at function calls, but it's messy, as the language has hardly any support for it. We find now that we catch a lot of errors this way, that might otherwise go undetected, or show up in strange ways. Unfortunately, the codebase has hardly any tests, and that could have helped, but I still think type checking and unit tests complement each other (as I've said in other postings about not having to write lots of otherwise unnecessary tests).

> > As I said, the same problem exists in languages with no
> > type declaration on functions: any errors in the types
> of
> > passed values are only (if even then) reported from the
> > function implementation, not at the call site, where
> the
> > error actually is.
>
> Yes, but usually you get the stack. For instance, in
> Smalltalk, you get a walkback (debugger) on the program
> that usually shows you right where your error is. These
> problems are easy to find and fix.

Not in our experience. Yes, you may walk the stacktrace, and inspect each function call and parameters up to main(), but it would be much easier if the error message pointe to the actual error (as in the function call, not inside the function).

> > This problem may be eliminated with support for
> "concepts"
> > (abstract requirements on types, such as a type
> supporting
> > the "+" operator, and what type that operator returns,
> > etc.),
>
> To me, this is just more evidence that duck typing is the
> saner system.

"concept checking" is meant to give "duck typing" similar type-checking adavantage as ordinary types, without giving up the advantages, such as not requiring inheritance to work, etc. I think you may be misunderstanding what "concepts" are about, or we may mean something different with "duck typing".

Besides, what do you find "not sane" of what I described above? This is, as mentioned, also how it works in Haskell, ML, etc. (perhaps also Squeak, from what you describe)

> There is a continual loosening of typing
> constraints going on in c++

I'm not sure what you refer to, here. Ever since templates came, in the 80's, you could call a function template with any type. However, because of the popularity of templates, and the mentioned problems with this "duck typing", work is now underway to try to give "duck typing" type checking, as well, in the form of "concepts". I think this will be one of the next big things, in C++.

> "concepts" sounds suspiciously like "traits"
> which has recently been added to Squeak Smalltalk.

Traits, what the term mean in C++, anyway, is a way to "work around" the lack of support for "concepts" in the language. We've found that you really need language support for this (it can't be done completely as a library, unlike traits, which is a language feature, typically).

> Several other languages are beginning to adopt them as
> s well. Basically they are method bundles that can be
> adapted to arbitrary classes without hierarchical
> constraints.

Then "traits" in Smalltalk appears to be quite different from the C++ use of it. :) And, yes, several languages has this, including, apparently, Squeak. Vesa has shown examples of it in ML, and it aso exists in the form of "type classes" in Haskell.

> > even better, catching the error at
> > the point it exists.
>
> That's a fairly fuzzy concept I think.

What I meant was like the example with sort(), above. sort() has a strict set of requiremenst on its "comparator" object (including function pointer/reference), that is passed in. If what you pass in doesn't conform to these requirements, then you've violated the interface/contract of sort(), and the violation clearly is in the call to sort(), not in sort() itself. Agree? It's very clear; there's nothing fuzzy about it.

> > 2) It's a completely safe operation: Downcasting in C++
> > using dynamic_cast either succeeds or returns NULL,
> that
> > you may check for, so there's no risk of undefined
> > behaviour, as long as you check the result (it performs
> a
> > run-time check, if necessary).
>
> Its ugly and verbose.

You complained it was an unsafe operation. I replied with that it's not, unless you count forgetting to check the return value as a risk. However, in modern C++, you typically use something else than a "bare" pointer, that may catch these problems, as well as eliminating the verbosity you show. The need for try-catch may indicate a lack of understanding for good use of RAII (where you typically can avoid that).

> A* a = new B();
> ...
> B* b = dynamic_cast<B>(a);
> if(b)
> {
> b.boo();
> }
> else
> {
> throw new TypeCastError("Expected B here");
> }
>
> vs
>
> a.boo(); // throws if boo not implemented on a
>
> What's the difference apart from the second one gets me
> out of a lot of typing.

In this case, hardly any. But if you pass in "a" to a function; one checks its type, another doesn't, then: plenty.

Regards,

Terje

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Well trodden path Posted: Sep 22, 2005 4:41 AM
Reply to this message Reply
> I've several years of experience with developing
> applications in PHP, and my experience (as well as my
> coworkers), is that type-related errors stand for a large
> part of our bugs, as well as the difficulty in finding the
> correct place the error originates.
>
Sorry, PHP can't be accepted in a discussion about strong dynamic typing Vs strong static typing, since it barely has any concept of type, and that it's typing system is at best weak.
> > > As I said, the same problem exists in languages with
> no
> > > type declaration on functions: any errors in the
> types
> > of
> > > passed values are only (if even then) reported from
> the
> > > function implementation, not at the call site, where
> > the
> > > error actually is.
> >
> > Yes, but usually you get the stack. For instance, in
> > Smalltalk, you get a walkback (debugger) on the program
> > that usually shows you right where your error is.
> These
> > problems are easy to find and fix.
>
> Not in our experience. Yes, you may walk the stacktrace,
> and inspect each function call and parameters up to
> main(), but it would be much easier if the error message
> pointe to the actual error (as in the function call, not
> inside the function).
>
In the sort example, the stacktrace of "modern languages" (where modern stands for "not PHP or anything even remotely close to it) will point to the test itself, saying that there is an incompatibility with the tested values (Operator not implemented, incompatible operator, or whatever).

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Implicit versus Explicit Dynamic Typing Posted: Sep 22, 2005 6:47 AM
Reply to this message Reply
> > What is with this irrational fear of verbosity?
> Verbosity
> > is a Good Thing.
>
> Oh really?
>
> So you think
>
> Button b = new Button();
> b.addActionListener(new ActionListener() {
> public void actionPerformed(Component target) {
> System.out.println("Button was clicked"); }});
>
> is better than
>
> b := Button new.
> b onClickDo: [:btn | Transcript show: 'Button was
> clicked'].
>
> One of these is hopelessly cluttered with worthless
> boilerplate and one is clear as day.
>
> Verbosity limits your productivity.

Your example is hand-picked and more shows the faults of Java than of explicit typing. Consider another example:

public List<People> getCustomers(SearchFilter filter)
{
...
}

compared to:

def getCustomers(filter):
...

Which one is easier to use/modify 6 months after it was written?

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Implicit versus Explicit Dynamic Typing Posted: Sep 22, 2005 9:38 AM
Reply to this message Reply
> Your example is hand-picked and more shows the faults of
> Java than of explicit typing.

Well, they're all hand-picked. :-)

> Consider another example:
>
> public List<People> getCustomers(SearchFilter filter)
> {
> ...
> }
>
> compared to:
>
> def getCustomers(filter):
> ...
>
> Which one is easier to use/modify 6 months after it was
> written?

My initial reaction is that your naming convetion is poor and you're using type annotations to shore it up. I'm not clear on what this method does. Sounds like it extracts a subset of a list from a bigger list? In Smalltalk you'd write something like:

findCustomersMatching: aSearchFilter

which, you'll note is terribly close to english and can be read aloud. Although, given that you have blocks you'd probably not bother writing a method anyhow and simply do something like

anObject people collect: [:item | item isCustomer ]

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Implicit versus Explicit Dynamic Typing Posted: Sep 22, 2005 10:38 AM
Reply to this message Reply
Likewise, Pythonist would probably use either list comprehension to generate the output list or just use the built-in "filter" function.

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Implicit versus Explicit Dynamic Typing Posted: Sep 23, 2005 7:38 AM
Reply to this message Reply
> My initial reaction is that your naming convetion is poor
> and you're using type annotations to shore it up. I'm not
> clear on what this method does. Sounds like it extracts a
> subset of a list from a bigger list? In Smalltalk you'd
> write something like:
>
> findCustomersMatching: aSearchFilter

Naming conventions can only get you so far. If you imagine a method doing something fairly abstract, you could see how a user of that method might not know offhand what can be done with the object returned. Even the "findCustomersMatching" method might return a collection of Strings, or ids or People objects.

Plus, when modifying the findCustomersMatching, what type of object is the "aSearchFilter"? This is something I have to discover so I can effectively change the implementation.
>
> which, you'll note is terribly close to english and can be
> read aloud. Although, given that you have blocks you'd
> probably not bother writing a method anyhow and simply do
> something like
>
> anObject people collect: [:item | item isCustomer ]

You're making assumptions about the implementation details of getCustomers(SearchFilter). Maybe it can converted to look like this, maybe it can't. Maybe it was written 6 months earlier by someone else in the first place and now you have to determine if it can be converted into a block. And you'd have to find all the places in the code that use it so you could replace those calls with a block.

Of course, all these problems go away when we assume all developers work brilliantly and figure out method and variable naming conventions that make things obvious not only to them, but to you and me.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Implicit versus Explicit Dynamic Typing Posted: Sep 23, 2005 7:55 AM
Reply to this message Reply
> > findCustomersMatching: aSearchFilter
>
> Naming conventions can only get you so far. If you
> imagine a method doing something fairly abstract, you
> could see how a user of that method might not know offhand
> what can be done with the object returned. Even the
> "findCustomersMatching" method might return a collection
> of Strings, or ids or People objects.

If you are writing it, you'll know and if you are going to use it, just call it and inspect the result. What's the big deal?

> Plus, when modifying the findCustomersMatching, what type
> of object is the "aSearchFilter"?

I would assume its an object of type SearchFilter.

> You're making assumptions about the implementation details
> of getCustomers(SearchFilter).

I said that - I didn't invent the function - how else to carry forward the discussion?

> Of course, all these problems go away when we assume all
> developers work brilliantly and figure out method and
> variable naming conventions that make things obvious not
> only to them, but to you and me.

You should download Squeak and browse the sources in the image, the code is wonderfully self documenting and would not be helped much by type annotations as the method and variable names themselves reveal the types. The same is true in the Cocoa sources on Mac OS X. Method names reveal the types. For instance [dictionary setObject: anObject forKey: aKey].

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Method Names reveal the type Posted: Sep 23, 2005 9:26 AM
Reply to this message Reply
>
> If you are writing it, you'll know and if you are going to
> use it, just call it and inspect the result. What's the
> big deal?

That is a big deal. I think maybe I'd do that 5 times before I got disgusted with that process. There is no comparison to code where the type information is available on sight.

One might suggest you are using naming conventions to shore up a lack of static typing in the language. If I have a choice of reading code and A) depending on a naming convention to tell me the type of an object or B) a type annotation to tell me the type of an object, I will prefer B because it is more rigorous and more clear. It also leaves room for a different kind of information in my source code via variable/method names that don't have to indicate object type.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Method Names reveal the type Posted: Sep 23, 2005 10:34 AM
Reply to this message Reply
> >
> > If you are writing it, you'll know and if you are going
> to
> > use it, just call it and inspect the result. What's
> the
> > big deal?
>
> That is a big deal. I think maybe I'd do that 5 times
> before I got disgusted with that process. There is no
> comparison to code where the type information is available
> on sight.
>
> One might suggest you are using naming conventions to
> shore up a lack of static typing in the language. If I
> have a choice of reading code and A) depending on a naming
> convention to tell me the type of an object or B) a type
> annotation to tell me the type of an object, I will prefer
> B because it is more rigorous and more clear. It also
> leaves room for a different kind of information in my
> source code via variable/method names that don't have to
> indicate object type.

The difference comes when you want to change things. In some ways, spreading type annotations throughout a code base is like taking a piece of machinery that you expect to reconfigure and squirting glue into it.

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Method Names reveal the type Posted: Sep 23, 2005 11:12 AM
Reply to this message Reply
> The difference comes when you want to change things. In
> some ways, spreading type annotations throughout a code
> base is like taking a piece of machinery that you expect
> to reconfigure and squirting glue into it.

I would say it's more like fixing everything together with velcro - when you "change things", the things that break as a result make a loud ripping sound and it's easy to locate the problems.

Oh, I know, you have unit tests for everything and they'll tell you everything that broke. I have no answer for that except enormous envy of your good fortune.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Method Names reveal the type Posted: Sep 23, 2005 11:22 AM
Reply to this message Reply
> > The difference comes when you want to change things.
> In
> > some ways, spreading type annotations throughout a code
> > base is like taking a piece of machinery that you
> expect
> > to reconfigure and squirting glue into it.
>
> I would say it's more like fixing everything together with
> velcro - when you "change things", the things that break
> as a result make a loud ripping sound and it's easy to
> locate the problems.

Or like a large bandaid on a hairy arm. You have to pull it off slooooowly. :-)

> Oh, I know, you have unit tests for everything and they'll
> tell you everything that broke. I have no answer for that
> except enormous envy of your good fortune.

True, not everyone has them, but in a way aren't tests more flexible than type systems? If we looked at it from an a priori software engineering point of view, isn't it odd to couple the structure of code to its semantic constraints? Yes, type systems give us universal quantification: "for all class X" but there are constraints which don't tie to all. Tests can deal with those, and I suspect that some of the static checks that aspect systems have might be a good way of moving forward also. If you want constraints on a particular area of a program, create them externally and apply them or not during compilation.

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

Re: Method Names reveal the type Posted: Sep 23, 2005 12:58 PM
Reply to this message Reply
> > > The difference comes when you want to change things.
> > In
> > > some ways, spreading type annotations throughout a
> code
> > > base is like taking a piece of machinery that you
> > expect
> > > to reconfigure and squirting glue into it.
> >
> > I would say it's more like fixing everything together
> with
> > velcro - when you "change things", the things that
> break
> > as a result make a loud ripping sound and it's easy to
> > locate the problems.
>
> Or like a large bandaid on a hairy arm. You have to pull
> it off slooooowly. :-)

Sigh. Very colorful and flip, but like your first analogy you're not actually saying something meaningful.

>
> > Oh, I know, you have unit tests for everything and
> they'll
> > tell you everything that broke. I have no answer for
> that
> > except enormous envy of your good fortune.
>
> True, not everyone has them, but in a way aren't tests
> more flexible than type systems? If we looked at it from
> an a priori software engineering point of view, isn't it
> odd to couple the structure of code to its semantic
> constraints? Yes, type systems give us universal
> quantification: "for all class X" but there are
> constraints which don't tie to all. Tests can deal with
> those, and I suspect that some of the static checks that
> aspect systems have might be a good way of moving forward
> also. If you want constraints on a particular area of a
> program, create them externally and apply them or not
> during compilation.

I don't know anyone who has them. The flexibility of tests means mostly that they don't get written at all - that's how flexible they are. Also, a unit test that exists somewhere in the codebase can't easily help you uncover the object types in the code you're looking at right this moment.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Method Names reveal the type Posted: Sep 23, 2005 1:06 PM
Reply to this message Reply
> I don't know anyone who has them. The flexibility of
> tests means mostly that they don't get written at all -
> that's how flexible they are.

And, you called me flip? :) Seriously, if you're interested in finding teams that have extensive unit tests, it's pretty easy to do and worth looking into.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: Method Names reveal the type Posted: Sep 23, 2005 1:07 PM
Reply to this message Reply
> The difference comes when you want to change things. In
> some ways, spreading type annotations throughout a code
> base is like taking a piece of machinery that you expect
> to reconfigure and squirting glue into it.

Yep. That's where type inference helps. Instead of having to spread type annotations everywhere, the type specifications can be limited to interface specifications. When you change the specification, the type checker will be able to point you to the places where the expected and actual types do not match.

Flat View: This topic has 95 replies on 7 pages [ « | 2  3  4  5  6  7 | » ]
Topic: Bridging Static and Dynamic Typing Previous Topic   Next Topic Topic: Where Did All the Beautiful Code Go?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use