# Functional programming

Steven D'Aprano steve at pearwood.info
Tue Mar 4 06:35:24 CET 2014

```On Tue, 04 Mar 2014 05:37:27 +1100, Chris Angelico wrote:

> On Tue, Mar 4, 2014 at 4:27 AM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>> On Tue, 04 Mar 2014 02:01:47 +1100, Chris Angelico wrote:
>>
>>> This is why it's tricky to put rules in based on type inference. The
>>> programmer's intent isn't in the picture.
>>
>> Of course it is. If I assign 23 to variable x, that signals my intent
>> to assign an int to x. By Occam's razor, it is reasonable to
>> extrapolate that intent to mean "x is an int", rather than "an int, or
>> a list" or "an odd int larger than 7 but smaller than 25", or "any int
>> except 13". Type inference picks the type which involves the fewest
>> additional assumptions. The programmer can always over-ride the type
>> inference by explicitly stating the type.
>
> Yes, and that's fine for most purposes. The problem isn't the inference,
> the problem is when rules are created based on that kind of guess - when
> the programmer's subsequent actions are governed by a guess the compiler
> takes.
>
> x = 23 # Compiler goes: Okay, x takes ints. x += 5 # Compiler: No prob,
> int += int --> int x = str(x) # Compiler: NO WAY! str(int) --> str, not
> allowed!
>
> It's fine and correct to infer that x is an int, x is an int, x is a
> str. It's *not* okay to make the third line a SyntaxError because you
> just put a str into an int variable.

It won't be a Syntax Error, it will be a compile-time Type Error. And,
yes, it is fine. That's the point of static typing! The tradeoff of being
able to detect a whole lot of errors *at compile time* is that you give
up the ability to re-use the same variable for different types in a
single scope. (You can have an x which is a string elsewhere, just not in
this scope where it is an int.)

It's okay if you personally prefer the flexibility and freedom of dynamic
typing. The cost of this choice is that you become responsible for
writing unit tests that ensure that code behaves safely when given
unexpected types. If you choose static typing instead, you get a whole
lot of error checking done at compile time, and likely a lot of compiler
optimizations. But the cost is that you can't write:

x = 23
x += 5
x = str(x)

x = 23
x += 5
s = str(x)

You should, I think, read this:

http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/

[...]
>> That's not type inference. That's ancient and annoying obligatory type
>> declarations as used by ancient languages with primitive type systems,
>> like Pascal and C.
>
> And that's exactly what Haskell apparently has, with homogeneous lists
> and no easy way to say that it can take more types.

That Haskell has homogeneous lists is not a property of the type system,
but a design choice. I'm sure Haskell will also have a tuple or record
type that allows fields of different types.

> Python's handling is: A list can hold anything.
[...]
> Haskell's handling apparently is: A list/array can hold one thing and
> one thing only. That 'thing' can be a union, but then you need to be
> REALLY explicit about which side is which.

Yes.

> It's not possible to
> sub-specify a type (like the "string('a'..'x')" type in Pike that will
> take only strings with nothing but the first 24 lower-case letters - not
> that I've ever needed that), but the compiler can work out everything
> else.

I have not used Haskell enough to tell you whether you can specify
subtypes. I know that, at least for numeric (integer) types, venerable
old Pascal allows you to define subtypes based on integer ranges, so I'd
be surprised if you couldn't do the same thing in Haskell.

The flexibility of the type system -- its ability to create subtypes and
union types -- is independent of whether it is explicitly declared or
uses type inference.

> The way I see it, Python's form is fully dynamic and open, Pike's is
> fully dynamic and the programmer's allowed to explicitly close things,
> and Haskell's is rigidly tight. That's not to say that tight is a bad
> thing (it's probably good for learning under), but personally, I'd
> rather have the freedom.

Hey, I'm a Python programmer! You don't have to sell me on the benefits
of dynamic typing. Before Python, my language of choice was Apple's
Hyperscript, which is untyped -- everything, and I mean everything, is a
string in Hyperscript. It works remarkably well, so long as you don't
care about speed. But even in the late 80s or early 1990s, on single-core
CPUs running at a piddly 7.8 MHz (compared to about 1000 MHz for desktops
today), you could get acceptable performance for a remarkable range of
applications.

But don't be fooled, those benefits aren't free. Static typing has
benefits too.

--
Steven

```