# Which concepts known from Python programming are useful in understanding Julia and which are not?

**URL:** <https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [June 11, 2024, 9:09am UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460 "2024-06-11T09:09:52Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [June 11, 2024, 7:16pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/21 "2024-06-11T19:16:41Z")

</div>

One pattern that gave me some friction when switching was how to handle complicated transformations mapped over a large input. In Python, I might do:

```python
input_list = [i for i in range(100_000)
def foo(x):
    return x/2
def bar(x):
    return x+5
def baz(x):
    return str(x)

output_list = [baz(bar(foo(x))) for x in input_list]

```

Whereas in Julia, I probably want to use broadcasting

```julia
input_list = collect(1:100_000)
output_list = @. baz(bar(foo(input_list)))

```

My Python brain says “Yikes, that’s 3 iterations when I could do it in 1”, but Julia will do loop fusion for me, so I don’t need to worry about it.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [June 11, 2024, 7:40pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/22 "2024-06-11T19:40:06Z")

</div>

> [@mbauman](#):
>
> But perhaps one is in how you structure large Python codebases vs. Julia: each individual `.py` file is _implicitly_ a (sub-)module whereas Julia’s `.jl`s are not.

well, not sure Python is the one being actively harmful here 😓

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [June 11, 2024, 7:41pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/23 "2024-06-11T19:41:31Z")

</div>

> [@mrufsvold](#):
>
> `output_list = @. baz(bar(foo(input_list)))`

This might be prettier?

```julia
output_list = @. input_list |> foo |> bar |> baz

```

(I don’t use that often, but it works, doesn’t it?)

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 11, 2024, 7:45pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/24 "2024-06-11T19:45:40Z")

</div>

I’ve changed my language to be more clearly non-judgmental. The point is that files and modules exist in both languages but behave quite differently in how they’re imported and used. Of course whichever model you prefer will be a preference. The challenge (or “harm”) to learning is simply that they’re different-but-named-the-same.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [June 11, 2024, 7:57pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/25 "2024-06-11T19:57:42Z")

</div>

One difference that can trip up Python users new to Julia is the scoping rules.

In Python, the first `x = 2` in a function defines a new `x` unless explicitly specified `nonlocal`.

```julia
In [4]: def f():
   ...: x = 1
   ...: def g():
   ...: x = 2
   ...: g()
   ...: return x
   ...: 

In [5]: f()
Out[5]: 1

```

In Julia it reuses the one from the enclosing scope:

```julia
julia> function f()
           x = 1
           function g()
               x = 2
           end
           g()
           return x
       end
f (generic function with 1 method)

julia> f()
2

```

In Python there are two different `x`s; in Julia there is only one.

Personally I think this Julia behavior risks accidentally mutating an existing variable so [I’d prefer](https://github.com/JuliaLang/julia/issues/51223) that separate syntax be used for definition `=` and reassignment `:=`, but for now you just have to be careful.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [June 11, 2024, 8:35pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/26 "2024-06-11T20:35:14Z")

</div>

Yeah, absolutely. I love the chain syntax! But I wanted to highlight the differences between broadcasting and list comprehension without adding another syntax 🙂

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 11, 2024, 9:22pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/27 "2024-06-11T21:22:43Z")

</div>

There are for sure concepts that are harmful to the sanity of own thoughts. If I mean 1 to 10 , I mean [1, 2, … , 9, 10] and not [1, 2, … 8, 9]. It is also sure that it is possible to adapt to any pattern keeping clear and sane mind, but some of such patterns are result of author’s confusion, so if you give-in to accept and assimilate them, you assimilate a bit of the confusion along with it. After 30 years of Python I am still forgetting the colon after function or loop definition and feel restricted in design of code text pattern by being forced to use appropriate indentation. Python, which aligned with my mental model much better than anything else 30 years ago does it no more - hence my search for an alternative. I was into Emacs … so learned to write eLisp code … but dropped it because of stubborn stackexchange community and the mess of Emacs core code base. Ruby and Lua are from my current perspective a better choice than Python considering the syntax. Python has much of the batteries included … and LLMs are currently best while writing Python code and fail on other programming languages. What I need a programming language for is to be the one which aligns best with the goal of respecting custom user preferences allowing adaptation to any other way of expressing algorithms and to the own “inner language”. If you like I encourage you to check out what oOo is about … I am as oOosys on github and dev.to - this would help to better understand my motivation and what I am actually after asking questions where the goal is _always_ increasing the level of understanding - anything else is an add-on to it.

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 11, 2024, 9:36pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/28 "2024-06-11T21:36:33Z")

</div>

This seems to go well along with my inner language and thought model … classes and inheritance were from my perspective always more confusing than helpful. The entire OOP concept resulted overall in the mainstream in code polluted with unnecessary encapsulations often also for a single line of code only … making it harder to grasp what the code is about because of the confusion out of which the classes and their hierarchy were designed in first place.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 13, 2024, 8:26pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/29 "2024-06-13T20:26:55Z")

</div>

Split this topic on June 13, 2024, 8:26pm UTC

10 posts were split to a new topic: [Confusion about scope in try-catch blocks](https://discourse.julialang.org/t/confusion-about-scope-in-try-catch-blocks/115622)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 12, 2024, 2:08am UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/32 "2024-06-12T02:08:15Z")

</div>

> [@mbauman](#):
>
> I’m struggling to think of _actively_ ~~harmful~~ confusing concepts in Python — most core concepts are directly transferable.

The performance model in Python (“loops / user code = slow; vectorized / built-in = fast”) can be misleading if you confuse it for a model of how the computer actually works, or if you try to apply it to languages that are more compiler-friendly.

---

<div class="post-metadata">

**Author:** ![Chriz\_Zend](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chriz_zend/32/209871_2.png) [@Chriz\_Zend](https://discourse.julialang.org/u/Chriz_Zend)\
**Post date:** [June 12, 2024, 4:27am UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/33 "2024-06-12T04:27:57Z")

</div>

_dir…_ Thank you. I remember now.

---

<div class="post-metadata">

**Author:** ![Chriz\_Zend](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chriz_zend/32/209871_2.png) [@Chriz\_Zend](https://discourse.julialang.org/u/Chriz_Zend)\
**Post date:** [June 12, 2024, 4:44am UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/34 "2024-06-12T04:44:02Z")

</div>

_methodswith_ is a good start… thank you… 🙂

But one thing I find confusing with Julia is how verbose it is in its answers… If I type _methodswith(DataFrame)_ , I have pages of information in the REPL. It would be nice if it was more concise or if it is allowed me to hit the space bar to go to the next page…

_Edit: apropos is much more concise…_

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [June 13, 2024, 4:18pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/40 "2024-06-13T16:18:36Z")

</div>

> [@Chriz\_Zend](#):
>
> It would be nice if it was more concise or if it is allowed me to hit the space bar to go to the next page

TerminalPager.jl enables spacebar to move pages.

```julia
using DataFrames, TerminalPager
methodswith(DataFrame) |> pager

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 13, 2024, 8:17pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/42 "2024-06-13T20:17:34Z")

</div>

Many highly respected educators focus on mental models. Here’s one great example:

> **[Notes on Teaching Python – Mental Models | Learn Python](https://www.naomiceder.tech/imports/notes-on-teaching-python-mental-models-learn-python/)**
>
> Notes on Teaching Python – Mental Models
> 
> 			
> I admit it – I’m just an old, cranky teacher. As much I love seeing so many people all around me teaching Python, as much as I love the notion of spre

> The question is not if our students will create mental models or not – we all form mental models as we learn. It’s our job as teachers to be thoughtful and help our students form useful and accurate ones.

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 13, 2024, 8:30pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/43 "2024-06-13T20:30:25Z")

</div>

> [@mbauman](#):
>
> [Notes on Teaching Python – Mental Models | Learn Python | Naomi Ceder](https://www.naomiceder.tech/imports/notes-on-teaching-python-mental-models-learn-python/)

Yes … some teachers are possibly aware of it … but are there experts extremely well skilled in programming aware of it too? May experience is that programmer have hard time to be able to grasp how it can be that others don’t share their inner mental model they are not aware of, but wondering about the effects of unable to arrive at some insight where issues others have could origin from …

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 13, 2024, 8:46pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/44 "2024-06-13T20:46:08Z")

</div>

A thought about the default numbering of an array/matrix diagonals:

Chosing the main diagonal as special with the number ZERO appears to me as insane as starting counting items in a container labeling the first index as 0 . If you want all diagonals … one after another … you can’t iterate over collect([1:sum(arr.size())] … you need first to determine if the matrix width is larger than height and then cover both cases differently … this is insane … there are width+height-1 diagonals . From my perspective the only sane approach to iterate over all of them is to start with the first one and go up to width+hight-1 … instead of being forced to cover two cases with separate code. Even if you want get only the upper or the lower ones … you still need to distinguish the cases depending on width \< height to get the range of diagonal k-values right …

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [June 13, 2024, 10:08pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/45 "2024-06-13T22:08:41Z")

</div>

Guess it depends on what you want to do with diagonals. In linear algebra, iterating over all of them is quite rare. Instead, working with the main diagonal or the ones just below or just above is quite natural. In that case, numbering them is as 0, negative (below) and positive (above) is good and in particular, the desired diagonal can be identified by a fixed offset independent of the size of the matrix.

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 13, 2024, 11:06pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/46 "2024-06-13T23:06:38Z")

</div>

> [@bertschi](#):
>
> Guess it depends on what you want to do with diagonals.

Sure the purpose and convenience can lead to making the main diagonal the center of the array/matrix world considering it from the “Earth in the Center of the Universe” point of view. If you are not interested in understanding why the planets make strange moves in the sky this is sure OK. A general purpose method may support an additional option for the convenience purposes making the main (anti-)diagonal the reference point on demand, but forcing everyone to follow the convenience of the majority is putting constrains on the freedom of choice. In my eyes a programming language should support the inner mental model of every possible user and refrain from trying to impose an own one major use based-one needed to be learned and assimilated first before using. If you use a fix offset no matter the array/matrix size you will run into trouble with indexing out of the available range. Just transpose an array and the fixed distance from the main diagonal will cause an error in case of width much greater than hight of an array/matrix, right?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [June 13, 2024, 11:45pm UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/47 "2024-06-13T23:45:46Z")

</div>

IMO, there are 4 reasons why numbering diagonals from corner to corner is crazier:

1. it is never(?) necessary. I don’t think I’ve ever heard of a case where “the third diagonal from the top right corner” has ever been needed for anything in an isolated context. Diagonals only ever matter if they’re relative to _the_ diagonal. This is in direct contradiction to the “earth is the center of the universe” argument you’re making. The main diagonal _is_ the center of the universe when talking about diagonals… Any other paradigm is prone to making “the planets make strange moves in the sky”.
2. It’s the diagonal that includes/starts with the first element. Surely it’s crazier to arbitrarily say the diagonal that includes the top-right element should be the “first one”? You could argue that the main diagonal should have index 1 instead of 0 though, and I could agree with you there tbh. The counterargument is that it makes the upper and lower diagonals inconsistent.
3. Iterating `[diag(A, i) for i in 1:size(A,1)+size(A,2)-1]` (the `1:k` proposal) is no easier or clearer than `[diag(A, i) for i in -(size(A, 1)-1):size(A, 2)-1]` (the current approach). Again, not that this code is frequently written… but if it has been, that’s what it would look like.
4. It even makes sense from the perspective of `diagm(2 => [1, 2, 3])`. Any other scheme of referring to diagonals doesn’t give enough information to actually build the matrix.

---

<div class="post-metadata">

**Author:** ![oOosys](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ooosys/32/209566_2.png) [@oOosys](https://discourse.julialang.org/u/oOosys)\
**Post date:** [June 14, 2024, 1:58am UTC](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460/48 "2024-06-14T01:58:55Z")

</div>

> [@tomerarnon](#):
>
> Iterating `[diag(A, i) for i in 1:size(A,1)+size(A,2)-1]` (the `1:k` proposal) is no easier or clearer than `[diag(A, i) for i in -(size(A, 1)-1):size(A, 2)-1]` (the current approach). Again, not that this code is frequently written… but if it has been, that’s what it would look like.

This does not generally work because you need to replace `size(A, 1)` with `size(A, 1) > size(A, 2) ? size(A, 1) : size(A, 2)` and the other one reference to size(A, 2) accordingly too.

The argument “code is not frequently written” is in my eyes not a valid argument at all, because the entire mainstream can go wrong … so what is today “frequently” can be tomorrow “obsolete” or what is considered “useful” from one perspective can be considered “insane” from another. It is about sanity of mind … and the “Earth in the center of the Universe” is sure a valid approach, but … generally just insane view on the actual reality leading to issues in another contexts than local ones. So argumentation that almost everyone does not leave Earth to the orbit or to the Moon/Planets does not make the Earth centered view on the Universe a sane one.

[Previous page](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460.md?page=1)

[Next page](https://discourse.julialang.org/t/which-concepts-known-from-python-programming-are-useful-in-understanding-julia-and-which-are-not/115460.md?page=3)
