views:

263

answers:

3

Is there any programming language (or type system) in which you could express the following Python-functions in a statically typed and type-safe way (without having to use casts, runtime-checks etc)?

#1:

# My function - What would its type be? 
def Apply(x):
    return x(x)

# Example usage
print Apply(lambda _: 42)

#2:

white = None
black = None

def White():
    for x in xrange(1, 10):
        print ("White move #%s" % x)
        yield black

def Black():
    for x in xrange(1, 10):
        print ("Black move #%s" % x)
        yield white

white = White()
black = Black()

# What would the type of the iterator objects be?
for it in white:
    it = it.next()
A: 

When it comes to example #1, you would have to specify the return type of Apply(), and then all functions x that you pass also must return this. Most statically typed languages would not be able to do that safely without checks, as the x function you pass in can return whatever.

In example #2 the type of the iterator objects are that they are iterators. If you mean what they return, they return iterators. I don't see why that wouldn't be possible in a static system, but maybe I'm missing something.

Lennart Regebro
Iterators are also generic since you need to know the type of the value it contains (Iterator<int>).
Dario
contains? Why? You need to know what they return, and in this case they return another iterator.
Lennart Regebro
Wait, you mean that we can't be sure that the iterator the iterator returns returns an iterator, and that's true.In short, no, in a static language, if use generic functions and pass them around, then no, you don't know what they return. In fact, this is typically something you do in a static language when you end up needing dynamic functionality. ;)
Lennart Regebro
+4  A: 

1# This is not typeable with a finite type. This means that very few (if any) programming languages will be able to type this.

However, as you have demonstrated, there is a specific type for x that allows the function to be typed:

x :: t -> B

Where B is some concrete type. This results in apply being typed as:

apply :: (t -> B) -> B

Note that Hindley-Milner will not derive this type.

2# This is easy to represent in Haskell (left as an exercise to the reader...)

jwoolard
To #2: Could you give a concrete example? I think one would implement this in Haskell in a quite different way (monads/continuations), but wouldn't typing the iterators be the same problem as in #1?
Dario
+2  A: 

I found a Haskell solution for #1 using Rank-N-Types (just for GHCi)

{-# LANGUAGE RankNTypes #-}
apply :: (forall a . a -> r) -> r
apply x = x x

apply $ const 42 -- Yields 42
Dario