# Python porting to Julia resources

**URL:** <https://discourse.julialang.org/t/python-porting-to-julia-resources/31953>\
**Category:** Machine Learning\
**Created:** [December 7, 2019, 12:42am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953 "2019-12-07T00:42:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vphom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vphom/32/11699_2.png) [@vphom](https://discourse.julialang.org/u/vphom)\
**Post date:** [December 7, 2019, 12:42am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/1 "2019-12-07T00:42:00Z")

</div>

I’m trying to port an Machine Learning app that was written in Python using Pytorch to Julia and I’m a newbie in Julia.  
Is there a resource,cheat sheet that show how the same thing work in Julia for examples  
Python Julia  
class ?  
**init**?  
**call**?  
**iter**?  
\*\*kwargs ?  
etc…  
I’ve been reading Julia doc but would take too long I want to get this done a little faster

---

<div class="post-metadata">

**Author:** ![Zach\_Christensen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zach_christensen/32/7220_2.png) [@Zach\_Christensen](https://discourse.julialang.org/u/Zach_Christensen)\
**Post date:** [December 7, 2019, 12:49am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/2 "2019-12-07T00:49:36Z")

</div>

Are you asking for help woth those specific things or a resource for the machine learning functions?

- Classes don’t exist in Julia
- Init isn’t necessary to create structures. Loook at [Constructors · The Julia Language](https://docs.julialang.org/en/v1/manual/constructors/)
- Iterators are pretty broad and what you want to do will depend on the type of iteration.
- You can just write `methodname(; kwargs...)`

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [December 7, 2019, 1:04am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/3 "2019-12-07T01:04:09Z")

</div>

If you intend to actually use Julia besides porting one application, you’ll probably be better off learning Julia properly. The documentation and several available tutorials are available for that. It quickly pays off when you don’t have to consult online forums for simple things.

---

<div class="post-metadata">

**Author:** ![vphom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vphom/32/11699_2.png) [@vphom](https://discourse.julialang.org/u/vphom)\
**Post date:** [December 8, 2019, 12:54am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/4 "2019-12-08T00:54:58Z")

</div>

I thought some one have done this before porting their Python app over to Julia  
they might have some resource that they used willing to share on the net.

---

<div class="post-metadata">

**Author:** ![Zach\_Christensen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zach_christensen/32/7220_2.png) [@Zach\_Christensen](https://discourse.julialang.org/u/Zach_Christensen)\
**Post date:** [December 8, 2019, 1:35am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/5 "2019-12-08T01:35:35Z")

</div>

I’m sure similar things have been ported over but it’s unclear what you would need. There’s not a general “How to convert Python to Julia” guide (although I’m sure there’s some sort of numpy to julia guide out there).

There’s not an exact PyTorch equivalent, but there are several neural net libraries. You can get a lot done with Flux.jl. I’m not personally familiar with Knet.jl, but I’ve heard it’s well implemented and easy to use. You could also use Tensorflow.jl which you might prefer if you’re familiar with Tensorflow but want the benefits of Julia.

Those libraries will give you a good idea of how to port standard layers that you’re probably use to in other ML libraries, but Julia takes an entirely different approach than the Python mega libraries out there. With Julia you can have many libraries be interoperable but still be fast. In Python each library has to reinvent a lot of stuff for their own use. In other words, you will likely need lots of tools that are much less involved than learning all of PyTorch.

---

<div class="post-metadata">

**Author:** ![vphom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vphom/32/11699_2.png) [@vphom](https://discourse.julialang.org/u/vphom)\
**Post date:** [December 8, 2019, 2:23am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/6 "2019-12-08T02:23:15Z")

</div>

Thank for the suggestion.

---

<div class="post-metadata">

**Author:** ![Zach\_Christensen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zach_christensen/32/7220_2.png) [@Zach\_Christensen](https://discourse.julialang.org/u/Zach_Christensen)\
**Post date:** [December 8, 2019, 3:12am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/7 "2019-12-08T03:12:43Z")

</div>

No problem. Feel free to ask more questions here. The Julia community is very friendly to newcomers.

---

<div class="post-metadata">

**Author:** ![klaff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/klaff/32/7637_2.png) [@klaff](https://discourse.julialang.org/u/klaff)\
**Post date:** [December 8, 2019, 11:38pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/8 "2019-12-08T23:38:55Z")

</div>

You may find this useful: [Noteworthy Differences from other Languages · The Julia Language](https://docs.julialang.org/en/v1/manual/noteworthy-differences/#Noteworthy-differences-from-Python-1)

---

<div class="post-metadata">

**Author:** ![frtps](https://avatars.discourse-cdn.com/v4/letter/f/73ab20/32.png) [@frtps](https://discourse.julialang.org/u/frtps)\
**Post date:** [December 9, 2019, 12:58am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/9 "2019-12-09T00:58:07Z")

</div>

I have recently worked through porting Lark (a Python parsing package) to Julia. Some little things to be prepared for:

- A single character ‘a’ and a single character string “a” are different in Julia, unlike Python. Equality tests in Julia will therefore fail where they succeed in Python. In general, make sure you know when a Julia function returns a character. You can add a method in Julia to make them equal, of course.
- Do you know how the syntax `a,=b` works in Python? In Julia? Check it out!
- Make sure you know the difference between `push!`, `append!` in Julia and Python’s `append`, `extend`, `+=`. Hint: `append` works differently.
- Python code loves things like `if b:`, where None and empty both count as `False`. `nothing` and an empty string/list/tuple are not `false` in Julia.
- Make sure that **both** Julia `hash` and `==` behave the same way as Python for your complex structures. I spent the most debugging time discovering that functions like unique!, Set(), Dict() had slightly different ideas as to the contents of lists and sets than I had.
- The Julia “join” function takes the joining string as the final argument, not the first.

To answer your original question, I do not know of a cheatsheet, and I suspect each Python codebase will be approached differently depending on the particular coding philosophy.

The strategy I took with ` __init__ ` was to define one or more outer constructors for that type.

`**kwargs` are handled by “splatting”" and “slurping”.

The only use of ` __call__ ` in my source codebase appeared to be a way of passing around a closure in an object…so I just created a closure in Julia.

I didn’t have to work with ` __iter__ `. Python generator functions (containing `yield`) can be modeled using unbuffered Julia Channels. But beware: as Python is single-threaded, the code after the `yield` is not executed until whichever code was yielded to calls back into the generator. However, in Julia code following a `put!` is executed as soon as the value is read, and runs right up until the next `put!`. So, if the Python code calling the generator sees fit to mutate any structures that the generator is using after it has received the value but before it calls for the next value, then the Julia code may diverge in behaviour, as it will be running in parallel with the generator, unlike the Python code. The way I solved this was to have a two-way channel so that the calling function had to send a dummy value back to allow calculations to proceed.

None of this is to imply that it might not be better to restructure the Julia code to use more natural Julia structures. As this codebase was not my own, I didn’t feel confident in getting too fancy until I had all the tests passing.

---

<div class="post-metadata">

**Author:** ![vphom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vphom/32/11699_2.png) [@vphom](https://discourse.julialang.org/u/vphom)\
**Post date:** [December 9, 2019, 11:44pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/10 "2019-12-09T23:44:10Z")

</div>

Thank, this is what I’m looking for you should put this on cheat sheet or web site,so those of us that come after you don’t have to spend hour debugging them to find out that it works a little differently. May be later when I have more time and better understanding of Julia I’ll rewrite it in Julia

---

<div class="post-metadata">

**Author:** ![vphom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vphom/32/11699_2.png) [@vphom](https://discourse.julialang.org/u/vphom)\
**Post date:** [December 9, 2019, 11:46pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/11 "2019-12-09T23:46:16Z")

</div>

Yes, It’s been helpful, thank.

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [January 19, 2020, 8:24pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/12 "2020-01-19T20:24:42Z")

</div>

I am in about the same position as @vphom - I just started to learn Julia, and I have a small application or two, which I would probably like to port from Python and further develop it in Julia. “Probably” in my case because whether we will really need the applications depends on many circumstances.

So in one case I started with the Python application and tried to port the most computational expensive part of it to Julia, than call it from Python through [pyjulia](https://pyjulia.readthedocs.io/en/latest/index.html). That actually worked on one of the computers, while on another one I couldn’t properly install it. Thus I could port the module function by function and check results against the original program.

To the list of the things to be prepared for (@frtps , thank you for your post), I would like to add one more - the scoping rules as discussed here: [Dicussion on scoping rules](https://discourse.julialang.org/t/scoping-rules-for-try-catch-finally/32617/11) . The nasty thing is that in many cases your `try` blocks and loops would work in Julia just as in Python - because you just happend to initialize the corresponding variable in some way.

As a general remark - from my recent experience: Julia may look familiar on the first glance, but pretty soon you will find out you need to invest time in reading at least a big part of the manual anyway.

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [January 19, 2020, 9:44pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/13 "2020-01-19T21:44:56Z")

</div>

Also:

> <https://gist.github.com/svaksha/bf2b287e85967dcaad03a26d8b1e523d>

---

<div class="post-metadata">

**Author:** ![raff](https://avatars.discourse-cdn.com/v4/letter/r/5e9695/32.png) [@raff](https://discourse.julialang.org/u/raff)\
**Post date:** [March 20, 2020, 2:22am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/14 "2020-03-20T02:22:12Z")

</div>

I recently wrote two libraries with the same functionalities in Julia and Python.  
In both version, I tried to make them as Julian and Pythonist as I could.  
This includes some design considerations like inheritance (normal in Python) vs composition (normal in Julia), as well as class design and the use of macros in Julia.  
There are also some differences in python vs julia syntax, like you mentioned: init, call, iter, kwargs.

Hopefully it can help. Here are the links:  
Julia version: [GitHub - rizalzaf/AdversarialPrediction.jl: Easily optimize generic performance metrics in differentiable learning.](https://github.com/rizalzaf/AdversarialPrediction.jl/)  
Python version: [GitHub - rizalzaf/ap\_perf: Easily optimize generic performance metrics in differentiable learning.](https://github.com/rizalzaf/ap_perf)

I also realized that those projects may not be the best way to write code in the best Julian and Pythonist way. Let me know if there is any suggestions.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [March 20, 2020, 8:18am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/15 "2020-03-20T08:18:09Z")

</div>

A short comparison of the structure / concepts between both languages, as far as I understood, maybe this is helpful for you. Please correct me if I am wrong.

| Python name | Python meaning | Julia name | Julia meaning |
| --- | --- | --- | --- |
| `def f(x,y):` | named function - duck-typing, no polymorphism | `fuction f(x,y)` | duck-typing, multiple dispatch to methods |
| `lambda x: x` | anonymous function | `(x) -> x` | anonymous function |
| `class MyClass(Parent)` | classical OOP class, multiple inheritance | `struct MyStruct{TypeParameters} <: AbstractParent` | data and constructor only, types inside struct can be parametrized, can inherit only from abstract types |
| method | function that belongs to a class (single dispatch on first argument `self`) | method | function implementation for concete parameter types (multiple dispatch on all arguments) |
| `def __init__ (self, x):` | constructor of a class, one per class | `MyStruct(x)` | Constructor method (multiple constructors can be defined, selected using multiple dispatch) |
| module | namespace - defined as a single `.py` file | `module` | namespace - defined independenly of file strucutre |
| package | directory with ` __init__.py` file | NA | directory structure independent of logical structure |
| package | bundled and installable, e.g. using `pip`, `conda` | package | includes dependencies (`Project.toml`), installable using `Pkg`, very light-weight |
| `@decorator` | applies a higher order function to the following `def`, often used for wrappers | `@macro` | transformation which has Julia expressions (code) as input and output (very powerful) |
| `with` block | context manager, used for opening and teardown of resources | `do` block | content of the block is passed as anonymous function to function before `do` statement |
| `raise Exception` | raising Exceptions | `throw(Exception)` | raising Exceptions |
| `try` - `except` - `finally` | Exception handling, can be used as part of normal program workflow | `try` - `catch` - `finally` | Exception handling, should not be part of normal program workflow due to performance reasons |

---

<div class="post-metadata">

**Author:** ![Zach\_Christensen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zach_christensen/32/7220_2.png) [@Zach\_Christensen](https://discourse.julialang.org/u/Zach_Christensen)\
**Post date:** [March 20, 2020, 9:17am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/16 "2020-03-20T09:17:19Z")

</div>

> def **init** (self, x):

`new` seems to be comparable.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 20, 2020, 10:53am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/17 "2020-03-20T10:53:36Z")

</div>

It would be great if the results of this discussion were used to update

[https://docs.julialang.org/en/latest/manual/noteworthy-differences/#Noteworthy-differences-from-Python-1](https://docs.julialang.org/en/latest/manual/noteworthy-differences/#Noteworthy-differences-from-Python-1)

---

<div class="post-metadata">

**Author:** ![mihalybaci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mihalybaci/32/13528_2.png) [@mihalybaci](https://discourse.julialang.org/u/mihalybaci)\
**Post date:** [March 20, 2020, 12:20pm UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/18 "2020-03-20T12:20:57Z")

</div>

I found [this](https://cheatsheets.quantecon.org/) great comparison of Julia, R, and Python syntax when poking around the Learning section of the JuliaLang homepage.

---

<div class="post-metadata">

**Author:** ![raff](https://avatars.discourse-cdn.com/v4/letter/r/5e9695/32.png) [@raff](https://discourse.julialang.org/u/raff)\
**Post date:** [March 21, 2020, 3:06am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/19 "2020-03-21T03:06:42Z")

</div>

I support the idea.  
Here are some additional differences I could think of.

- Julia requires `end` for indexing until the last element. `x[1:]` in Python is equivalent with `x[2:end]` in Julia.
- Julia’s range indexing has the format of x[start:step:stop], whereas Python’s format is x[start:stop:step]. Hence, `x[0:10:2]` in Python is equivalent to `x[1:2:10]` in Julia. Similarly, `x[::-1]` in Python, which refers to the reversed array, is equivalent to `x[end:-1:1]` in Julia.
- In Julia, indexing a matrix with arrays like `X[[1,2], [1,3]]` refers to a sub-matrix that contains the intersections of the first and second rows with the first and third columns. In Python, `X[[1,2], [1,3]]` refers to a vector that contains the values of cell [1,1] and [2,3] in the matrix. `X[[1,2], [1,3]]` in Julia is equivalent with `X[np.ix_([0,1],[0,2])]` in Python. `X[[0,1], [0,2]]` in Python is equivalent with `X[[CartesianIndex(1,1), CartesianIndex(2,3)]]` in Julia.
- Julia’s `max` and `min` are the equivalent of `np.maximum` and `np.minimum` respectively in Python. While `maximum` and `minimum` replace `np.max` and `np.min` in Python.
- The imaginary unit `sqrt(-1)` is represented in Julia as `im`, not `j` as in Python.
- In Julia, the exponentiation operator is `^`, not `**` as in Python.
- In Julia, we use `nothing` of type `Nothing` to represent null value, whereas Python uses `None` of type `NoneType`.
- In Julia, the standard operators over a matrix type are matrix operations, whereas, in Python, the standard operators are element-wise operations. When both `A` and `B` are matrices, `A * B` in Julia performs matrix multiplication, not element-wise multiplication as in Python. `A * B` in Julia is equivalent with `A @ B` in Python, whereas `A * B` in Python is equivalent with `A .* B` in Julia.
- The transpose operator `'` in Julia returns an adjoint of a vector (a lazy representation of row vector), whereas the transpose operator `.T` over a vector in Python returns the original vector (non-op).

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [March 21, 2020, 5:49am UTC](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953/20 "2020-03-21T05:49:56Z")

</div>

Good idea!  
Let’s continue to collect and then make a PR.  
How should we struture it best? Maybe one table for syntax (e.g. range vs. 1:10), and one for structuring, etc. (like functions, modules)?

[Next page](https://discourse.julialang.org/t/python-porting-to-julia-resources/31953.md?page=2)
