# Fixing the Piping/Chaining Issue

**URL:** <https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654>\
**Category:** Internals & Design\
**Tags:** proposal, piping, chaining, partial-evaluation, threading\
**Created:** [November 2, 2022, 11:04am UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654 "2022-11-02T11:04:36Z")\
**Posts on this page:** 1\
**Showing post:** 121

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [November 7, 2022, 6:21pm UTC](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654/121 "2022-11-07T18:21:31Z")

</div>

> [@Sukera](#):
>
> Polemic rhetoric aside, you could also just ask them how they continue to develop one of the big plotting packages in julia, [Makie.jl](https://github.com/MakieOrg/Makie.jl), if the autocomplete is so unbearable 🤷 They’re a main contributor after all and even published [a paper](https://joss.theoj.org/papers/10.21105/joss.03349) about it.

That’s quite impressive. Perhaps they can update their original question with the answer, as I have yet not found it.

> [@Sukera](#):
>
> I can get that to work in `ipython`, mind you, but the exact same also already works in our REPL.

Let’s see if we can do with Julia what we can do with Python…

**Python:**

Let’s define a class:

```python
class Foo:
    x = 1
    def bar(self):
        return self.x

```

Tab-complete shows the property `x` as well as the member method `bar`.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/4/d4b02c6dd3052eb1d69596e8675cfa05682eb088.png)

**Julia:**

The Julian way of writing this is to recognize that `Foo`’s member method `bar` probably generalizes across a range of other `Foo`-like types, so we define an `AbstractFoo` type and specialize our methods on it. (We could specialize to `Foo`, and that would do exactly the same thing as having a class member method, but that’s not as Julian.) First we write `Foo`-specialized methods which directly access its fields, and then write methods of `AbstractFoo` to call them.

```julia
abstract type AbstractFoo end
Base.@kwdef struct Foo <: AbstractFoo
    x = 1
end
getx(foo::Foo) = foo.x
bar(foo::AbstractFoo) = getx(foo)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/6/86bc8ba1f49709373373128a59731c5b913deaf9.png)

Because we have syntax sugar for `getproperty` (namely `.` dot), and because I have typed `Foo()`, it knows to call `propertynames` on this object (or something similar). Because I have typed the object description, and typed a dot, autocomplete has the information it needs to help me discover `x`.

However, it’s not Julian to access the object’s properties directly; the preferred idiom is instead to call methods on it. So let’s find those methods.

Unfortunately, the situation isn’t so good for helping me discover either `bar(::Foo)`, or `getx(::Foo)`:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/f/2fcb4e4fa0377c64c7f311da924a7e6e70e32b1d.png)

What I claim is simple: that one day, autocomplete will recognize that I intend to call a function that specializes on a `Foo`, and it will help me find it. However, because the pipe operator can only call single-argument functions, at the moment such an autocomplete would not be very useful; we need a preferred partial application technique first, so that we can capture the whole range of possible method signatures.

Unless, of course, we should just solve the problem by making every method a dotted member method:

```julia
abstract type AbstractFoo end
Base.@kwdef struct Foo <: AbstractFoo
    x = 1
    bar = function(self) self.x end
end
Base.getproperty(x::AbstractFoo, n::Symbol) = begin
    if getfield(x,n) isa Function
        return (a...;k...)->getfield(x,n)(x,a...;k...)
    end
    getfield(x,n)
end

```

Now we finally get method discoverability in Julia, but it shouldn’t be this hard (or entirely non-Julian) to do.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/e/bea0d1da82c9e776a9a9fb591002e18e6e611c4a.png)

> [@Sukera](#):
>
> What I can’t get to work even in `ipython` is then writing a function:
> 
> ```julia
> def baz(x):
> x.<TAB>
> 
> ```
> 
> and it won’t autocomplete. How could it? It has no idea what type `x` might be. This is the exact problem I’m trying to convey is hard.

That’s not the problem I care about, because I do not care about solving impossible problems. I would have no time left for living life if I did.

> [@dlakelan](#):
>
> The number of functions that take a generic type for a first argument will be very high because of generic duck typing in Julia so it isn’t going to be super helpful. You’ll wind up with 26000 options often enough.

You can consider a “member method” to be simply a function which is specialized to _exactly the concrete type_ of the class. When hoping to tab-complete on member methods, I’m trying to find the most specialized functions! Why should I wish to hit tab to see all the methods which are _not_ specialized to this object, nor to any object like it? I can just start typing random function names anyway.

> [@dlakelan](#):
>
> What it might do is help with top level scripts where global vars are being used.

Recall from inception the purpose of Julia, which is essentially to be a scripting language which compiles: to have the benefits of quick dev time and then quick run time. Scripting languages are quick and easy to develop in, partly because of not needing to assign types to objects, sure ok, but also because if you want to scratchpad something you can just casually start scratchpadding. You can hop into a REPL and experiment, and when you’ve found the appropriate methods, algorithms, and fragments of glue code you can copypaste back into the editor; or you can hit CTRL+ENTER in VSCode, or etc. It’s part of the preferred development style.

For sections of code where arguments are fully generic to `::Any`, and if you’re also not scratchpadding the code and getting global vars from it, I don’t see why anyone would expect autocomplete to help.

---

_[View the full topic](https://discourse.julialang.org/t/fixing-the-piping-chaining-issue/89654)._
