4
$\begingroup$

My question is basically how one can produce a python program from a functional programming language such as Lean or Haskell.

Personally, I am attracted to the functional programming style and some of the special capabilities (such as theorem proving). However, in practice, mature scientific computing packages are often written in python or some other imperative languages.

So I am wondering, if I write a small library (e.g. for matrix or numerical computation) in Lean (or Haskell), is there a good way to translate these into python code that use scientific libraries such as numpy and pytorch? What needs to be done conceptually?

More specifically, is this task a string-to-string translation from Lean to Python? Or, does it involve analyzing the syntax of both the source and the target languages, and translate between the syntax? Or does it require something else?

In the imperative world (more or less), I know that one can start from a language like Haxe and translate to the python target and many other targets, probably because Haxe and these target languages are quite similar. But I am not sure Lean (or other functional languages) has this kind of capabilities.

I realize that this question is a bit general. What I am interested is knowing (the principles of) how to generate python code or translate into python from a functional language like Lean. If I write a small library of matrix computation in Lean, how would I generate the corresponding python code? What is the proper way?

$\endgroup$
4
  • $\begingroup$ If you just want a one-off translation of a specific (smallish) codebase, and you want it to be idiomatic and readable in the target language (not the unreadable spaghetti that generated code typically is), the traditional way is to translate it by hand. $\endgroup$ Commented 21 hours ago
  • $\begingroup$ Does the Python code need to be idiomatic, or rather the process of generating it? $\endgroup$ Commented 18 hours ago
  • $\begingroup$ @KarlKnechtel For my purposes, the python code is smallish, and just need to get job done. I am interested in finding a sustainable way of generating it. I thought about generating strings of python, but thought that may be naive and error-prone. Hence the question here. $\endgroup$ Commented 11 hours ago
  • 1
    $\begingroup$ Are you concerned with python for the convenience of python programmers (as IMSoP assumes with his recommendation of FFI)? Or does your library depend on numpy (or pytorch or other existing scientific computing code with a python API)? $\endgroup$ Commented 24 mins ago

2 Answers 2

5
$\begingroup$

To convert a Haskell program to pure Python code, you could in theory:

  1. Identify the subset of Haskell functionality which your program needs
  2. Define an intermediate representation which abstracts that functionality away from Haskell-specific syntax (e.g. expands "syntax sugar" into multiple semantic steps)
  3. For each instruction in that intermediate representation, either a) identify a direct correspondence to Python syntax; or b) create an emulated implementation in Python
  4. Convert the Haskell program to the intermediate representation
  5. Convert the intermediate representation to pure Python code

This is roughly how "asm.js" (a predecessor of WebAssembly) worked - a subset of JavaScript was identified which could be used as the instructions of a virtual machine; compilers such as Emscripten compiled to that language as though it was a machine language.

However, this is probably not the best way to achieve your aim.

Your described use case does not require pure Python code, it requires code you can call from Python. The usual way of achieving this kind of inter-operability is using "bindings" or "foreign function interface" ("FFI") wrappers.

Large parts of libraries like NumPy and SciPy are written in various language like C, C++, and (perhaps surprisingly) Fortran, rather than Python. Since the aim in this case is performance, converting to Python code would defeat the purpose - it would execute slower than hand-coded Python for the same algorithms.

Instead, the compiled code is made available to Python functions via "extension modules".

So your actual process would look more like this:

  1. Compile your Haskell program to native machine code
  2. Create a C header which exports function for calling into that compiled code
  3. Create a Python extension module which exposes those entry points to Python programs
  4. Write and execute a Python program making use of the module

From a theoretical point of view, what you are doing is converting both the Haskell and Python code to a third language, which in this case is the machine language implemented by your hardware. In other cases, the target language might be JVM bytecode, .NET IR, or WebAssembly.

$\endgroup$
3
  • 2
    $\begingroup$ "a virtual machine was written in pure JavaScript which emulated a specific machine language" - I'd rather phrase that as "a subset of JavaScript syntax was identified that could be used as machine language instructions of a virtual machine". $\endgroup$ Commented 19 hours ago
  • $\begingroup$ @Bergi Fair point - I assumed there was more of a helper library required to run asm.js than is apparently the case. I've updated the wording, do you think that's a reasonable description now? $\endgroup$ Commented 11 hours ago
  • $\begingroup$ Yes that's perfect, thanks $\endgroup$ Commented 9 hours ago
0
$\begingroup$

What you want to achieve (create an idiomatic Python library but actually write it in Haskell or Lean) is most likely impossible or not achievable with reasonable means.

First of all, "idiomatic" implies that the target library should use structuring and naming conventions which are probably foreign to the source language. For example, many Python libraries use modules, classes, try to be compatible with the calling conventions and data formats of related libraries etc.

Even if you had some tool that could translate some functional language into "equivalent" Python code it would most likely not know how a well-designed library interface in Python should look and how to build one.

Using lower-level libraries such as numpy or pytorch would additionally require that this tool understands the intent of your functional code (which probably does not call a compatible library) and creates code that uses these libraries to achieve the functionality that your library should provide.

In a way, that's what proponents of code-writing generative AI systems hope to achieve. IMHO, we're not there yet, not even close.

So if your goal is to create a pythonic math library, just write it in Python, perhaps using the experience you've gained writing similar code in functional languages to guide your design decisions. Waiting for the magical tool that does this for you is most likely not going to work, and dedicating your career to creating such tools is not much more promising.

New contributor
Hans-Martin Mosner is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
$\endgroup$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.