Python 1.6 The balanced language
Alex Martelli
aleaxit at yahoo.com
Wed Sep 6 04:58:35 EDT 2000
More information about the Python-list mailing list
Wed Sep 6 04:58:35 EDT 2000
- Previous message (by thread): Python 1.6 The balanced language
- Next message (by thread): Python 1.6 The balanced language
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
"Suchandra Thapa" <ssthapa at harper.uchicago.edu> wrote in message news:slrn8rb7aa.92u.ssthapa at hepcat.uchicago.edu... > Manuel Gutierrez Algaba <thor at localhost.localdomain> wrote: > >On Tue, 5 Sep Alex Martelli <aleaxit at yahoo.com> wrote: > >> > >>You do have the notion of typeclasses in Python: "a sequence", > >>for example, or "a file-like object"; you just lack the way to > >>*EXPRESS* this notion simply, directly, and explicitly _in the > >>language itself_. So you express it in docs & comments, but > >>those are often not as precise as one would wish (and as an > >>expression in a formal language might make things): when > >>somebody says 'you pass a file-like object', what methods are > >>going to be called on it -- write? read? writelines? readlines? > >>close? _Good_ docs would say that -- but why not have a > >>way to say it in the language itself? > > > >No, an object that implements those methods required to be > >considered a sequence is not a type(object )= sequence > > > >Fortunately, the notion of objects that accomplish certain > >behaviours is far more general and flexible than types. > > I think Alex was trying to make the point that the notion > of a type class captures the idea of specifying that a certain > object needs to have certain properties. For example, in Of course -- it's ONE of the thing it does. Further (a point I had not mentioned in the above quote), a typeclass offers one of the best and most elegant way to do 'mixin' kinds of jobs: help the programmer when N methods may be defined in terms of each other. The technique is well-known, and well worth knowing since it also applies to Python, so, here's an example: In Python, you could do this (relying on inheritance of implementation, and overriding, exclusively): class WritableFileMixin: def write(self, stuff): self.writelines((stuff,)) def writelines(self, stuff): for stiff in stuff: self.write(stiff) These two mutually recursive methods do not appear very useful, do they?-) But, they *are*! The usage convention is that a user class, that wants to implement a writable-file-like-object, inherits from the mixin and overrides EITHER of the two methods; automatically, then, the other method will be defined in terms of the overridden one. It's of course OK to override both, but then it's the programmer's concern to ensure the semantic consistency is kept; this might be useful basically for efficiency in some cases (avoiding an unneeded indirectness). Deriving this while overriding neither method is a violation of protocol that will lead to a serious runtime error (a stack-overflow due to unbounded mutual recursion) if either method is ever called. Pity there is no way to express this protocol in the Python language: it must be left to docs and/or comments *exclusively* (hmmm, I wonder if a metaclass or extensionclass might in fact be used to optionally check the protocol -- it would still be at runtime, of course, but, at least, the usage error would be diagnosed much earlier and in a possibly more direct/usable way; this bears thinking...). Anyway, a typeclass would directly both express 'the type implements these methods', AND offer implementation help when 'deriving' a type from the typeclass. > Haskell type classes are used to specify what types can be tested > for equality and to define how to test these types for > equality (through the use of an instance declaration). I think you're one metalevel off here -- it's not that _types_ can be tested for equality, but rather _two objects both belonging to a type_ (which instances Eq) can be so tested. It's unfortunately easy to verbally slip between metalevels when discussing this (I'm sure I've committed several such errors myself in these discussions). > >>Now THIS is 'wasting the possibilities some functions > >>may provide' -- because the language is not expressive > >>enough to supply a notation for the typesystem it is > >>in fact using... > > > >Ok, in python apart from ints and char , we don't use types, > >not at all, we don't need them and they're ugly. If we really > >need to do some checkings we can check the properties of the > >object, that is much flexible and exhaustive than type. > > But typeclasses capture the notion of needing certain > properties for given types. With static type checking, you > gain something over a runtime check since you don't need to > keep type information and don't need to deal with runtime errors. Well, you still do need to deal with SOME 'runtime errors', aka (synchronous) 'exceptions', but if the compiler can do some of that work for you earlier, it does lessen your runtime burden a bit, yes. However, in a Python context I don't see the runtime-efficiency as being the paramount consideration; rather, "expressive power" seems to me to be more important and Pythonic. Explicit is better than implicit -- one of the Python mantras. Being able to say *in the language* "and this here argument will need to implement these here methods" would let the programmer make explicit what currently must be left implicit -- I would see it as _more Pythonic_, even if only modest code-generation benefits ensued (Python is so nicely fluid & dynamic -- features we *DON'T* want to lose! -- that compile-time ensuring things is in general a very hard problem; so the compiler would have to insert the runtime-checks -- still a bit better than having to do them by hand, mind you:-). Something akin to a typeclass would be a pretty nice, usable way to let these kind of things be explicitly expressed. > Even with your concept of just checking for properties, you still > need to insert code into the compiled version that deals with the case > where you don't have the proper method. Yes, and in practice full checking may well turn out to be too hard -- it's not enough that 'foo' has a 'write' method, that method must be callable with exactly one argument, for example. In practice, a try/except around the foo.write(whatever) call may be better (assuming you have any idea of what to do when the call attempt fails in various ways -- a non-Pythonic but practical mantra is "don't check for errors that you don't know what to do about":-). > >>Having a *good* typesystem need be nothing as confining as > >>that; you don't seem to have much experience using such > >>typesystems -- I strongly suggest you try out a few before > >>expressing such trenchant judgments. > >> > > > >I have programmed in C for countless years, a bit in C++ and > >a bit in Java. And in Pascal . And yes, I won't like types, ever. > > > >The two brightest languages that come to my mind ( LISP, python) > >don't use types. > > C/C++, Java and Pascal don't really have good type systems. Agreed (and neither does Eiffel IMHO -- too much burden being placed on the single idea of 'class', no type-inference, &c). > The compiler can't figure out types without explicit declarations. > With a good type system, your compiler can use type inference to > figure out what types to expect and just needs explicit type declarations > at a few places as hints. For example in Haskell code like, > > data Color = Red | Green | Blue > deriving Eq > > permute x | x == Red = Green > | x == Green = Blue > | x == Blue = Red > > asking for the type of permute returns permute :: Color -> Color. The compiler > is smart enough to figure out that x needs to belong to the color type and > that permute returns a color. This is in contrast to C/C++ where you would > need to define permute with explicit type declarations. If you compare this > to the equivalent python or lisp code, they are remarkably similar. Plus, in Haskell you *MAY* add an explicit assertion about permute's type IF YOU WANT: it's up to you, as a programmer, to decide whether here it is worth being explicit (for clarity, to help future readers of your code understand what's going on, for example) or whether it's better to just let type-inference work by itself. Alex
- Previous message (by thread): Python 1.6 The balanced language
- Next message (by thread): Python 1.6 The balanced language
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list