27 comments

[ 2.8 ms ] story [ 61.4 ms ] thread
Interesting approach to bootstrapping a library ecosystem :) I wonder if this works on any nontrivial Python packages.
Still seems to fail on a trivial one, so I'm guessing that's a "no".

Edit: Got a quick fix from the author and got a result which is not compiling correctly out of the box, but I'd be happy to finish manually. Definitely saves a lot of typing.

I have long thought that we need a generic way of expressing foundational library code (datetimes, regex, math, json, http, etc) that could easily be lifted to other nascent languages. At minimum, the unit tests behind battle-tested packages that have encountered all of the edge cases that a green-field design is going to miss.
For many languages isn't that the FFI to C?
Kind of but not really? That requires considerable effort adapting the target for anything written in a language with first-class object support and is woefully unergonomic.
Agreed C isn't an ergonomic one. A better one would need manual memory management, though, to avoid running an additional gc. In contrast to the target languages, it would need at least as much type information.

I haven't worked with Rust, but I wonder if that will move into this space.

Could webassembly provide that? As far as I understand it can be seen as a target callable from any runtime (C, rust, python, the browser...) so a new language could implement wasm and all its libraries could be used?
There was a time when Parrot was going to be the one ring.
If I understand correctly, OpenVMS made this straightforward—it was easy to call code written in one language from code written in another language.

What we have today:

1) stick to languages which target a common VM,

2) hope your language supports FFI for the library's language, or

3) microservices, in the old-school fashion (piping to/from Unix binaries) or the new-school fashion (HTTPing JSON to/from containerized applications).

Epic! But... why?
Crystal is supposed to be fast, and type safe, with an easy syntax. This might help people try it, because they still can fall back on python, and get hooked.
It is insanely fast. Some text munging python script once told me it would take 14 hours. I ported it to Crystal in 40 minutes, and it completed ten minutes later.
I've only looked at it, but that is a good story to convert Python programmers.
To be fair, there are lots of tricks to get stuff moving faster in Python, usually by invoking some module that delegates to native code. This was, IIRC, doing everything in the most straightforward way. But I did port the source code essentially line-by-line and this was within the first week of using Crystal. Any grave (i. e. measurable in O-notation) errors would have just carried over, and no sophistication was involved in my Crystal code.
As other have suggested, this could be a great way to port some of Python's huge ecosystem to Crystal.
Yeah, that's the thought - reduce the friction for converting Python to Crystal. I wouldn't expect many non-trivial programs to work out of the box, but if this tool reduces the time needed to port something, it's served its purpose.
What is the use case?

FYI All I know about crystal is that it's Ruby with Python style syntax.

> it's Ruby with Python style syntax.

It's not. It's a language on its own with Ruby-style syntax and close-but-not-same semantics.

(comment deleted)
You have some Python code but you don't want it to be slow and full of type errors.
Python to Crystal??! But Crystal is a statically compiled version of Ruby, not Python.
It's not a version of Ruby. And Ruby and Python are roughly equivalent, so if you can convert one, you can likely convert the other. (see also https://github.com/whymirror/unholy)
"roughly equivalent"? They're chalk and cheese to me. Python metaprogramming, anyone? Each? Blocks? Real lambdas? Don't get me started. I'm not saying you can't do it, just why would you want to when you end-up with something that doesn't resemble what you started with?
Roughly equivalent as in they have very similar object model and each construct is trivial to convert into the other. each is just a fancy for with new scope, blocks can be replaced with local functions, etc. They don't have anything that's not a trivial transform away (like for example: tail calls, callcc, macros, compile time transformations, ...).

I mean, you may prefer one of these:

    foo.each { |i| ... }
    for i in foo: ...
but after fixing up the scope issues, they're the same thing.
This project started with this request: https://github.com/crystal-community/crystal-libraries-neede...

However, it is heavily based on the (abandoned?) py2rb work by Naitoh which I made enhancements to.

IMO, Rubyists should have an easier time with Crystal syntax since it is more similar. Also, the likelihood of having type annotations in Python is much higher than Ruby because type annotations have been around longer in Python, iirc.

But the momentum behind gradual typing in Ruby is much greater due to the input from Stripe and Shopify.