# My mental load using Julia is much higher than, e.g., in Python. How to reduce it?

**URL:** https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902
**Category:** General Usage
**Tags:** question, python, workflow
**Created:** [December 21, 2018, 3:49pm UTC](https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902 "2018-12-21T15:49:44Z")
**Posts on this page:** 1
**Showing post:** 5

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [December 21, 2018, 4:59pm UTC](https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902/5 "2018-12-21T16:59:27Z")

</div>

I think these are all reasonable points, but I hope I can help a little bit.

> [@jules](#):
>
> I made tons of use of extending existing objects, for chains like `line.mirror(along: axis).drawInContext(ctx)` and I thought this would be similarly possible in Julia

I think what you’re talking about is “fluent interfaces”, and it’s true that we don’t really do that in Julia, at least not in the same way. You might find the `|>` operator useful, since you can do:

```julia
x |> f |> g

```

as an alternative notation for `g(f(x))`. This should become even better when we (eventually) get [RFC: curry underscore arguments to create anonymous functions by stevengj · Pull Request #24990 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/24990) which would allow you to write:

```julia
line |> mirror(_, along=axis) |> drawInContext(_, ctx)

```

which is pretty close to the fluent interface but is in some ways even better. Notably, in a fluent interface, there is no way to chain a function that _isn’t_ a method of the returned object. So if `sort()` is a generic function (and not a method of whatever drawInContext returns), then you can’t do:

```julia
line.mirror.drawIncontext(ctx).sort()

```

but in Julia, you certainly can:

```julia
line |> mirror |> x -> drawInContext(x, ctx) |> sort

```

or, in the future:

```julia
line |> mirror |> drawInContext(_, ctx) |> sort

```

This actually gets at something that I definitely struggled with when coming from Python, and which you’ve mentioned as well, which is that it can be hard to figure out what you’re supposed to _do_ with a given object in Julia. It’s true that in Python I would often type `ax.<tab>` to get some sense of what I can do with an object. But there’s a downside of that: the things you see when you do `ax.<tab>` are almost never a good representation of all the things you can do with `ax`, they’re just the methods it happens to define.

For example, given a `list` in python, we can sort it with its `sort` method and reverse it with its `reverse` method. But what if we want to enumerate it? Well, that’s actually `enumerate(x)` instead of `x.enumerate()`, but you’d never find that from `x.<tab>`. And what if we want a reversed copy of the list, instead of doing it in-place? That’s `reversed(x)`, but not `x.reverse()`. In Julia things are more consistent: we have `enumerate(x)` and `sort(x)` and `sort!(x)`. One isn’t somehow more special than the other by virtue of being a method rather than a generic function.

I do agree that `methodswith` is kind of an awkward tool to use–this seems like exactly the kind of thing that better editors and interfaces will help with. We’re not there yet, but I think it can be done.

> [@jules](#):
>
> In many code examples I see that people are pulling tons of functions into the global namespace with `using` , which is comparable to do `from xxx import *` in Python. This is pretty bad practice in my opinion, because reading the code you can often not know where a certain function being called is from, you would have to execute and trace which method was dispatched.

Yeah, I don’t love this. Inside packages I try to have between 0 and 1 plain `using Foo` statements, with all other imports done explicitly as:

```julia
using Foo: bar, baz

```

which makes it easier to see where things come from. However, it’s worth noting that `using` is not _nearly_ as bad as `from Foo import *` would be in Python. `from ... import *` in Python is bad because:

1. It makes it hard to tell where things come from
2. It can _silently replace things_ in your current namespace and break your code in crazy ways. If package Foo has a function called `sin` and you do: `from Foo import *`, you’d better hope you weren’t relying on some other definition of `sin`.

Issue 1 still applies to Julia, but issue 2 does not. Julia won’t let you accidentally blow away things in your current namespace just by `using` some package:

```julia
julia> module Foo
       export sin
       sin(x) = 1
       end
Main.Foo

julia> using .Foo

julia> sin(5)
WARNING: both Foo and Base export "sin"; uses of it in module Main must be qualified
ERROR: UndefVarError: sin not defined

```

for that reason, I think `using` in Julia is perfectly acceptable, but I agree that we should limit our use of it in packages.

---

_[View the full topic](https://discourse.julialang.org/t/my-mental-load-using-julia-is-much-higher-than-e-g-in-python-how-to-reduce-it/18902)._
