Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Tuesday, April 3, 2012

Some type systems are much better than others.

As a shortcut, I previously complained about C and Java's type systems leaving bad impressions. Let's broaden that to the realm of type system research, avoiding useless discussion of the relative merits of this or that programming language as a whole. Some type systems let you express more of the set of valid programs, or different subsets. More out of the theoretical realm, but because we are human, different inference engines are better at figuring out types in different situations.

There is a nice graphic in Gödel, Escher, Bach that illustrates this issue: it displays the universe split into the true and the false, and elaborate structures covered with appendages illustrating “proof”. Of all valid programs¹, many are “typeable”, meaning that we can prove that they are sound, type-wise, with a particular type system; conversely, most invalid programs are not typeable.

However, you might imagine that the fingers stretch into the invalid space on occasion, and they don't cover the valid space entirely either; for any given type system, there are valid programs that are rejected, and there are invalid programs that are accepted.

Not so simple math

The goal of type system research is to both accept more valid programs and reject more invalid programs. Let's consider these three programs in three different languages, which implement one step of a divide-and-conquer list reduction strategy.
     def pm(x, y, z):                # Python
         return x + y - z
     
     pm x y z = x + y - z            -- Haskell
     -- inferred as Num a ⇒ a → a → a → a
     
     int pm(int x, int y, int z) {   /* C */
       return x + y - z;
     }
First, the expressive problem in C is easy to spot: you can only add and subtract ints. You have to reimplement this for each number type, even if the code stays the same.

The Haskell expressive problem is a little more obscure, but more obvious given the inferred type: all the numbers must be of the same type. You can see this with some partial application:
     pm (1::Int)      -- Int → Int → Int
     pm (1::Integer)  -- Integer → Integer → Integer
     pm (1::Float)    -- Float → Float → Float
The Python version works on a numeric tower: once you introduce a float, it sticks. This may be good for you, or it may be bad. If you are reducing some data with pm and a float sneaks in there, you won't see it until you get the final output. So with dynamic promotion, pm works with everything, even some things you probably don't want.

There are adjustments you can make to get the Haskell version to be more general, but this all depends on the kind of generalization you mean. This is a matter of continued innovation, even in the standard library; many commonly used libraries provide alternative, more generic versions of built-in Prelude functions, such as fmap for functors, one of many, many generalizations that work with lists, in this case replacing map.


Footnotes

[1] Use whatever meaning you like for “valid”, but if you want something more formal, perhaps “it terminates” will suffice.

Wednesday, August 5, 2009

Recursive directory creation API

Right way: succeed if directory exists. Examples: GNU Coreutils, Common Lisp.

Wrong way: fail if directory exists. Example: Python.

I should think that if a recursive directory creator thinks that failure in the case of existence of the final directory in the series is an option, it should also fail if the parent exists, and so on, proceeding to fail in the case of the existence of ‘/’, when all else doesn't fail.

Tuesday, July 7, 2009

PLIP #42: Remove Zope dependency

Manage requests, persistence, and scaling directly within Plone, eliminating a system that is confusing to first-time users

Proposed by

Stephen Compall

Seconded by
None as yet


Proposal type
Core

State
being-discussed

Motivation

A frequent complaint of newcomers to Plone deployment and development is the use of Zope to provide features such as HTTP request handling, object persistence, transactional safety, and load sharing. It is difficult enough to learn one large system at a time; by requiring the learning of two large systems, Plone effectively makes things twice as hard for newcomers. It is also inconvenient for users to have to install Python 2.4 when they frequently already have 2.5 or 2.6 installed.

Plone is now large enough that it should be able to stand on its own, without Zope.

Assumptions

This proposal suggests the removal of Zope only. Others have suggested, variously:
  • Removal of Python dependency;
  • Allow extension via CLR;
  • Allow extension via PHP;
  • Portability to abacuses.
This proposal only concerns Zope.

Proposal & Implementation

By removing all imports of Zope Python packages and fixing any problems indicated by unit and user testing, and possibly replacing remaining functionality that Zope might provide with Plone-specific packages, we can remove Zope entirely from future buildouts and installations. A wider variety of Python versions may also be used.

Deliverables

Included are:
  • New versions of all Plone packages with Zope dependencies removed.
  • A new paster to replace ZopeSkel, with a buildout skeleton that does not include the zope2instance recipe.
  • New Plone packages as needed to replace remaining Zope functionality that might be convenient.
  • Replacement of all mention of "products", a decidedly Zope-centric term, with "goodies".

Risks

Users of add-on packages that have not been ported to become goodie-compliant by removing their Zope dependencies may have trouble working with a Plone implementing this proposal, and make take a little time to port.

To mitigate this inconvenience, we might offer a compatibility package, Nine, which provides features of Zope 2 and 3 for Plone 4 add-on goodies that need them.

Participants

The maintainers of the respective packages in Plone Core are responsible for removing the Zope dependencies in their packages. Zope dependencies will be removed from Collective and third-party add-ons as a matter of course.

Progress

Many existing utilities do not call Zope methods and functions at all, and thus may be considered already ported. Many references to Zope do remain in Plone, however.