Why not FP for Money?

Alex Martelli aleaxit at yahoo.com
Sun Sep 26 05:09:15 EDT 2004


Andrew Dalke <adalke at mindspring.com> wrote:
   ...
> Suppose Python3.0 goes the other way and uses decimal as
> the native number type and requires some suffix for floats?
> 
>    x = 3.04      # this is a decimal
>    y = 3.14159f  # this is an IEEE 754 float

I'd like that.  But, playing devil's advocate: there would be no harm
done if 3.04d meant just the same thing as 3.04 without a suffix.

So, e.g., Python 2.5 would let you spell out explicitly 3.04d or 3.04f.
If you didn't, writing just 3.04, that would currently default to the
same as 3.04f for backwards compatibility.  In Python 3.0 the 3.04d and
3.04f forms would remain and bare 3.04 would change meaning -- perhaps
it might be arranged to go through a time where at least optionally
warning would be given (not by default, but with a -W switch or so -- in
"late" Python 2.* warning that 3.04 changes meaning in Python 3.0, in
early Python 3.* warning that 3.04 used to mean something different in
Python 2.*).  So, even though I don't particularly love the proposed
syntax, it seems that at least a good migration path would exist.

> > But you sure find it more convenient to type (1.12+2.9i), don't you?
> 
> My point is that I find it more convient that most
> objects get created via the same call-style interface.
> I would find
> 
>    s = url"http://www.python.org/"
> 
> more convenient to type than
> 
>    s = urllib.urlopen("http://www.python.org/").read()
> 
> Doesn't mean I want it.

While I unfortunately don't think we can get there from here, I
sometimes toy with the idea of making some <name><separator><content>
form be taken by the parser as equivalent to <name>(stringifiedcontent),
basically giving an alternative syntax for calls that's suitable for
literals -- with the semantic twist that the call happens during parse
time and the <name> must be known at that time in some suitable
namespace.

The problem is determining what separator is suitable, how does one tell
when the content ends, etc.  Strawman proposal to show concrete
examples: let's have a 'binary @' like unary @ is used for decorators,
and say content ends at nonescaped whitespace.  Then one could have:

x = d at 3.14 + d at 0.21

meaning

x = d('3.14') + d('0.21')

with the calls done at compile-time if 'd' is previously injected into
some suitable namespace (not __builtins__, I think; rather, some other
special module which is not normally accessed in the usual runtime
lookup rules, so that such names can't be accidentally trampled).

Similarly, s=url at http://www.python.org/ would call such a 'url' named
factory, which in turn could urlopen and read, or whatever.

The alternative syntax <name><string> is also attractive for most uses,
it matches existing u'foo' and r'fee' uses, but has the unfortunate
connotation of 'stringiness' which might make d'3.14' not quite as
attractive as d at 3.14 (personally I like it better, but that's just
because the @ splat is SO ugly;-).  Yet other alternatives might include
parentheses-like separators to indicate compiletime rather than runtime
call (and implied stringification, lexically speaking), say d{3.14} and
url{http://www.python.org}.

One way or another, what I really dream of is an _extensible_ syntax to
get arbitrary factories with names called at compiletime on string
contents, once the names have been registered in the namespace dedicated
to that task.  Yeah, I'm aware that this might be abused to make the
equivalent of a full-fledged macro system, with the attendant problems.
I've toyed also with hypotheses on how to ameliorate that, e.g. making
the dedicated namespace "write-once" -- if any code ever tries rebinding
a name in that space, it gets an exception.  But for all these musings,
"we can't get there from here" IS quite possible.


Alex



More information about the Python-list mailing list