Functional programming language for Python programmers and friends

Just for you, and this time in the Pythonesque rendering.

module main:
    import std (range)
    import std.io (printf, IO)

    # print the Fahrenheit-Celcius table for fahr = 0, 20, ..., 300
    function main(mutable IO io):
        Int lower = 0    # lower bound
        Int upper = 300  # upper bound
        Int step = 20    # step
        for Int fahr in range(lower, upper, step):
            Double celcius = 5 * (fahr - 32) / 9
            std.io.printf(io, "%3d\t%6.1f\n", fahr, celcius)

It does not really look like it, but this language is purely functional. It represents side effects using unique types. If you declare a mutable parameter, you basically declare a unique input parameter and a unique output parameter.

I’m also giving you a list implementation

module std.container.list:

    ## The standard singly-linked list type
    type List[E]:
        Nil                     ## empty list
        Node:
            E value             ## current value
            List[E] next        ## remaining list
 


And yes, both languages should be able to be represented using the same abstract syntax tree. The only change is the replacement of the opening curly brace by a colon, the removal of the closing curly bracket and semicolons, the replacement of C-style comments with Python-style comments and the requirement of indentation; oh and the for statement gets a bit lighter as well.

5 thoughts on “Functional programming language for Python programmers and friends

    1. Not sure that would be a good idea. Brackets and whitespace are a sore point and I am glad to see them gone, but the order of type to identifier should probably come from languages where type actually matters, like C. As in that looks fine to me. But otherwise, I would recommend thinking about Zen of Python and see where that could be aplicable in language design. It has helped me a lot to create easy to maintain Python software.

      1. Go and Haskell are good examples where the type comes after the identifier. Given that typing should obviously be optional in any good functional programming language, and that Python’s functions annotations are used for annotating Python functions with types (actually also other stuff, but usually types), they seem like a good idea for a Pythonic syntax.

        The following example (with slightly revised type constructor syntax [in function notation, to avoid the block, as that works against pattern matching, and ‘def’ instead of ‘function’ for more Pythonicness):

        type List[E]:
            Nil
            Cons(car: E, cdr: List[E])
        
        def first(list: List[E]) -> E throws:
            switch list:
                case Cons(car, cdr): return car
                case Nil: raise EmptyListException("The list is empty")
        
        def rest(list: List[E]) -> List[E] throws:
            switch list:
                case Cons(car, cdr): return cdr
                case Nil: raise EmptyListException("The list is empty")
        

        And yes, the switch statement does pattern matching

      2. The second example also has exceptions. How exceptions will actually appear is questionable, and the keyword in the function signature will not be throws, at least not in Pythonic syntax, but raises.

        And yes, it’s using checked exceptions to some extent, you at least need to declare that you can throw an exception, I think that’s useful. Well, if you do not use explicit types, the compiler should infer that, obviously. I haven’t checked how complicated something like this is, though.

Comments are closed.