Inefficiency of __getattr__

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Wed Oct 4 05:03:00 EDT 2000


[crossposted]

Wed, 04 Oct 2000 05:41:01 GMT, Kragen Sitaker <kragen at dnaco.net> pisze:

> OK, so you agree that silent coercions cause problems in some cases
> in C++, some of which cases are built into the language.
> 
> So what's the advantage of static typing over dynamic typing?

More errors are fixed at compile time, before testing. Easier to
make changes, where all uses of something need to be replaced with
another construction.

Sometimes tools in the language are more expressible because of
static typing, sometimes less. The "more expressive" part relies
on the ability to determine the meaning by the context of usage.

My favorite languages, Haskell and OCaml, have static typing and no
implicit coercions at all.

> Does it help you catch bugs, and if so, which ones?

It certainly does help. It's rare that a large piece of newly written
code compiles the first time. OTOH it usually works the first time
once compiles.

Most bugs are trivial: spelling errors, forgetting about an argument
or putting too many of them (e.g. in recursive functions, common in
functional programming, where the "interface" of that helper function
is very local and easily changing), forgetting about importing a
module, misusing the result of a function which is available in a
different form than I remembered (e.g. is tupled with something) or
prividing an argument in an inappropriate form (e.g. a list of things
was expected), using a value which is not available in the given scope.

Explicit type signatures are optional in both Haskell and OCaml, but
Haskell encourages to write them more than OCaml. The effect is that
when there is a type error in an OCaml program, sometimes I have to
spend some time finding it, often by adding explicit type signatures
to see if a function is incorrectly defined or incorrectly used.

It clearly indicates that if the program was written in a language
without static typing *in the OCaml's style*, it would be hard to find
that bugs basing only on runtime behavior, even if tests covered the
whole code.

One thing applying especially to Haskell: it's harder to add debugging
output. It's the basic functional nature, returning expressions
instead of performing computation steps. So finding bugs at runtime is
harder, and finding bugs at compile time is easier than in imperative
languages.

I think that the functional style encourages operating on a bit higher
level of abstraction: combining partially applied functions themselves
instead of stating what the result is when applied to an argument,
using wrappers like foldr (Python's reduce) instead of explicit
recursion, using monads, using custom higher order functions, passing
lists instead of iteration. Also more values are passed explicitly
instead of relying on an implicit state.

In this style there are more "levels" of objects present at the same
time: plain values, functions of varying arity, monadic actions, lists,
tuples. Programs are shorter but denser. To manage this complexity of
flow control and passed state, a static type system is very helpful:
it is easy to make mistakes by confusing those "levels", and they
are almost always catched at compile time.

-- 
 __("<  Marcin Kowalczyk * qrczak at knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZASTĘPCZA
QRCZAK



More information about the Python-list mailing list